From ed608e3b17a901c0d309751d9e80cb882c51e4be Mon Sep 17 00:00:00 2001 From: sawinglogz <3787776-sawinglogz@users.noreply.gitlab.com> Date: Sun, 20 Oct 2019 21:09:34 -0400 Subject: [PATCH] Convert F3V3 and F3V6 parsers to use PRS1Import::AddEvent entirely. This is again confirmed not to change import results, but is still very duplicative. --- oscar/SleepLib/loader_plugins/prs1_loader.cpp | 138 +++++------------- 1 file changed, 39 insertions(+), 99 deletions(-) diff --git a/oscar/SleepLib/loader_plugins/prs1_loader.cpp b/oscar/SleepLib/loader_plugins/prs1_loader.cpp index e098acf4..64e47d28 100644 --- a/oscar/SleepLib/loader_plugins/prs1_loader.cpp +++ b/oscar/SleepLib/loader_plugins/prs1_loader.cpp @@ -1537,6 +1537,7 @@ static const QHash> PRS1ImportChannelMap { PRS1MinuteVentilationEvent::TYPE, { &CPAP_MinuteVent } }, { PRS1PatientTriggeredBreathsEvent::TYPE, { &CPAP_PTB } }, { PRS1TimedBreathEvent::TYPE, { &PRS1_TimedBreath } }, + { PRS1FlowRateEvent::TYPE, { &CPAP_FlowRate } }, // Only reported by F3V3 // TODO: should this stat be calculated from flow waveforms on other models? // TODO: Distinguish between pressure-set and average-pressure events // F0 imports pressure-set events and ignores pressure average events. @@ -1551,8 +1552,8 @@ static const QHash> PRS1ImportChannelMap { PRS1IPAPLowEvent::TYPE, { &CPAP_IPAPLo } }, { PRS1IPAPHighEvent::TYPE, { &CPAP_IPAPHi } }, - { PRS1Test1Event::TYPE, { &CPAP_Test1 } }, - { PRS1Test2Event::TYPE, { &CPAP_Test2 } }, + { PRS1Test1Event::TYPE, { &CPAP_Test1 } }, // ??? F3V6 + { PRS1Test2Event::TYPE, { &CPAP_Test2 } }, // ??? F3V6 { PRS1PressurePulseEvent::TYPE, { &CPAP_PressurePulse } }, { PRS1ApneaAlarmEvent::TYPE, { /* Not imported */ } }, @@ -2711,40 +2712,6 @@ bool PRS1Import::ParseEventsF3V6() return false; } - // Required channels - EventList *CA = GetImportChannel(CPAP_ClearAirway); - EventList *OA = GetImportChannel(CPAP_Obstructive); - EventList *HY = GetImportChannel(CPAP_Hypopnea); - - // No FL detection? - EventList *SNORE = GetImportChannel(CPAP_Snore); // snore count statistic - // No individual VS events reported - EventList *VS2 = GetImportChannel(CPAP_VSnore2); // flags nonzero snore-count intervals on overview - EventList *RE = GetImportChannel(CPAP_RERA); - - EventList *PB = GetImportChannel(CPAP_PB); - EventList *LL = GetImportChannel(CPAP_LargeLeak); - EventList *TOTLEAK = GetImportChannel(CPAP_LeakTotal); - EventList *LEAK = GetImportChannel(CPAP_Leak); - - EventList *RR = GetImportChannel(CPAP_RespRate); - //EventList *TV = GetImportChannel(CPAP_TidalVolume); - EventList *MV = GetImportChannel(CPAP_MinuteVent); - EventList *PTB = GetImportChannel(CPAP_PTB); - - // TB could be on-demand - EventList *TB = GetImportChannel(PRS1_TimedBreath); - - //EventList *IPAP = GetImportChannel(CPAP_IPAP); - //EventList *EPAP = GetImportChannel(CPAP_EPAP); - //EventList *PS = GetImportChannel(CPAP_PS); - - EventList *TMV = GetImportChannel(CPAP_Test1); // ??? - EventList *FLOW = GetImportChannel(CPAP_Test2); // ??? - - // On-demand channels - EventList *PP = nullptr; - EventDataType currentPressure=0; qint64 duration; @@ -2776,72 +2743,69 @@ bool PRS1Import::ParseEventsF3V6() // they can express durations less than 1 second. // TODO: consider allowing OSCAR to record millisecond durations so that the display will say "2.1" instead of "21" or "2". duration = e->m_duration * 100L; // for now do this here rather than in parser, since parser events don't use milliseconds - TB->AddEvent(t - duration, e->m_duration * 0.1F); // TODO: a gain of 0.1 should render this unnecessary, but gain doesn't seem to work currently + AddEvent(*channels.at(0), t - duration, e->m_duration * 0.1F, 1); // TODO: a gain of 0.1 should render this unnecessary, but gain doesn't seem to work currently break; case PRS1ObstructiveApneaEvent::TYPE: - OA->AddEvent(t, e->m_duration); + AddEvent(*channels.at(0), t, e->m_duration, e->m_gain); break; case PRS1ClearAirwayEvent::TYPE: - CA->AddEvent(t, e->m_duration); + AddEvent(*channels.at(0), t, e->m_duration, e->m_gain); break; case PRS1HypopneaEvent::TYPE: - HY->AddEvent(t, e->m_duration); + AddEvent(*channels.at(0), t, e->m_duration, e->m_gain); break; case PRS1PeriodicBreathingEvent::TYPE: // TODO: The graphs silently treat the timestamp of a span as an end time rather than start (see gFlagsLine::paint). // Decide whether to preserve that behavior or change it universally and update either this code or comment. duration = e->m_duration * 1000L; - PB->AddEvent(t + duration, e->m_duration); + AddEvent(*channels.at(0), t + duration, e->m_duration, e->m_gain); break; case PRS1LargeLeakEvent::TYPE: // TODO: see PB comment above. duration = e->m_duration * 1000L; - LL->AddEvent(t + duration, e->m_duration); + AddEvent(*channels.at(0), t + duration, e->m_duration, e->m_gain); break; case PRS1TotalLeakEvent::TYPE: - TOTLEAK->AddEvent(t, e->m_value); + AddEvent(*channels.at(0), t, e->m_value, e->m_gain); break; case PRS1LeakEvent::TYPE: - LEAK->AddEvent(t, e->m_value); + AddEvent(*channels.at(0), t, e->m_value, e->m_gain); break; case PRS1SnoreEvent::TYPE: // snore count that shows up in flags but not waveform // TODO: The numeric snore graph is the right way to present this information, // but it needs to be shifted left 2 minutes, since it's not a starting value // but a past statistic. - SNORE->AddEvent(t, e->m_value); + AddEvent(CPAP_Snore, t, e->m_value, e->m_gain); if (e->m_value > 0) { // TODO: currently these get drawn on our waveforms, but they probably shouldn't, // since they don't have a precise timestamp. They should continue to be drawn // on the flags overview. - VS2->AddEvent(t, 0); + AddEvent(CPAP_VSnore2, t, 0, 1); } break; case PRS1RespiratoryRateEvent::TYPE: - RR->AddEvent(t, e->m_value); + AddEvent(*channels.at(0), t, e->m_value, e->m_gain); break; case PRS1PatientTriggeredBreathsEvent::TYPE: - PTB->AddEvent(t, e->m_value); + AddEvent(*channels.at(0), t, e->m_value, e->m_gain); break; case PRS1MinuteVentilationEvent::TYPE: - MV->AddEvent(t, e->m_value); + AddEvent(*channels.at(0), t, e->m_value, e->m_gain); break; case PRS1TidalVolumeEvent::TYPE: AddEvent(*channels.at(0), t, e->m_value, e->m_gain); break; case PRS1RERAEvent::TYPE: - RE->AddEvent(t, e->m_value); + AddEvent(*channels.at(0), t, e->m_value, e->m_gain); break; case PRS1Test1Event::TYPE: - TMV->AddEvent(t, e->m_value); + AddEvent(*channels.at(0), t, e->m_value, e->m_gain); break; case PRS1Test2Event::TYPE: - FLOW->AddEvent(t, e->m_value); + AddEvent(*channels.at(0), t, e->m_value, e->m_gain); break; case PRS1PressurePulseEvent::TYPE: - if (!PP) { - if (!(PP = session->AddEventList(CPAP_PressurePulse, EVL_Event))) { return false; } - } - PP->AddEvent(t, e->m_value); + AddEvent(*channels.at(0), t, e->m_value, e->m_gain); break; case PRS1UnknownDataEvent::TYPE: // These will show up in chunk YAML and any user alerts will be driven @@ -3050,34 +3014,9 @@ bool PRS1Import::ParseEventsF3V3() GAIN = 0.125F; // TODO: parameterize this somewhere better } - // Required channels - EventList *CA = session->AddEventList(CPAP_ClearAirway, EVL_Event); - EventList *OA = session->AddEventList(CPAP_Obstructive, EVL_Event); - EventList *HY = session->AddEventList(CPAP_Hypopnea, EVL_Event); - - // No FL detection - // No VS detection - // No RERA detection - - // No PB detection - // No LL detection - EventList *TOTLEAK = session->AddEventList(CPAP_LeakTotal, EVL_Event); - EventList *LEAK = session->AddEventList(CPAP_Leak, EVL_Event); - - EventList *RR = session->AddEventList(CPAP_RespRate, EVL_Event); - EventList *TV = session->AddEventList(CPAP_TidalVolume, EVL_Event, 10.0F); - EventList *MV = session->AddEventList(CPAP_MinuteVent, EVL_Event); - EventList *PTB = session->AddEventList(CPAP_PTB, EVL_Event); - - // No TB reported - - EventList *IPAP = session->AddEventList(CPAP_IPAP, EVL_Event, GAIN); - EventList *EPAP = session->AddEventList(CPAP_EPAP, EVL_Event, GAIN); - EventList *PS = session->AddEventList(CPAP_PS, EVL_Event, GAIN); - - EventList *FLOW = session->AddEventList(CPAP_FlowRate, EVL_Event); // TODO: should this stat be calculated from flow waveforms on other models? - - // No PP reported + if (!CreateEventChannels()) { + return false; + } EventDataType currentPressure=0; @@ -3092,46 +3031,47 @@ bool PRS1Import::ParseEventsF3V3() for (int i=0; i < event->m_parsedData.count(); i++) { PRS1ParsedEvent* e = event->m_parsedData.at(i); + QVector channels = PRS1ImportChannelMap[e->m_type]; t = qint64(event->timestamp + e->m_start) * 1000L; switch (e->m_type) { - case PRS1IPAPAverageEvent::TYPE: // TODO: This belongs in an average channel rather than setting channel. - IPAP->AddEvent(t, e->m_value); + case PRS1IPAPAverageEvent::TYPE: + AddEvent(*channels.at(0), t, e->m_value, e->m_gain); // TODO: This belongs in an average channel rather than setting channel. currentPressure = e->m_value; break; - case PRS1EPAPAverageEvent::TYPE: // TODO: This belongs in an average channel rather than setting channel. - EPAP->AddEvent(t, e->m_value); - PS->AddEvent(t, currentPressure - e->m_value); // Pressure Support + case PRS1EPAPAverageEvent::TYPE: + AddEvent(CPAP_EPAP, t, e->m_value, e->m_gain); // TODO: This belongs in an average channel rather than setting channel. + AddEvent(CPAP_PS, t, currentPressure - e->m_value, e->m_gain); // Pressure Support break; case PRS1ObstructiveApneaEvent::TYPE: - OA->AddEvent(t, e->m_duration); + AddEvent(*channels.at(0), t, e->m_duration, e->m_gain); break; case PRS1ClearAirwayEvent::TYPE: - CA->AddEvent(t, e->m_duration); + AddEvent(*channels.at(0), t, e->m_duration, e->m_gain); break; case PRS1HypopneaEvent::TYPE: - HY->AddEvent(t, e->m_duration); + AddEvent(*channels.at(0), t, e->m_duration, e->m_gain); break; case PRS1TotalLeakEvent::TYPE: - TOTLEAK->AddEvent(t, e->m_value); + AddEvent(*channels.at(0), t, e->m_value, e->m_gain); break; case PRS1LeakEvent::TYPE: - LEAK->AddEvent(t, e->m_value); + AddEvent(*channels.at(0), t, e->m_value, e->m_gain); break; case PRS1RespiratoryRateEvent::TYPE: - RR->AddEvent(t, e->m_value); + AddEvent(*channels.at(0), t, e->m_value, e->m_gain); break; case PRS1PatientTriggeredBreathsEvent::TYPE: - PTB->AddEvent(t, e->m_value); + AddEvent(*channels.at(0), t, e->m_value, e->m_gain); break; case PRS1MinuteVentilationEvent::TYPE: - MV->AddEvent(t, e->m_value); + AddEvent(*channels.at(0), t, e->m_value, e->m_gain); break; case PRS1TidalVolumeEvent::TYPE: - TV->AddEvent(t, e->m_value); + AddEvent(*channels.at(0), t, e->m_value, e->m_gain); break; case PRS1FlowRateEvent::TYPE: - FLOW->AddEvent(t, e->m_value); + AddEvent(*channels.at(0), t, e->m_value, e->m_gain); break; default: qWarning() << "Unknown PRS1 event type" << (int) e->m_type;