mirror of
https://gitlab.com/pholy/OSCAR-code.git
synced 2025-04-05 10:40:42 +00:00
Add leak to 900X, clean up summary stats and old implementation.
This commit is contained in:
parent
d9152436de
commit
ec73958b4a
@ -1590,7 +1590,7 @@ void PRS1DataChunk::AddEvent(PRS1ParsedEvent* const event)
|
||||
m_parsedData.push_back(event);
|
||||
}
|
||||
|
||||
bool PRS1Import::ParseF5EventsFV3()
|
||||
bool PRS1Import::ParseEventsF5V3()
|
||||
{
|
||||
// F5V3 uses a gain of 0.125 rather than 0.1 to allow for a maximum value of 30 cmH2O
|
||||
static const float GAIN = 0.125F; // TODO: parameterize this somewhere better
|
||||
@ -1622,16 +1622,7 @@ bool PRS1Import::ParseF5EventsFV3()
|
||||
// On-demand channels
|
||||
EventList *PP = nullptr;
|
||||
|
||||
// Unintentional leak calculation, see zMaskProfile:calcLeak in calcs.cpp for explanation
|
||||
EventDataType currentPressure=0, leak;
|
||||
|
||||
bool calcLeaks = p_profile->cpap->calculateUnintentionalLeaks();
|
||||
EventDataType lpm4 = p_profile->cpap->custom4cmH2OLeaks();
|
||||
EventDataType lpm20 = p_profile->cpap->custom20cmH2OLeaks();
|
||||
|
||||
EventDataType lpm = lpm20 - lpm4;
|
||||
EventDataType ppm = lpm / 16.0;
|
||||
|
||||
EventDataType currentPressure=0;
|
||||
|
||||
qint64 duration;
|
||||
qint64 t = qint64(event->timestamp) * 1000L;
|
||||
@ -1695,12 +1686,9 @@ bool PRS1Import::ParseF5EventsFV3()
|
||||
break;
|
||||
case PRS1TotalLeakEvent::TYPE:
|
||||
TOTLEAK->AddEvent(t, e->m_value);
|
||||
leak = e->m_value;
|
||||
if (calcLeaks) { // Much Quicker doing this here than the recalc method.
|
||||
leak -= (((currentPressure/10.0f) - 4.0) * ppm + lpm4);
|
||||
if (leak < 0) leak = 0;
|
||||
LEAK->AddEvent(t, leak);
|
||||
}
|
||||
break;
|
||||
case PRS1LeakEvent::TYPE:
|
||||
LEAK->AddEvent(t, e->m_value);
|
||||
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,
|
||||
@ -1760,156 +1748,6 @@ bool PRS1Import::ParseF5EventsFV3()
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
// 900X series
|
||||
bool PRS1DataChunk::ParseEventsF5V3(void)
|
||||
{
|
||||
if (this->family != 5 || this->familyVersion != 3) {
|
||||
qWarning() << "ParseEventsF5V3 called with family" << this->family << "familyVersion" << this->familyVersion;
|
||||
return false;
|
||||
}
|
||||
|
||||
EventDataType data0, data1, data2, data3, data4, data5;
|
||||
Q_UNUSED(data3)
|
||||
|
||||
int t = 0;
|
||||
int pos = 0;
|
||||
//int cnt = 0;
|
||||
short delta;//,duration;
|
||||
//bool badcode = false;
|
||||
unsigned char lastcode3 = 0, lastcode2 = 0, lastcode = 0, code = 0;
|
||||
int lastpos = 0, startpos = 0, lastpos2 = 0, lastpos3 = 0;
|
||||
|
||||
int size = this->m_data.size();
|
||||
unsigned char * buffer = (unsigned char *)this->m_data.data();
|
||||
|
||||
while (pos < size) {
|
||||
lastcode3 = lastcode2;
|
||||
lastcode2 = lastcode;
|
||||
lastcode = code;
|
||||
lastpos3 = lastpos2;
|
||||
lastpos2 = lastpos;
|
||||
lastpos = startpos;
|
||||
startpos = pos;
|
||||
code = buffer[pos++];
|
||||
|
||||
if (code >= 0x12) {
|
||||
qDebug() << "Illegal PRS1 code " << hex << int(code) << " appeared at " << hex << startpos << "in" << this->sessionid;;
|
||||
qDebug() << "1: (" << int(lastcode) << hex << lastpos << ")";
|
||||
qDebug() << "2: (" << int(lastcode2) << hex << lastpos2 << ")";
|
||||
qDebug() << "3: (" << int(lastcode3) << hex << lastpos3 << ")";
|
||||
this->AddEvent(new PRS1UnknownDataEvent(m_data, startpos));
|
||||
return false;
|
||||
}
|
||||
delta = buffer[pos];
|
||||
//delta=buffer[pos+1] << 8 | buffer[pos];
|
||||
pos += 2;
|
||||
t += delta;
|
||||
|
||||
switch(code) {
|
||||
case 0x01: // Leak ???
|
||||
data0 = buffer[pos++];
|
||||
//tt -= qint64(data0) * 1000L; // Subtract Time Offset
|
||||
break;
|
||||
case 0x02: // Meh??? Timed Breath??
|
||||
data0 = buffer[pos++];
|
||||
this->AddEvent(new PRS1TimedBreathEvent(t - data0, data0));
|
||||
break;
|
||||
case 0x03: // Graph Data
|
||||
data0 = buffer[pos++];
|
||||
this->AddEvent(new PRS1IPAPEvent(t, data0)); // 00=IAP
|
||||
data4 = buffer[pos++];
|
||||
this->AddEvent(new PRS1IPAPLowEvent(t, data4)); // 01=IAP Low
|
||||
data5 = buffer[pos++];
|
||||
this->AddEvent(new PRS1IPAPHighEvent(t, data5)); // 02=IAP High
|
||||
this->AddEvent(new PRS1TotalLeakEvent(t, buffer[pos++])); // 03=LEAK
|
||||
|
||||
|
||||
this->AddEvent(new PRS1RespiratoryRateEvent(t, buffer[pos++])); // 04=Breaths Per Minute
|
||||
this->AddEvent(new PRS1PatientTriggeredBreathsEvent(t, buffer[pos++])); // 05=Patient Triggered Breaths
|
||||
this->AddEvent(new PRS1MinuteVentilationEvent(t, buffer[pos++])); // 06=Minute Ventilation
|
||||
//tmp=buffer[pos++] * 10.0;
|
||||
this->AddEvent(new PRS1TidalVolumeEvent(t, buffer[pos++])); // 07=Tidal Volume
|
||||
this->AddEvent(new PRS1SnoreEvent(t, buffer[pos++])); // 08=Snore
|
||||
this->AddEvent(new PRS1EPAPEvent(t, buffer[pos++])); // 09=EPAP
|
||||
data0 = buffer[pos++];
|
||||
|
||||
|
||||
break;
|
||||
case 0x05:
|
||||
data0 = buffer[pos++];
|
||||
this->AddEvent(new PRS1ObstructiveApneaEvent(t - data0, data0));
|
||||
|
||||
// PS->AddEvent(tt, data0);
|
||||
break;
|
||||
case 0x06: // Clear Airway
|
||||
data0 = buffer[pos++];
|
||||
this->AddEvent(new PRS1ClearAirwayEvent(t - data0, data0));
|
||||
|
||||
// PTB->AddEvent(tt, data0);
|
||||
break;
|
||||
case 0x07:
|
||||
data0 = buffer[pos++];
|
||||
data1 = buffer[pos++];
|
||||
//tt -= qint64(data0) * 1000L; // Subtract Time Offset
|
||||
|
||||
|
||||
break;
|
||||
case 0x08: // Flow Limitation
|
||||
data0 = buffer[pos++];
|
||||
this->AddEvent(new PRS1FlowLimitationEvent(t - data0, data0));
|
||||
break;
|
||||
case 0x09:
|
||||
data0 = buffer[pos++];
|
||||
data1 = buffer[pos++];
|
||||
data2 = buffer[pos++];
|
||||
data3 = buffer[pos++];
|
||||
//tt -= qint64(data0) * 1000L; // Subtract Time Offset
|
||||
|
||||
|
||||
// TB->AddEvent(tt, data0);
|
||||
break;
|
||||
case 0x0a: // Periodic Breathing?
|
||||
data0 = (buffer[pos + 1] << 8 | buffer[pos]);
|
||||
data0 *= 2;
|
||||
pos += 2;
|
||||
data1 = buffer[pos++];
|
||||
this->AddEvent(new PRS1PeriodicBreathingEvent(t - data1, data0));
|
||||
|
||||
break;
|
||||
case 0x0b: // Large Leak
|
||||
data0 = (buffer[pos + 1] << 8 | buffer[pos]);
|
||||
data0 *= 2;
|
||||
pos += 2;
|
||||
data1 = buffer[pos++];
|
||||
this->AddEvent(new PRS1LargeLeakEvent(t - data1, data0));
|
||||
|
||||
break;
|
||||
case 0x0d: // flag ??
|
||||
data0 = buffer[pos++];
|
||||
this->AddEvent(new PRS1HypopneaEvent(t - data0, data0));
|
||||
|
||||
|
||||
break;
|
||||
case 0x0e:
|
||||
data0 = buffer[pos++];
|
||||
this->AddEvent(new PRS1HypopneaEvent(t - data0, data0));
|
||||
|
||||
break;
|
||||
default:
|
||||
qDebug() << "Unknown code:" << hex << code << "in" << this->sessionid << "at" << startpos;
|
||||
this->AddEvent(new PRS1UnknownDataEvent(m_data, startpos));
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// Outer loop based on ParseSummaryF5V3 along with hint as to event codes from old ParseEventsF5V3,
|
||||
// except this actually does something with the data.
|
||||
bool PRS1DataChunk::ParseEventsF5V3(void)
|
||||
@ -1979,14 +1817,14 @@ bool PRS1DataChunk::ParseEventsF5V3(void)
|
||||
this->AddEvent(new PRS1IPAPEvent(t, data[pos++], GAIN)); // 00=IPAP (average?)
|
||||
this->AddEvent(new PRS1IPAPLowEvent(t, data[pos++], GAIN)); // 01=IAP Low
|
||||
this->AddEvent(new PRS1IPAPHighEvent(t, data[pos++], GAIN)); // 02=IAP High
|
||||
this->AddEvent(new PRS1TotalLeakEvent(t, data[pos++])); // 03=LEAK (average?)
|
||||
this->AddEvent(new PRS1TotalLeakEvent(t, data[pos++])); // 03=Total leak (average?)
|
||||
this->AddEvent(new PRS1RespiratoryRateEvent(t, data[pos++])); // 04=Breaths Per Minute (average?)
|
||||
this->AddEvent(new PRS1PatientTriggeredBreathsEvent(t, data[pos++])); // 05=Patient Triggered Breaths (average?)
|
||||
this->AddEvent(new PRS1MinuteVentilationEvent(t, data[pos++])); // 06=Minute Ventilation (average?)
|
||||
this->AddEvent(new PRS1TidalVolumeEvent(t, data[pos++])); // 07=Tidal Volume (average?)
|
||||
this->AddEvent(new PRS1SnoreEvent(t, data[pos++])); // 08=Snore count // TODO: not a VS on official waveform, but appears in flags and contributes to overall VS index
|
||||
this->AddEvent(new PRS1EPAPEvent(t, data[pos++], GAIN)); // 09=EPAP (average? see event 1 above)
|
||||
//data0 = data[pos++]; // 0A = ??? TODO: what is this? should probably graph it as a test channel
|
||||
this->AddEvent(new PRS1LeakEvent(t, data[pos++])); // 0A=Leak (average?)
|
||||
break;
|
||||
case 0x04: // Pressure Pulse
|
||||
duration = data[pos++]; // TODO: is this a duration?
|
||||
@ -2061,7 +1899,6 @@ bool PRS1DataChunk::ParseEventsF5V3(void)
|
||||
default:
|
||||
qWarning() << "Unknown event:" << code << "in" << this->sessionid << "at" << startpos-1;
|
||||
this->AddEvent(new PRS1UnknownDataEvent(m_data, startpos-1, size+1));
|
||||
//UNEXPECTED_VALUE(code, "known event code");
|
||||
break;
|
||||
}
|
||||
pos = startpos + size;
|
||||
@ -4582,22 +4419,22 @@ bool PRS1DataChunk::ParseSummaryF5V3(void)
|
||||
//CHECK_VALUE(data[pos+0xb], 0x00);
|
||||
//CHECK_VALUE(data[pos+0xc], 0x14); // 16-bit VS count
|
||||
//CHECK_VALUE(data[pos+0xd], 0x00);
|
||||
//CHECK_VALUE(data[pos+0xe], 0x05); // probably 16-bit value (VS count in F0V6)?
|
||||
CHECK_VALUE(data[pos+0xf], 0x00);
|
||||
//CHECK_VALUE(data[pos+0x10], 0x00); // probably 16-bit value (maybe H count in F0V6?)
|
||||
CHECK_VALUE(data[pos+0x11], 0x00);
|
||||
//CHECK_VALUE(data[pos+0xe], 0x05); // 16-bit H count for type 0xd
|
||||
//CHECK_VALUE(data[pos+0xf], 0x00);
|
||||
//CHECK_VALUE(data[pos+0x10], 0x00); // 16-bit H count for type 7
|
||||
//CHECK_VALUE(data[pos+0x11], 0x00);
|
||||
//CHECK_VALUE(data[pos+0x12], 0x02); // 16-bit FL count
|
||||
//CHECK_VALUE(data[pos+0x13], 0x00);
|
||||
//CHECK_VALUE(data[pos+0x14], 0x28); // 0x69 (105)
|
||||
//CHECK_VALUE(data[pos+0x15], 0x17); // average total leak
|
||||
//CHECK_VALUE(data[pos+0x16], 0x5b); // 0x7d (125)
|
||||
//CHECK_VALUE(data[pos+0x17], 0x09); // 0x00
|
||||
CHECK_VALUE(data[pos+0x18], 0x00);
|
||||
//CHECK_VALUE(data[pos+0x17], 0x09); // 16-bit H count for type 0xe
|
||||
//CHECK_VALUE(data[pos+0x18], 0x00);
|
||||
//CHECK_VALUE(data[pos+0x19], 0x10); // average breath rate
|
||||
//CHECK_VALUE(data[pos+0x1a], 0x2d); // average TV / 10
|
||||
//CHECK_VALUE(data[pos+0x1b], 0x63); // average % PTB
|
||||
//CHECK_VALUE(data[pos+0x1c], 0x07); // average minute vent
|
||||
//CHECK_VALUE(data[pos+0x1d], 0x06); // 0x51 (81)
|
||||
//CHECK_VALUE(data[pos+0x1d], 0x06); // average leak
|
||||
break;
|
||||
case 2: // Equipment Off
|
||||
tt += data[pos] | (data[pos+1] << 8);
|
||||
@ -5132,7 +4969,7 @@ bool PRS1Import::ParseEvents()
|
||||
break;
|
||||
case 5:
|
||||
if (event->fileVersion==3) {
|
||||
res = ParseF5EventsFV3();
|
||||
res = ParseEventsF5V3();
|
||||
} else {
|
||||
res = ParseF5Events();
|
||||
}
|
||||
|
@ -276,7 +276,7 @@ public:
|
||||
//! \brief Parse a single data chunk from a .002 file containing event data for a family 5 ASV machine (which has a different format)
|
||||
bool ParseF5Events();
|
||||
//! \brief Parse a single data chunk from a .002 file containing event data for a family 5 ASV file version 3 machine (which has a different format again)
|
||||
bool ParseF5EventsFV3();
|
||||
bool ParseEventsF5V3();
|
||||
|
||||
|
||||
protected:
|
||||
|
Loading…
Reference in New Issue
Block a user