diff --git a/Graphs/gGraphView.cpp b/Graphs/gGraphView.cpp index 6c112f1d..639cb148 100644 --- a/Graphs/gGraphView.cpp +++ b/Graphs/gGraphView.cpp @@ -2457,8 +2457,8 @@ bool gGraphView::renderGraphs() for (int i=0;idrawGLBuf(); } - lines->draw(); quads->draw(); + lines->draw(); // lines->setSize(linesize); DrawTextQue(); diff --git a/Graphs/gSummaryChart.cpp b/Graphs/gSummaryChart.cpp index 24a373a2..ca43cdec 100644 --- a/Graphs/gSummaryChart.cpp +++ b/Graphs/gSummaryChart.cpp @@ -52,15 +52,46 @@ void SummaryChart::SetDay(Day * nullday) m_maxx=0; - int dn; EventDataType tmp,tmp2,total; ChannelID code; + if (m_label==STR_TR_Pressure) { + CPAPMode mode=(CPAPMode)(int)PROFILE.calcSettingsMax(CPAP_Mode,MT_CPAP,PROFILE.FirstDay(MT_CPAP),PROFILE.LastDay(MT_CPAP)); + m_codes.clear(); + m_colors.clear(); + m_type.clear(); + m_zeros.clear(); + m_typeval.clear(); + + if (mode>=MODE_ASV) { + addSlice(CPAP_EPAP,QColor("green"),ST_SETMIN,true); + + addSlice(CPAP_IPAPLo,QColor("light blue"),ST_SETMIN,true); + addSlice(CPAP_IPAPHi,QColor("blue"),ST_SETMAX,true); + } else if (mode>=MODE_BIPAP) { + addSlice(CPAP_EPAP,QColor("green"),ST_SETMIN,true); + addSlice(CPAP_EPAP,QColor("light green"),ST_PERC,true,0.95); + + addSlice(CPAP_IPAP,QColor("light blue"),ST_PERC,true,0.95); + addSlice(CPAP_IPAP,QColor("blue"),ST_SETMAX,true); + } else if (mode>=MODE_APAP) { + addSlice(CPAP_PressureMin,QColor("orange"),ST_SETMIN,true); + addSlice(CPAP_Pressure,QColor("dark green"),ST_WAVG,true); + addSlice(CPAP_Pressure,QColor("grey"),ST_PERC,true,0.95); + addSlice(CPAP_PressureMax,QColor("red"),ST_SETMAX,true); + } else { + addSlice(CPAP_Pressure,QColor("dark green"),ST_SETWAVG,true); + } + + } + m_goodcodes.resize(m_codes.size()); for (int i=0;isettings_max(CPAP_Mode); if (day->machine_type()!=m_machinetype) continue; //m_values[dn][j+1]=0; @@ -147,6 +179,19 @@ void SummaryChart::SetDay(Day * nullday) day->settingExists(code) || day->hasData(code,type); + if (code==CPAP_Pressure) { + if (mode==MODE_CPAP) { + if (type==ST_PERC) + hascode=false; + else if (type==ST_WAVG) { + //hascode=false; + type=ST_SETWAVG; + } + + } else { + type=m_type[j]; + } + } if (hascode) { m_days[dn]=day; switch(m_type[j]) { @@ -180,10 +225,6 @@ void SummaryChart::SetDay(Day * nullday) m_goodcodes[j]=true; fnd=true; break; - } else { - if (code==CPAP_PressureMin) { - int i=5; - } } } } @@ -196,10 +237,10 @@ void SummaryChart::SetDay(Day * nullday) if (total>m_maxy) m_maxy=total; } //m_empty=false; - } else m_hours[dn]=0; + }// else m_hours[dn]=0; } } - if (m_graphtype!=GT_SESSIONS) + /* if (m_graphtype!=GT_SESSIONS) for (int j=0;j >::iterator d=m_values.find(zd); + + QVector goodcodes; + goodcodes.resize(m_goodcodes.size()); // if (d==m_values.end()) { // d=m_values.find(zd--); // } @@ -343,10 +387,12 @@ void SummaryChart::paint(gGraph & w,int left, int top, int width, int height) } else { totalvalues[i]=0; } + goodcodes[i]=false; if (!m_goodcodes[i]) continue; // lastvalues[i]=0; lastX[i]=px; - if (d!=m_values.end()) { + if (d!=m_values.end() && d.value().contains(i+1)) { + tmp=d.value()[i+1]; h=tmp*ymult; } else { @@ -370,9 +416,14 @@ void SummaryChart::paint(gGraph & w,int left, int top, int width, int height) d=m_values.find(zd); qint64 extra=86400000; - if (Qleft+width) x2=left+width; - if (x20) { if (day) { @@ -428,11 +482,16 @@ void SummaryChart::paint(gGraph & w,int left, int top, int width, int height) py=top+height; //} + bool good; for (QHash::iterator g=d.value().begin();g!=d.value().end();g++) { short j=g.key(); if (!j) continue; j--; - if (!m_goodcodes[j]) continue; + good=m_goodcodes[j]; + if (!good) + continue; + + goodcodes[j]=good; tmp=g.value(); @@ -477,7 +536,12 @@ void SummaryChart::paint(gGraph & w,int left, int top, int width, int height) col.setAlpha(128); px2=px+barw; py2=(top+height-2)-h; - py2+=j; + //py2+=j; + + // If more than 1 day between records, skip the vertical crud. + if ((px2-lastX[j])>barw+1) { + lastdaygood=false; + } if (lastdaygood) { if (lastY[j]!=py2) // vertical line lines->add(lastX[j],lastY[j],px,py2,m_colors[j]); @@ -487,7 +551,6 @@ void SummaryChart::paint(gGraph & w,int left, int top, int width, int height) } lastX[j]=px2; lastY[j]=py2; - //} } } // for(QHashTrigger(2000); QHash >::iterator d=m_values.find(hl_day); + + QHash & valhash=d.value(); + x+=gYAxis::Margin+gGraphView::titleWidth; //graph->m_marginleft+ int y=event->y()+rtop-15; //QDateTime dt1=QDateTime::fromTime_t(hl_day*86400).toLocalTime(); @@ -669,7 +740,7 @@ bool SummaryChart::mouseMoveEvent(QMouseEvent *event) if (m_graphtype==GT_SESSIONS) { if (m_type[0]==ST_HOURS) { - int t=day->hours()*3600.0; + int t=m_hours[zd]*3600.0; int h=t/3600; int m=(t / 60) % 60; //int s=t % 60; @@ -705,7 +776,10 @@ bool SummaryChart::mouseMoveEvent(QMouseEvent *event) } else { QString a; for (int i=0;ichannelExists(m_codes[i]) || day->settingExists(m_codes[i]))) { schema::Channel & chan=schema::channel[m_codes[i]]; + EventDataType v; + if (valhash.contains(i+1)) + v=valhash[i+1]; + else v=0; + if (m_codes[i]==Journal_Weight) { - val=weightString(d.value()[i+1],PROFILE.general->unitSystem()); - } else - val=QString::number(d.value()[i+1],'f',2); + val=weightString(v,PROFILE.general->unitSystem()); + } else { + val=QString::number(v,'f',2); + } z+="\r\n"+chan.label()+" "+a+"="+val; //} } diff --git a/SleepLib/common.h b/SleepLib/common.h index a3934c12..de261d39 100644 --- a/SleepLib/common.h +++ b/SleepLib/common.h @@ -40,6 +40,7 @@ const QString STR_PROP_SubModel="SubModel"; const QString STR_PROP_Serial="Serial"; const QString STR_PROP_DataVersion="DataVersion"; const QString STR_PROP_Path="Path"; +const QString STR_PROP_LastImported="LastImported"; const QString STR_MACH_ResMed="ResMed"; const QString STR_MACH_PRS1="PRS1"; @@ -54,6 +55,7 @@ const QString STR_TR_PulseRate=QObject::tr("Pulse Rate"); const QString STR_TR_SpO2=QObject::tr("SpO2"); const QString STR_TR_Plethy=QObject::tr("Plethy"); const QString STR_TR_FlowRate=QObject::tr("Flow Rate"); +const QString STR_TR_Pressure=QObject::tr("Pressure"); const QString STR_TR_Daily=QObject::tr("Daily"); const QString STR_TR_Overview=QObject::tr("Overview"); diff --git a/SleepLib/loader_plugins/prs1_loader.cpp b/SleepLib/loader_plugins/prs1_loader.cpp index 7c7fa535..216bdb0a 100644 --- a/SleepLib/loader_plugins/prs1_loader.cpp +++ b/SleepLib/loader_plugins/prs1_loader.cpp @@ -384,22 +384,18 @@ int PRS1Loader::OpenMachine(Machine *m,QString path,Profile *profile) sess->settings[CPAP_PresReliefType]=PR_BIFLEX; } - sess->setAvg(CPAP_Pressure,(sess->avg(CPAP_EPAP)+sess->avg(CPAP_IPAP))/2.0); - sess->setWavg(CPAP_Pressure,(sess->wavg(CPAP_EPAP)+sess->wavg(CPAP_IPAP))/2.0); - sess->setMin(CPAP_Pressure,sess->Min(CPAP_EPAP)); - sess->setMax(CPAP_Pressure,sess->Max(CPAP_IPAP)); - sess->set90p(CPAP_Pressure,(sess->p90(CPAP_IPAP)+sess->p90(CPAP_EPAP))/2.0); - //sess->p90(CPAP_EPAP); - //sess->p90(CPAP_IPAP); - } else { - //sess->avg(CPAP_Pressure); - //sess->wavg(CPAP_Pressure); - //sess->p90(CPAP_Pressure); - //sess->Min(CPAP_Pressure); - //sess->Max(CPAP_Pressure); - //sess->cph(CPAP_Pressure); + EventDataType min=sess->settings[CPAP_PressureMin].toDouble(); + EventDataType max=sess->settings[CPAP_PressureMax].toDouble(); + sess->settings[CPAP_EPAP]=min; + sess->settings[CPAP_IPAP]=max; + sess->settings[CPAP_PS]=max-min; + sess->settings.erase(sess->settings.find(CPAP_PressureMin)); + sess->settings.erase(sess->settings.find(CPAP_PressureMax)); - if (!sess->settings.contains(CPAP_PressureMin)) { + + } else { + + if (!sess->settings.contains(CPAP_Pressure) && !sess->settings.contains(CPAP_PressureMin)) { sess->settings[CPAP_BrokenSummary]=true; //sess->set_last(sess->first()); if (sess->Min(CPAP_Pressure)==sess->Max(CPAP_Pressure)) { @@ -411,7 +407,7 @@ int PRS1Loader::OpenMachine(Machine *m,QString path,Profile *profile) } } - if (sess->settings[CPAP_Mode]==MODE_CPAP) { + if (sess->settings[CPAP_Mode].toInt()==(int)MODE_CPAP) { //sess->settings[CPAP_PressureMax]=sess->settings[CPAP_PressureMin]; } @@ -424,7 +420,7 @@ int PRS1Loader::OpenMachine(Machine *m,QString path,Profile *profile) } m->properties[STR_PROP_DataVersion]=QString().sprintf("%i",prs1_data_version); - m->properties["LastImported"]=QDateTime::currentDateTime().toString(Qt::ISODate); + m->properties[STR_PROP_LastImported]=QDateTime::currentDateTime().toString(Qt::ISODate); m->Save(); // Save any new sessions to disk in our format if (qprogress) qprogress->setValue(100); @@ -466,13 +462,13 @@ bool PRS1Loader::ParseSummary(Machine *mach, qint32 sequence, quint32 timestamp, session->settings[CPAP_RampTime]=(int)data[offset+0x06]; // Minutes. Convert to seconds/hours here? session->settings[CPAP_RampPressure]=(EventDataType)data[offset+0x07]/10.0; - if (max>0) { // Ignoring bipap until I see some more data. + if (max>0) { // Ignoring bipap until we see some more data during import session->settings[CPAP_Mode]=(int)MODE_APAP; - session->settings[CPAP_PressureMin]=(double)min; - session->settings[CPAP_PressureMax]=(double)max; + session->settings[CPAP_PressureMin]=(EventDataType)min; + session->settings[CPAP_PressureMax]=(EventDataType)max; } else { session->settings[CPAP_Mode]=(int)MODE_CPAP; - session->settings[CPAP_Pressure]=(double)min; + session->settings[CPAP_Pressure]=(EventDataType)min; } // This is incorrect.. @@ -486,7 +482,7 @@ bool PRS1Loader::ParseSummary(Machine *mach, qint32 sequence, quint32 timestamp, session->settings[CPAP_PresReliefMode]=(int)PM_FullTime; // only has one mode - session->settings[PRS1_FlexSet]=(int)(data[offset+0x08] & 3); + session->settings[CPAP_PresReliefSet]=(int)(data[offset+0x08] & 3); session->settings[PRS1_HumidSetting]=(int)data[offset+0x09]&0x0f; session->settings[PRS1_HumidStatus]=(data[offset+0x09]&0x80)==0x80; session->settings[PRS1_SysLock]=(data[offset+0x0a]&0x80)==0x80; @@ -508,8 +504,8 @@ bool PRS1Loader::ParseSummary(Machine *mach, qint32 sequence, quint32 timestamp, if (max>0) { session->setMin(CPAP_Pressure,min); session->setMax(CPAP_Pressure,max); + session->setWavg(CPAP_Pressure,min); } - session->setWavg(CPAP_Pressure,min); } else { // 0X28 & 0X29 is length on r5 @@ -530,12 +526,12 @@ bool PRS1Loader::ParseSummary(Machine *mach, qint32 sequence, quint32 timestamp, p90p=float(data[offset+0x18])/10.0; avgp=float(data[offset+0x19])/10.0; - if (minp>0) session->setMin(CPAP_Pressure,minp); else session->setMin(CPAP_Pressure,min); - if (maxp>0) session->setMax(CPAP_Pressure,maxp); else session->setMax(CPAP_Pressure,min); - if (avgp>0) session->setWavg(CPAP_Pressure,avgp); else session->setWavg(CPAP_Pressure,min); - if (p90p>0) session->set90p(CPAP_Pressure,p90p); else session->set90p(CPAP_Pressure,min); - - + if (minp>0) session->setMin(CPAP_Pressure,minp); + if (maxp>0) session->setMax(CPAP_Pressure,maxp); + if (avgp>0) session->setWavg(CPAP_Pressure,avgp); + if (p90p>0) { + session->set90p(CPAP_Pressure,p90p); + } int oc, cc, hc, rc, fc; session->setCount(CPAP_Obstructive,oc=(int)data[offset+0x1C] | (data[offset+0x1D] << 8)); @@ -1155,281 +1151,6 @@ bool PRS1Loader::OpenFile(Machine *mach, QString filename) } - - -/*// v2 event parser. -bool PRS1Loader::Parse002(Session *session,unsigned char *buffer,int size,qint64 timestamp,long fpos) -{ -// ChannelID Codes[]={ -// PRS1_Unknown00, PRS1_Unknown01, CPAP_Pressure, CPAP_EPAP, CPAP_PressurePulse, CPAP_RERA, CPAP_Obstructive, CPAP_ClearAirway, -// PRS1_Unknown08, PRS1_Unknown09, CPAP_Hypopnea, PRS1_Unknown0B, CPAP_FlowLimit, CPAP_VSnore, PRS1_Unknown0E, CPAP_CSR, PRS1_Unknown10, -// CPAP_LeakTotal, PRS1_Unknown12 -// }; -// int ncodes=sizeof(Codes)/sizeof(ChannelID); - - //QHash Code; - EventList * Code[0x20]={NULL}; - - EventDataType data[10]; - - session->updateFirst(timestamp); - //qint64 start=timestamp; - qint64 t=timestamp; - qint64 tt; - int pos=0; - while (pos0x12) { - } - delta=0; - if (code!=0x12) { - delta=buffer[pos+1] << 8 | buffer[pos]; - pos+=2; - t+=qint64(delta)*1000L; - tt=t; - } - - session->updateLast(t); - - return true; -} - -bool PRS1Loader::Parse002ASV(Session *session,unsigned char *buffer,int size,qint64 timestamp,long fpos) -{ -} - -bool PRS1Loader::OpenSummary(Session *session,QString filename) // Read .001/.000 file -{ - int size,seconds,br,htype,version,sequence; - qint64 timestamp; - unsigned char header[24]; - unsigned char ext,sum; - - //qDebug() << "Opening PRS1 Summary " << filename; - QFile f(filename); - - if (!f.open(QIODevice::ReadOnly)) - return false; - - if (!f.exists()) - return false; - - int hl=16; - - br=f.read((char *)header,hl); - - if (header[0]!=PRS1_MAGIC_NUMBER) - return false; - - sequence=size=timestamp=seconds=ext=0; - sequence=(header[10] << 24) | (header[9] << 16) | (header[8] << 8) | header[7]; - timestamp=(header[14] << 24) | (header[13] << 16) | (header[12] << 8) | header[11]; - size=(header[2] << 8) | header[1]; - ext=header[6]; // 0 = compliance only, 1 = has data - - htype=header[3]; // 00 = normal // 01=waveform // could be a bool? - version=header[4]; - sequence=sequence; - version=version; // don't need it here? - - htype=htype; // shut the warning up.. this is useless. - - if (ext!=PRS1_SUMMARY_FILE) - return false; - - size-=(hl+2); - - // Calculate header checksum and compare to verify header - sum=0; - for (int i=0; iset_first(date); - - double max; - session->settings[CPAP_PressureMin]=(EventDataType)buffer[0x03]/10.0; - session->settings[CPAP_PressureMax]=max=(EventDataType)buffer[0x04]/10.0; - int offset=0; - if (buffer[0x05]!=0) { // This is a time value for ASV stuff - // non zero adds extra fields.. - offset=4; - } - - session->settings[CPAP_RampTime]=(int)buffer[offset+0x06]; // Minutes. Convert to seconds/hours here? - session->settings[CPAP_RampPressure]=(EventDataType)buffer[offset+0x07]/10.0; - - if (max>0) { // Ignoring bipap until I see some more data. - session->settings[CPAP_Mode]=(int)MODE_APAP; - } else session->settings[CPAP_Mode]=(int)MODE_CPAP; - - // This is incorrect.. - if (buffer[offset+0x08] & 0x80) { // Flex Setting - if (buffer[offset+0x08] & 0x08) { - if (max>0) session->settings[PRS1_FlexMode]=(int)PR_AFLEX; - else session->settings[PRS1_FlexMode]=(int)PR_CFLEXPLUS; - } else session->settings[PRS1_FlexMode]=(int)PR_CFLEX; - } else session->settings[PRS1_FlexMode]=(int)PR_NONE; - - session->settings["FlexSet"]=(int)buffer[offset+0x08] & 3; - session->settings["HumidSet"]=(int)buffer[offset+0x09]&0x0f; - session->settings["HumidStat"]=(buffer[offset+0x09]&0x80)==0x80; - session->settings["SysLock"]=(buffer[offset+0x0a]&0x80)==0x80; - session->settings["SysOneResistStat"]=(buffer[offset+0x0a]&0x40)==0x40; - session->settings["SysOneResistSet"]=(int)buffer[offset+0x0a]&7; - session->settings["HoseDiam"]=((buffer[offset+0x0a]&0x08)?"15mm":"22mm"); - session->settings["AutoOff"]=(buffer[offset+0x0c]&0x10)==0x10; - session->settings["MaskAlert"]=(buffer[offset+0x0c]&0x08)==0x08; - session->settings["ShowAHI"]=(buffer[offset+0x0c]&0x04)==0x04; - - unsigned duration=buffer[offset+0x14] | (buffer[0x15] << 8); - //session->settings[CPAP_Duration]=(int)duration; - //qDebug() << "ID: " << session->session() << " " << duration; - //float hours=float(duration)/3600.0; - //session->set_hours(hours); - if (!duration) - return false; - - session->set_last(date+qint64(duration)*1000L); - //session->settings[PRS1_PressureMinAchieved]=buffer[offset+0x16]/10.0; - //session->settings[PRS1_PressureMaxAchieved]=buffer[offset+0x17]/10.0; - //session->settings[PRS1_PressureAvg]=buffer[offset+0x18]/10.0; - //session->settings[PRS1_Pressure90]=buffer[offset+0x19]/10.0; - - if (max==0) { - // session->settings[PRS1_PressureAvg]=session->settings[PRS1_PressureMin]; - } - - - - -// if (size==0x4d) { - -// session->settings[CPAP_Obstructive]=(int)buffer[offset+0x1C] | (buffer[offset+0x1D] << 8); -// session->settings[CPAP_ClearAirway]=(int)buffer[offset+0x20] | (buffer[offset+0x21] << 8); -// session->settings[CPAP_Hypopnea]=(int)buffer[offset+0x2A] | (buffer[offset+0x2B] << 8); -// session->settings[CPAP_RERA]=(int)buffer[offset+0x2E] | (buffer[offset+0x2F] << 8); -// session->settings[CPAP_FlowLimit]=(int)buffer[offset+0x30] | (buffer[offset+0x31] << 8); -// } - return true; -} - -bool PRS1Loader::OpenEvents(Session *session,QString filename) -{ - int size,sequence,seconds,br,version; - qint64 timestamp; - unsigned char header[24]; // use m_buffer? - unsigned char ext,htype; - - QFile f(filename); - if (!f.open(QIODevice::ReadOnly)) - return false; - - int hl=16; - int chunk=0; - - // Who'd of thought this chunked.. it does on certain ASV machines.. - - long pos=0; - do { - br=f.read((char *)header,hl); - - if (header[0]!=PRS1_MAGIC_NUMBER) { - if (chunk==0) - return false; - break; - } - sequence=size=timestamp=seconds=ext=0; - sequence=(header[10] << 24) | (header[9] << 16) | (header[8] << 8) | header[7]; - timestamp=(header[14] << 24) | (header[13] << 16) | (header[12] << 8) | header[11]; - size=(header[2] << 8) | header[1]; - ext=header[6]; - htype=header[3]; // 00 = normal // 01=waveform // could be a bool? - version=header[4];// == 5 - - htype=htype; - sequence=sequence; - if (ext!=PRS1_EVENT_FILE) { // 2 == Event file - if (chunk==0) - return false; - break; // just end and take what we got.. - } - - //size|=(header[3]<<16) | (header[4]<<24); // the jury is still out on the 32bitness of one. doesn't matter here anyway. - - size-=(hl+2); - - unsigned char sum=0; - for (int i=0; igain; epap=sig->data[dn]*sig->gain; sess->settings[CPAP_EPAP]=epap; sess->setMin(CPAP_EPAP,epap); @@ -704,7 +705,7 @@ int ResmedLoader::Open(QString & path,Profile *profile) valmed=sig->data[dn]; sess->setMedian(CPAP_Leak,valmed*sig->gain*60.0); sess->m_gain[CPAP_Leak]=sig->gain*60.0; - sess->m_valuesummary[CPAP_Leak][valmed]=50; + sess->m_valuesummary[CPAP_Leak][valmed]=51; } if (stredf.lookup.contains("Leak 95")) { sig=stredf.lookup["Leak 95"]; @@ -716,7 +717,7 @@ int ResmedLoader::Open(QString & path,Profile *profile) sig=stredf.lookup["Leak Max"]; valmax=sig->data[dn]; sess->setMax(CPAP_Leak,valmax*sig->gain*60.0); - sess->m_valuesummary[CPAP_Leak][valmax]=5; + sess->m_valuesummary[CPAP_Leak][valmax]=4; } if (stredf.lookup.contains("Min Vent Med")) { @@ -724,7 +725,7 @@ int ResmedLoader::Open(QString & path,Profile *profile) valmed=sig->data[dn]; sess->setMedian(CPAP_MinuteVent,valmed*sig->gain); sess->m_gain[CPAP_MinuteVent]=sig->gain; - sess->m_valuesummary[CPAP_MinuteVent][valmed]=50; + sess->m_valuesummary[CPAP_MinuteVent][valmed]=51; } if (stredf.lookup.contains("Min Vent 95")) { sig=stredf.lookup["Min Vent 95"]; @@ -736,14 +737,14 @@ int ResmedLoader::Open(QString & path,Profile *profile) sig=stredf.lookup["Min Vent Max"]; valmax=sig->data[dn]; sess->setMax(CPAP_MinuteVent,valmax*sig->gain); - sess->m_valuesummary[CPAP_MinuteVent][valmax]=5; + sess->m_valuesummary[CPAP_MinuteVent][valmax]=4; } if (stredf.lookup.contains("RR Med")) { sig=stredf.lookup["RR Med"]; valmed=sig->data[dn]; sess->setMedian(CPAP_RespRate,valmed*sig->gain); sess->m_gain[CPAP_RespRate]=sig->gain; - sess->m_valuesummary[CPAP_RespRate][valmed]=50; + sess->m_valuesummary[CPAP_RespRate][valmed]=51; } if (stredf.lookup.contains("RR 95")) { sig=stredf.lookup["RR 95"]; @@ -755,7 +756,7 @@ int ResmedLoader::Open(QString & path,Profile *profile) sig=stredf.lookup["RR Max"]; valmax=sig->data[dn]; sess->setMax(CPAP_RespRate,valmax*sig->gain); - sess->m_valuesummary[CPAP_RespRate][valmax]=5; + sess->m_valuesummary[CPAP_RespRate][valmax]=4; } if (stredf.lookup.contains("Tid Vol Med")) { @@ -763,7 +764,7 @@ int ResmedLoader::Open(QString & path,Profile *profile) valmed=sig->data[dn]; sess->setMedian(CPAP_TidalVolume,valmed*sig->gain); sess->m_gain[CPAP_TidalVolume]=sig->gain; - sess->m_valuesummary[CPAP_TidalVolume][valmed]=50; + sess->m_valuesummary[CPAP_TidalVolume][valmed]=51; } if (stredf.lookup.contains("Tid Vol 95")) { sig=stredf.lookup["Tid Vol 95"]; @@ -775,7 +776,7 @@ int ResmedLoader::Open(QString & path,Profile *profile) sig=stredf.lookup["Tid Vol Max"]; valmax=sig->data[dn]; sess->setMax(CPAP_TidalVolume,valmax*sig->gain); - sess->m_valuesummary[CPAP_TidalVolume][valmax]=5; + sess->m_valuesummary[CPAP_TidalVolume][valmax]=4; } if (stredf.lookup.contains("Targ Vent Med")) { @@ -783,7 +784,7 @@ int ResmedLoader::Open(QString & path,Profile *profile) valmed=sig->data[dn]; sess->setMedian(CPAP_TgMV,valmed*sig->gain); sess->m_gain[CPAP_TgMV]=sig->gain; - sess->m_valuesummary[CPAP_TgMV][valmed]=50; + sess->m_valuesummary[CPAP_TgMV][valmed]=51; } if (stredf.lookup.contains("Targ Vent 95")) { sig=stredf.lookup["Targ Vent 95"]; @@ -795,7 +796,7 @@ int ResmedLoader::Open(QString & path,Profile *profile) sig=stredf.lookup["Targ Vent Max"]; valmax=sig->data[dn]; sess->setMax(CPAP_TgMV,valmax*sig->gain); - sess->m_valuesummary[CPAP_TgMV][valmax]=5; + sess->m_valuesummary[CPAP_TgMV][valmax]=4; } @@ -804,7 +805,7 @@ int ResmedLoader::Open(QString & path,Profile *profile) valmed=sig->data[dn]; sess->setMedian(CPAP_IE,valmed*sig->gain); sess->m_gain[CPAP_IE]=sig->gain; - sess->m_valuesummary[CPAP_IE][valmed]=50; + sess->m_valuesummary[CPAP_IE][valmed]=51; } if (stredf.lookup.contains("I:E 95")) { sig=stredf.lookup["I:E 95"]; @@ -816,7 +817,7 @@ int ResmedLoader::Open(QString & path,Profile *profile) sig=stredf.lookup["I:E Max"]; valmax=sig->data[dn]; sess->setMax(CPAP_IE,valmax*sig->gain); - sess->m_valuesummary[CPAP_IE][valmax]=5; + sess->m_valuesummary[CPAP_IE][valmax]=4; } @@ -826,7 +827,7 @@ int ResmedLoader::Open(QString & path,Profile *profile) valmed=sig->data[dn]; sess->setMedian(CPAP_Pressure,valmed*sig->gain); sess->m_gain[CPAP_Pressure]=sig->gain; - sess->m_valuesummary[CPAP_Pressure][valmed]=50; + sess->m_valuesummary[CPAP_Pressure][valmed]=51; } if (stredf.lookup.contains("Mask Pres 95")) { sig=stredf.lookup["Mask Pres 95"]; @@ -838,7 +839,7 @@ int ResmedLoader::Open(QString & path,Profile *profile) sig=stredf.lookup["Mask Pres Max"]; valmax=sig->data[dn]; sess->setMax(CPAP_Pressure,valmax*sig->gain); - sess->m_valuesummary[CPAP_Pressure][valmax]=5; + sess->m_valuesummary[CPAP_Pressure][valmax]=4; } if (stredf.lookup.contains("Insp Pres Med")) { @@ -846,7 +847,7 @@ int ResmedLoader::Open(QString & path,Profile *profile) valmed=sig->data[dn]; sess->setMedian(CPAP_IPAP,valmed*sig->gain); sess->m_gain[CPAP_IPAP]=sig->gain; - sess->m_valuesummary[CPAP_IPAP][valmed]=50; + sess->m_valuesummary[CPAP_IPAP][valmed]=51; } if (stredf.lookup.contains("Insp Pres 95")) { sig=stredf.lookup["Insp Pres 95"]; @@ -858,14 +859,14 @@ int ResmedLoader::Open(QString & path,Profile *profile) sig=stredf.lookup["Insp Pres Max"]; valmax=sig->data[dn]; sess->setMax(CPAP_IPAP,valmax*sig->gain); - sess->m_valuesummary[CPAP_IPAP][valmax]=5; + sess->m_valuesummary[CPAP_IPAP][valmax]=4; } if (stredf.lookup.contains("Exp Pres Med")) { sig=stredf.lookup["Exp Pres Med"]; valmed=sig->data[dn]; sess->setMedian(CPAP_EPAP,valmed*sig->gain); sess->m_gain[CPAP_EPAP]=sig->gain; - sess->m_valuesummary[CPAP_EPAP][valmed]=50; + sess->m_valuesummary[CPAP_EPAP][valmed]=51; } if (stredf.lookup.contains("Exp Pres 95")) { sig=stredf.lookup["Exp Pres 95"]; @@ -877,7 +878,7 @@ int ResmedLoader::Open(QString & path,Profile *profile) sig=stredf.lookup["Exp Pres Max"]; valmax=sig->data[dn]; sess->setMax(CPAP_EPAP,valmax*sig->gain); - sess->m_valuesummary[CPAP_EPAP][valmax]=5; + sess->m_valuesummary[CPAP_EPAP][valmax]=4; } if (stredf.lookup.contains("Mask Dur")) { diff --git a/SleepLib/loader_plugins/resmed_loader.h b/SleepLib/loader_plugins/resmed_loader.h index c52f1058..6093da6e 100644 --- a/SleepLib/loader_plugins/resmed_loader.h +++ b/SleepLib/loader_plugins/resmed_loader.h @@ -64,22 +64,22 @@ public: QString physical_dimension; //! \brief The minimum limits of the ungained data - double physical_minimum; + EventDataType physical_minimum; //! \brief The maximum limits of the ungained data - double physical_maximum; + EventDataType physical_maximum; //! \brief The minimum limits of the data with gain and offset applied - double digital_minimum; + EventDataType digital_minimum; //! \brief The maximum limits of the data with gain and offset applied - double digital_maximum; + EventDataType digital_maximum; //! \brief Raw integer data is multiplied by this value - double gain; + EventDataType gain; //! \brief This value is added to the raw data - double offset; + EventDataType offset; //! \brief Any prefiltering methods used (usually blank) QString prefiltering; diff --git a/SleepLib/machine.cpp b/SleepLib/machine.cpp index 831ce91f..d81c7096 100644 --- a/SleepLib/machine.cpp +++ b/SleepLib/machine.cpp @@ -10,7 +10,6 @@ #include #include #include -//#include #include #include "machine.h" @@ -30,13 +29,9 @@ Machine::Machine(Profile *p,MachineID id) profile=p; if (!id) { srand(time(NULL)); - //std::tr1::minstd_rand gen; - //std::tr1::uniform_int unif(1, 0x7fffffff); - //gen.seed((unsigned int) time(NULL)); MachineID temp; do { temp = rand(); - //temp = unif(gen); //unif(gen) << 32 | } while (profile->machlist.find(temp)!=profile->machlist.end()); m_id=temp; diff --git a/SleepLib/profiles.cpp b/SleepLib/profiles.cpp index cd71f275..7235925e 100644 --- a/SleepLib/profiles.cpp +++ b/SleepLib/profiles.cpp @@ -581,8 +581,12 @@ const char * US_STR_CalculateRDI="CalculateRDI"; int Profile::countDays(MachineType mt, QDate start, QDate end) { - if (!start.isValid()) start=LastDay(mt); - if (!end.isValid()) end=LastDay(mt); + if (!start.isValid()) + return 0; + //start=LastDay(mt); + if (!end.isValid()) + return 0; + //end=LastDay(mt); QDate date=start; int days=0; do { @@ -780,15 +784,17 @@ EventDataType Profile::calcPercentile(ChannelID code, EventDataType percent, Mac QVector array; QHash >::iterator vsi; - float gain; + EventDataType val,gain; bool setgain=false; + //double val=0,tmp,hours=0; do { Day * day=GetGoodDay(date,mt); if (day) { for (int i=0;isize();i++) { for (QVector::iterator s=day->begin();s!=day->end();s++) { - if (!(*s)->enabled()) continue; + if (!(*s)->enabled()) + continue; Session *sess=*s; gain=sess->m_gain[code]; @@ -801,7 +807,10 @@ EventDataType Profile::calcPercentile(ChannelID code, EventDataType percent, Mac for (QHash::iterator k=vsum.begin();k!=vsum.end();k++) { for (int z=0;z::iterator k=summary.begin();k!=summary.end();k++) { // for (int i=0;i0) { int s=p+1; if (s>size-1) s=size-1; @@ -892,6 +901,8 @@ QDate Profile::FirstGoodDay(MachineType mt) QDate d=FirstDay(mt); QDate l=LastDay(mt); + if (!d.isValid() || !l.isValid()) + return QDate(); do { if (GetGoodDay(d,mt)!=NULL) return d; d=d.addDays(1); diff --git a/docs/channels.xml b/docs/channels.xml index 12e38623..fba680dd 100644 --- a/docs/channels.xml +++ b/docs/channels.xml @@ -24,8 +24,8 @@ Important: One id code per item, DO NOT CHANGE ID NUMBERS!!! - - + + @@ -101,7 +101,7 @@ Important: One id code per item, DO NOT CHANGE ID NUMBERS!!! - + diff --git a/mainwindow.cpp b/mainwindow.cpp index 941e100e..2af2d641 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -403,7 +403,12 @@ EventDataType calcAHI(QDate start, QDate end) +p_profile->calcCount(CPAP_Apnea,MT_CPAP,start,end)); if (PROFILE.general->calculateRDI()) val+=p_profile->calcCount(CPAP_RERA,MT_CPAP,start,end); - val/=p_profile->calcHours(MT_CPAP,start,end); + EventDataType hours=p_profile->calcHours(MT_CPAP,start,end); + + if (hours>0) + val/=hours; + else + val=0; return val; } @@ -449,38 +454,6 @@ enum RXSortMode { RX_first, RX_last, RX_days, RX_ahi, RX_mode, RX_min, RX_max, R RXSortMode RXsort=RX_first; bool RXorder=false; -//bool operator<(const RXChange & comp1, const RXChange & comp2) { -// if (RXorder) { -// switch (RXsort) { -// case RX_ahi: return comp1.ahi < comp2.ahi; -// case RX_days: return comp1.days < comp2.days; -// case RX_first: return comp1.first < comp2.first; -// case RX_last: return comp1.last < comp2.last; -// case RX_mode: return comp1.mode < comp2.mode; -// case RX_min: return comp1.min < comp2.min; -// case RX_max: return comp1.max < comp2.max; -// case RX_maxhi: return comp1.maxhi < comp2.maxhi; -// case RX_per1: return comp1.per1 < comp2.per1; -// case RX_per2: return comp1.per2 < comp2.per2; -// case RX_weighted: return comp1.weighted < comp2.weighted; -// }; -// } else { -// switch (RXsort) { -// case RX_ahi: return comp1.ahi > comp2.ahi; -// case RX_days: return comp1.days > comp2.days; -// case RX_first: return comp1.first > comp2.first; -// case RX_last: return comp1.last > comp2.last; -// case RX_mode: return comp1.mode > comp2.mode; -// case RX_min: return comp1.min > comp2.min; -// case RX_max: return comp1.max > comp2.max; -// case RX_maxhi: return comp1.maxhi > comp2.maxhi; -// case RX_per1: return comp1.per1 > comp2.per1; -// case RX_per2: return comp1.per2 > comp2.per2; -// case RX_weighted: return comp1.weighted > comp2.weighted; -// }; -// } -// return true; -//} bool RXSort(const RXChange * comp1, const RXChange * comp2) { if (RXorder) { switch (RXsort) { @@ -805,8 +778,8 @@ void MainWindow::on_summaryButton_clicked() CPAPMode mode,cmode=MODE_UNKNOWN; EventDataType cmin=0,cmax=0,cmaxhi=0, min,max,maxhi; Machine *mach,*lastmach=NULL; - PRTypes prelief=PR_UNKNOWN; - short prelset=0; + PRTypes lastpr, prelief=PR_UNKNOWN; + short prelset, lastprelset=-1; QDate date=lastcpap; Day * day; bool lastchanged=false; @@ -833,7 +806,8 @@ void MainWindow::on_summaryButton_clicked() bestAHIdate=date; } } - + prelief=(PRTypes)round(day->settings_wavg(CPAP_PresReliefType)); + prelset=round(day->settings_wavg(CPAP_PresReliefSet)); mode=(CPAPMode)round(day->settings_wavg(CPAP_Mode)); if (mode>=MODE_ASV) { min=day->settings_min(CPAP_EPAP); @@ -848,7 +822,7 @@ void MainWindow::on_summaryButton_clicked() } else { min=day->settings_min(CPAP_Pressure); } - if ((mode!=cmode) || (min!=cmin) || (max!=cmax) || (maxhi!=cmaxhi) || (day->machine!=lastmach)) { + if ((mode!=cmode) || (min!=cmin) || (max!=cmax) || (maxhi!=cmaxhi) || (day->machine!=lastmach) || (prelief!=lastpr)) { if (cmode!=MODE_UNKNOWN) { first=date.addDays(1); int days=PROFILE.countDays(MT_CPAP,first,last); @@ -861,8 +835,8 @@ void MainWindow::on_summaryButton_clicked() rx.min=cmin; rx.max=cmax; rx.maxhi=cmaxhi; - rx.prelief=prelief; - rx.prelset=prelset; + rx.prelief=lastpr; + rx.prelset=lastprelset; if (modecalcPercentile(CPAP_Pressure,percentile,MT_CPAP,first,last); @@ -881,6 +855,8 @@ void MainWindow::on_summaryButton_clicked() cmin=min; cmax=max; cmaxhi=maxhi; + lastpr=prelief; + lastprelset=prelset; last=date; lastmach=day->machine; lastchanged=true; @@ -890,6 +866,7 @@ void MainWindow::on_summaryButton_clicked() date=date.addDays(-1); } while (date>=firstcpap); + lastchanged=false; if (!lastchanged) { // last=date.addDays(1); first=firstcpap; @@ -903,6 +880,8 @@ void MainWindow::on_summaryButton_clicked() rx.min=min; rx.max=max; rx.maxhi=maxhi; + rx.prelief=prelief; + rx.prelset=prelset; if (modecalcPercentile(CPAP_Pressure,0.9,MT_CPAP,first,last); rx.per2=0; @@ -1040,12 +1019,13 @@ void MainWindow::on_summaryButton_clicked() extratxt=QString("%1") .arg(tr("Pressure")); } - html+=QString("%1%2%3%4%5%6") + html+=QString("%1%2%3%4%5%6%7") .arg(tr("First")) .arg(tr("Last")) .arg(tr("Days")) .arg(ahitxt) .arg(tr("Mode")) + .arg(tr("Pr. Rel.")) .arg(extratxt); for (int i=0;iMODE_CPAP) { extratxt=QString("%1%2").arg(rx.max,0,'f',2).arg(rx.per1,0,'f',2); } else extratxt=""; - html+=QString("%3%4%5%6%7%8%9") + QString presrel; + if (rx.prelset>0) { + presrel=schema::channel[CPAP_PresReliefType].option(int(rx.prelief)); + presrel+=QString(" x%1").arg(rx.prelset); + } else presrel="None"; + html+=QString("%3%4%5%6%7%8%9%10") .arg(rx.first.toString(Qt::ISODate)) .arg(rx.last.toString(Qt::ISODate)) .arg(rx.first.toString(Qt::SystemLocaleShortDate)) @@ -1076,6 +1061,7 @@ void MainWindow::on_summaryButton_clicked() .arg(rx.days) .arg(rx.ahi,0,'f',2) .arg(schema::channel[CPAP_Mode].option(int(rx.mode)-1)) + .arg(presrel) .arg(rx.min,0,'f',2) .arg(extratxt); } diff --git a/overview.cpp b/overview.cpp index e87b8439..f243b42d 100644 --- a/overview.cpp +++ b/overview.cpp @@ -99,7 +99,7 @@ Overview::Overview(QWidget *parent,gGraphView * shared) : US=createGraph(tr("Session Times"),tr("Session Times\n(hours)"),YT_Time); - PR=createGraph(tr("Pressure"),tr("Pressure\n(cmH2O)")); + PR=createGraph(STR_TR_Pressure,tr("Pressure\n(cmH2O)")); SET=createGraph(tr("Settings"),("Settings")); LK=createGraph(tr("Leaks"),tr("Leak Rate\n(L/min)")); NPB=createGraph(tr("% in PB"),tr("Periodic\nBreathing\n(% of night)")); @@ -179,9 +179,9 @@ Overview::Overview(QWidget *parent,gGraphView * shared) : set=new SummaryChart("",GT_LINE); //set->addSlice(PRS1_SysOneResistSet,QColor("grey"),ST_SETAVG); set->addSlice(PRS1_HumidSetting,QColor("blue"),ST_SETWAVG,true); - set->addSlice(PRS1_FlexSet,QColor("red"),ST_SETWAVG,true); - set->addSlice(RMS9_EPRSet,QColor("green"),ST_SETWAVG,true); - set->addSlice(INTP_SmartFlex,QColor("purple"),ST_SETWAVG,true); + set->addSlice(CPAP_PresReliefSet,QColor("red"),ST_SETWAVG,true); + //set->addSlice(RMS9_EPRSet,QColor("green"),ST_SETWAVG,true); + //set->addSlice(INTP_SmartFlex,QColor("purple"),ST_SETWAVG,true); SET->setRecMinY(0); SET->setRecMaxY(5); SET->AddLayer(set); @@ -190,6 +190,7 @@ Overview::Overview(QWidget *parent,gGraphView * shared) : rr->addSlice(CPAP_RespRate,QColor("light blue"),ST_MIN,true); rr->addSlice(CPAP_RespRate,QColor("light green"),ST_PERC,true,0.95); rr->addSlice(CPAP_RespRate,QColor("blue"),ST_WAVG,true); + rr->addSlice(CPAP_RespRate,QColor("green"),ST_MAX,true); RR->AddLayer(rr); tv=new SummaryChart(tr("L/b"),GT_LINE); @@ -211,28 +212,28 @@ Overview::Overview(QWidget *parent,gGraphView * shared) : ptb->addSlice(CPAP_PTB,QColor("orange"),ST_WAVG,true); PTB->AddLayer(ptb); - pr=new SummaryChart(STR_UNIT_CMH2O,GT_LINE); + pr=new SummaryChart(STR_TR_Pressure,GT_LINE); //PR->setRecMinY(4.0); //PR->setRecMaxY(12.0); CPAPMode mode=(CPAPMode)(int)PROFILE.calcSettingsMax(CPAP_Mode,MT_CPAP,PROFILE.FirstDay(MT_CPAP),PROFILE.LastDay(MT_CPAP)); - if (mode>=MODE_BIPAP) { - pr->addSlice(CPAP_EPAP,QColor("green"),ST_MIN,true); - pr->addSlice(CPAP_EPAP,QColor("light green"),ST_PERC,true,0.95); +// //if (mode>=MODE_BIPAP) { +// pr->addSlice(CPAP_EPAP,QColor("green"),ST_SETMIN,true); +// pr->addSlice(CPAP_EPAP,QColor("light green"),ST_PERC,true,0.95); - pr->addSlice(CPAP_IPAP,QColor("light blue"),ST_PERC,true,0.95); - pr->addSlice(CPAP_IPAP,QColor("blue"),ST_MAX,true); - } else if (mode>MODE_CPAP) { - pr->addSlice(CPAP_Pressure,QColor("dark green"),ST_WAVG,true); - pr->addSlice(CPAP_Pressure,QColor("orange"),ST_MIN,true); - pr->addSlice(CPAP_Pressure,QColor("red"),ST_MAX,true); - //pr->addSlice(CPAP_Pressure,QColor("grey"),ST_90P,true); - pr->addSlice(CPAP_Pressure,QColor("grey"),ST_PERC,true,0.95); - } else { +// pr->addSlice(CPAP_IPAP,QColor("light blue"),ST_PERC,true,0.95); +// pr->addSlice(CPAP_IPAP,QColor("blue"),ST_SETMAX,true); +// //} else if (mode>MODE_CPAP) { +// pr->addSlice(CPAP_PressureMin,QColor("orange"),ST_SETMIN,true); +// pr->addSlice(CPAP_Pressure,QColor("dark green"),ST_WAVG,true); +// //pr->addSlice(CPAP_Pressure,QColor("grey"),ST_90P,true); +// pr->addSlice(CPAP_Pressure,QColor("grey"),ST_PERC,true,0.95); +// pr->addSlice(CPAP_PressureMax,QColor("red"),ST_SETMAX,true); +// //} else { - pr->addSlice(CPAP_Pressure,QColor("grey"),ST_SETWAVG,true); - } +// pr->addSlice(CPAP_Pressure,QColor("dark green"),ST_SETWAVG,true); +// //} PR->AddLayer(pr); lk=new SummaryChart(tr("Avg Leak"),GT_LINE);