From c01ed2c5c0cd2665cd969e4a529b6bebe51c039a Mon Sep 17 00:00:00 2001 From: Mark Watkins Date: Sat, 31 Dec 2011 16:54:51 +1000 Subject: [PATCH] VPAP progress.. (still more, but fixes a startup bug) --- SleepLib/loader_plugins/resmed_loader.cpp | 322 +++++++++++++++++++--- SleepLib/machine.cpp | 2 +- SleepLib/machine_common.h | 4 +- SleepLib/profiles.cpp | 1 + SleepLib/schema.cpp | 2 + daily.cpp | 34 ++- docs/channels.xml | 3 + 7 files changed, 319 insertions(+), 49 deletions(-) diff --git a/SleepLib/loader_plugins/resmed_loader.cpp b/SleepLib/loader_plugins/resmed_loader.cpp index d4717bf4..252a907f 100644 --- a/SleepLib/loader_plugins/resmed_loader.cpp +++ b/SleepLib/loader_plugins/resmed_loader.cpp @@ -340,7 +340,7 @@ int ResmedLoader::Open(QString & path,Profile *profile) if (i.key()=="PCD") { // Lookup Product Code for real model string bool ok; - int j=i.value().toInt(); + int j=i.value().toInt(&ok); if (ok) m->properties[STR_PROP_Model]=RMS9ModelMap[j]; } } @@ -386,16 +386,16 @@ int ResmedLoader::Open(QString & path,Profile *profile) qint64 duration=stredf.GetNumDataRecords()*stredf.GetDuration(); int days=duration/86400000L; - QDateTime dt1=QDateTime::fromTime_t(stredf.startdate/1000L); - QDateTime dt2=QDateTime::fromTime_t(stredf.enddate/1000L); - QDate dd1=dt1.date(); - QDate dd2=dt2.date(); + //QDateTime dt1=QDateTime::fromTime_t(stredf.startdate/1000L); + //QDateTime dt2=QDateTime::fromTime_t(stredf.enddate/1000L); + //QDate dd1=dt1.date(); + //QDate dd2=dt2.date(); - for (int s=0;sreally_set_first(qint64(st)*1000L); sess->really_set_last(qint64(et)*1000L); + sess->SetChanged(true); + m->AddSession(sess,profile); + } + // Add the actual data to the last session + EventDataType tmp,dur; + if (sess) { ///////////////////////////////////////////////////////////////////// // CPAP Mode ///////////////////////////////////////////////////////////////////// @@ -619,32 +625,78 @@ int ResmedLoader::Open(QString & path,Profile *profile) } } else { // VPAP or Auto if (mode>5) { - sess->settings[CPAP_Mode]=MODE_BIPAP; + if (mode>=7) + sess->settings[CPAP_Mode]=MODE_ASV; + else + sess->settings[CPAP_Mode]=MODE_BIPAP; + + EventDataType tmp,epap=0,ipap=0; + if (stredf.lookup.contains("EPAP")) { + sig=stredf.lookup["EPAP"]; + epap=sig->data[dn]*sig->gain; + sess->settings[CPAP_EPAP]=epap; + sess->setMin(CPAP_EPAP,epap); + } + if (stredf.lookup.contains("IPAP")) { + sig=stredf.lookup["IPAP"]; + ipap=sig->data[dn]*sig->gain; + sess->settings[CPAP_IPAP]=ipap; + } + if (stredf.lookup.contains("PS")) { + sig=stredf.lookup["PS"]; + tmp=sig->data[dn]*sig->gain; + sess->settings[CPAP_PS]=tmp; // technically this is IPAP-EPAP + if (!ipap) { + // not really possible. but anyway, just in case.. + sess->settings[CPAP_IPAP]=epap+tmp; + } + } + if (stredf.lookup.contains("Min PS")) { + sig=stredf.lookup["Min PS"]; + tmp=sig->data[dn]*sig->gain; + sess->settings[CPAP_PSMin]=tmp; + sess->settings[CPAP_IPAPLo]=epap+tmp; + sess->setMin(CPAP_IPAP,epap+tmp); + } + if (stredf.lookup.contains("Max PS")) { + sig=stredf.lookup["Max PS"]; + tmp=sig->data[dn]*sig->gain; + sess->settings[CPAP_PSMax]=tmp; + sess->settings[CPAP_IPAPHi]=epap+tmp; + } + if (stredf.lookup.contains("RR")) { // Is this a setting to force respiratory rate on S/T machines? + sig=stredf.lookup["RR"]; + tmp=sig->data[dn]; + sess->settings[CPAP_RespRate]=tmp*sig->gain; + } + + if (stredf.lookup.contains("Easy-Breathe")) { + sig=stredf.lookup["Easy-Breathe"]; + tmp=sig->data[dn]*sig->gain; + + sess->settings[CPAP_PresReliefSet]=tmp; + sess->settings[CPAP_PresReliefType]=(int)PR_EASYBREATHE; + sess->settings[CPAP_PresReliefMode]=(int)PM_FullTime; + } + } else { sess->settings[CPAP_Mode]=MODE_APAP; + sig=stredf.lookupSignal(CPAP_PressureMin); + if (sig) { + EventDataType pressure=sig->data[dn]*sig->gain; + sess->settings[CPAP_PressureMin]=pressure; + sess->setMin(CPAP_Pressure,pressure); + } + sig=stredf.lookupSignal(CPAP_PressureMax); + if (sig) { + EventDataType pressure=sig->data[dn]*sig->gain; + sess->settings[CPAP_PressureMax]=pressure; + sess->setMax(CPAP_Pressure,pressure); + } } - sig=stredf.lookupSignal(CPAP_PressureMin); - if (sig) { - EventDataType pressure=sig->data[dn]*sig->gain; - sess->settings[CPAP_PressureMin]=pressure; - sess->setMin(CPAP_Pressure,pressure); - } - sig=stredf.lookupSignal(CPAP_PressureMax); - if (sig) { - EventDataType pressure=sig->data[dn]*sig->gain; - sess->settings[CPAP_PressureMax]=pressure; - sess->setMax(CPAP_Pressure,pressure); - } } - sess->SetChanged(true); - m->AddSession(sess,profile); - - } - // Add the remainder to the last session - EventDataType tmp,dur; - if (sess) { EventDataType valmed=0,valmax=0,val95=0; if (stredf.lookup.contains("Leak Med")) { @@ -667,6 +719,108 @@ int ResmedLoader::Open(QString & path,Profile *profile) sess->m_valuesummary[CPAP_Leak][valmax]=5; } + if (stredf.lookup.contains("Min Vent Med")) { + sig=stredf.lookup["Min Vent Med"]; + 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; + } + if (stredf.lookup.contains("Min Vent 95")) { + sig=stredf.lookup["Min Vent 95"]; + val95=sig->data[dn]; + sess->set95p(CPAP_MinuteVent,val95*sig->gain); + sess->m_valuesummary[CPAP_MinuteVent][val95]=45; + } + if (stredf.lookup.contains("Min Vent Max")) { + sig=stredf.lookup["Min Vent Max"]; + valmax=sig->data[dn]; + sess->setMax(CPAP_MinuteVent,valmax*sig->gain); + sess->m_valuesummary[CPAP_MinuteVent][valmax]=5; + } + 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; + } + if (stredf.lookup.contains("RR 95")) { + sig=stredf.lookup["RR 95"]; + val95=sig->data[dn]; + sess->set95p(CPAP_RespRate,val95*sig->gain); + sess->m_valuesummary[CPAP_RespRate][val95]=45; + } + if (stredf.lookup.contains("RR Max")) { + sig=stredf.lookup["RR Max"]; + valmax=sig->data[dn]; + sess->setMax(CPAP_RespRate,valmax*sig->gain); + sess->m_valuesummary[CPAP_RespRate][valmax]=5; + } + + if (stredf.lookup.contains("Tid Vol Med")) { + sig=stredf.lookup["Tid Vol Med"]; + 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; + } + if (stredf.lookup.contains("Tid Vol 95")) { + sig=stredf.lookup["Tid Vol 95"]; + val95=sig->data[dn]; + sess->set95p(CPAP_TidalVolume,val95*sig->gain); + sess->m_valuesummary[CPAP_TidalVolume][val95]=45; + } + if (stredf.lookup.contains("Tid Vol Max")) { + sig=stredf.lookup["Tid Vol Max"]; + valmax=sig->data[dn]; + sess->setMax(CPAP_TidalVolume,valmax*sig->gain); + sess->m_valuesummary[CPAP_TidalVolume][valmax]=5; + } + + if (stredf.lookup.contains("Targ Vent Med")) { + sig=stredf.lookup["Targ Vent Med"]; + 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; + } + if (stredf.lookup.contains("Targ Vent 95")) { + sig=stredf.lookup["Targ Vent 95"]; + val95=sig->data[dn]; + sess->set95p(CPAP_TgMV,val95*sig->gain); + sess->m_valuesummary[CPAP_TgMV][val95]=45; + } + if (stredf.lookup.contains("Targ Vent Max")) { + sig=stredf.lookup["Targ Vent Max"]; + valmax=sig->data[dn]; + sess->setMax(CPAP_TgMV,valmax*sig->gain); + sess->m_valuesummary[CPAP_TgMV][valmax]=5; + } + + + if (stredf.lookup.contains("I:E Med")) { + sig=stredf.lookup["I:E Med"]; + 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; + } + if (stredf.lookup.contains("I:E 95")) { + sig=stredf.lookup["I:E 95"]; + val95=sig->data[dn]; + sess->set95p(CPAP_IE,val95*sig->gain); + sess->m_valuesummary[CPAP_IE][val95]=45; + } + if (stredf.lookup.contains("I:E Max")) { + sig=stredf.lookup["I:E Max"]; + valmax=sig->data[dn]; + sess->setMax(CPAP_IE,valmax*sig->gain); + sess->m_valuesummary[CPAP_IE][valmax]=5; + } + + + if (stredf.lookup.contains("Mask Pres Med")) { sig=stredf.lookup["Mask Pres Med"]; valmed=sig->data[dn]; @@ -687,6 +841,44 @@ int ResmedLoader::Open(QString & path,Profile *profile) sess->m_valuesummary[CPAP_Pressure][valmax]=5; } + if (stredf.lookup.contains("Insp Pres Med")) { + sig=stredf.lookup["Insp Pres Med"]; + 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; + } + if (stredf.lookup.contains("Insp Pres 95")) { + sig=stredf.lookup["Insp Pres 95"]; + val95=sig->data[dn]; + sess->set95p(CPAP_IPAP,val95*sig->gain); + sess->m_valuesummary[CPAP_IPAP][val95]=45; + } + if (stredf.lookup.contains("Insp Pres Max")) { + sig=stredf.lookup["Insp Pres Max"]; + valmax=sig->data[dn]; + sess->setMax(CPAP_IPAP,valmax*sig->gain); + sess->m_valuesummary[CPAP_IPAP][valmax]=5; + } + 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; + } + if (stredf.lookup.contains("Exp Pres 95")) { + sig=stredf.lookup["Exp Pres 95"]; + val95=sig->data[dn]; + sess->set95p(CPAP_EPAP,val95*sig->gain); + sess->m_valuesummary[CPAP_EPAP][val95]=45; + } + if (stredf.lookup.contains("Exp Pres Max")) { + sig=stredf.lookup["Exp Pres Max"]; + valmax=sig->data[dn]; + sess->setMax(CPAP_EPAP,valmax*sig->gain); + sess->m_valuesummary[CPAP_EPAP][valmax]=5; + } if (stredf.lookup.contains("Mask Dur")) { sig=stredf.lookup["Mask Dur"]; @@ -798,20 +990,70 @@ int ResmedLoader::Open(QString & path,Profile *profile) sess->settings[CPAP_PresReliefSet]=sig->data[dn]; } + if (mode==0) { sess->settings[CPAP_Mode]=MODE_CPAP; sig=stredf.lookupSignal(RMS9_SetPressure); // ?? What's meant by Set Pressure? if (sig) { EventDataType pressure=sig->data[dn]*sig->gain; - sess->settings[CPAP_PressureMin]=pressure; + sess->settings[CPAP_Pressure]=pressure; } - } else { - if (mode>5) { + } else if (mode>5) { + if (mode>=7) + sess->settings[CPAP_Mode]=MODE_ASV; + else sess->settings[CPAP_Mode]=MODE_BIPAP; - } else { - sess->settings[CPAP_Mode]=MODE_APAP; + EventDataType tmp,epap=0,ipap=0; + if (stredf.lookup.contains("EPAP")) { + sig=stredf.lookup["EPAP"]; + epap=sig->data[dn]*sig->gain; + sess->settings[CPAP_EPAP]=epap; } + if (stredf.lookup.contains("IPAP")) { + sig=stredf.lookup["IPAP"]; + ipap=sig->data[dn]*sig->gain; + sess->settings[CPAP_IPAP]=ipap; + } + if (stredf.lookup.contains("PS")) { + sig=stredf.lookup["PS"]; + tmp=sig->data[dn]*sig->gain; + sess->settings[CPAP_PS]=tmp; // technically this is IPAP-EPAP + if (!ipap) { + // not really possible. but anyway, just in case.. + sess->settings[CPAP_IPAP]=epap+tmp; + } + } + if (stredf.lookup.contains("Min PS")) { + sig=stredf.lookup["Min PS"]; + tmp=sig->data[dn]*sig->gain; + sess->settings[CPAP_PSMin]=tmp; + sess->settings[CPAP_IPAPLo]=epap+tmp; + sess->setMin(CPAP_IPAP,epap+tmp); + } + if (stredf.lookup.contains("Max PS")) { + sig=stredf.lookup["Max PS"]; + tmp=sig->data[dn]*sig->gain; + sess->settings[CPAP_PSMax]=tmp; + sess->settings[CPAP_IPAPHi]=epap+tmp; + } + if (stredf.lookup.contains("RR")) { // Is this a setting to force respiratory rate on S/T machines? + sig=stredf.lookup["RR"]; + tmp=sig->data[dn]; + sess->settings[CPAP_RespRate]=tmp*sig->gain; + } + + if (stredf.lookup.contains("Easy-Breathe")) { + sig=stredf.lookup["Easy-Breathe"]; + tmp=sig->data[dn]*sig->gain; + + sess->settings[CPAP_PresReliefSet]=tmp; + sess->settings[CPAP_PresReliefType]=(int)PR_EASYBREATHE; + sess->settings[CPAP_PresReliefMode]=(int)PM_FullTime; + } + + } else { + sess->settings[CPAP_Mode]=MODE_APAP; sig=stredf.lookupSignal(CPAP_PressureMin); if (sig) { EventDataType pressure=sig->data[dn]*sig->gain; @@ -824,8 +1066,8 @@ int ResmedLoader::Open(QString & path,Profile *profile) sess->settings[CPAP_PressureMax]=pressure; sess->setMax(CPAP_Pressure,pressure); } - } + } } @@ -879,7 +1121,7 @@ bool ResmedLoader::LoadEVE(Session *sess,EDFParser &edf) bool sign,ok; double d; double tt; - ChannelID code; + //ChannelID code; //Event *e; //totaldur=edf.GetNumDataRecords()*edf.GetDuration(); @@ -961,7 +1203,7 @@ bool ResmedLoader::LoadEVE(Session *sess,EDFParser &edf) } EL[2]->AddEvent(tt,duration); } else if (t=="central apnea") { - code=CPAP_ClearAirway; + //code=CPAP_ClearAirway; if (!EL[3]) { if (!(EL[3]=sess->AddEventList(CPAP_ClearAirway,EVL_Event))) return false; } diff --git a/SleepLib/machine.cpp b/SleepLib/machine.cpp index 6283235c..831ce91f 100644 --- a/SleepLib/machine.cpp +++ b/SleepLib/machine.cpp @@ -450,7 +450,7 @@ CPAP_RERA, CPAP_PressurePulse, CPAP_FlowLimit, CPAP_FlowRate, CPAP_MaskPressure, CPAP_RespEvent, CPAP_Snore, CPAP_MinuteVent, CPAP_RespRate, CPAP_TidalVolume, CPAP_PTB, CPAP_Leak, CPAP_LeakMedian, CPAP_LeakTotal, CPAP_MaxLeak, CPAP_FLG, CPAP_IE, CPAP_Te, CPAP_Ti, CPAP_TgMV, CPAP_UserFlag1, CPAP_UserFlag2, CPAP_BrokenSummary, CPAP_BrokenWaveform, CPAP_RDI, -CPAP_PresReliefSet, CPAP_PresReliefMode, CPAP_PresReliefType; +CPAP_PresReliefSet, CPAP_PresReliefMode, CPAP_PresReliefType, CPAP_PSMin, CPAP_PSMax; ChannelID RMS9_E01, RMS9_E02, RMS9_EPR, RMS9_EPRSet, RMS9_SetPressure; diff --git a/SleepLib/machine_common.h b/SleepLib/machine_common.h index 74842437..9c690dea 100644 --- a/SleepLib/machine_common.h +++ b/SleepLib/machine_common.h @@ -61,7 +61,7 @@ enum CPAPMode//:short */ enum PRTypes//:short { - PR_UNKNOWN=0,PR_NONE,PR_CFLEX,PR_CFLEXPLUS,PR_AFLEX,PR_BIFLEX,PR_EPR,PR_SMARTFLEX + PR_UNKNOWN=0,PR_NONE,PR_CFLEX,PR_CFLEXPLUS,PR_AFLEX,PR_BIFLEX,PR_EPR,PR_SMARTFLEX,PR_EASYBREATHE }; enum PRModes//:short { @@ -90,7 +90,7 @@ CPAP_RERA, CPAP_PressurePulse, CPAP_FlowLimit, CPAP_FlowRate, CPAP_MaskPressure, CPAP_RespEvent, CPAP_Snore, CPAP_MinuteVent, CPAP_RespRate, CPAP_TidalVolume, CPAP_PTB, CPAP_Leak, CPAP_LeakMedian, CPAP_LeakTotal, CPAP_MaxLeak, CPAP_FLG, CPAP_IE, CPAP_Te, CPAP_Ti, CPAP_TgMV, CPAP_UserFlag1, CPAP_UserFlag2, CPAP_BrokenSummary, CPAP_BrokenWaveform, CPAP_RDI, -CPAP_PresReliefSet, CPAP_PresReliefMode, CPAP_PresReliefType; +CPAP_PresReliefSet, CPAP_PresReliefMode, CPAP_PresReliefType, CPAP_PSMin, CPAP_PSMax; extern ChannelID RMS9_E01, RMS9_E02, RMS9_EPR, RMS9_EPRSet, RMS9_SetPressure; extern ChannelID INTP_SmartFlex; diff --git a/SleepLib/profiles.cpp b/SleepLib/profiles.cpp index 57284439..cd71f275 100644 --- a/SleepLib/profiles.cpp +++ b/SleepLib/profiles.cpp @@ -904,6 +904,7 @@ QDate Profile::LastGoodDay(MachineType mt) return FirstDay(); QDate d=LastDay(mt); QDate f=FirstDay(mt); + if (!(d.isValid() && f.isValid())) return QDate(); do { if (GetGoodDay(d,mt)!=NULL) return d; d=d.addDays(-1); diff --git a/SleepLib/schema.cpp b/SleepLib/schema.cpp index 230a3d5a..67509a54 100644 --- a/SleepLib/schema.cpp +++ b/SleepLib/schema.cpp @@ -69,6 +69,8 @@ void init() CPAP_EPAP=schema::channel["EPAP"].id(); CPAP_Pressure=schema::channel["Pressure"].id(); CPAP_PS=schema::channel["PS"].id(); + CPAP_PSMin=schema::channel["PSMin"].id(); + CPAP_PSMax=schema::channel["PSMax"].id(); CPAP_Mode=schema::channel["PAPMode"].id(); CPAP_BrokenSummary=schema::channel["BrokenSummary"].id(); CPAP_PressureMin=schema::channel["PressureMin"].id(); diff --git a/daily.cpp b/daily.cpp index 8df9cd2b..42a1964b 100644 --- a/daily.cpp +++ b/daily.cpp @@ -761,12 +761,34 @@ void Daily::Load(QDate date) CPAPMode mode=(CPAPMode)(int)cpap->settings_max(CPAP_Mode); html+="Mode: "; - EventDataType min=cpap->settings_min(CPAP_PressureMin); - EventDataType max=cpap->settings_max(CPAP_PressureMax); - if (mode==MODE_CPAP) html+=tr("CPAP")+" "+QString::number(min)+STR_UNIT_CMH2O; - else if (mode==MODE_APAP) html+=tr("APAP")+" "+QString::number(min)+"-"+QString::number(max)+STR_UNIT_CMH2O; - else if (mode==MODE_BIPAP) html+=tr("Bi-Level"); - else if (mode==MODE_ASV) html+=tr("ASV"); + if (mode==MODE_CPAP) { + EventDataType min=cpap->settings_min(CPAP_PressureMin); + html+=tr("CPAP")+" "+QString::number(min)+STR_UNIT_CMH2O; + } else if (mode==MODE_APAP) { + EventDataType min=cpap->settings_min(CPAP_PressureMin); + EventDataType max=cpap->settings_max(CPAP_PressureMax); + html+=tr("APAP")+" "+QString::number(min)+"-"+QString::number(max)+STR_UNIT_CMH2O; + } else if (mode==MODE_BIPAP) { + EventDataType epap=cpap->settings_min(CPAP_EPAP); + EventDataType ipap=cpap->settings_max(CPAP_IPAP); + EventDataType ps=cpap->settings_max(CPAP_PS); + html+=tr("Bi-Level")+QString("
EPAP: %1 IPAP: %2 %3
PS: %4") + .arg(epap,0,'f',1).arg(ipap,0,'f',1).arg(STR_UNIT_CMH2O).arg(ps,0,'f',1); + } + else if (mode==MODE_ASV) { + EventDataType epap=cpap->settings_min(CPAP_EPAP); + EventDataType low=cpap->settings_min(CPAP_IPAPLo); + EventDataType high=cpap->settings_max(CPAP_IPAPHi); + EventDataType psl=cpap->settings_min(CPAP_PSMin); + EventDataType psh=cpap->settings_max(CPAP_PSMax); + html+=tr("ASV")+QString("
EPAP: %1 IPAP: %2 - %3 %4
PS: %5 / %6") + .arg(epap,0,'f',1) + .arg(low,0,'f',1) + .arg(high,0,'f',1) + .arg(STR_UNIT_CMH2O) + .arg(psl,0,'f',1) + .arg(psh,0,'f',1); + } else html+=tr("Unknown"); html+="\n"; diff --git a/docs/channels.xml b/docs/channels.xml index 1c53415c..12e38623 100644 --- a/docs/channels.xml +++ b/docs/channels.xml @@ -55,6 +55,8 @@ Important: One id code per item, DO NOT CHANGE ID NUMBERS!!! + + @@ -92,6 +94,7 @@ Important: One id code per item, DO NOT CHANGE ID NUMBERS!!!