mirror of
https://gitlab.com/pholy/OSCAR-code.git
synced 2025-04-21 21:20:45 +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);
|
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
|
// 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
|
static const float GAIN = 0.125F; // TODO: parameterize this somewhere better
|
||||||
@ -1622,16 +1622,7 @@ bool PRS1Import::ParseF5EventsFV3()
|
|||||||
// On-demand channels
|
// On-demand channels
|
||||||
EventList *PP = nullptr;
|
EventList *PP = nullptr;
|
||||||
|
|
||||||
// Unintentional leak calculation, see zMaskProfile:calcLeak in calcs.cpp for explanation
|
EventDataType currentPressure=0;
|
||||||
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;
|
|
||||||
|
|
||||||
|
|
||||||
qint64 duration;
|
qint64 duration;
|
||||||
qint64 t = qint64(event->timestamp) * 1000L;
|
qint64 t = qint64(event->timestamp) * 1000L;
|
||||||
@ -1695,12 +1686,9 @@ bool PRS1Import::ParseF5EventsFV3()
|
|||||||
break;
|
break;
|
||||||
case PRS1TotalLeakEvent::TYPE:
|
case PRS1TotalLeakEvent::TYPE:
|
||||||
TOTLEAK->AddEvent(t, e->m_value);
|
TOTLEAK->AddEvent(t, e->m_value);
|
||||||
leak = e->m_value;
|
break;
|
||||||
if (calcLeaks) { // Much Quicker doing this here than the recalc method.
|
case PRS1LeakEvent::TYPE:
|
||||||
leak -= (((currentPressure/10.0f) - 4.0) * ppm + lpm4);
|
LEAK->AddEvent(t, e->m_value);
|
||||||
if (leak < 0) leak = 0;
|
|
||||||
LEAK->AddEvent(t, leak);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case PRS1SnoreEvent::TYPE: // snore count that shows up in flags but not waveform
|
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,
|
// 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,
|
// Outer loop based on ParseSummaryF5V3 along with hint as to event codes from old ParseEventsF5V3,
|
||||||
// except this actually does something with the data.
|
// except this actually does something with the data.
|
||||||
bool PRS1DataChunk::ParseEventsF5V3(void)
|
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 PRS1IPAPEvent(t, data[pos++], GAIN)); // 00=IPAP (average?)
|
||||||
this->AddEvent(new PRS1IPAPLowEvent(t, data[pos++], GAIN)); // 01=IAP Low
|
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 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 PRS1RespiratoryRateEvent(t, data[pos++])); // 04=Breaths Per Minute (average?)
|
||||||
this->AddEvent(new PRS1PatientTriggeredBreathsEvent(t, data[pos++])); // 05=Patient Triggered Breaths (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 PRS1MinuteVentilationEvent(t, data[pos++])); // 06=Minute Ventilation (average?)
|
||||||
this->AddEvent(new PRS1TidalVolumeEvent(t, data[pos++])); // 07=Tidal Volume (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 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)
|
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;
|
break;
|
||||||
case 0x04: // Pressure Pulse
|
case 0x04: // Pressure Pulse
|
||||||
duration = data[pos++]; // TODO: is this a duration?
|
duration = data[pos++]; // TODO: is this a duration?
|
||||||
@ -2061,7 +1899,6 @@ bool PRS1DataChunk::ParseEventsF5V3(void)
|
|||||||
default:
|
default:
|
||||||
qWarning() << "Unknown event:" << code << "in" << this->sessionid << "at" << startpos-1;
|
qWarning() << "Unknown event:" << code << "in" << this->sessionid << "at" << startpos-1;
|
||||||
this->AddEvent(new PRS1UnknownDataEvent(m_data, startpos-1, size+1));
|
this->AddEvent(new PRS1UnknownDataEvent(m_data, startpos-1, size+1));
|
||||||
//UNEXPECTED_VALUE(code, "known event code");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
pos = startpos + size;
|
pos = startpos + size;
|
||||||
@ -4582,22 +4419,22 @@ bool PRS1DataChunk::ParseSummaryF5V3(void)
|
|||||||
//CHECK_VALUE(data[pos+0xb], 0x00);
|
//CHECK_VALUE(data[pos+0xb], 0x00);
|
||||||
//CHECK_VALUE(data[pos+0xc], 0x14); // 16-bit VS count
|
//CHECK_VALUE(data[pos+0xc], 0x14); // 16-bit VS count
|
||||||
//CHECK_VALUE(data[pos+0xd], 0x00);
|
//CHECK_VALUE(data[pos+0xd], 0x00);
|
||||||
//CHECK_VALUE(data[pos+0xe], 0x05); // probably 16-bit value (VS count in F0V6)?
|
//CHECK_VALUE(data[pos+0xe], 0x05); // 16-bit H count for type 0xd
|
||||||
CHECK_VALUE(data[pos+0xf], 0x00);
|
//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+0x10], 0x00); // 16-bit H count for type 7
|
||||||
CHECK_VALUE(data[pos+0x11], 0x00);
|
//CHECK_VALUE(data[pos+0x11], 0x00);
|
||||||
//CHECK_VALUE(data[pos+0x12], 0x02); // 16-bit FL count
|
//CHECK_VALUE(data[pos+0x12], 0x02); // 16-bit FL count
|
||||||
//CHECK_VALUE(data[pos+0x13], 0x00);
|
//CHECK_VALUE(data[pos+0x13], 0x00);
|
||||||
//CHECK_VALUE(data[pos+0x14], 0x28); // 0x69 (105)
|
//CHECK_VALUE(data[pos+0x14], 0x28); // 0x69 (105)
|
||||||
//CHECK_VALUE(data[pos+0x15], 0x17); // average total leak
|
//CHECK_VALUE(data[pos+0x15], 0x17); // average total leak
|
||||||
//CHECK_VALUE(data[pos+0x16], 0x5b); // 0x7d (125)
|
//CHECK_VALUE(data[pos+0x16], 0x5b); // 0x7d (125)
|
||||||
//CHECK_VALUE(data[pos+0x17], 0x09); // 0x00
|
//CHECK_VALUE(data[pos+0x17], 0x09); // 16-bit H count for type 0xe
|
||||||
CHECK_VALUE(data[pos+0x18], 0x00);
|
//CHECK_VALUE(data[pos+0x18], 0x00);
|
||||||
//CHECK_VALUE(data[pos+0x19], 0x10); // average breath rate
|
//CHECK_VALUE(data[pos+0x19], 0x10); // average breath rate
|
||||||
//CHECK_VALUE(data[pos+0x1a], 0x2d); // average TV / 10
|
//CHECK_VALUE(data[pos+0x1a], 0x2d); // average TV / 10
|
||||||
//CHECK_VALUE(data[pos+0x1b], 0x63); // average % PTB
|
//CHECK_VALUE(data[pos+0x1b], 0x63); // average % PTB
|
||||||
//CHECK_VALUE(data[pos+0x1c], 0x07); // average minute vent
|
//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;
|
break;
|
||||||
case 2: // Equipment Off
|
case 2: // Equipment Off
|
||||||
tt += data[pos] | (data[pos+1] << 8);
|
tt += data[pos] | (data[pos+1] << 8);
|
||||||
@ -5132,7 +4969,7 @@ bool PRS1Import::ParseEvents()
|
|||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
if (event->fileVersion==3) {
|
if (event->fileVersion==3) {
|
||||||
res = ParseF5EventsFV3();
|
res = ParseEventsF5V3();
|
||||||
} else {
|
} else {
|
||||||
res = ParseF5Events();
|
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)
|
//! \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();
|
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)
|
//! \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:
|
protected:
|
||||||
|
Loading…
Reference in New Issue
Block a user