From fda1fe85e44ad8d354fc57d708329a009130ebce Mon Sep 17 00:00:00 2001 From: Mark Watkins Date: Tue, 19 Aug 2014 02:10:47 +1000 Subject: [PATCH] CMS50F37 added PerfusionIndex graph and stuff --- .../loader_plugins/cms50f37_loader.cpp | 19 ++++++--- sleepyhead/SleepLib/machine_common.cpp | 2 +- sleepyhead/SleepLib/machine_common.h | 2 +- sleepyhead/SleepLib/schema.cpp | 5 +++ sleepyhead/SleepLib/serialoximeter.h | 11 ++++-- sleepyhead/daily.cpp | 3 +- sleepyhead/oximeterimport.cpp | 39 ++++++++++++++++++- 7 files changed, 68 insertions(+), 13 deletions(-) diff --git a/sleepyhead/SleepLib/loader_plugins/cms50f37_loader.cpp b/sleepyhead/SleepLib/loader_plugins/cms50f37_loader.cpp index 7254e003..4310ba09 100644 --- a/sleepyhead/SleepLib/loader_plugins/cms50f37_loader.cpp +++ b/sleepyhead/SleepLib/loader_plugins/cms50f37_loader.cpp @@ -168,6 +168,8 @@ void CMS50F37Loader::processBytes(QByteArray bytes) QString user; QString user_number; + unsigned char mask; + OxiRecord s1, s2, s3; do { unsigned char res = bytes.at(idx); @@ -242,6 +244,8 @@ void CMS50F37Loader::processBytes(QByteArray bytes) m_itemCnt=0; m_itemTotal=5000; + + have_perfindex = (res == 0x9); m_startTime = QDateTime(imp_date, imp_time); oxirec = new QVector; oxirec->reserve(30000); @@ -260,14 +264,19 @@ void CMS50F37Loader::processBytes(QByteArray bytes) } if (res == 0x09) { - int pi = buffer.at(idx + 4) | buffer.at(idx + 5) << 7; - oxirec->append(OxiRecord(buffer.at(idx+3), buffer.at(idx+2), pi)); + mask = buffer.at(idx+1); // 9,80,e1,c4,ce,82 // cms50i data + int pi = buffer.at(idx + 4) | buffer.at(idx + 5) << 7; + + oxirec->append((mask == 0x80) ? OxiRecord(buffer.at(idx+3), buffer.at(idx+2), pi) : OxiRecord(0,0,0)); + } else if (res == 0x0f) { - oxirec->append(OxiRecord(buffer.at(idx+3), buffer.at(idx+2))); - oxirec->append(OxiRecord(buffer.at(idx+5), buffer.at(idx+4))); - oxirec->append(OxiRecord(buffer.at(idx+7), buffer.at(idx+6))); // f,80,de,c2,de,c2,de,c2 cms50F data... + mask = buffer.at(idx+1); + + oxirec->append((mask & 0x02) ? OxiRecord(0,0) : OxiRecord(buffer.at(idx+3), buffer.at(idx+2))); + oxirec->append((mask & 0x08) ? OxiRecord(0,0) : OxiRecord(buffer.at(idx+5), buffer.at(idx+4))); + oxirec->append((mask & 0x20) ? OxiRecord(0,0) : OxiRecord(buffer.at(idx+7), buffer.at(idx+6))); } QStringList str; diff --git a/sleepyhead/SleepLib/machine_common.cpp b/sleepyhead/SleepLib/machine_common.cpp index 8dbb4901..c4eaecf6 100644 --- a/sleepyhead/SleepLib/machine_common.cpp +++ b/sleepyhead/SleepLib/machine_common.cpp @@ -34,7 +34,7 @@ ChannelID PRS1_00, PRS1_01, PRS1_08, PRS1_0A, PRS1_0B, PRS1_0C, PRS1_0E, PRS1_0F PRS1_SysOneResistStat, PRS1_SysOneResistSet, PRS1_HoseDiam, PRS1_AutoOn, PRS1_AutoOff, PRS1_MaskAlert, PRS1_ShowAHI; -ChannelID OXI_Pulse, OXI_SPO2, OXI_PulseChange, OXI_SPO2Drop, OXI_Plethy; +ChannelID OXI_Pulse, OXI_SPO2, OXI_Perf, OXI_PulseChange, OXI_SPO2Drop, OXI_Plethy; ChannelID Journal_Notes, Journal_Weight, Journal_BMI, Journal_ZombieMeter, LastUpdated, Bookmark_Start, Bookmark_End, Bookmark_Notes; diff --git a/sleepyhead/SleepLib/machine_common.h b/sleepyhead/SleepLib/machine_common.h index c4f43252..39e5ab58 100644 --- a/sleepyhead/SleepLib/machine_common.h +++ b/sleepyhead/SleepLib/machine_common.h @@ -157,7 +157,7 @@ extern ChannelID PRS1_00, PRS1_01, PRS1_08, PRS1_0A, PRS1_0B, PRS1_0C, PRS1_0E, extern ChannelID INTELLIPAP_Unknown1, INTELLIPAP_Unknown2; -extern ChannelID OXI_Pulse, OXI_SPO2, OXI_PulseChange, OXI_SPO2Drop, OXI_Plethy; +extern ChannelID OXI_Pulse, OXI_SPO2, OXI_Perf, OXI_PulseChange, OXI_SPO2Drop, OXI_Plethy; extern ChannelID Journal_Notes, Journal_Weight, Journal_BMI, Journal_ZombieMeter, Bookmark_Start, Bookmark_End, Bookmark_Notes, LastUpdated; diff --git a/sleepyhead/SleepLib/schema.cpp b/sleepyhead/SleepLib/schema.cpp index c98ac8fc..3d8819a4 100644 --- a/sleepyhead/SleepLib/schema.cpp +++ b/sleepyhead/SleepLib/schema.cpp @@ -258,6 +258,7 @@ void init() QObject::tr("Pulse Rate"), QObject::tr("Heart rate in beats per minute"), QObject::tr("Pulse Rate"), STR_UNIT_BPM, DEFAULT, QColor("red"))); + schema::channel.add(GRP_OXI, new Channel(OXI_SPO2 = 0x1801, WAVEFORM, SESSION, "SPO2", QObject::tr("SpO2 %"), QObject::tr("Blood-oxygen saturation percentage"), QObject::tr("SpO2"), STR_UNIT_Percentage, DEFAULT, QColor("blue"))); @@ -267,6 +268,10 @@ void init() QObject::tr("An optical Photo-plethysomogram showing heart rhythm"), QObject::tr("Plethy"), STR_UNIT_Hz, DEFAULT, QColor("#404040"))); + schema::channel.add(GRP_OXI, new Channel(OXI_Perf = 0x1805, WAVEFORM, SESSION, "Perf. Index", + QObject::tr("Perfusion Index"), QObject::tr(""), + QObject::tr("Perfusion Index"), STR_UNIT_Unknown, DEFAULT, QColor("aqua"))); + schema::channel.add(GRP_OXI, new Channel(OXI_PulseChange = 0x1803, FLAG, SESSION, "PulseChange", QObject::tr("Pulse Change"), QObject::tr("A sudden (user definable) change in heart rate"), diff --git a/sleepyhead/SleepLib/serialoximeter.h b/sleepyhead/SleepLib/serialoximeter.h index 011f7ed9..6f6ac0bb 100644 --- a/sleepyhead/SleepLib/serialoximeter.h +++ b/sleepyhead/SleepLib/serialoximeter.h @@ -21,12 +21,12 @@ struct OxiRecord { quint8 pulse; quint8 spo2; - quint16 pl_inf; + quint16 perf; - OxiRecord():pulse(0), spo2(0),pl_inf(0) {} + OxiRecord():pulse(0), spo2(0),perf(0) {} OxiRecord(quint8 p, quint8 s): pulse(p), spo2(s) {} - OxiRecord(quint8 p, quint8 s, quint16 pi): pulse(p), spo2(s), pl_inf(pi) {} - OxiRecord(const OxiRecord & copy) { pulse = copy.pulse; spo2 = copy.spo2; pl_inf = copy.pl_inf; } + OxiRecord(quint8 p, quint8 s, quint16 pi): pulse(p), spo2(s), perf(pi) {} // with perfusion index + OxiRecord(const OxiRecord & copy) { pulse = copy.pulse; spo2 = copy.spo2; perf = copy.perf; } }; class SerialOximeter : public MachineLoader @@ -36,6 +36,7 @@ public: SerialOximeter() : MachineLoader() { m_importing = m_streaming = false; m_productID = m_vendorID = 0; + have_perfindex = false; } virtual ~SerialOximeter() {} @@ -58,6 +59,7 @@ public: inline bool isStreaming() { return m_streaming; } inline bool isImporting() { return m_importing; } + bool havePerfIndex() { return have_perfindex; } virtual void process() {} @@ -113,6 +115,7 @@ protected: bool m_streaming; bool m_importing; + bool have_perfindex; }; diff --git a/sleepyhead/daily.cpp b/sleepyhead/daily.cpp index 96537125..8061207f 100644 --- a/sleepyhead/daily.cpp +++ b/sleepyhead/daily.cpp @@ -172,7 +172,7 @@ Daily::Daily(QWidget *parent,gGraphView * shared) int cpapsize = sizeof(cpapcodes) / sizeof(ChannelID); ChannelID oxicodes[] = { - OXI_Pulse, OXI_SPO2, OXI_Plethy + OXI_Pulse, OXI_SPO2, OXI_Perf, OXI_Plethy }; int oxisize = sizeof(oxicodes) / sizeof(ChannelID); @@ -406,6 +406,7 @@ Daily::Daily(QWidget *parent,gGraphView * shared) graphlist[schema::channel[OXI_Pulse].code()]->AddLayer(AddOXI(new gLineChart(OXI_Pulse, square))); graphlist[schema::channel[OXI_SPO2].code()]->AddLayer(AddOXI(new gLineChart(OXI_SPO2, true))); + graphlist[schema::channel[OXI_Perf].code()]->AddLayer(AddOXI(new gLineChart(OXI_Perf, false))); graphlist[schema::channel[OXI_Plethy].code()]->AddLayer(AddOXI(new gLineChart(OXI_Plethy, false))); diff --git a/sleepyhead/oximeterimport.cpp b/sleepyhead/oximeterimport.cpp index b81e0389..e0163e63 100644 --- a/sleepyhead/oximeterimport.cpp +++ b/sleepyhead/oximeterimport.cpp @@ -724,11 +724,16 @@ void OximeterImport::on_saveButton_clicked() } EventList * ELpulse = nullptr; EventList * ELspo2 = nullptr; + EventList * ELperf = nullptr; quint16 lastpulse = 0; quint16 lastspo2 = 0; + quint16 lastperf = 0; quint16 lastgoodpulse = 0; quint16 lastgoodspo2 = 0; + quint16 lastgoodperf = 0; + + bool haveperf = oximodule->havePerfIndex(); quint64 ti = start; @@ -782,6 +787,28 @@ void OximeterImport::on_saveButton_clicked() } lastspo2 = rec->spo2; + // Perfusion Index + if (rec->perf > 0) { + if (lastperf == 0) { + ELperf = session->AddEventList(OXI_Perf, EVL_Event); + } + if (lastperf != rec->perf) { + if (lastperf > 0) { + ELperf->AddEvent(ti, lastperf); + } + ELperf->AddEvent(ti, rec->perf); + } + lastgoodperf = rec->perf; + } else { + // end section properly + if (lastgoodperf > 0) { + ELperf->AddEvent(ti, lastperf); + session->setLast(OXI_Perf, ti); + lastgoodperf = 0; + } + } + lastperf = rec->perf; + ti += step; } ti -= step; @@ -795,14 +822,21 @@ void OximeterImport::on_saveButton_clicked() session->setLast(OXI_SPO2, ti); } + if (lastperf > 0) { + ELperf->AddEvent(ti, lastperf); + session->setLast(OXI_Perf, ti); + } + calcSPO2Drop(session); calcPulseChange(session); session->first(OXI_Pulse); session->first(OXI_SPO2); + session->first(OXI_Perf); session->last(OXI_Pulse); session->last(OXI_SPO2); + session->last(OXI_Perf); session->first(OXI_PulseChange); session->first(OXI_SPO2Drop); @@ -817,12 +851,15 @@ void OximeterImport::on_saveButton_clicked() session->count(OXI_Pulse); session->count(OXI_SPO2); + session->count(OXI_Perf); session->count(OXI_PulseChange); session->count(OXI_SPO2Drop); session->Min(OXI_Pulse); - session->Max(OXI_Pulse); session->Min(OXI_SPO2); + session->Min(OXI_Perf); + session->Max(OXI_Pulse); session->Max(OXI_SPO2); + session->Max(OXI_Perf); session->really_set_last(ti); session->SetChanged(true);