ResMed S9 import fix for German machines

This commit is contained in:
Mark Watkins 2011-11-25 22:13:35 +10:00
parent 54fd38bf96
commit 45cdd1d172
5 changed files with 88 additions and 47 deletions

View File

@ -60,7 +60,7 @@ void gLineChart::paint(gGraph & w,int left, int top, int width, int height)
if (!m_day)
return;
if (!m_day->channelExists(m_code)) return;
//if (!m_day->channelExists(m_code)) return;
if (width<0)
return;

View File

@ -24,6 +24,20 @@ extern QProgressBar *qprogress;
QHash<int,QString> RMS9ModelMap;
QHash<ChannelID, QVector<QString> > resmed_codes;
EDFSignal * EDFParser::lookupSignal(ChannelID ch)
{
QHash<ChannelID, QVector<QString> >::iterator ci;
QHash<QString,EDFSignal *>::iterator jj;
ci=resmed_codes.find(ch);
if (ci==resmed_codes.end()) return NULL;
for (int i=0;i<ci.value().size();i++) {
jj=lookup.find(ci.value()[i]);
if (jj==lookup.end()) continue;
return jj.value();
}
return NULL;
}
EDFParser::EDFParser(QString name)
{
buffer=NULL;
@ -384,6 +398,7 @@ int ResmedLoader::Open(QString & path,Profile *profile)
if (qprogress) qprogress->setValue(33.0+(float(++cnt)/float(size)*33.0));
QApplication::processEvents();
EDFSignal *sig;
if (!sess) continue;
if (!sess->first()) {
delete sess;
@ -394,37 +409,46 @@ int ResmedLoader::Open(QString & path,Profile *profile)
int dn=dif/86400000L;
if (dn<days) {
int mode;
if (stredf.lookup.contains("Mode"))
mode=(*stredf.lookup["Mode"]).data[dn];
else mode=0;
sig=stredf.lookupSignal(CPAP_Mode);
if (sig) {
mode=sig->data[dn];
} else mode=0;
// AutoSV machines don't have both fields
if (stredf.lookup.contains("EPR"))
sess->settings["EPR"]=(*stredf.lookup["EPR"]).data[dn];
if (stredf.lookup.contains("EPRSet"))
sess->settings["EPRSet"]=(*stredf.lookup["EPR Level"]).data[dn];
sig=stredf.lookupSignal("EPR");
if (sig) {
sess->settings["EPR"]=sig->data[dn];
}
sig=stredf.lookupSignal("EPRLevel");
if (sig) {
sess->settings["EPRSet"]=sig->data[dn];
}
EDFSignal *sig;
if (mode==0) {
sess->settings[CPAP_Mode]=MODE_CPAP;
sig=stredf.lookup["Set Pressure"];
EventDataType pressure=sig->data[dn]*sig->gain;
sess->settings[CPAP_Pressure]=pressure;
sess->setWavg(CPAP_Pressure,pressure);
sess->setAvg(CPAP_Pressure,pressure);
sess->set90p(CPAP_Pressure,pressure);
sess->setMax(CPAP_Pressure,pressure);
sess->setMin(CPAP_Pressure,pressure);
sig=stredf.lookupSignal("Set Pressure");
if (sig) {
EventDataType pressure=sig->data[dn]*sig->gain;
sess->settings[CPAP_Pressure]=pressure;
sess->setWavg(CPAP_Pressure,pressure);
sess->setAvg(CPAP_Pressure,pressure);
sess->set90p(CPAP_Pressure,pressure);
sess->setMax(CPAP_Pressure,pressure);
sess->setMin(CPAP_Pressure,pressure);
}
} else {
if (mode>5) {
sess->settings[CPAP_Mode]=MODE_BIPAP;
} else {
sess->settings[CPAP_Mode]=MODE_APAP;
}
sig=stredf.lookup["Min Pressure"];
sig=stredf.lookupSignal(CPAP_PressureMin);
if (sig)
sess->setMin(CPAP_Pressure,sig->data[dn]*sig->gain);
sig=stredf.lookup["Max Pressure"];
sig=stredf.lookupSignal(CPAP_PressureMax);
if (sig)
sess->setMax(CPAP_Pressure,sig->data[dn]*sig->gain);
}
@ -643,7 +667,7 @@ bool ResmedLoader::LoadSAD(Session *sess,EDFParser &edf)
//qDebug() << "SAD:" << es.label << es.digital_maximum << es.digital_minimum << es.physical_maximum << es.physical_minimum;
long recs=edf.edfsignals[s]->nr*edf.GetNumDataRecords();
ChannelID code;
if (edf.edfsignals[s]->label=="Pulse") {
if (edf.edfsignals[s]->label.startsWith("Puls")) {
code=OXI_Pulse;
} else if (edf.edfsignals[s]->label=="SpO2") {
code=OXI_SPO2;
@ -694,7 +718,7 @@ bool ResmedLoader::LoadPLD(Session *sess,EDFParser &edf)
if (es.label=="Snore Index") {
code=CPAP_Snore;
a=ToTimeDelta(sess,edf,es, code,recs,duration,0,0);
} else if (es.label=="Therapy Pres") {
} else if (es.label.startsWith("Therapy Pres")) {
code=CPAP_Pressure; //TherapyPressure;
a=ToTimeDelta(sess,edf,es, code,recs,duration,0,0);
} else if (es.label=="Insp Pressure") {
@ -704,7 +728,7 @@ bool ResmedLoader::LoadPLD(Session *sess,EDFParser &edf)
} else if (es.label=="MV") {
code=CPAP_MinuteVent;
a=ToTimeDelta(sess,edf,es, code,recs,duration,0,0);
} else if (es.label=="RR") {
} else if ((es.label=="RR") || (es.label=="AF")) {
code=CPAP_RespRate;
a=sess->AddEventList(code,EVL_Waveform,es.gain,es.offset,0,0,rate);
a->AddWaveform(edf.startdate,es.data,recs,duration);
@ -713,7 +737,7 @@ bool ResmedLoader::LoadPLD(Session *sess,EDFParser &edf)
es.physical_maximum=es.physical_minimum=0;
es.gain*=1000.0;
a=ToTimeDelta(sess,edf,es, code,recs,duration,0,0);
} else if (es.label=="Leak") {
} else if ((es.label=="Leak") || (es.label.startsWith("Leck"))) {
code=CPAP_Leak;
es.gain*=60;
es.physical_dimension="L/M";
@ -803,8 +827,13 @@ void ResInitModelMap()
resmed_codes[CPAP_EPAP].push_back("Exp Press");
resmed_codes[CPAP_EPAP].push_back("Exp Pressure"); // vpap
resmed_codes[CPAP_Leak].push_back("Leak");
resmed_codes[CPAP_Leak].push_back("Leck.");
resmed_codes[CPAP_RespRate].push_back("RR");
resmed_codes[CPAP_RespRate].push_back("AF");
resmed_codes[CPAP_TidalVolume].push_back("Vt");
resmed_codes[CPAP_MinuteVent].push_back("MV");
resmed_codes[CPAP_IE].push_back("I:E"); // vpap
@ -817,6 +846,7 @@ void ResInitModelMap()
// Sad (oximetry)
resmed_codes[OXI_Pulse].push_back("Pulse");
resmed_codes[OXI_Pulse].push_back("Puls");
resmed_codes[OXI_SPO2].push_back("SpO2");
// Event annotations
@ -825,6 +855,18 @@ void ResInitModelMap()
resmed_codes[CPAP_Apnea].push_back("Apnea");
resmed_codes[CPAP_ClearAirway].push_back("Central apnea");
resmed_codes[CPAP_Mode].push_back("Mode");
resmed_codes[CPAP_Mode].push_back("Modus");
resmed_codes["Set Pressure"].push_back("Eingest. Druck");
resmed_codes["Set Pressure"].push_back("Set Pressure");
resmed_codes["EPR"].push_back("EPR");
resmed_codes["EPRLevel"].push_back("EPR Level");
resmed_codes["EPRLevel"].push_back("EPR-Stufe");
resmed_codes[CPAP_PressureMax].push_back("Max Pressure");
resmed_codes[CPAP_PressureMax].push_back("Max. Druck");
resmed_codes[CPAP_PressureMin].push_back("Min Pressure");
resmed_codes[CPAP_PressureMin].push_back("Min. Druck");
// STR.edf
}

View File

@ -70,6 +70,7 @@ public:
QVector<EDFSignal *> edfsignals;
QHash<QString,EDFSignal *> lookup;
EDFSignal * lookupSignal(ChannelID);
long GetNumSignals() { return num_signals; }
long GetNumDataRecords() { return num_data_records; }

View File

@ -229,29 +229,29 @@ void SerialOximeter::compactToEvent(EventList *el)
EventList nel(EVL_Waveform);
EventDataType t,lastt=el->data(0);
qint64 ti=el->time(0);
for (qint32 i=0;i<el->count();i++) {
for (quint32 i=0;i<el->count();i++) {
t=el->data(i);
if (t!=lastt) {
nel.AddEvent(ti,lastt);
ti=el->time(i);
nel.AddEvent(ti,t);
}
lastt=t;
}
nel.AddEvent(el->last(),t);
el->getData().clear();
el->getTime().clear();
el->setCount(nel.count());
el->setCount(0);//nel.count());
el->getData()=nel.getData();
el->getTime()=nel.getTime();
//el->getData()=nel.getData();
//el->getTime()=nel.getTime();
/* for (int i=0;i<nel.count();i++) {
for (int i=0;i<nel.count();i++) {
el->getData().push_back(nel.data(i));
el->getTime().push_back(nel.g)
}*/
el->getTime().push_back(nel.time(i));
}
/*double rate=double(el->duration())/double(el->count());
el->setType(EVL_Waveform);
@ -265,24 +265,14 @@ void SerialOximeter::compactAll()
for (i=session->eventlist.begin();i!=session->eventlist.end();i++) {
for (int j=0;j<i.value().size();j++) {
if (i.key()==OXI_Plethy) {
compactToWaveform(i.value()[j]);
} else {
if (i.key()==OXI_SPO2) {
compactToEvent(i.value()[j]);
} else {
compactToWaveform(i.value()[j]);
}
}
}
}
/*void SerialOximeter::addEvents(EventDataType pr,EventDataType o2, EventDataType pleth)
{
lasttime=qint64(QDateTime::currentDateTime().toTime_t())*1000L;
addPulse(lasttime,pr);
addSpO2(lasttime,o2);
addPlethy(lasttime,pleth);
session->set_last(lasttime);
//emit(dataChanged());
}*/
}
Session *SerialOximeter::createSession()
{
@ -529,6 +519,13 @@ void CMS50Serial::onReadyRead()
}
}
}
if (import_mode && waitf6 && (cntf6==0)) {
failcnt++;
if (failcnt>2) {
emit(importAborted());
return;
}
}
emit(dataChanged());
}
@ -537,6 +534,7 @@ bool CMS50Serial::startImport()
import_mode=true;
waitf6=true;
cntf6=0;
failcnt=0;
//QMessageBox::information(0,"!!!Important Notice!!!","This Oximetry import method does NOT allow syncing of Oximetry and CPAP data.\nIf you really wish to record your oximetry data and have sync, you have to use the Live View mode (click Start) with the Oximeter connected to a computer via USB cable all night..\nEven then it will be out a bit because of your CPAP machines realtime clock drifts.",QMessageBox::Ok);
if (!Open(QextSerialPort::EventDriven)) return false;
connect(this,SIGNAL(importProcess()),this,SLOT(on_import_process()));
@ -869,9 +867,9 @@ void Oximetry::import_finished()
void Oximetry::on_import_aborted()
{
qDebug() << "Oximetry import failed";
import_finished();
}
void Oximetry::on_import_complete(Session * session)
{
qDebug() << "Oximetry import complete";
@ -901,7 +899,6 @@ void Oximetry::on_import_complete(Session * session)
PULSE->SetMaxX(l);
SPO2->SetMaxX(l);
PLETHY->forceMinY(0);
PLETHY->forceMaxY(128);
PULSE->forceMinY(30);

View File

@ -120,6 +120,7 @@ protected:
virtual void onReadyRead();
bool waitf6;
short cntf6;
short failcnt;
QByteArray data;
QVector<QDateTime> f2time;