mirror of
https://gitlab.com/pholy/OSCAR-code.git
synced 2025-04-08 04:00:44 +00:00
Improve event duplicate check, added resync preference
This commit is contained in:
parent
4f3e2ff37d
commit
86eed559ad
@ -22,7 +22,7 @@
|
|||||||
extern double round(double number);
|
extern double round(double number);
|
||||||
|
|
||||||
|
|
||||||
bool SearchEvent(Session * session, ChannelID code, qint64 time, EventStoreType dur, qint64 dist)
|
bool SearchEvent(Session * session, ChannelID code, qint64 time, int dur, bool update=true)
|
||||||
{
|
{
|
||||||
qint64 t, start;
|
qint64 t, start;
|
||||||
QHash<ChannelID, QVector<EventList *> >::iterator it;
|
QHash<ChannelID, QVector<EventList *> >::iterator it;
|
||||||
@ -34,9 +34,10 @@ bool SearchEvent(Session * session, ChannelID code, qint64 time, EventStoreType
|
|||||||
int cnt;
|
int cnt;
|
||||||
|
|
||||||
//qint64 rate;
|
//qint64 rate;
|
||||||
bool fixdurations = (session->machine()->GetClass() != STR_MACH_ResMed);
|
// bool fixdurations = (session->machine()->GetClass() != STR_MACH_ResMed);
|
||||||
if (!fixdurations) {
|
|
||||||
dur=0;
|
if (!p_profile->cpap->resyncFromUserFlagging()) {
|
||||||
|
update=false;
|
||||||
}
|
}
|
||||||
|
|
||||||
QHash<ChannelID, QVector<EventList *> >::iterator evend = session->eventlist.end();
|
QHash<ChannelID, QVector<EventList *> >::iterator evend = session->eventlist.end();
|
||||||
@ -59,12 +60,22 @@ bool SearchEvent(Session * session, ChannelID code, qint64 time, EventStoreType
|
|||||||
for (int j = 0; j < cnt; j++) {
|
for (int j = 0; j < cnt; j++) {
|
||||||
t = start + *tptr;
|
t = start + *tptr;
|
||||||
|
|
||||||
if (qAbs(time - t) < dist) {
|
// Move the position and set the duration
|
||||||
|
qint64 end1 = time + 5000L;
|
||||||
|
qint64 start1 = end1 - quint64(dur+10)*1000L;
|
||||||
|
|
||||||
// Move the position and set the duration
|
qint64 end2 = t + 5000L;
|
||||||
if (dur>0) {
|
qint64 start2 = end2 - quint64(*dptr+10)*1000L;
|
||||||
*tptr = time - start;
|
|
||||||
*dptr = (EventStoreType)dur;
|
bool overlap = (start1 <= end2) && (start2 <= end1);
|
||||||
|
|
||||||
|
if (overlap) {
|
||||||
|
if (update) {
|
||||||
|
qint32 delta = time-start;
|
||||||
|
if (delta >= 0) {
|
||||||
|
*tptr = delta;
|
||||||
|
*dptr = (EventStoreType)dur;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -78,27 +89,26 @@ bool SearchEvent(Session * session, ChannelID code, qint64 time, EventStoreType
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SearchApnea(Session *session, qint64 time, double dur, qint64 dist)
|
bool SearchApnea(Session *session, qint64 time, double dur)
|
||||||
{
|
{
|
||||||
if (session->SearchEvent(CPAP_UserFlag1, time, dist))
|
if (SearchEvent(session, CPAP_Obstructive, time, dur))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (session->SearchEvent(CPAP_UserFlag2, time, dist))
|
if (SearchEvent(session, CPAP_Apnea, time, dur))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (SearchEvent(session, CPAP_Obstructive, time, dur, dist))
|
if (SearchEvent(session, CPAP_ClearAirway, time, dur))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (SearchEvent(session, CPAP_Apnea, time, dur, dist))
|
if (SearchEvent(session, CPAP_Hypopnea, time, dur, false))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (SearchEvent(session, CPAP_ClearAirway, time, dur, dist))
|
if (SearchEvent(session, CPAP_UserFlag1, time, dur, false))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
if (SearchEvent(session, CPAP_Hypopnea, time, dur, dist))
|
if (SearchEvent(session, CPAP_UserFlag2, time, dur, false))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -776,13 +786,13 @@ void FlowParser::flagUserEvents(ChannelID code, EventDataType restriction, Event
|
|||||||
bs = bend[i];
|
bs = bend[i];
|
||||||
be = bstart[i + 1];
|
be = bstart[i + 1];
|
||||||
st = start + bs * m_rate;
|
st = start + bs * m_rate;
|
||||||
et = start + be * m_rate;
|
et = start + be * m_rate;
|
||||||
|
|
||||||
len = et - st;
|
len = et - st;
|
||||||
dur = len / 1000.0;
|
dur = len / 1000.0;
|
||||||
|
|
||||||
if (dur >= duration) {
|
if (dur >= duration) {
|
||||||
if (allowDuplicates || !SearchApnea(m_session, et, dur, 15000)) {
|
if (allowDuplicates || !SearchApnea(m_session, et, dur)) {
|
||||||
if (!uf) {
|
if (!uf) {
|
||||||
uf = m_session->AddEventList(code, EVL_Event);
|
uf = m_session->AddEventList(code, EVL_Event);
|
||||||
}
|
}
|
||||||
|
@ -140,7 +140,7 @@ class FlowParser
|
|||||||
EventDataType *m_buffers[num_filter_buffers];
|
EventDataType *m_buffers[num_filter_buffers];
|
||||||
};
|
};
|
||||||
|
|
||||||
bool SearchApnea(Session *session, qint64 time, double dur, qint64 dist = 15000);
|
bool SearchApnea(Session *session, qint64 time, double dur);
|
||||||
|
|
||||||
//! \brief Calculate Respiratory Rate, Tidal Volume & Minute Ventilation for PRS1 data
|
//! \brief Calculate Respiratory Rate, Tidal Volume & Minute Ventilation for PRS1 data
|
||||||
void calcRespRate(Session *session, FlowParser *flowparser = nullptr);
|
void calcRespRate(Session *session, FlowParser *flowparser = nullptr);
|
||||||
|
@ -278,6 +278,8 @@ const QString STR_CS_UserEventDuration = "UserEventDuration";
|
|||||||
const QString STR_CS_UserFlowRestriction2 = "UserFlowRestriction2";
|
const QString STR_CS_UserFlowRestriction2 = "UserFlowRestriction2";
|
||||||
const QString STR_CS_UserEventDuration2 = "UserEventDuration2";
|
const QString STR_CS_UserEventDuration2 = "UserEventDuration2";
|
||||||
const QString STR_CS_UserEventDuplicates = "UserEventDuplicates";
|
const QString STR_CS_UserEventDuplicates = "UserEventDuplicates";
|
||||||
|
const QString STR_CS_ResyncFromUserFlagging = "ResyncFromUserFlagging";
|
||||||
|
|
||||||
const QString STR_CS_AHIWindow = "AHIWindow";
|
const QString STR_CS_AHIWindow = "AHIWindow";
|
||||||
const QString STR_CS_AHIReset = "AHIReset";
|
const QString STR_CS_AHIReset = "AHIReset";
|
||||||
const QString STR_CS_ClockDrift = "ClockDrift";
|
const QString STR_CS_ClockDrift = "ClockDrift";
|
||||||
@ -528,6 +530,7 @@ class CPAPSettings : public ProfileSettings
|
|||||||
initPref(STR_CS_LeakRedline, 24.0);
|
initPref(STR_CS_LeakRedline, 24.0);
|
||||||
initPref(STR_CS_ShowLeakRedline, true);
|
initPref(STR_CS_ShowLeakRedline, true);
|
||||||
initPref(STR_CS_UserEventPieChart, false);
|
initPref(STR_CS_UserEventPieChart, false);
|
||||||
|
initPref(STR_CS_ResyncFromUserFlagging, false);
|
||||||
|
|
||||||
initPref(STR_CS_ClockDrift, (int)0);
|
initPref(STR_CS_ClockDrift, (int)0);
|
||||||
m_clock_drift = getPref(STR_CS_ClockDrift).toInt();
|
m_clock_drift = getPref(STR_CS_ClockDrift).toInt();
|
||||||
@ -558,6 +561,8 @@ class CPAPSettings : public ProfileSettings
|
|||||||
EventDataType leakRedline() const { return getPref(STR_CS_LeakRedline).toFloat(); }
|
EventDataType leakRedline() const { return getPref(STR_CS_LeakRedline).toFloat(); }
|
||||||
bool showLeakRedline() const { return getPref(STR_CS_ShowLeakRedline).toBool(); }
|
bool showLeakRedline() const { return getPref(STR_CS_ShowLeakRedline).toBool(); }
|
||||||
bool userEventPieChart() const { return getPref(STR_CS_UserEventPieChart).toBool(); }
|
bool userEventPieChart() const { return getPref(STR_CS_UserEventPieChart).toBool(); }
|
||||||
|
bool resyncFromUserFlagging() const { return getPref(STR_CS_ResyncFromUserFlagging).toBool(); }
|
||||||
|
|
||||||
|
|
||||||
//Setters
|
//Setters
|
||||||
void setMode(CPAPMode mode) { setPref(STR_CS_PrescribedMode, (int)mode); }
|
void setMode(CPAPMode mode) { setPref(STR_CS_PrescribedMode, (int)mode); }
|
||||||
@ -588,6 +593,7 @@ class CPAPSettings : public ProfileSettings
|
|||||||
void setLeakRedline(EventDataType value) { setPref(STR_CS_LeakRedline, value); }
|
void setLeakRedline(EventDataType value) { setPref(STR_CS_LeakRedline, value); }
|
||||||
void setShowLeakRedline(bool reset) { setPref(STR_CS_ShowLeakRedline, reset); }
|
void setShowLeakRedline(bool reset) { setPref(STR_CS_ShowLeakRedline, reset); }
|
||||||
void setUserEventPieChart(bool b) { setPref(STR_CS_UserEventPieChart, b); }
|
void setUserEventPieChart(bool b) { setPref(STR_CS_UserEventPieChart, b); }
|
||||||
|
void setResyncFromUserFlagging(bool b) { setPref(STR_CS_ResyncFromUserFlagging, b); }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
int m_clock_drift;
|
int m_clock_drift;
|
||||||
|
@ -171,6 +171,7 @@ PreferencesDialog::PreferencesDialog(QWidget *parent, Profile *_profile) :
|
|||||||
ui->maskTypeCombo->setCurrentIndex(mt);
|
ui->maskTypeCombo->setCurrentIndex(mt);
|
||||||
on_maskTypeCombo_activated(mt);
|
on_maskTypeCombo_activated(mt);
|
||||||
|
|
||||||
|
ui->resyncMachineDetectedEvents->setChecked(profile->cpap->resyncFromUserFlagging());
|
||||||
|
|
||||||
ui->maskDescription->setText(profile->cpap->maskDescription());
|
ui->maskDescription->setText(profile->cpap->maskDescription());
|
||||||
ui->useAntiAliasing->setChecked(profile->appearance->antiAliasing());
|
ui->useAntiAliasing->setChecked(profile->appearance->antiAliasing());
|
||||||
@ -491,6 +492,7 @@ bool PreferencesDialog::Save()
|
|||||||
|
|
||||||
profile->cpap->setUserEventFlagging(ui->customEventGroupbox->isChecked());
|
profile->cpap->setUserEventFlagging(ui->customEventGroupbox->isChecked());
|
||||||
|
|
||||||
|
profile->cpap->setResyncFromUserFlagging(ui->resyncMachineDetectedEvents->isChecked());
|
||||||
profile->cpap->setUserEventDuration(ui->apneaDuration->value());
|
profile->cpap->setUserEventDuration(ui->apneaDuration->value());
|
||||||
profile->cpap->setUserFlowRestriction(ui->apneaFlowRestriction->value());
|
profile->cpap->setUserFlowRestriction(ui->apneaFlowRestriction->value());
|
||||||
profile->cpap->setUserEventDuration2(ui->apneaDuration2->value());
|
profile->cpap->setUserEventDuration2(ui->apneaDuration2->value());
|
||||||
|
@ -878,6 +878,83 @@ This option must be enabled before import, otherwise a purge is required.</strin
|
|||||||
<property name="spacing">
|
<property name="spacing">
|
||||||
<number>4</number>
|
<number>4</number>
|
||||||
</property>
|
</property>
|
||||||
|
<item row="3" column="1">
|
||||||
|
<widget class="QDoubleSpinBox" name="apneaFlowRestriction2">
|
||||||
|
<property name="suffix">
|
||||||
|
<string>%</string>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<double>10.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="1" colspan="5">
|
||||||
|
<widget class="QCheckBox" name="showUserFlagsInPie">
|
||||||
|
<property name="text">
|
||||||
|
<string>Show in Event Breakdown Piechart</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="0">
|
||||||
|
<widget class="QLabel" name="label_49">
|
||||||
|
<property name="text">
|
||||||
|
<string>#1</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QLabel" name="label_50">
|
||||||
|
<property name="text">
|
||||||
|
<string>#2</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1">
|
||||||
|
<widget class="QLabel" name="label_35">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Flow Restriction</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="3">
|
||||||
|
<widget class="QDoubleSpinBox" name="apneaDuration2">
|
||||||
|
<property name="suffix">
|
||||||
|
<string>s</string>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<double>10.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="3">
|
||||||
|
<widget class="QLabel" name="label_38">
|
||||||
|
<property name="text">
|
||||||
|
<string>Event Duration</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="3">
|
||||||
|
<widget class="QDoubleSpinBox" name="apneaDuration">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Duration of airflow restriction</string>
|
||||||
|
</property>
|
||||||
|
<property name="suffix">
|
||||||
|
<string>s</string>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<double>1.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<double>10.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item row="2" column="1">
|
<item row="2" column="1">
|
||||||
<widget class="QDoubleSpinBox" name="apneaFlowRestriction">
|
<widget class="QDoubleSpinBox" name="apneaFlowRestriction">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
@ -898,33 +975,14 @@ A value of 20% works well for detecting apneas. </string>
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="4">
|
<item row="6" column="1" colspan="5">
|
||||||
<spacer name="horizontalSpacer_4">
|
<widget class="QCheckBox" name="userEventDuplicates">
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>40</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="1">
|
|
||||||
<widget class="QLabel" name="label_35">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Flow Restriction</string>
|
<string>Allow duplicates near machine events.</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="0" colspan="5">
|
<item row="0" column="0" colspan="6">
|
||||||
<widget class="QLabel" name="label_34">
|
<widget class="QLabel" name="label_34">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
|
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
|
||||||
@ -952,74 +1010,26 @@ p, li { white-space: pre-wrap; }
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="3">
|
<item row="2" column="5">
|
||||||
<widget class="QDoubleSpinBox" name="apneaDuration">
|
<spacer name="horizontalSpacer_4">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="1" colspan="5">
|
||||||
|
<widget class="QCheckBox" name="resyncMachineDetectedEvents">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>Duration of airflow restriction</string>
|
<string>This experimental option attempts to use SleepyHead's event flagging system to improve machine detected event positioning.</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="suffix">
|
|
||||||
<string>s</string>
|
|
||||||
</property>
|
|
||||||
<property name="minimum">
|
|
||||||
<double>1.000000000000000</double>
|
|
||||||
</property>
|
|
||||||
<property name="value">
|
|
||||||
<double>10.000000000000000</double>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="3">
|
|
||||||
<widget class="QLabel" name="label_38">
|
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Event Duration</string>
|
<string>Resync Machine Detected Events (Experimental)</string>
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="1">
|
|
||||||
<widget class="QDoubleSpinBox" name="apneaFlowRestriction2">
|
|
||||||
<property name="suffix">
|
|
||||||
<string>%</string>
|
|
||||||
</property>
|
|
||||||
<property name="value">
|
|
||||||
<double>10.000000000000000</double>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="0">
|
|
||||||
<widget class="QLabel" name="label_50">
|
|
||||||
<property name="text">
|
|
||||||
<string>#2</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="5" column="1" colspan="4">
|
|
||||||
<widget class="QCheckBox" name="userEventDuplicates">
|
|
||||||
<property name="text">
|
|
||||||
<string>Allow duplicates near machine events.</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="3">
|
|
||||||
<widget class="QDoubleSpinBox" name="apneaDuration2">
|
|
||||||
<property name="suffix">
|
|
||||||
<string>s</string>
|
|
||||||
</property>
|
|
||||||
<property name="value">
|
|
||||||
<double>10.000000000000000</double>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="0">
|
|
||||||
<widget class="QLabel" name="label_49">
|
|
||||||
<property name="text">
|
|
||||||
<string>#1</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="1" colspan="4">
|
|
||||||
<widget class="QCheckBox" name="showUserFlagsInPie">
|
|
||||||
<property name="text">
|
|
||||||
<string>Show in Event Breakdown Piechart</string>
|
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
Loading…
Reference in New Issue
Block a user