From cfca3781605cb6f40a2cf4da866508edf90f03c6 Mon Sep 17 00:00:00 2001 From: sawinglogz <3787776-sawinglogz@users.noreply.gitlab.com> Date: Mon, 27 Apr 2020 14:12:16 -0400 Subject: [PATCH 01/13] Move pressure chart class into its own files. --- oscar/Graphs/gPressureChart.cpp | 200 ++++++++++++++++++++++++++++ oscar/Graphs/gPressureChart.h | 48 +++++++ oscar/Graphs/gSessionTimesChart.cpp | 197 +-------------------------- oscar/Graphs/gSessionTimesChart.h | 36 +---- oscar/oscar.pro | 2 + oscar/overview.cpp | 4 +- 6 files changed, 256 insertions(+), 231 deletions(-) create mode 100644 oscar/Graphs/gPressureChart.cpp create mode 100644 oscar/Graphs/gPressureChart.h diff --git a/oscar/Graphs/gPressureChart.cpp b/oscar/Graphs/gPressureChart.cpp new file mode 100644 index 00000000..b494a2af --- /dev/null +++ b/oscar/Graphs/gPressureChart.cpp @@ -0,0 +1,200 @@ +/* gPressureChart Implementation + * + * Copyright (c) 2020 The Oscar Team + * Copyright (c) 2011-2018 Mark Watkins <mark@jedimark.net> + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of the source code + * for more details. */ + +#include "gPressureChart.h" + +gPressureChart::gPressureChart() + : gSummaryChart("Pressure", MT_CPAP) +{ + + // Do not reorder these!!! :P + addCalc(CPAP_Pressure, ST_SETMAX, schema::channel[CPAP_Pressure].defaultColor()); // 00 + addCalc(CPAP_Pressure, ST_MID, schema::channel[CPAP_Pressure].defaultColor()); // 01 + addCalc(CPAP_Pressure, ST_90P, brighten(schema::channel[CPAP_Pressure].defaultColor(), 1.33f)); // 02 + addCalc(CPAP_PressureMin, ST_SETMIN, schema::channel[CPAP_PressureMin].defaultColor()); // 03 + addCalc(CPAP_PressureMax, ST_SETMAX, schema::channel[CPAP_PressureMax].defaultColor()); // 04 + + addCalc(CPAP_EPAP, ST_SETMAX, schema::channel[CPAP_EPAP].defaultColor()); // 05 + addCalc(CPAP_IPAP, ST_SETMAX, schema::channel[CPAP_IPAP].defaultColor()); // 06 + addCalc(CPAP_EPAPLo, ST_SETMAX, schema::channel[CPAP_EPAPLo].defaultColor()); // 07 + addCalc(CPAP_IPAPHi, ST_SETMAX, schema::channel[CPAP_IPAPHi].defaultColor()); // 08 + + addCalc(CPAP_EPAP, ST_MID, schema::channel[CPAP_EPAP].defaultColor()); // 09 + addCalc(CPAP_EPAP, ST_90P, brighten(schema::channel[CPAP_EPAP].defaultColor(),1.33f)); // 10 + addCalc(CPAP_IPAP, ST_MID, schema::channel[CPAP_IPAP].defaultColor()); // 11 + addCalc(CPAP_IPAP, ST_90P, brighten(schema::channel[CPAP_IPAP].defaultColor(),1.33f)); // 12 +} + +void gPressureChart::afterDraw(QPainter &, gGraph &graph, QRectF rect) +{ + int pressure_cnt = calcitems[0].cnt; + int pressuremin_cnt = calcitems[3].cnt; + int epap_cnt = calcitems[5].cnt; + int ipap_cnt = calcitems[6].cnt; + int ipaphi_cnt = calcitems[8].cnt; + int epaplo_cnt = calcitems[7].cnt; + + QStringList presstr; + + float mid = 0; + + if (pressure_cnt > 0) { + mid = calcitems[0].mid(); + presstr.append(QString("%1 %2/%3/%4"). + arg(STR_TR_CPAP). + arg(calcitems[0].min,0,'f',1). + arg(mid, 0, 'f', 1). + arg(calcitems[0].max,0,'f',1)); + } + if (pressuremin_cnt > 0) { + presstr.append(QString("%1 %2/%3/%4/%5"). + arg(STR_TR_APAP). + arg(calcitems[3].min,0,'f',1). + arg(calcitems[1].mid(), 0, 'f', 1). + arg(calcitems[2].mid(),0,'f',1). + arg(calcitems[4].max, 0, 'f', 1)); + + } + if (epap_cnt > 0) { + presstr.append(QString("%1 %2/%3/%4"). + arg(STR_TR_EPAP). + arg(calcitems[5].min,0,'f',1). + arg(calcitems[5].mid(), 0, 'f', 1). + arg(calcitems[5].max, 0, 'f', 1)); + } + if (ipap_cnt > 0) { + presstr.append(QString("%1 %2/%3/%4"). + arg(STR_TR_IPAP). + arg(calcitems[6].min,0,'f',1). + arg(calcitems[6].mid(), 0, 'f', 1). + arg(calcitems[6].max, 0, 'f', 1)); + } + if (epaplo_cnt > 0) { + presstr.append(QString("%1 %2/%3/%4"). + arg(STR_TR_EPAPLo). + arg(calcitems[7].min,0,'f',1). + arg(calcitems[7].mid(), 0, 'f', 1). + arg(calcitems[7].max, 0, 'f', 1)); + } + + if (ipaphi_cnt > 0) { + presstr.append(QString("%1 %2/%3/%4"). + arg(STR_TR_IPAPHi). + arg(calcitems[8].min,0,'f',1). + arg(calcitems[8].mid(), 0, 'f', 1). + arg(calcitems[8].max, 0, 'f', 1)); + } + QString txt = presstr.join(" "); + graph.renderText(txt, rect.left(), rect.top()-5*graph.printScaleY(), 0); + +} + + +void gPressureChart::populate(Day * day, int idx) +{ + float tmp; + CPAPMode mode = (CPAPMode)(int)qRound(day->settings_wavg(CPAP_Mode)); + QVector<SummaryChartSlice> & slices = cache[idx]; + + if (mode == MODE_CPAP) { + float pr = day->settings_max(CPAP_Pressure); + slices.append(SummaryChartSlice(&calcitems[0], pr, pr, schema::channel[CPAP_Pressure].label(), calcitems[0].color)); + } else if (mode == MODE_APAP) { + float min = day->settings_min(CPAP_PressureMin); + float max = day->settings_max(CPAP_PressureMax); + + tmp = min; + + slices.append(SummaryChartSlice(&calcitems[3], min, min, schema::channel[CPAP_PressureMin].label(), calcitems[3].color)); + if (!day->summaryOnly()) { + float med = day->calcMiddle(CPAP_Pressure); + slices.append(SummaryChartSlice(&calcitems[1], med, med - tmp, day->calcMiddleLabel(CPAP_Pressure), calcitems[1].color)); + tmp += med - tmp; + + float p90 = day->calcPercentile(CPAP_Pressure); + slices.append(SummaryChartSlice(&calcitems[2], p90, p90 - tmp, day->calcPercentileLabel(CPAP_Pressure), calcitems[2].color)); + tmp += p90 - tmp; + } + slices.append(SummaryChartSlice(&calcitems[4], max, max - tmp, schema::channel[CPAP_PressureMax].label(), calcitems[4].color)); + + } else if (mode == MODE_BILEVEL_FIXED) { + float epap = day->settings_max(CPAP_EPAP); + float ipap = day->settings_max(CPAP_IPAP); + + slices.append(SummaryChartSlice(&calcitems[5], epap, epap, schema::channel[CPAP_EPAP].label(), calcitems[5].color)); + slices.append(SummaryChartSlice(&calcitems[6], ipap, ipap - epap, schema::channel[CPAP_IPAP].label(), calcitems[6].color)); + + } else if (mode == MODE_BILEVEL_AUTO_FIXED_PS) { + float epap = day->settings_max(CPAP_EPAPLo); + tmp = epap; + float ipap = day->settings_max(CPAP_IPAPHi); + + slices.append(SummaryChartSlice(&calcitems[7], epap, epap, schema::channel[CPAP_EPAPLo].label(), calcitems[7].color)); + if (!day->summaryOnly()) { + + float e50 = day->calcMiddle(CPAP_EPAP); + slices.append(SummaryChartSlice(&calcitems[9], e50, e50 - tmp, day->calcMiddleLabel(CPAP_EPAP), calcitems[9].color)); + tmp += e50 - tmp; + + float e90 = day->calcPercentile(CPAP_EPAP); + slices.append(SummaryChartSlice(&calcitems[10], e90, e90 - tmp, day->calcPercentileLabel(CPAP_EPAP), calcitems[10].color)); + tmp += e90 - tmp; + + float i50 = day->calcMiddle(CPAP_IPAP); + slices.append(SummaryChartSlice(&calcitems[11], i50, i50 - tmp, day->calcMiddleLabel(CPAP_IPAP), calcitems[11].color)); + tmp += i50 - tmp; + + float i90 = day->calcPercentile(CPAP_IPAP); + slices.append(SummaryChartSlice(&calcitems[12], i90, i90 - tmp, day->calcPercentileLabel(CPAP_IPAP), calcitems[12].color)); + tmp += i90 - tmp; + } + slices.append(SummaryChartSlice(&calcitems[8], ipap, ipap - tmp, schema::channel[CPAP_IPAPHi].label(), calcitems[8].color)); + } else if ((mode == MODE_BILEVEL_AUTO_VARIABLE_PS) || (mode == MODE_ASV_VARIABLE_EPAP)) { + float epap = day->settings_max(CPAP_EPAPLo); + tmp = epap; + + slices.append(SummaryChartSlice(&calcitems[7], epap, epap, schema::channel[CPAP_EPAPLo].label(), calcitems[7].color)); + if (!day->summaryOnly()) { + float e50 = day->calcMiddle(CPAP_EPAP); + slices.append(SummaryChartSlice(&calcitems[9], e50, e50 - tmp, day->calcMiddleLabel(CPAP_EPAP), calcitems[9].color)); + tmp += e50 - tmp; + + float e90 = day->calcPercentile(CPAP_EPAP); + slices.append(SummaryChartSlice(&calcitems[10], e90, e90 - tmp, day->calcPercentileLabel(CPAP_EPAP), calcitems[10].color)); + tmp += e90 - tmp; + + float i50 = day->calcMiddle(CPAP_IPAP); + slices.append(SummaryChartSlice(&calcitems[11], i50, i50 - tmp, day->calcMiddleLabel(CPAP_IPAP), calcitems[11].color)); + tmp += i50 - tmp; + + float i90 = day->calcPercentile(CPAP_IPAP); + slices.append(SummaryChartSlice(&calcitems[12], i90, i90 - tmp, day->calcPercentileLabel(CPAP_IPAP), calcitems[12].color)); + tmp += i90 - tmp; + } + float ipap = day->settings_max(CPAP_IPAPHi); + slices.append(SummaryChartSlice(&calcitems[8], ipap, ipap - tmp, schema::channel[CPAP_IPAPHi].label(), calcitems[8].color)); + } else if (mode == MODE_ASV) { + float epap = day->settings_max(CPAP_EPAP); + tmp = epap; + + slices.append(SummaryChartSlice(&calcitems[5], epap, epap, schema::channel[CPAP_EPAP].label(), calcitems[5].color)); + if (!day->summaryOnly()) { + float i50 = day->calcMiddle(CPAP_IPAP); + slices.append(SummaryChartSlice(&calcitems[11], i50, i50 - tmp, day->calcMiddleLabel(CPAP_IPAP), calcitems[11].color)); + tmp += i50 - tmp; + + float i90 = day->calcPercentile(CPAP_IPAP); + slices.append(SummaryChartSlice(&calcitems[12], i90, i90 - tmp, day->calcPercentileLabel(CPAP_IPAP), calcitems[12].color)); + tmp += i90 - tmp; + } + float ipap = day->settings_max(CPAP_IPAPHi); + slices.append(SummaryChartSlice(&calcitems[8], ipap, ipap - tmp, schema::channel[CPAP_IPAPHi].label(), calcitems[8].color)); + } + +} diff --git a/oscar/Graphs/gPressureChart.h b/oscar/Graphs/gPressureChart.h new file mode 100644 index 00000000..fbfb9822 --- /dev/null +++ b/oscar/Graphs/gPressureChart.h @@ -0,0 +1,48 @@ +/* gPressureChart Header + * + * Copyright (c) 2020 The Oscar Team + * Copyright (C) 2011-2018 Mark Watkins <mark@jedimark.net> + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of the source code + * for more details. */ + +#ifndef GPRESSURECHART_H +#define GPRESSURECHART_H + +#include "gSessionTimesChart.h" + +class gPressureChart : public gSummaryChart +{ +public: + gPressureChart(); + virtual ~gPressureChart() {} + + virtual Layer * Clone() { + gPressureChart * sc = new gPressureChart(); + gSummaryChart::CloneInto(sc); + return sc; + } + +// virtual void preCalc(); + virtual void customCalc(Day *day, QVector<SummaryChartSlice> &slices) { + int size = slices.size(); + float hour = day->hours(m_machtype); + for (int i=0; i < size; ++i) { + SummaryChartSlice & slice = slices[i]; + SummaryCalcItem * calc = slices[i].calc; + + calc->update(slice.value, hour); + } + } + virtual void afterDraw(QPainter &, gGraph &, QRectF); + + virtual void populate(Day * day, int idx); + + virtual QString tooltipData(Day * day, int idx) { + return day->getCPAPModeStr() + "\n" + day->getPressureSettings() + gSummaryChart::tooltipData(day, idx); + } + +}; + +#endif // GPRESSURECHART_H diff --git a/oscar/Graphs/gSessionTimesChart.cpp b/oscar/Graphs/gSessionTimesChart.cpp index b64373a2..7e380852 100644 --- a/oscar/Graphs/gSessionTimesChart.cpp +++ b/oscar/Graphs/gSessionTimesChart.cpp @@ -1,5 +1,6 @@ /* gSessionTimesChart Implementation * + * Copyright (c) 2020 The Oscar Team * Copyright (c) 2011-2018 Mark Watkins <mark@jedimark.net> * * This file is subject to the terms and conditions of the GNU General Public @@ -1288,199 +1289,3 @@ QString gAHIChart::tooltipData(Day *day, int idx) } return QString("\n%1: %2").arg(STR_TR_AHI).arg(float(total) / hour,0,'f',2)+txt; } - - -gPressureChart::gPressureChart() - :gSummaryChart("Pressure", MT_CPAP) -{ - - // Do not reorder these!!! :P - addCalc(CPAP_Pressure, ST_SETMAX, schema::channel[CPAP_Pressure].defaultColor()); // 00 - addCalc(CPAP_Pressure, ST_MID, schema::channel[CPAP_Pressure].defaultColor()); // 01 - addCalc(CPAP_Pressure, ST_90P, brighten(schema::channel[CPAP_Pressure].defaultColor(), 1.33f)); // 02 - addCalc(CPAP_PressureMin, ST_SETMIN, schema::channel[CPAP_PressureMin].defaultColor()); // 03 - addCalc(CPAP_PressureMax, ST_SETMAX, schema::channel[CPAP_PressureMax].defaultColor()); // 04 - - addCalc(CPAP_EPAP, ST_SETMAX, schema::channel[CPAP_EPAP].defaultColor()); // 05 - addCalc(CPAP_IPAP, ST_SETMAX, schema::channel[CPAP_IPAP].defaultColor()); // 06 - addCalc(CPAP_EPAPLo, ST_SETMAX, schema::channel[CPAP_EPAPLo].defaultColor()); // 07 - addCalc(CPAP_IPAPHi, ST_SETMAX, schema::channel[CPAP_IPAPHi].defaultColor()); // 08 - - addCalc(CPAP_EPAP, ST_MID, schema::channel[CPAP_EPAP].defaultColor()); // 09 - addCalc(CPAP_EPAP, ST_90P, brighten(schema::channel[CPAP_EPAP].defaultColor(),1.33f)); // 10 - addCalc(CPAP_IPAP, ST_MID, schema::channel[CPAP_IPAP].defaultColor()); // 11 - addCalc(CPAP_IPAP, ST_90P, brighten(schema::channel[CPAP_IPAP].defaultColor(),1.33f)); // 12 -} - -void gPressureChart::afterDraw(QPainter &, gGraph &graph, QRectF rect) -{ - int pressure_cnt = calcitems[0].cnt; - int pressuremin_cnt = calcitems[3].cnt; - int epap_cnt = calcitems[5].cnt; - int ipap_cnt = calcitems[6].cnt; - int ipaphi_cnt = calcitems[8].cnt; - int epaplo_cnt = calcitems[7].cnt; - - QStringList presstr; - - float mid = 0; - - if (pressure_cnt > 0) { - mid = calcitems[0].mid(); - presstr.append(QString("%1 %2/%3/%4"). - arg(STR_TR_CPAP). - arg(calcitems[0].min,0,'f',1). - arg(mid, 0, 'f', 1). - arg(calcitems[0].max,0,'f',1)); - } - if (pressuremin_cnt > 0) { - presstr.append(QString("%1 %2/%3/%4/%5"). - arg(STR_TR_APAP). - arg(calcitems[3].min,0,'f',1). - arg(calcitems[1].mid(), 0, 'f', 1). - arg(calcitems[2].mid(),0,'f',1). - arg(calcitems[4].max, 0, 'f', 1)); - - } - if (epap_cnt > 0) { - presstr.append(QString("%1 %2/%3/%4"). - arg(STR_TR_EPAP). - arg(calcitems[5].min,0,'f',1). - arg(calcitems[5].mid(), 0, 'f', 1). - arg(calcitems[5].max, 0, 'f', 1)); - } - if (ipap_cnt > 0) { - presstr.append(QString("%1 %2/%3/%4"). - arg(STR_TR_IPAP). - arg(calcitems[6].min,0,'f',1). - arg(calcitems[6].mid(), 0, 'f', 1). - arg(calcitems[6].max, 0, 'f', 1)); - } - if (epaplo_cnt > 0) { - presstr.append(QString("%1 %2/%3/%4"). - arg(STR_TR_EPAPLo). - arg(calcitems[7].min,0,'f',1). - arg(calcitems[7].mid(), 0, 'f', 1). - arg(calcitems[7].max, 0, 'f', 1)); - } - - if (ipaphi_cnt > 0) { - presstr.append(QString("%1 %2/%3/%4"). - arg(STR_TR_IPAPHi). - arg(calcitems[8].min,0,'f',1). - arg(calcitems[8].mid(), 0, 'f', 1). - arg(calcitems[8].max, 0, 'f', 1)); - } - QString txt = presstr.join(" "); - graph.renderText(txt, rect.left(), rect.top()-5*graph.printScaleY(), 0); - -} - - -void gPressureChart::populate(Day * day, int idx) -{ - float tmp; - CPAPMode mode = (CPAPMode)(int)qRound(day->settings_wavg(CPAP_Mode)); - QVector<SummaryChartSlice> & slices = cache[idx]; - - if (mode == MODE_CPAP) { - float pr = day->settings_max(CPAP_Pressure); - slices.append(SummaryChartSlice(&calcitems[0], pr, pr, schema::channel[CPAP_Pressure].label(), calcitems[0].color)); - } else if (mode == MODE_APAP) { - float min = day->settings_min(CPAP_PressureMin); - float max = day->settings_max(CPAP_PressureMax); - - tmp = min; - - slices.append(SummaryChartSlice(&calcitems[3], min, min, schema::channel[CPAP_PressureMin].label(), calcitems[3].color)); - if (!day->summaryOnly()) { - float med = day->calcMiddle(CPAP_Pressure); - slices.append(SummaryChartSlice(&calcitems[1], med, med - tmp, day->calcMiddleLabel(CPAP_Pressure), calcitems[1].color)); - tmp += med - tmp; - - float p90 = day->calcPercentile(CPAP_Pressure); - slices.append(SummaryChartSlice(&calcitems[2], p90, p90 - tmp, day->calcPercentileLabel(CPAP_Pressure), calcitems[2].color)); - tmp += p90 - tmp; - } - slices.append(SummaryChartSlice(&calcitems[4], max, max - tmp, schema::channel[CPAP_PressureMax].label(), calcitems[4].color)); - - } else if (mode == MODE_BILEVEL_FIXED) { - float epap = day->settings_max(CPAP_EPAP); - float ipap = day->settings_max(CPAP_IPAP); - - slices.append(SummaryChartSlice(&calcitems[5], epap, epap, schema::channel[CPAP_EPAP].label(), calcitems[5].color)); - slices.append(SummaryChartSlice(&calcitems[6], ipap, ipap - epap, schema::channel[CPAP_IPAP].label(), calcitems[6].color)); - - } else if (mode == MODE_BILEVEL_AUTO_FIXED_PS) { - float epap = day->settings_max(CPAP_EPAPLo); - tmp = epap; - float ipap = day->settings_max(CPAP_IPAPHi); - - slices.append(SummaryChartSlice(&calcitems[7], epap, epap, schema::channel[CPAP_EPAPLo].label(), calcitems[7].color)); - if (!day->summaryOnly()) { - - float e50 = day->calcMiddle(CPAP_EPAP); - slices.append(SummaryChartSlice(&calcitems[9], e50, e50 - tmp, day->calcMiddleLabel(CPAP_EPAP), calcitems[9].color)); - tmp += e50 - tmp; - - float e90 = day->calcPercentile(CPAP_EPAP); - slices.append(SummaryChartSlice(&calcitems[10], e90, e90 - tmp, day->calcPercentileLabel(CPAP_EPAP), calcitems[10].color)); - tmp += e90 - tmp; - - float i50 = day->calcMiddle(CPAP_IPAP); - slices.append(SummaryChartSlice(&calcitems[11], i50, i50 - tmp, day->calcMiddleLabel(CPAP_IPAP), calcitems[11].color)); - tmp += i50 - tmp; - - float i90 = day->calcPercentile(CPAP_IPAP); - slices.append(SummaryChartSlice(&calcitems[12], i90, i90 - tmp, day->calcPercentileLabel(CPAP_IPAP), calcitems[12].color)); - tmp += i90 - tmp; - } - slices.append(SummaryChartSlice(&calcitems[8], ipap, ipap - tmp, schema::channel[CPAP_IPAPHi].label(), calcitems[8].color)); - } else if ((mode == MODE_BILEVEL_AUTO_VARIABLE_PS) || (mode == MODE_ASV_VARIABLE_EPAP)) { - float epap = day->settings_max(CPAP_EPAPLo); - tmp = epap; - - slices.append(SummaryChartSlice(&calcitems[7], epap, epap, schema::channel[CPAP_EPAPLo].label(), calcitems[7].color)); - if (!day->summaryOnly()) { - float e50 = day->calcMiddle(CPAP_EPAP); - slices.append(SummaryChartSlice(&calcitems[9], e50, e50 - tmp, day->calcMiddleLabel(CPAP_EPAP), calcitems[9].color)); - tmp += e50 - tmp; - - float e90 = day->calcPercentile(CPAP_EPAP); - slices.append(SummaryChartSlice(&calcitems[10], e90, e90 - tmp, day->calcPercentileLabel(CPAP_EPAP), calcitems[10].color)); - tmp += e90 - tmp; - - float i50 = day->calcMiddle(CPAP_IPAP); - slices.append(SummaryChartSlice(&calcitems[11], i50, i50 - tmp, day->calcMiddleLabel(CPAP_IPAP), calcitems[11].color)); - tmp += i50 - tmp; - - float i90 = day->calcPercentile(CPAP_IPAP); - slices.append(SummaryChartSlice(&calcitems[12], i90, i90 - tmp, day->calcPercentileLabel(CPAP_IPAP), calcitems[12].color)); - tmp += i90 - tmp; - } - float ipap = day->settings_max(CPAP_IPAPHi); - slices.append(SummaryChartSlice(&calcitems[8], ipap, ipap - tmp, schema::channel[CPAP_IPAPHi].label(), calcitems[8].color)); - } else if (mode == MODE_ASV) { - float epap = day->settings_max(CPAP_EPAP); - tmp = epap; - - slices.append(SummaryChartSlice(&calcitems[5], epap, epap, schema::channel[CPAP_EPAP].label(), calcitems[5].color)); - if (!day->summaryOnly()) { - float i50 = day->calcMiddle(CPAP_IPAP); - slices.append(SummaryChartSlice(&calcitems[11], i50, i50 - tmp, day->calcMiddleLabel(CPAP_IPAP), calcitems[11].color)); - tmp += i50 - tmp; - - float i90 = day->calcPercentile(CPAP_IPAP); - slices.append(SummaryChartSlice(&calcitems[12], i90, i90 - tmp, day->calcPercentileLabel(CPAP_IPAP), calcitems[12].color)); - tmp += i90 - tmp; - } - float ipap = day->settings_max(CPAP_IPAPHi); - slices.append(SummaryChartSlice(&calcitems[8], ipap, ipap - tmp, schema::channel[CPAP_IPAPHi].label(), calcitems[8].color)); - } - -} - -//void gPressureChart::afterDraw(QPainter &painter, gGraph &graph, QRect rect) -//{ -//} - diff --git a/oscar/Graphs/gSessionTimesChart.h b/oscar/Graphs/gSessionTimesChart.h index 5e56c0d0..87988313 100644 --- a/oscar/Graphs/gSessionTimesChart.h +++ b/oscar/Graphs/gSessionTimesChart.h @@ -1,5 +1,6 @@ -/* gSessionTimesChart Header +/* gSessionTimesChart Header * + * Copyright (c) 2020 The Oscar Team * Copyright (C) 2011-2018 Mark Watkins <mark@jedimark.net> * * This file is subject to the terms and conditions of the GNU General Public @@ -429,37 +430,4 @@ public: }; -class gPressureChart : public gSummaryChart -{ -public: - gPressureChart(); - virtual ~gPressureChart() {} - - virtual Layer * Clone() { - gPressureChart * sc = new gPressureChart(); - gSummaryChart::CloneInto(sc); - return sc; - } - -// virtual void preCalc(); - virtual void customCalc(Day *day, QVector<SummaryChartSlice> &slices) { - int size = slices.size(); - float hour = day->hours(m_machtype); - for (int i=0; i < size; ++i) { - SummaryChartSlice & slice = slices[i]; - SummaryCalcItem * calc = slices[i].calc; - - calc->update(slice.value, hour); - } - } - virtual void afterDraw(QPainter &, gGraph &, QRectF); - - virtual void populate(Day * day, int idx); - - virtual QString tooltipData(Day * day, int idx) { - return day->getCPAPModeStr() + "\n" + day->getPressureSettings() + gSummaryChart::tooltipData(day, idx); - } - -}; - #endif // GSESSIONTIMESCHART_H diff --git a/oscar/oscar.pro b/oscar/oscar.pro index a021d135..be134f98 100644 --- a/oscar/oscar.pro +++ b/oscar/oscar.pro @@ -305,6 +305,7 @@ SOURCES += \ SleepLib/serialoximeter.cpp \ SleepLib/loader_plugins/md300w1_loader.cpp \ Graphs/gSessionTimesChart.cpp \ + Graphs/gPressureChart.cpp \ logger.cpp \ SleepLib/machine_common.cpp \ SleepLib/loader_plugins/weinmann_loader.cpp \ @@ -383,6 +384,7 @@ HEADERS += \ SleepLib/serialoximeter.h \ SleepLib/loader_plugins/md300w1_loader.h \ Graphs/gSessionTimesChart.h \ + Graphs/gPressureChart.h \ logger.h \ SleepLib/loader_plugins/weinmann_loader.h \ Graphs/gdailysummary.h \ diff --git a/oscar/overview.cpp b/oscar/overview.cpp index 9cc986a0..9dc2d8e9 100644 --- a/oscar/overview.cpp +++ b/oscar/overview.cpp @@ -1,5 +1,6 @@ -/* Overview GUI Implementation +/* Overview GUI Implementation * + * Copyright (c) 2020 The Oscar Team * Copyright (c) 2011-2018 Mark Watkins <mark@jedimark.net> * * This file is subject to the terms and conditions of the GNU General Public @@ -23,6 +24,7 @@ #include "Graphs/gXAxis.h" #include "Graphs/gLineChart.h" #include "Graphs/gYAxis.h" +#include "Graphs/gPressureChart.h" #include "cprogressbar.h" #include "mainwindow.h" From 0ebf4e70a36a374cebab591101cb2176303f4c56 Mon Sep 17 00:00:00 2001 From: sawinglogz <3787776-sawinglogz@users.noreply.gitlab.com> Date: Mon, 27 Apr 2020 14:46:49 -0400 Subject: [PATCH 02/13] Clean up gPressureChart constructor, with minor refactoring. --- oscar/Graphs/gPressureChart.cpp | 35 ++++++++++++++++++----------- oscar/Graphs/gPressureChart.h | 1 + oscar/Graphs/gSessionTimesChart.cpp | 11 +++++++++ oscar/Graphs/gSessionTimesChart.h | 9 ++------ 4 files changed, 36 insertions(+), 20 deletions(-) diff --git a/oscar/Graphs/gPressureChart.cpp b/oscar/Graphs/gPressureChart.cpp index b494a2af..cac04bfa 100644 --- a/oscar/Graphs/gPressureChart.cpp +++ b/oscar/Graphs/gPressureChart.cpp @@ -14,21 +14,30 @@ gPressureChart::gPressureChart() { // Do not reorder these!!! :P - addCalc(CPAP_Pressure, ST_SETMAX, schema::channel[CPAP_Pressure].defaultColor()); // 00 - addCalc(CPAP_Pressure, ST_MID, schema::channel[CPAP_Pressure].defaultColor()); // 01 - addCalc(CPAP_Pressure, ST_90P, brighten(schema::channel[CPAP_Pressure].defaultColor(), 1.33f)); // 02 - addCalc(CPAP_PressureMin, ST_SETMIN, schema::channel[CPAP_PressureMin].defaultColor()); // 03 - addCalc(CPAP_PressureMax, ST_SETMAX, schema::channel[CPAP_PressureMax].defaultColor()); // 04 + addCalc(CPAP_Pressure, ST_SETMAX); // 00 + addCalc(CPAP_Pressure, ST_MID); // 01 + addCalc(CPAP_Pressure, ST_90P); // 02 + addCalc(CPAP_PressureMin, ST_SETMIN); // 03 + addCalc(CPAP_PressureMax, ST_SETMAX); // 04 - addCalc(CPAP_EPAP, ST_SETMAX, schema::channel[CPAP_EPAP].defaultColor()); // 05 - addCalc(CPAP_IPAP, ST_SETMAX, schema::channel[CPAP_IPAP].defaultColor()); // 06 - addCalc(CPAP_EPAPLo, ST_SETMAX, schema::channel[CPAP_EPAPLo].defaultColor()); // 07 - addCalc(CPAP_IPAPHi, ST_SETMAX, schema::channel[CPAP_IPAPHi].defaultColor()); // 08 + addCalc(CPAP_EPAP, ST_SETMAX); // 05 + addCalc(CPAP_IPAP, ST_SETMAX); // 06 + addCalc(CPAP_EPAPLo, ST_SETMAX); // 07 + addCalc(CPAP_IPAPHi, ST_SETMAX); // 08 - addCalc(CPAP_EPAP, ST_MID, schema::channel[CPAP_EPAP].defaultColor()); // 09 - addCalc(CPAP_EPAP, ST_90P, brighten(schema::channel[CPAP_EPAP].defaultColor(),1.33f)); // 10 - addCalc(CPAP_IPAP, ST_MID, schema::channel[CPAP_IPAP].defaultColor()); // 11 - addCalc(CPAP_IPAP, ST_90P, brighten(schema::channel[CPAP_IPAP].defaultColor(),1.33f)); // 12 + addCalc(CPAP_EPAP, ST_MID); // 09 + addCalc(CPAP_EPAP, ST_90P); // 10 + addCalc(CPAP_IPAP, ST_MID); // 11 + addCalc(CPAP_IPAP, ST_90P); // 12 +} + +int gPressureChart::addCalc(ChannelID code, SummaryType type) { + QColor color = schema::channel[code].defaultColor(); + if (type == ST_90P) { + color = brighten(color, 1.33f); + } + int index = gSummaryChart::addCalc(code, type, color); + return index; } void gPressureChart::afterDraw(QPainter &, gGraph &graph, QRectF rect) diff --git a/oscar/Graphs/gPressureChart.h b/oscar/Graphs/gPressureChart.h index fbfb9822..5ecf5364 100644 --- a/oscar/Graphs/gPressureChart.h +++ b/oscar/Graphs/gPressureChart.h @@ -43,6 +43,7 @@ public: return day->getCPAPModeStr() + "\n" + day->getPressureSettings() + gSummaryChart::tooltipData(day, idx); } + virtual int addCalc(ChannelID code, SummaryType type); }; #endif // GPRESSURECHART_H diff --git a/oscar/Graphs/gSessionTimesChart.cpp b/oscar/Graphs/gSessionTimesChart.cpp index 7e380852..29aafb29 100644 --- a/oscar/Graphs/gSessionTimesChart.cpp +++ b/oscar/Graphs/gSessionTimesChart.cpp @@ -102,6 +102,17 @@ void gSummaryChart::SetDay(Day *unused_day) //QMap<QDate, int> gSummaryChart::dayindex; //QList<Day *> gSummaryChart::daylist; +int gSummaryChart::addCalc(ChannelID code, SummaryType type, QColor color) +{ + calcitems.append(SummaryCalcItem(code, type, color)); + return calcitems.size() - 1; // return the index of the newly appended calc +} + +int gSummaryChart::addCalc(ChannelID code, SummaryType type) +{ + return addCalc(code, type, schema::channel[code].defaultColor()); +} + bool gSummaryChart::keyPressEvent(QKeyEvent *event, gGraph *graph) { diff --git a/oscar/Graphs/gSessionTimesChart.h b/oscar/Graphs/gSessionTimesChart.h index 87988313..bdd8bcc8 100644 --- a/oscar/Graphs/gSessionTimesChart.h +++ b/oscar/Graphs/gSessionTimesChart.h @@ -189,13 +189,8 @@ public: cache.clear(); } - - void addCalc(ChannelID code, SummaryType type, QColor color) { - calcitems.append(SummaryCalcItem(code, type, color)); - } - void addCalc(ChannelID code, SummaryType type) { - calcitems.append(SummaryCalcItem(code, type, schema::channel[code].defaultColor())); - } + virtual int addCalc(ChannelID code, SummaryType type, QColor color); + virtual int addCalc(ChannelID code, SummaryType type); virtual Layer * Clone() { gSummaryChart * sc = new gSummaryChart(m_label, m_machtype); From d13109bbeda1b0dbef15227b1999da8ab337d9f7 Mon Sep 17 00:00:00 2001 From: sawinglogz <3787776-sawinglogz@users.noreply.gitlab.com> Date: Mon, 27 Apr 2020 15:28:15 -0400 Subject: [PATCH 03/13] Replace gPressureChart array indices with channel-based references. --- oscar/Graphs/gPressureChart.cpp | 123 ++++++++++++++++---------------- oscar/Graphs/gPressureChart.h | 5 ++ 2 files changed, 67 insertions(+), 61 deletions(-) diff --git a/oscar/Graphs/gPressureChart.cpp b/oscar/Graphs/gPressureChart.cpp index cac04bfa..bcdca7db 100644 --- a/oscar/Graphs/gPressureChart.cpp +++ b/oscar/Graphs/gPressureChart.cpp @@ -12,8 +12,6 @@ gPressureChart::gPressureChart() : gSummaryChart("Pressure", MT_CPAP) { - - // Do not reorder these!!! :P addCalc(CPAP_Pressure, ST_SETMAX); // 00 addCalc(CPAP_Pressure, ST_MID); // 01 addCalc(CPAP_Pressure, ST_90P); // 02 @@ -37,67 +35,68 @@ int gPressureChart::addCalc(ChannelID code, SummaryType type) { color = brighten(color, 1.33f); } int index = gSummaryChart::addCalc(code, type, color); + m_calcs[code][type] = index; return index; } +SummaryCalcItem* gPressureChart::getCalc(ChannelID code, SummaryType type) +{ + return &calcitems[m_calcs[code][type]]; +} + void gPressureChart::afterDraw(QPainter &, gGraph &graph, QRectF rect) { - int pressure_cnt = calcitems[0].cnt; - int pressuremin_cnt = calcitems[3].cnt; - int epap_cnt = calcitems[5].cnt; - int ipap_cnt = calcitems[6].cnt; - int ipaphi_cnt = calcitems[8].cnt; - int epaplo_cnt = calcitems[7].cnt; - QStringList presstr; + SummaryCalcItem* calc; - float mid = 0; - - if (pressure_cnt > 0) { - mid = calcitems[0].mid(); + calc = getCalc(CPAP_Pressure); + if (calc->cnt > 0) { presstr.append(QString("%1 %2/%3/%4"). arg(STR_TR_CPAP). - arg(calcitems[0].min,0,'f',1). - arg(mid, 0, 'f', 1). - arg(calcitems[0].max,0,'f',1)); + arg(calc->min,0,'f',1). + arg(calc->mid(), 0, 'f', 1). + arg(calc->max,0,'f',1)); } - if (pressuremin_cnt > 0) { + if (getCalc(CPAP_PressureMin, ST_SETMIN)->cnt > 0) { presstr.append(QString("%1 %2/%3/%4/%5"). arg(STR_TR_APAP). - arg(calcitems[3].min,0,'f',1). - arg(calcitems[1].mid(), 0, 'f', 1). - arg(calcitems[2].mid(),0,'f',1). - arg(calcitems[4].max, 0, 'f', 1)); + arg(getCalc(CPAP_PressureMin, ST_SETMIN)->min,0,'f',1). + arg(getCalc(CPAP_Pressure, ST_MID)->mid(), 0, 'f', 1). + arg(getCalc(CPAP_Pressure, ST_90P)->mid(),0,'f',1). + arg(getCalc(CPAP_PressureMax, ST_SETMAX)->max, 0, 'f', 1)); } - if (epap_cnt > 0) { + calc = getCalc(CPAP_EPAP); + if (calc->cnt > 0) { presstr.append(QString("%1 %2/%3/%4"). arg(STR_TR_EPAP). - arg(calcitems[5].min,0,'f',1). - arg(calcitems[5].mid(), 0, 'f', 1). - arg(calcitems[5].max, 0, 'f', 1)); + arg(calc->min,0,'f',1). + arg(calc->mid(), 0, 'f', 1). + arg(calc->max, 0, 'f', 1)); } - if (ipap_cnt > 0) { + calc = getCalc(CPAP_IPAP); + if (calc->cnt > 0) { presstr.append(QString("%1 %2/%3/%4"). arg(STR_TR_IPAP). - arg(calcitems[6].min,0,'f',1). - arg(calcitems[6].mid(), 0, 'f', 1). - arg(calcitems[6].max, 0, 'f', 1)); + arg(calc->min,0,'f',1). + arg(calc->mid(), 0, 'f', 1). + arg(calc->max, 0, 'f', 1)); } - if (epaplo_cnt > 0) { + calc = getCalc(CPAP_EPAPLo); + if (calc->cnt > 0) { presstr.append(QString("%1 %2/%3/%4"). arg(STR_TR_EPAPLo). - arg(calcitems[7].min,0,'f',1). - arg(calcitems[7].mid(), 0, 'f', 1). - arg(calcitems[7].max, 0, 'f', 1)); + arg(calc->min,0,'f',1). + arg(calc->mid(), 0, 'f', 1). + arg(calc->max, 0, 'f', 1)); } - - if (ipaphi_cnt > 0) { + calc = getCalc(CPAP_IPAPHi); + if (calc->cnt > 0) { presstr.append(QString("%1 %2/%3/%4"). arg(STR_TR_IPAPHi). - arg(calcitems[8].min,0,'f',1). - arg(calcitems[8].mid(), 0, 'f', 1). - arg(calcitems[8].max, 0, 'f', 1)); + arg(calc->min,0,'f',1). + arg(calc->mid(), 0, 'f', 1). + arg(calc->max, 0, 'f', 1)); } QString txt = presstr.join(" "); graph.renderText(txt, rect.left(), rect.top()-5*graph.printScaleY(), 0); @@ -110,100 +109,102 @@ void gPressureChart::populate(Day * day, int idx) float tmp; CPAPMode mode = (CPAPMode)(int)qRound(day->settings_wavg(CPAP_Mode)); QVector<SummaryChartSlice> & slices = cache[idx]; + SummaryCalcItem* calc; if (mode == MODE_CPAP) { + calc = getCalc(CPAP_Pressure); float pr = day->settings_max(CPAP_Pressure); - slices.append(SummaryChartSlice(&calcitems[0], pr, pr, schema::channel[CPAP_Pressure].label(), calcitems[0].color)); + slices.append(SummaryChartSlice(calc, pr, pr, schema::channel[CPAP_Pressure].label(), calc->color)); } else if (mode == MODE_APAP) { float min = day->settings_min(CPAP_PressureMin); float max = day->settings_max(CPAP_PressureMax); tmp = min; - slices.append(SummaryChartSlice(&calcitems[3], min, min, schema::channel[CPAP_PressureMin].label(), calcitems[3].color)); + slices.append(SummaryChartSlice(getCalc(CPAP_PressureMin, ST_SETMIN), min, min, schema::channel[CPAP_PressureMin].label(), getCalc(CPAP_PressureMin, ST_SETMIN)->color)); if (!day->summaryOnly()) { float med = day->calcMiddle(CPAP_Pressure); - slices.append(SummaryChartSlice(&calcitems[1], med, med - tmp, day->calcMiddleLabel(CPAP_Pressure), calcitems[1].color)); + slices.append(SummaryChartSlice(getCalc(CPAP_Pressure, ST_MID), med, med - tmp, day->calcMiddleLabel(CPAP_Pressure), getCalc(CPAP_Pressure, ST_MID)->color)); tmp += med - tmp; float p90 = day->calcPercentile(CPAP_Pressure); - slices.append(SummaryChartSlice(&calcitems[2], p90, p90 - tmp, day->calcPercentileLabel(CPAP_Pressure), calcitems[2].color)); + slices.append(SummaryChartSlice(getCalc(CPAP_Pressure, ST_90P), p90, p90 - tmp, day->calcPercentileLabel(CPAP_Pressure), getCalc(CPAP_Pressure, ST_90P)->color)); tmp += p90 - tmp; } - slices.append(SummaryChartSlice(&calcitems[4], max, max - tmp, schema::channel[CPAP_PressureMax].label(), calcitems[4].color)); + slices.append(SummaryChartSlice(getCalc(CPAP_PressureMax, ST_SETMAX), max, max - tmp, schema::channel[CPAP_PressureMax].label(), getCalc(CPAP_PressureMax, ST_SETMAX)->color)); } else if (mode == MODE_BILEVEL_FIXED) { float epap = day->settings_max(CPAP_EPAP); float ipap = day->settings_max(CPAP_IPAP); - slices.append(SummaryChartSlice(&calcitems[5], epap, epap, schema::channel[CPAP_EPAP].label(), calcitems[5].color)); - slices.append(SummaryChartSlice(&calcitems[6], ipap, ipap - epap, schema::channel[CPAP_IPAP].label(), calcitems[6].color)); + slices.append(SummaryChartSlice(getCalc(CPAP_EPAP), epap, epap, schema::channel[CPAP_EPAP].label(), getCalc(CPAP_EPAP)->color)); + slices.append(SummaryChartSlice(getCalc(CPAP_IPAP), ipap, ipap - epap, schema::channel[CPAP_IPAP].label(), getCalc(CPAP_IPAP)->color)); } else if (mode == MODE_BILEVEL_AUTO_FIXED_PS) { float epap = day->settings_max(CPAP_EPAPLo); tmp = epap; float ipap = day->settings_max(CPAP_IPAPHi); - slices.append(SummaryChartSlice(&calcitems[7], epap, epap, schema::channel[CPAP_EPAPLo].label(), calcitems[7].color)); + slices.append(SummaryChartSlice(getCalc(CPAP_EPAPLo), epap, epap, schema::channel[CPAP_EPAPLo].label(), getCalc(CPAP_EPAPLo)->color)); if (!day->summaryOnly()) { float e50 = day->calcMiddle(CPAP_EPAP); - slices.append(SummaryChartSlice(&calcitems[9], e50, e50 - tmp, day->calcMiddleLabel(CPAP_EPAP), calcitems[9].color)); + slices.append(SummaryChartSlice(getCalc(CPAP_EPAP, ST_MID), e50, e50 - tmp, day->calcMiddleLabel(CPAP_EPAP), getCalc(CPAP_EPAP, ST_MID)->color)); tmp += e50 - tmp; float e90 = day->calcPercentile(CPAP_EPAP); - slices.append(SummaryChartSlice(&calcitems[10], e90, e90 - tmp, day->calcPercentileLabel(CPAP_EPAP), calcitems[10].color)); + slices.append(SummaryChartSlice(getCalc(CPAP_EPAP, ST_90P), e90, e90 - tmp, day->calcPercentileLabel(CPAP_EPAP), getCalc(CPAP_EPAP, ST_90P)->color)); tmp += e90 - tmp; float i50 = day->calcMiddle(CPAP_IPAP); - slices.append(SummaryChartSlice(&calcitems[11], i50, i50 - tmp, day->calcMiddleLabel(CPAP_IPAP), calcitems[11].color)); + slices.append(SummaryChartSlice(getCalc(CPAP_IPAP, ST_MID), i50, i50 - tmp, day->calcMiddleLabel(CPAP_IPAP), getCalc(CPAP_IPAP, ST_MID)->color)); tmp += i50 - tmp; float i90 = day->calcPercentile(CPAP_IPAP); - slices.append(SummaryChartSlice(&calcitems[12], i90, i90 - tmp, day->calcPercentileLabel(CPAP_IPAP), calcitems[12].color)); + slices.append(SummaryChartSlice(getCalc(CPAP_IPAP, ST_90P), i90, i90 - tmp, day->calcPercentileLabel(CPAP_IPAP), getCalc(CPAP_IPAP, ST_90P)->color)); tmp += i90 - tmp; } - slices.append(SummaryChartSlice(&calcitems[8], ipap, ipap - tmp, schema::channel[CPAP_IPAPHi].label(), calcitems[8].color)); + slices.append(SummaryChartSlice(getCalc(CPAP_IPAPHi), ipap, ipap - tmp, schema::channel[CPAP_IPAPHi].label(), getCalc(CPAP_IPAPHi)->color)); } else if ((mode == MODE_BILEVEL_AUTO_VARIABLE_PS) || (mode == MODE_ASV_VARIABLE_EPAP)) { float epap = day->settings_max(CPAP_EPAPLo); tmp = epap; - slices.append(SummaryChartSlice(&calcitems[7], epap, epap, schema::channel[CPAP_EPAPLo].label(), calcitems[7].color)); + slices.append(SummaryChartSlice(getCalc(CPAP_EPAPLo), epap, epap, schema::channel[CPAP_EPAPLo].label(), getCalc(CPAP_EPAPLo)->color)); if (!day->summaryOnly()) { float e50 = day->calcMiddle(CPAP_EPAP); - slices.append(SummaryChartSlice(&calcitems[9], e50, e50 - tmp, day->calcMiddleLabel(CPAP_EPAP), calcitems[9].color)); + slices.append(SummaryChartSlice(getCalc(CPAP_EPAP, ST_MID), e50, e50 - tmp, day->calcMiddleLabel(CPAP_EPAP), getCalc(CPAP_EPAP, ST_MID)->color)); tmp += e50 - tmp; float e90 = day->calcPercentile(CPAP_EPAP); - slices.append(SummaryChartSlice(&calcitems[10], e90, e90 - tmp, day->calcPercentileLabel(CPAP_EPAP), calcitems[10].color)); + slices.append(SummaryChartSlice(getCalc(CPAP_EPAP, ST_90P), e90, e90 - tmp, day->calcPercentileLabel(CPAP_EPAP), getCalc(CPAP_EPAP, ST_90P)->color)); tmp += e90 - tmp; float i50 = day->calcMiddle(CPAP_IPAP); - slices.append(SummaryChartSlice(&calcitems[11], i50, i50 - tmp, day->calcMiddleLabel(CPAP_IPAP), calcitems[11].color)); + slices.append(SummaryChartSlice(getCalc(CPAP_IPAP, ST_MID), i50, i50 - tmp, day->calcMiddleLabel(CPAP_IPAP), getCalc(CPAP_IPAP, ST_MID)->color)); tmp += i50 - tmp; float i90 = day->calcPercentile(CPAP_IPAP); - slices.append(SummaryChartSlice(&calcitems[12], i90, i90 - tmp, day->calcPercentileLabel(CPAP_IPAP), calcitems[12].color)); + slices.append(SummaryChartSlice(getCalc(CPAP_IPAP, ST_90P), i90, i90 - tmp, day->calcPercentileLabel(CPAP_IPAP), getCalc(CPAP_IPAP, ST_90P)->color)); tmp += i90 - tmp; } float ipap = day->settings_max(CPAP_IPAPHi); - slices.append(SummaryChartSlice(&calcitems[8], ipap, ipap - tmp, schema::channel[CPAP_IPAPHi].label(), calcitems[8].color)); + slices.append(SummaryChartSlice(getCalc(CPAP_IPAPHi), ipap, ipap - tmp, schema::channel[CPAP_IPAPHi].label(), getCalc(CPAP_IPAPHi)->color)); } else if (mode == MODE_ASV) { float epap = day->settings_max(CPAP_EPAP); tmp = epap; - slices.append(SummaryChartSlice(&calcitems[5], epap, epap, schema::channel[CPAP_EPAP].label(), calcitems[5].color)); + slices.append(SummaryChartSlice(getCalc(CPAP_EPAP), epap, epap, schema::channel[CPAP_EPAP].label(), getCalc(CPAP_EPAP)->color)); if (!day->summaryOnly()) { float i50 = day->calcMiddle(CPAP_IPAP); - slices.append(SummaryChartSlice(&calcitems[11], i50, i50 - tmp, day->calcMiddleLabel(CPAP_IPAP), calcitems[11].color)); + slices.append(SummaryChartSlice(getCalc(CPAP_IPAP, ST_MID), i50, i50 - tmp, day->calcMiddleLabel(CPAP_IPAP), getCalc(CPAP_IPAP, ST_MID)->color)); tmp += i50 - tmp; float i90 = day->calcPercentile(CPAP_IPAP); - slices.append(SummaryChartSlice(&calcitems[12], i90, i90 - tmp, day->calcPercentileLabel(CPAP_IPAP), calcitems[12].color)); + slices.append(SummaryChartSlice(getCalc(CPAP_IPAP, ST_90P), i90, i90 - tmp, day->calcPercentileLabel(CPAP_IPAP), getCalc(CPAP_IPAP, ST_90P)->color)); tmp += i90 - tmp; } float ipap = day->settings_max(CPAP_IPAPHi); - slices.append(SummaryChartSlice(&calcitems[8], ipap, ipap - tmp, schema::channel[CPAP_IPAPHi].label(), calcitems[8].color)); + slices.append(SummaryChartSlice(getCalc(CPAP_IPAPHi), ipap, ipap - tmp, schema::channel[CPAP_IPAPHi].label(), getCalc(CPAP_IPAPHi)->color)); } } diff --git a/oscar/Graphs/gPressureChart.h b/oscar/Graphs/gPressureChart.h index 5ecf5364..eff94267 100644 --- a/oscar/Graphs/gPressureChart.h +++ b/oscar/Graphs/gPressureChart.h @@ -44,6 +44,11 @@ public: } virtual int addCalc(ChannelID code, SummaryType type); + +protected: + SummaryCalcItem* getCalc(ChannelID code, SummaryType type = ST_SETMAX); + + QHash<ChannelID,QHash<SummaryType,int>> m_calcs; }; #endif // GPRESSURECHART_H From c5768a64fe9a0e1d0750c4a64f11550a829d0bf8 Mon Sep 17 00:00:00 2001 From: sawinglogz <3787776-sawinglogz@users.noreply.gitlab.com> Date: Mon, 27 Apr 2020 16:06:08 -0400 Subject: [PATCH 04/13] Simplify gPressureChart upper label formatting. --- oscar/Graphs/gPressureChart.cpp | 94 +++++++++++++++------------------ oscar/Graphs/gPressureChart.h | 1 + 2 files changed, 45 insertions(+), 50 deletions(-) diff --git a/oscar/Graphs/gPressureChart.cpp b/oscar/Graphs/gPressureChart.cpp index bcdca7db..fee63208 100644 --- a/oscar/Graphs/gPressureChart.cpp +++ b/oscar/Graphs/gPressureChart.cpp @@ -12,50 +12,53 @@ gPressureChart::gPressureChart() : gSummaryChart("Pressure", MT_CPAP) { - addCalc(CPAP_Pressure, ST_SETMAX); // 00 - addCalc(CPAP_Pressure, ST_MID); // 01 - addCalc(CPAP_Pressure, ST_90P); // 02 - addCalc(CPAP_PressureMin, ST_SETMIN); // 03 - addCalc(CPAP_PressureMax, ST_SETMAX); // 04 + addCalc(CPAP_Pressure, ST_SETMAX); + addCalc(CPAP_Pressure, ST_MID); + addCalc(CPAP_Pressure, ST_90P); + addCalc(CPAP_PressureMin, ST_SETMIN); + addCalc(CPAP_PressureMax, ST_SETMAX); - addCalc(CPAP_EPAP, ST_SETMAX); // 05 - addCalc(CPAP_IPAP, ST_SETMAX); // 06 - addCalc(CPAP_EPAPLo, ST_SETMAX); // 07 - addCalc(CPAP_IPAPHi, ST_SETMAX); // 08 + addCalc(CPAP_EPAP, ST_SETMAX); + addCalc(CPAP_IPAP, ST_SETMAX); + addCalc(CPAP_EPAPLo, ST_SETMAX); + addCalc(CPAP_IPAPHi, ST_SETMAX); - addCalc(CPAP_EPAP, ST_MID); // 09 - addCalc(CPAP_EPAP, ST_90P); // 10 - addCalc(CPAP_IPAP, ST_MID); // 11 - addCalc(CPAP_IPAP, ST_90P); // 12 + addCalc(CPAP_EPAP, ST_MID); + addCalc(CPAP_EPAP, ST_90P); + addCalc(CPAP_IPAP, ST_MID); + addCalc(CPAP_IPAP, ST_90P); } -int gPressureChart::addCalc(ChannelID code, SummaryType type) { + +int gPressureChart::addCalc(ChannelID code, SummaryType type) +{ QColor color = schema::channel[code].defaultColor(); if (type == ST_90P) { color = brighten(color, 1.33f); } + int index = gSummaryChart::addCalc(code, type, color); + + // Save the code and type used to add this calculation so that getCalc() + // can retrieve it by code and type instead of by hard-coded index. m_calcs[code][type] = index; + return index; } + SummaryCalcItem* gPressureChart::getCalc(ChannelID code, SummaryType type) { return &calcitems[m_calcs[code][type]]; } + void gPressureChart::afterDraw(QPainter &, gGraph &graph, QRectF rect) { QStringList presstr; - SummaryCalcItem* calc; - calc = getCalc(CPAP_Pressure); - if (calc->cnt > 0) { - presstr.append(QString("%1 %2/%3/%4"). - arg(STR_TR_CPAP). - arg(calc->min,0,'f',1). - arg(calc->mid(), 0, 'f', 1). - arg(calc->max,0,'f',1)); + if (getCalc(CPAP_Pressure)->cnt > 0) { + presstr.append(channelRange(CPAP_Pressure, STR_TR_CPAP)); } if (getCalc(CPAP_PressureMin, ST_SETMIN)->cnt > 0) { presstr.append(QString("%1 %2/%3/%4/%5"). @@ -66,37 +69,17 @@ void gPressureChart::afterDraw(QPainter &, gGraph &graph, QRectF rect) arg(getCalc(CPAP_PressureMax, ST_SETMAX)->max, 0, 'f', 1)); } - calc = getCalc(CPAP_EPAP); - if (calc->cnt > 0) { - presstr.append(QString("%1 %2/%3/%4"). - arg(STR_TR_EPAP). - arg(calc->min,0,'f',1). - arg(calc->mid(), 0, 'f', 1). - arg(calc->max, 0, 'f', 1)); + if (getCalc(CPAP_EPAP)->cnt > 0) { + presstr.append(channelRange(CPAP_EPAP, STR_TR_EPAP)); } - calc = getCalc(CPAP_IPAP); - if (calc->cnt > 0) { - presstr.append(QString("%1 %2/%3/%4"). - arg(STR_TR_IPAP). - arg(calc->min,0,'f',1). - arg(calc->mid(), 0, 'f', 1). - arg(calc->max, 0, 'f', 1)); + if (getCalc(CPAP_IPAP)->cnt > 0) { + presstr.append(channelRange(CPAP_IPAP, STR_TR_IPAP)); } - calc = getCalc(CPAP_EPAPLo); - if (calc->cnt > 0) { - presstr.append(QString("%1 %2/%3/%4"). - arg(STR_TR_EPAPLo). - arg(calc->min,0,'f',1). - arg(calc->mid(), 0, 'f', 1). - arg(calc->max, 0, 'f', 1)); + if (getCalc(CPAP_EPAPLo)->cnt > 0) { + presstr.append(channelRange(CPAP_EPAPLo, STR_TR_EPAPLo)); } - calc = getCalc(CPAP_IPAPHi); - if (calc->cnt > 0) { - presstr.append(QString("%1 %2/%3/%4"). - arg(STR_TR_IPAPHi). - arg(calc->min,0,'f',1). - arg(calc->mid(), 0, 'f', 1). - arg(calc->max, 0, 'f', 1)); + if (getCalc(CPAP_IPAPHi)->cnt > 0) { + presstr.append(channelRange(CPAP_IPAPHi, STR_TR_IPAPHi)); } QString txt = presstr.join(" "); graph.renderText(txt, rect.left(), rect.top()-5*graph.printScaleY(), 0); @@ -104,6 +87,17 @@ void gPressureChart::afterDraw(QPainter &, gGraph &graph, QRectF rect) } +QString gPressureChart::channelRange(ChannelID code, const QString & label) +{ + SummaryCalcItem* calc = getCalc(code); + return QString("%1 %2/%3/%4"). + arg(label). + arg(calc->min, 0, 'f', 1). + arg(calc->mid(), 0, 'f', 1). + arg(calc->max, 0, 'f', 1); +} + + void gPressureChart::populate(Day * day, int idx) { float tmp; diff --git a/oscar/Graphs/gPressureChart.h b/oscar/Graphs/gPressureChart.h index eff94267..46e1a76b 100644 --- a/oscar/Graphs/gPressureChart.h +++ b/oscar/Graphs/gPressureChart.h @@ -47,6 +47,7 @@ public: protected: SummaryCalcItem* getCalc(ChannelID code, SummaryType type = ST_SETMAX); + QString channelRange(ChannelID code, const QString & label); QHash<ChannelID,QHash<SummaryType,int>> m_calcs; }; From 33eacab53f0d4f84c77fec52152bdc777ef23d09 Mon Sep 17 00:00:00 2001 From: sawinglogz <3787776-sawinglogz@users.noreply.gitlab.com> Date: Mon, 27 Apr 2020 16:46:25 -0400 Subject: [PATCH 05/13] Refactor gPressureChart::populate(). --- oscar/Graphs/gPressureChart.cpp | 98 ++++++++++++++++++--------------- oscar/Graphs/gPressureChart.h | 6 ++ 2 files changed, 59 insertions(+), 45 deletions(-) diff --git a/oscar/Graphs/gPressureChart.cpp b/oscar/Graphs/gPressureChart.cpp index fee63208..85da32be 100644 --- a/oscar/Graphs/gPressureChart.cpp +++ b/oscar/Graphs/gPressureChart.cpp @@ -98,107 +98,115 @@ QString gPressureChart::channelRange(ChannelID code, const QString & label) } +void gPressureChart::addSlice(float value, ChannelID code, SummaryType type) +{ + SummaryCalcItem* calc = getCalc(code, type); + float height = value - m_height; + QString label; + + switch (type) { + case ST_SETMIN: + case ST_SETMAX: + label = schema::channel[code].label(); + break; + case ST_MID: + label = m_day->calcMiddleLabel(code); + break; + case ST_90P: + label = m_day->calcPercentileLabel(code); + break; + default: + qWarning() << "Unsupported summary type in gPressureChart"; + break; + } + + m_slices->append(SummaryChartSlice(calc, value, height, label, calc->color)); + m_height += height; +} + + void gPressureChart::populate(Day * day, int idx) { - float tmp; CPAPMode mode = (CPAPMode)(int)qRound(day->settings_wavg(CPAP_Mode)); - QVector<SummaryChartSlice> & slices = cache[idx]; - SummaryCalcItem* calc; + m_day = day; + m_slices = &cache[idx]; + m_height = 0; if (mode == MODE_CPAP) { - calc = getCalc(CPAP_Pressure); float pr = day->settings_max(CPAP_Pressure); - slices.append(SummaryChartSlice(calc, pr, pr, schema::channel[CPAP_Pressure].label(), calc->color)); + addSlice(pr, CPAP_Pressure); } else if (mode == MODE_APAP) { float min = day->settings_min(CPAP_PressureMin); float max = day->settings_max(CPAP_PressureMax); - tmp = min; - - slices.append(SummaryChartSlice(getCalc(CPAP_PressureMin, ST_SETMIN), min, min, schema::channel[CPAP_PressureMin].label(), getCalc(CPAP_PressureMin, ST_SETMIN)->color)); + addSlice(min, CPAP_PressureMin, ST_SETMIN); if (!day->summaryOnly()) { float med = day->calcMiddle(CPAP_Pressure); - slices.append(SummaryChartSlice(getCalc(CPAP_Pressure, ST_MID), med, med - tmp, day->calcMiddleLabel(CPAP_Pressure), getCalc(CPAP_Pressure, ST_MID)->color)); - tmp += med - tmp; + addSlice(med, CPAP_Pressure, ST_MID); float p90 = day->calcPercentile(CPAP_Pressure); - slices.append(SummaryChartSlice(getCalc(CPAP_Pressure, ST_90P), p90, p90 - tmp, day->calcPercentileLabel(CPAP_Pressure), getCalc(CPAP_Pressure, ST_90P)->color)); - tmp += p90 - tmp; + addSlice(p90, CPAP_Pressure, ST_90P); } - slices.append(SummaryChartSlice(getCalc(CPAP_PressureMax, ST_SETMAX), max, max - tmp, schema::channel[CPAP_PressureMax].label(), getCalc(CPAP_PressureMax, ST_SETMAX)->color)); + addSlice(max, CPAP_PressureMax, ST_SETMAX); } else if (mode == MODE_BILEVEL_FIXED) { float epap = day->settings_max(CPAP_EPAP); float ipap = day->settings_max(CPAP_IPAP); - slices.append(SummaryChartSlice(getCalc(CPAP_EPAP), epap, epap, schema::channel[CPAP_EPAP].label(), getCalc(CPAP_EPAP)->color)); - slices.append(SummaryChartSlice(getCalc(CPAP_IPAP), ipap, ipap - epap, schema::channel[CPAP_IPAP].label(), getCalc(CPAP_IPAP)->color)); + addSlice(epap, CPAP_EPAP); + addSlice(ipap, CPAP_IPAP); } else if (mode == MODE_BILEVEL_AUTO_FIXED_PS) { float epap = day->settings_max(CPAP_EPAPLo); - tmp = epap; float ipap = day->settings_max(CPAP_IPAPHi); - slices.append(SummaryChartSlice(getCalc(CPAP_EPAPLo), epap, epap, schema::channel[CPAP_EPAPLo].label(), getCalc(CPAP_EPAPLo)->color)); + addSlice(epap, CPAP_EPAPLo); if (!day->summaryOnly()) { float e50 = day->calcMiddle(CPAP_EPAP); - slices.append(SummaryChartSlice(getCalc(CPAP_EPAP, ST_MID), e50, e50 - tmp, day->calcMiddleLabel(CPAP_EPAP), getCalc(CPAP_EPAP, ST_MID)->color)); - tmp += e50 - tmp; + addSlice(e50, CPAP_EPAP, ST_MID); float e90 = day->calcPercentile(CPAP_EPAP); - slices.append(SummaryChartSlice(getCalc(CPAP_EPAP, ST_90P), e90, e90 - tmp, day->calcPercentileLabel(CPAP_EPAP), getCalc(CPAP_EPAP, ST_90P)->color)); - tmp += e90 - tmp; + addSlice(e90, CPAP_EPAP, ST_90P); float i50 = day->calcMiddle(CPAP_IPAP); - slices.append(SummaryChartSlice(getCalc(CPAP_IPAP, ST_MID), i50, i50 - tmp, day->calcMiddleLabel(CPAP_IPAP), getCalc(CPAP_IPAP, ST_MID)->color)); - tmp += i50 - tmp; + addSlice(i50, CPAP_IPAP, ST_MID); float i90 = day->calcPercentile(CPAP_IPAP); - slices.append(SummaryChartSlice(getCalc(CPAP_IPAP, ST_90P), i90, i90 - tmp, day->calcPercentileLabel(CPAP_IPAP), getCalc(CPAP_IPAP, ST_90P)->color)); - tmp += i90 - tmp; + addSlice(i90, CPAP_IPAP, ST_90P); } - slices.append(SummaryChartSlice(getCalc(CPAP_IPAPHi), ipap, ipap - tmp, schema::channel[CPAP_IPAPHi].label(), getCalc(CPAP_IPAPHi)->color)); + addSlice(ipap, CPAP_IPAPHi); } else if ((mode == MODE_BILEVEL_AUTO_VARIABLE_PS) || (mode == MODE_ASV_VARIABLE_EPAP)) { float epap = day->settings_max(CPAP_EPAPLo); - tmp = epap; - slices.append(SummaryChartSlice(getCalc(CPAP_EPAPLo), epap, epap, schema::channel[CPAP_EPAPLo].label(), getCalc(CPAP_EPAPLo)->color)); + addSlice(epap, CPAP_EPAPLo); if (!day->summaryOnly()) { float e50 = day->calcMiddle(CPAP_EPAP); - slices.append(SummaryChartSlice(getCalc(CPAP_EPAP, ST_MID), e50, e50 - tmp, day->calcMiddleLabel(CPAP_EPAP), getCalc(CPAP_EPAP, ST_MID)->color)); - tmp += e50 - tmp; + addSlice(e50, CPAP_EPAP, ST_MID); float e90 = day->calcPercentile(CPAP_EPAP); - slices.append(SummaryChartSlice(getCalc(CPAP_EPAP, ST_90P), e90, e90 - tmp, day->calcPercentileLabel(CPAP_EPAP), getCalc(CPAP_EPAP, ST_90P)->color)); - tmp += e90 - tmp; + addSlice(e90, CPAP_EPAP, ST_90P); float i50 = day->calcMiddle(CPAP_IPAP); - slices.append(SummaryChartSlice(getCalc(CPAP_IPAP, ST_MID), i50, i50 - tmp, day->calcMiddleLabel(CPAP_IPAP), getCalc(CPAP_IPAP, ST_MID)->color)); - tmp += i50 - tmp; + addSlice(i50, CPAP_IPAP, ST_MID); float i90 = day->calcPercentile(CPAP_IPAP); - slices.append(SummaryChartSlice(getCalc(CPAP_IPAP, ST_90P), i90, i90 - tmp, day->calcPercentileLabel(CPAP_IPAP), getCalc(CPAP_IPAP, ST_90P)->color)); - tmp += i90 - tmp; + addSlice(i90, CPAP_IPAP, ST_90P); } float ipap = day->settings_max(CPAP_IPAPHi); - slices.append(SummaryChartSlice(getCalc(CPAP_IPAPHi), ipap, ipap - tmp, schema::channel[CPAP_IPAPHi].label(), getCalc(CPAP_IPAPHi)->color)); + addSlice(ipap, CPAP_IPAPHi); } else if (mode == MODE_ASV) { float epap = day->settings_max(CPAP_EPAP); - tmp = epap; - slices.append(SummaryChartSlice(getCalc(CPAP_EPAP), epap, epap, schema::channel[CPAP_EPAP].label(), getCalc(CPAP_EPAP)->color)); + addSlice(epap, CPAP_EPAP); if (!day->summaryOnly()) { float i50 = day->calcMiddle(CPAP_IPAP); - slices.append(SummaryChartSlice(getCalc(CPAP_IPAP, ST_MID), i50, i50 - tmp, day->calcMiddleLabel(CPAP_IPAP), getCalc(CPAP_IPAP, ST_MID)->color)); - tmp += i50 - tmp; + addSlice(i50, CPAP_IPAP, ST_MID); float i90 = day->calcPercentile(CPAP_IPAP); - slices.append(SummaryChartSlice(getCalc(CPAP_IPAP, ST_90P), i90, i90 - tmp, day->calcPercentileLabel(CPAP_IPAP), getCalc(CPAP_IPAP, ST_90P)->color)); - tmp += i90 - tmp; + addSlice(i90, CPAP_IPAP, ST_90P); } float ipap = day->settings_max(CPAP_IPAPHi); - slices.append(SummaryChartSlice(getCalc(CPAP_IPAPHi), ipap, ipap - tmp, schema::channel[CPAP_IPAPHi].label(), getCalc(CPAP_IPAPHi)->color)); + addSlice(ipap, CPAP_IPAPHi); } - } diff --git a/oscar/Graphs/gPressureChart.h b/oscar/Graphs/gPressureChart.h index 46e1a76b..692b11ad 100644 --- a/oscar/Graphs/gPressureChart.h +++ b/oscar/Graphs/gPressureChart.h @@ -48,8 +48,14 @@ public: protected: SummaryCalcItem* getCalc(ChannelID code, SummaryType type = ST_SETMAX); QString channelRange(ChannelID code, const QString & label); + void addSlice(float value, ChannelID code, SummaryType type = ST_SETMAX); QHash<ChannelID,QHash<SummaryType,int>> m_calcs; + + // State passed between populate() and addSlice(): + Day* m_day; + QVector<SummaryChartSlice>* m_slices; + float m_height; }; #endif // GPRESSURECHART_H From 670693dd5f12f9c077fc15fddb6e94ad47e72ebd Mon Sep 17 00:00:00 2001 From: sawinglogz <3787776-sawinglogz@users.noreply.gitlab.com> Date: Mon, 27 Apr 2020 16:55:56 -0400 Subject: [PATCH 06/13] Move gPressureChart value calculation into addSlice. --- oscar/Graphs/gPressureChart.cpp | 97 ++++++++++++--------------------- oscar/Graphs/gPressureChart.h | 2 +- 2 files changed, 35 insertions(+), 64 deletions(-) diff --git a/oscar/Graphs/gPressureChart.cpp b/oscar/Graphs/gPressureChart.cpp index 85da32be..55d3e2ea 100644 --- a/oscar/Graphs/gPressureChart.cpp +++ b/oscar/Graphs/gPressureChart.cpp @@ -98,21 +98,26 @@ QString gPressureChart::channelRange(ChannelID code, const QString & label) } -void gPressureChart::addSlice(float value, ChannelID code, SummaryType type) +void gPressureChart::addSlice(ChannelID code, SummaryType type) { - SummaryCalcItem* calc = getCalc(code, type); - float height = value - m_height; + float value = 0; QString label; switch (type) { case ST_SETMIN: + value = m_day->settings_min(code); + label = schema::channel[code].label(); + break; case ST_SETMAX: + value = m_day->settings_max(code); label = schema::channel[code].label(); break; case ST_MID: + value = m_day->calcMiddle(code); label = m_day->calcMiddleLabel(code); break; case ST_90P: + value = m_day->calcPercentile(code); label = m_day->calcPercentileLabel(code); break; default: @@ -120,6 +125,9 @@ void gPressureChart::addSlice(float value, ChannelID code, SummaryType type) break; } + SummaryCalcItem* calc = getCalc(code, type); + float height = value - m_height; + m_slices->append(SummaryChartSlice(calc, value, height, label, calc->color)); m_height += height; } @@ -133,80 +141,43 @@ void gPressureChart::populate(Day * day, int idx) m_height = 0; if (mode == MODE_CPAP) { - float pr = day->settings_max(CPAP_Pressure); - addSlice(pr, CPAP_Pressure); + addSlice(CPAP_Pressure); } else if (mode == MODE_APAP) { - float min = day->settings_min(CPAP_PressureMin); - float max = day->settings_max(CPAP_PressureMax); - - addSlice(min, CPAP_PressureMin, ST_SETMIN); + addSlice(CPAP_PressureMin, ST_SETMIN); if (!day->summaryOnly()) { - float med = day->calcMiddle(CPAP_Pressure); - addSlice(med, CPAP_Pressure, ST_MID); - - float p90 = day->calcPercentile(CPAP_Pressure); - addSlice(p90, CPAP_Pressure, ST_90P); + addSlice(CPAP_Pressure, ST_MID); + addSlice(CPAP_Pressure, ST_90P); } - addSlice(max, CPAP_PressureMax, ST_SETMAX); + addSlice(CPAP_PressureMax, ST_SETMAX); } else if (mode == MODE_BILEVEL_FIXED) { - float epap = day->settings_max(CPAP_EPAP); - float ipap = day->settings_max(CPAP_IPAP); - - addSlice(epap, CPAP_EPAP); - addSlice(ipap, CPAP_IPAP); + addSlice(CPAP_EPAP); + addSlice(CPAP_IPAP); } else if (mode == MODE_BILEVEL_AUTO_FIXED_PS) { - float epap = day->settings_max(CPAP_EPAPLo); - float ipap = day->settings_max(CPAP_IPAPHi); - - addSlice(epap, CPAP_EPAPLo); + addSlice(CPAP_EPAPLo); if (!day->summaryOnly()) { - - float e50 = day->calcMiddle(CPAP_EPAP); - addSlice(e50, CPAP_EPAP, ST_MID); - - float e90 = day->calcPercentile(CPAP_EPAP); - addSlice(e90, CPAP_EPAP, ST_90P); - - float i50 = day->calcMiddle(CPAP_IPAP); - addSlice(i50, CPAP_IPAP, ST_MID); - - float i90 = day->calcPercentile(CPAP_IPAP); - addSlice(i90, CPAP_IPAP, ST_90P); + addSlice(CPAP_EPAP, ST_MID); + addSlice(CPAP_EPAP, ST_90P); + addSlice(CPAP_IPAP, ST_MID); + addSlice(CPAP_IPAP, ST_90P); } - addSlice(ipap, CPAP_IPAPHi); + addSlice(CPAP_IPAPHi); } else if ((mode == MODE_BILEVEL_AUTO_VARIABLE_PS) || (mode == MODE_ASV_VARIABLE_EPAP)) { - float epap = day->settings_max(CPAP_EPAPLo); - - addSlice(epap, CPAP_EPAPLo); + addSlice(CPAP_EPAPLo); if (!day->summaryOnly()) { - float e50 = day->calcMiddle(CPAP_EPAP); - addSlice(e50, CPAP_EPAP, ST_MID); - - float e90 = day->calcPercentile(CPAP_EPAP); - addSlice(e90, CPAP_EPAP, ST_90P); - - float i50 = day->calcMiddle(CPAP_IPAP); - addSlice(i50, CPAP_IPAP, ST_MID); - - float i90 = day->calcPercentile(CPAP_IPAP); - addSlice(i90, CPAP_IPAP, ST_90P); + addSlice(CPAP_EPAP, ST_MID); + addSlice(CPAP_EPAP, ST_90P); + addSlice(CPAP_IPAP, ST_MID); + addSlice(CPAP_IPAP, ST_90P); } - float ipap = day->settings_max(CPAP_IPAPHi); - addSlice(ipap, CPAP_IPAPHi); + addSlice(CPAP_IPAPHi); } else if (mode == MODE_ASV) { - float epap = day->settings_max(CPAP_EPAP); - - addSlice(epap, CPAP_EPAP); + addSlice(CPAP_EPAP); if (!day->summaryOnly()) { - float i50 = day->calcMiddle(CPAP_IPAP); - addSlice(i50, CPAP_IPAP, ST_MID); - - float i90 = day->calcPercentile(CPAP_IPAP); - addSlice(i90, CPAP_IPAP, ST_90P); + addSlice(CPAP_IPAP, ST_MID); + addSlice(CPAP_IPAP, ST_90P); } - float ipap = day->settings_max(CPAP_IPAPHi); - addSlice(ipap, CPAP_IPAPHi); + addSlice(CPAP_IPAPHi); } } diff --git a/oscar/Graphs/gPressureChart.h b/oscar/Graphs/gPressureChart.h index 692b11ad..842d1c94 100644 --- a/oscar/Graphs/gPressureChart.h +++ b/oscar/Graphs/gPressureChart.h @@ -48,7 +48,7 @@ public: protected: SummaryCalcItem* getCalc(ChannelID code, SummaryType type = ST_SETMAX); QString channelRange(ChannelID code, const QString & label); - void addSlice(float value, ChannelID code, SummaryType type = ST_SETMAX); + void addSlice(ChannelID code, SummaryType type = ST_SETMAX); QHash<ChannelID,QHash<SummaryType,int>> m_calcs; From 4a5322c3502b2f70cdfac74918788a475c73738c Mon Sep 17 00:00:00 2001 From: sawinglogz <3787776-sawinglogz@users.noreply.gitlab.com> Date: Mon, 27 Apr 2020 17:35:50 -0400 Subject: [PATCH 07/13] Fix overview pressure chart for PRS1 pressure setting channels. --- oscar/Graphs/gPressureChart.cpp | 71 ++++++++++++++++++++++++++++----- 1 file changed, 61 insertions(+), 10 deletions(-) diff --git a/oscar/Graphs/gPressureChart.cpp b/oscar/Graphs/gPressureChart.cpp index 55d3e2ea..83b94427 100644 --- a/oscar/Graphs/gPressureChart.cpp +++ b/oscar/Graphs/gPressureChart.cpp @@ -27,6 +27,14 @@ gPressureChart::gPressureChart() addCalc(CPAP_EPAP, ST_90P); addCalc(CPAP_IPAP, ST_MID); addCalc(CPAP_IPAP, ST_90P); + + // PRS1 reports pressure adjustments instead of observed pressures on some machines + addCalc(CPAP_PressureSet, ST_MID); + addCalc(CPAP_PressureSet, ST_90P); + addCalc(CPAP_EPAPSet, ST_MID); + addCalc(CPAP_EPAPSet, ST_90P); + addCalc(CPAP_IPAPSet, ST_MID); + addCalc(CPAP_IPAPSet, ST_90P); } @@ -60,27 +68,50 @@ void gPressureChart::afterDraw(QPainter &, gGraph &graph, QRectF rect) if (getCalc(CPAP_Pressure)->cnt > 0) { presstr.append(channelRange(CPAP_Pressure, STR_TR_CPAP)); } + if (getCalc(CPAP_PressureMin, ST_SETMIN)->cnt > 0) { + // TODO: If using machines from different manufacturers in an overview, + // the below may not accurately find the APAP pressure channel for all + // days; but it only affects the summary label at the top. + ChannelID pressure = CPAP_Pressure; + if (getCalc(CPAP_PressureSet, ST_MID)->cnt > 0) { + pressure = CPAP_PressureSet; + } presstr.append(QString("%1 %2/%3/%4/%5"). arg(STR_TR_APAP). arg(getCalc(CPAP_PressureMin, ST_SETMIN)->min,0,'f',1). - arg(getCalc(CPAP_Pressure, ST_MID)->mid(), 0, 'f', 1). - arg(getCalc(CPAP_Pressure, ST_90P)->mid(),0,'f',1). + arg(getCalc(pressure, ST_MID)->mid(), 0, 'f', 1). + arg(getCalc(pressure, ST_90P)->mid(),0,'f',1). arg(getCalc(CPAP_PressureMax, ST_SETMAX)->max, 0, 'f', 1)); } + if (getCalc(CPAP_EPAP)->cnt > 0) { - presstr.append(channelRange(CPAP_EPAP, STR_TR_EPAP)); + // See CPAP_PressureSet note above. + ChannelID epap = CPAP_EPAP; + if (getCalc(CPAP_EPAPSet, ST_MID)->cnt > 0) { + epap = CPAP_EPAPSet; + } + presstr.append(channelRange(epap, STR_TR_EPAP)); } + if (getCalc(CPAP_IPAP)->cnt > 0) { - presstr.append(channelRange(CPAP_IPAP, STR_TR_IPAP)); + // See CPAP_PressureSet note above. + ChannelID ipap = CPAP_IPAP; + if (getCalc(CPAP_IPAPSet, ST_MID)->cnt > 0) { + ipap = CPAP_IPAPSet; + } + presstr.append(channelRange(ipap, STR_TR_IPAP)); } + if (getCalc(CPAP_EPAPLo)->cnt > 0) { presstr.append(channelRange(CPAP_EPAPLo, STR_TR_EPAPLo)); } + if (getCalc(CPAP_IPAPHi)->cnt > 0) { presstr.append(channelRange(CPAP_IPAPHi, STR_TR_IPAPHi)); } + QString txt = presstr.join(" "); graph.renderText(txt, rect.left(), rect.top()-5*graph.printScaleY(), 0); @@ -142,11 +173,17 @@ void gPressureChart::populate(Day * day, int idx) if (mode == MODE_CPAP) { addSlice(CPAP_Pressure); + } else if (mode == MODE_APAP) { addSlice(CPAP_PressureMin, ST_SETMIN); if (!day->summaryOnly()) { - addSlice(CPAP_Pressure, ST_MID); - addSlice(CPAP_Pressure, ST_90P); + // Handle PRS1 pressure adjustments reported separately from average (EPAP) pressure + ChannelID pressure = CPAP_Pressure; + if (m_day->channelHasData(CPAP_PressureSet)) { + pressure = CPAP_PressureSet; + } + addSlice(pressure, ST_MID); + addSlice(pressure, ST_90P); } addSlice(CPAP_PressureMax, ST_SETMAX); @@ -163,15 +200,26 @@ void gPressureChart::populate(Day * day, int idx) addSlice(CPAP_IPAP, ST_90P); } addSlice(CPAP_IPAPHi); + } else if ((mode == MODE_BILEVEL_AUTO_VARIABLE_PS) || (mode == MODE_ASV_VARIABLE_EPAP)) { addSlice(CPAP_EPAPLo); if (!day->summaryOnly()) { - addSlice(CPAP_EPAP, ST_MID); - addSlice(CPAP_EPAP, ST_90P); - addSlice(CPAP_IPAP, ST_MID); - addSlice(CPAP_IPAP, ST_90P); + // Handle PRS1 pressure adjustments when reported instead of observed pressures + ChannelID epap = CPAP_EPAP; + if (m_day->channelHasData(CPAP_EPAPSet)) { + epap = CPAP_EPAPSet; + } + ChannelID ipap = CPAP_IPAP; + if (m_day->channelHasData(CPAP_IPAPSet)) { + ipap = CPAP_IPAPSet; + } + addSlice(epap, ST_MID); + addSlice(epap, ST_90P); + addSlice(ipap, ST_MID); + addSlice(ipap, ST_90P); } addSlice(CPAP_IPAPHi); + } else if (mode == MODE_ASV) { addSlice(CPAP_EPAP); if (!day->summaryOnly()) { @@ -179,5 +227,8 @@ void gPressureChart::populate(Day * day, int idx) addSlice(CPAP_IPAP, ST_90P); } addSlice(CPAP_IPAPHi); + + } else if (mode == MODE_AVAPS) { + // TODO } } From a8cd0a72b46c853fefc07fc3e65e5daa1b2a001b Mon Sep 17 00:00:00 2001 From: sawinglogz <3787776-sawinglogz@users.noreply.gitlab.com> Date: Mon, 27 Apr 2020 20:13:26 -0400 Subject: [PATCH 08/13] Add support for AVAPS in overview pressure chart. --- Htmldocs/release_notes.html | 2 ++ oscar/Graphs/gPressureChart.cpp | 7 ++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/Htmldocs/release_notes.html b/Htmldocs/release_notes.html index 50d8d281..b35375ed 100644 --- a/Htmldocs/release_notes.html +++ b/Htmldocs/release_notes.html @@ -21,6 +21,8 @@ </ul> <li>[new] Add the "peak flow" channel reported by pre-DreamStation ventilators.</li> <li>[new] Automatically detect and resolve graphics-related crashes on Windows.</li> + <li>[new] Support AVAPS in the Overview pressure chart.</li> + <li>[fix] Fix missing bars in the Overview pressure chart for Philips Respironics devices.</li> <li>[fix] Add support for the Bi-Flex lock setting on pre-DreamStation ventilators.</li> <li>[fix] Fix the pressure waveform scale for the BiPAP autoSV Advanced 30 (960T)</li> <li>[fix] Add support for rise time mode on DreamStation BiPAP devices (600X-700X).</li> diff --git a/oscar/Graphs/gPressureChart.cpp b/oscar/Graphs/gPressureChart.cpp index 83b94427..e7f8b98d 100644 --- a/oscar/Graphs/gPressureChart.cpp +++ b/oscar/Graphs/gPressureChart.cpp @@ -229,6 +229,11 @@ void gPressureChart::populate(Day * day, int idx) addSlice(CPAP_IPAPHi); } else if (mode == MODE_AVAPS) { - // TODO + addSlice(CPAP_EPAP); + if (!day->summaryOnly()) { + addSlice(CPAP_IPAP, ST_MID); + addSlice(CPAP_IPAP, ST_90P); + } + addSlice(CPAP_IPAPHi); } } From 0680424759a877d7f23304f553a3350855d35343 Mon Sep 17 00:00:00 2001 From: sawinglogz <3787776-sawinglogz@users.noreply.gitlab.com> Date: Tue, 28 Apr 2020 12:06:45 -0400 Subject: [PATCH 09/13] Refactor CSV export slightly to make it easier to add new channels. No functional change. --- oscar/exportcsv.cpp | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/oscar/exportcsv.cpp b/oscar/exportcsv.cpp index 635922cc..5842cfd3 100644 --- a/oscar/exportcsv.cpp +++ b/oscar/exportcsv.cpp @@ -1,5 +1,6 @@ -/* ExportCSV module implementation +/* ExportCSV module implementation * + * Copyright (c) 2020 The OSCAR Team * Copyright (c) 2011-2018 Mark Watkins <mark@jedimark.net> * * This file is subject to the terms and conditions of the GNU General Public @@ -180,24 +181,16 @@ void ExportCSV::on_exportButton_clicked() countlist.append(CPAP_UserFlag2); countlist.append(CPAP_PressurePulse); - avglist.append(CPAP_Pressure); - avglist.append(CPAP_IPAP); - avglist.append(CPAP_EPAP); - avglist.append(CPAP_FLG); // Pholynyk, 25Aug2015, add ResMed Flow Limitation + QVector<ChannelID> statChannels = { CPAP_Pressure, CPAP_IPAP, CPAP_EPAP, CPAP_FLG }; + for (auto & chan : statChannels) { + avglist.append(chan); + p90list.append(chan); + maxlist.append(chan); + } - p90list.append(CPAP_Pressure); - p90list.append(CPAP_IPAP); - p90list.append(CPAP_EPAP); - p90list.append(CPAP_FLG); - float percentile=p_profile->general->prefCalcPercentile()/100.0; // Pholynyk, 18Aug2015 EventDataType percent = percentile; // was 0.90F - maxlist.append(CPAP_Pressure); // Pholynyk, 18Aug2015, add maximums - maxlist.append(CPAP_IPAP); - maxlist.append(CPAP_EPAP); - maxlist.append(CPAP_FLG); - // Not sure this section should be translateable.. :-/ if (ui->rb1_details->isChecked()) { header = tr("DateTime") + sep + tr("Session") + sep + tr("Event") + sep + tr("Data/Duration"); From 7b65a85c144853fa2904af49ee145efa3c3aa0bc Mon Sep 17 00:00:00 2001 From: sawinglogz <3787776-sawinglogz@users.noreply.gitlab.com> Date: Tue, 28 Apr 2020 12:11:41 -0400 Subject: [PATCH 10/13] Add PRS1 pressure-set channels to CSV export. --- Htmldocs/release_notes.html | 1 + oscar/exportcsv.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Htmldocs/release_notes.html b/Htmldocs/release_notes.html index b35375ed..83b4b468 100644 --- a/Htmldocs/release_notes.html +++ b/Htmldocs/release_notes.html @@ -23,6 +23,7 @@ <li>[new] Automatically detect and resolve graphics-related crashes on Windows.</li> <li>[new] Support AVAPS in the Overview pressure chart.</li> <li>[fix] Fix missing bars in the Overview pressure chart for Philips Respironics devices.</li> + <li>[fix] Add missing Philips Respironics pressure channels to CSV export.</li> <li>[fix] Add support for the Bi-Flex lock setting on pre-DreamStation ventilators.</li> <li>[fix] Fix the pressure waveform scale for the BiPAP autoSV Advanced 30 (960T)</li> <li>[fix] Add support for rise time mode on DreamStation BiPAP devices (600X-700X).</li> diff --git a/oscar/exportcsv.cpp b/oscar/exportcsv.cpp index 5842cfd3..4c5e6a32 100644 --- a/oscar/exportcsv.cpp +++ b/oscar/exportcsv.cpp @@ -181,7 +181,7 @@ void ExportCSV::on_exportButton_clicked() countlist.append(CPAP_UserFlag2); countlist.append(CPAP_PressurePulse); - QVector<ChannelID> statChannels = { CPAP_Pressure, CPAP_IPAP, CPAP_EPAP, CPAP_FLG }; + QVector<ChannelID> statChannels = { CPAP_Pressure, CPAP_PressureSet, CPAP_IPAP, CPAP_IPAPSet, CPAP_EPAP, CPAP_EPAPSet, CPAP_FLG }; for (auto & chan : statChannels) { avglist.append(chan); p90list.append(chan); From 6261752022049ba5ad2a35ed18ea6b1dea1e5e44 Mon Sep 17 00:00:00 2001 From: sawinglogz <3787776-sawinglogz@users.noreply.gitlab.com> Date: Tue, 28 Apr 2020 13:00:58 -0400 Subject: [PATCH 11/13] Fix zero AHI in CSV session export when there are multiple slices. This only affected PRS1, and it seems like the other places where the broken Session::hours() result was used were: - GT_SESSIONS, which seems to be unused - settings_wavg, where it had no effect The other uses of Settings::hours() were where there was only a single slice, in which case it returned the right result: - gSessionTimesChar::paint (the one still in use) - Icon loader - Resmed loader --- Htmldocs/release_notes.html | 1 + oscar/SleepLib/session.h | 1 + 2 files changed, 2 insertions(+) diff --git a/Htmldocs/release_notes.html b/Htmldocs/release_notes.html index 83b4b468..24050842 100644 --- a/Htmldocs/release_notes.html +++ b/Htmldocs/release_notes.html @@ -24,6 +24,7 @@ <li>[new] Support AVAPS in the Overview pressure chart.</li> <li>[fix] Fix missing bars in the Overview pressure chart for Philips Respironics devices.</li> <li>[fix] Add missing Philips Respironics pressure channels to CSV export.</li> + <li>[fix] Fix zero Philips Respironics AHI in CSV session export.</li> <li>[fix] Add support for the Bi-Flex lock setting on pre-DreamStation ventilators.</li> <li>[fix] Fix the pressure waveform scale for the BiPAP autoSV Advanced 30 (960T)</li> <li>[fix] Add support for rise time mode on DreamStation BiPAP devices (600X-700X).</li> diff --git a/oscar/SleepLib/session.h b/oscar/SleepLib/session.h index 80a167a5..4350dbdc 100644 --- a/oscar/SleepLib/session.h +++ b/oscar/SleepLib/session.h @@ -194,6 +194,7 @@ class Session t += slice.end - slice.start; } } + t = t / 3600000.0; } return t; } From 5f0960aa4d2a371dfdd6b6ee8578687b4a0df1ed Mon Sep 17 00:00:00 2001 From: sawinglogz <3787776-sawinglogz@users.noreply.gitlab.com> Date: Wed, 29 Apr 2020 10:22:12 -0400 Subject: [PATCH 12/13] Add support for PRS1 sessions with oximetry data split between files. --- oscar/SleepLib/loader_plugins/prs1_loader.cpp | 60 ++++++++++--------- oscar/SleepLib/loader_plugins/prs1_loader.h | 6 +- 2 files changed, 34 insertions(+), 32 deletions(-) diff --git a/oscar/SleepLib/loader_plugins/prs1_loader.cpp b/oscar/SleepLib/loader_plugins/prs1_loader.cpp index 61488972..e2f3672a 100644 --- a/oscar/SleepLib/loader_plugins/prs1_loader.cpp +++ b/oscar/SleepLib/loader_plugins/prs1_loader.cpp @@ -982,12 +982,9 @@ void PRS1Loader::ScanFiles(const QStringList & paths, int sessionid_base, Machin // All samples exhibiting this behavior are DreamStations. task->m_wavefiles.append(fi.canonicalFilePath()); } else if (ext == 6) { - if (!task->oxifile.isEmpty()) { - qDebug() << sid << "already has oximetry file" << relativePath(task->oxifile) - << "skipping" << relativePath(fi.canonicalFilePath()); - continue; - } - task->oxifile = fi.canonicalFilePath(); + // Oximetry data can also be split into multiple files, see waveform + // comment above. + task->m_oxifiles.append(fi.canonicalFilePath()); } continue; @@ -8413,7 +8410,7 @@ bool PRS1Import::ParseSession(void) // If are no mask-on slices, then there's not any meaningful event or waveform data for the session. // If there's no no event or waveform data, mark this session as a summary. - if (session->m_slices.count() == 0 || (m_event_chunks.count() == 0 && m_wavefiles.isEmpty() && oxifile.isEmpty())) { + if (session->m_slices.count() == 0 || (m_event_chunks.count() == 0 && m_wavefiles.isEmpty() && m_oxifiles.isEmpty())) { session->setSummaryOnly(true); save = true; break; // and skip the occasional fragmentary event or waveform data @@ -8430,13 +8427,26 @@ bool PRS1Import::ParseSession(void) if (!m_wavefiles.isEmpty()) { // Parse .005 Waveform files - ImportWaveforms(); + waveforms = ReadWaveformData(m_wavefiles, "Waveform"); + + if (session->eventlist.contains(CPAP_FlowRate)) { + if (waveforms.size() > 0) { + // Delete anything called "Flow rate" picked up in the events file if high-resolution data is present + // TODO: Is this still used anywhere? + qWarning() << session->session() << "Deleting flow rate events due to flow rate waveform data"; + session->destroyEvent(CPAP_FlowRate); + } + } + + // Extract raw data into channels. + ParseWaveforms(); } - if (!oxifile.isEmpty()) { - // Parse .006 Waveform file - oximetry = loader->ParseFile(oxifile); - oximetry = CoalesceWaveformChunks(oximetry); + if (!m_oxifiles.isEmpty()) { + // Parse .006 Waveform files + oximetry = ReadWaveformData(m_oxifiles, "Oximetry"); + + // Extract raw data into channels. ParseOximetry(); } @@ -8447,16 +8457,17 @@ bool PRS1Import::ParseSession(void) } -void PRS1Import::ImportWaveforms() +QList<PRS1DataChunk *> PRS1Import::ReadWaveformData(QList<QString> & files, const char* label) { QMap<qint64,PRS1DataChunk *> waveform_chunks; + QList<PRS1DataChunk *> result; - if (m_wavefiles.count() > 1) { - qDebug() << session->session() << "Waveform data split across multiple files"; + if (files.count() > 1) { + qDebug() << session->session() << label << "data split across multiple files"; } - for (auto & f : m_wavefiles) { - // Parse a single .005 Waveform file + for (auto & f : files) { + // Parse a single .005 or .006 waveform file QList<PRS1DataChunk *> file_chunks = loader->ParseFile(f); for (auto & chunk : file_chunks) { PRS1DataChunk* previous = waveform_chunks[chunk->timestamp]; @@ -8471,21 +8482,12 @@ void PRS1Import::ImportWaveforms() } // Get the list of pointers sorted by timestamp. - waveforms = waveform_chunks.values(); + result = waveform_chunks.values(); // Coalesce contiguous waveform chunks into larger chunks. - waveforms = CoalesceWaveformChunks(waveforms); + result = CoalesceWaveformChunks(result); - if (session->eventlist.contains(CPAP_FlowRate)) { - if (waveforms.size() > 0) { - // Delete anything called "Flow rate" picked up in the events file if real data is present - qWarning() << session->session() << "Deleting flow rate events due to flow rate waveform data"; - session->destroyEvent(CPAP_FlowRate); - } - } - - // Extract raw data into channels. - ParseWaveforms(); + return result; } diff --git a/oscar/SleepLib/loader_plugins/prs1_loader.h b/oscar/SleepLib/loader_plugins/prs1_loader.h index f6469895..c7270010 100644 --- a/oscar/SleepLib/loader_plugins/prs1_loader.h +++ b/oscar/SleepLib/loader_plugins/prs1_loader.h @@ -295,7 +295,7 @@ public: QList<QString> m_wavefiles; - QString oxifile; + QList<QString> m_oxifiles; //! \brief Imports .000 files for bricks. bool ImportCompliance(); @@ -306,8 +306,8 @@ public: //! \brief Imports the .002 event file(s). bool ImportEvents(); - //! \brief Imports the .005 event file(s). - void ImportWaveforms(); + //! \brief Reads the .005 or .006 waveform file(s). + QList<PRS1DataChunk *> ReadWaveformData(QList<QString> & files, const char* label); //! \brief Coalesce contiguous .005 or .006 waveform chunks from the file into larger chunks for import. QList<PRS1DataChunk *> CoalesceWaveformChunks(QList<PRS1DataChunk *> & allchunks); From 01c7f7cdc00e5505f380bc4615be57a347d66dc8 Mon Sep 17 00:00:00 2001 From: sawinglogz <3787776-sawinglogz@users.noreply.gitlab.com> Date: Wed, 29 Apr 2020 10:40:23 -0400 Subject: [PATCH 13/13] Exclude additional invalid samples in PRS1 oximetry. Also clean up some function names and remove unnecessary code. --- Htmldocs/release_notes.html | 1 + oscar/SleepLib/loader_plugins/prs1_loader.cpp | 27 +++++++------------ oscar/SleepLib/loader_plugins/prs1_loader.h | 4 +-- 3 files changed, 12 insertions(+), 20 deletions(-) diff --git a/Htmldocs/release_notes.html b/Htmldocs/release_notes.html index 24050842..4ccde935 100644 --- a/Htmldocs/release_notes.html +++ b/Htmldocs/release_notes.html @@ -29,6 +29,7 @@ <li>[fix] Fix the pressure waveform scale for the BiPAP autoSV Advanced 30 (960T)</li> <li>[fix] Add support for rise time mode on DreamStation BiPAP devices (600X-700X).</li> <li>[fix] Remove the ramp time and pressure settings when the ramp is disabled on pre-DreamStation devices.</li> + <li>[fix] Improve import of Philips Respironics oximetry data.</li> <li>[fix] Fix occasional failure to save imported Viatom data.</li> </ul> <p> diff --git a/oscar/SleepLib/loader_plugins/prs1_loader.cpp b/oscar/SleepLib/loader_plugins/prs1_loader.cpp index e2f3672a..6e9a3982 100644 --- a/oscar/SleepLib/loader_plugins/prs1_loader.cpp +++ b/oscar/SleepLib/loader_plugins/prs1_loader.cpp @@ -8149,7 +8149,7 @@ QList<PRS1DataChunk *> PRS1Import::CoalesceWaveformChunks(QList<PRS1DataChunk *> } -void PRS1Import::ParseOximetry() +void PRS1Import::ImportOximetry() { int size = oximetry.size(); @@ -8205,10 +8205,10 @@ void PRS1Import::ImportOximetryChannel(ChannelID channel, QByteArray & data, qui quint64 start_ti; int start_i; - // Split eventlist on invalid values (255) + // Split eventlist on invalid values (254-255) for (int i=0; i < data.size(); i++) { unsigned char value = raw[i]; - bool valid = (value != 255); + bool valid = (value < 254); if (valid) { if (pending_samples == false) { @@ -8218,7 +8218,7 @@ void PRS1Import::ImportOximetryChannel(ChannelID channel, QByteArray & data, qui } if (channel == OXI_Pulse) { - if (value > 200) UNEXPECTED_VALUE(value, "<= 200 bpm"); + if (value > 240) UNEXPECTED_VALUE(value, "<= 240 bpm"); } else { if (value > 100) UNEXPECTED_VALUE(value, "<= 100%"); } @@ -8242,7 +8242,7 @@ void PRS1Import::ImportOximetryChannel(ChannelID channel, QByteArray & data, qui } -void PRS1Import::ParseWaveforms() +void PRS1Import::ImportWaveforms() { int size = waveforms.size(); quint64 s1, s2; @@ -8429,25 +8429,16 @@ bool PRS1Import::ParseSession(void) // Parse .005 Waveform files waveforms = ReadWaveformData(m_wavefiles, "Waveform"); - if (session->eventlist.contains(CPAP_FlowRate)) { - if (waveforms.size() > 0) { - // Delete anything called "Flow rate" picked up in the events file if high-resolution data is present - // TODO: Is this still used anywhere? - qWarning() << session->session() << "Deleting flow rate events due to flow rate waveform data"; - session->destroyEvent(CPAP_FlowRate); - } - } - - // Extract raw data into channels. - ParseWaveforms(); + // Extract and import raw data into channels. + ImportWaveforms(); } if (!m_oxifiles.isEmpty()) { // Parse .006 Waveform files oximetry = ReadWaveformData(m_oxifiles, "Oximetry"); - // Extract raw data into channels. - ParseOximetry(); + // Extract and import raw data into channels. + ImportOximetry(); } save = true; diff --git a/oscar/SleepLib/loader_plugins/prs1_loader.h b/oscar/SleepLib/loader_plugins/prs1_loader.h index c7270010..d44d7f4a 100644 --- a/oscar/SleepLib/loader_plugins/prs1_loader.h +++ b/oscar/SleepLib/loader_plugins/prs1_loader.h @@ -313,10 +313,10 @@ public: QList<PRS1DataChunk *> CoalesceWaveformChunks(QList<PRS1DataChunk *> & allchunks); //! \brief Takes the parsed list of Flow/MaskPressure waveform chunks and adds them to the database - void ParseWaveforms(); + void ImportWaveforms(); //! \brief Takes the parsed list of oximeter waveform chunks and adds them to the database. - void ParseOximetry(); + void ImportOximetry(); //! \brief Adds a single channel of continuous oximetry data to the database, splitting on any missing samples. void ImportOximetryChannel(ChannelID channel, QByteArray & data, quint64 ti, qint64 dur);