mirror of
https://gitlab.com/pholy/OSCAR-code.git
synced 2025-04-05 02:30:44 +00:00
386 lines
10 KiB
C++
386 lines
10 KiB
C++
/* SleepLib RESMED Loader Header
|
|
*
|
|
* Copyright (C) 2011-2018 Mark Watkins <mark@jedimark.net>
|
|
*
|
|
* This file is subject to the terms and conditions of the GNU General Public
|
|
* License. See the file COPYING in the main directory of the source code
|
|
* for more details. */
|
|
|
|
#ifndef RESMED_LOADER_H
|
|
#define RESMED_LOADER_H
|
|
|
|
#include <QVector>
|
|
#include "SleepLib/machine.h" // Base class: MachineLoader
|
|
#include "SleepLib/machine_loader.h"
|
|
#include "SleepLib/profiles.h"
|
|
#include "SleepLib/loader_plugins/edfparser.h"
|
|
|
|
//********************************************************************************************
|
|
/// IMPORTANT!!!
|
|
//********************************************************************************************
|
|
// Please INCREMENT the following value when making changes to this loaders implementation.
|
|
//
|
|
const int resmed_data_version = 11;
|
|
//
|
|
//********************************************************************************************
|
|
|
|
enum EDFType { EDF_UNKNOWN, EDF_BRP, EDF_PLD, EDF_SAD, EDF_EVE, EDF_CSL };
|
|
|
|
EDFType lookupEDFType(const QString & text);
|
|
|
|
const QString resmed_class_name = STR_MACH_ResMed;
|
|
|
|
class ResMedEDFInfo : public EDFInfo
|
|
{
|
|
public:
|
|
ResMedEDFInfo();
|
|
~ResMedEDFInfo();
|
|
|
|
virtual bool Parse(QByteArray * fileData) override; // overrides and calls the super's Parse
|
|
|
|
virtual qint64 GetDurationMillis() { return dur_data_record; } // overrides the super
|
|
|
|
EDFSignal *lookupSignal(ChannelID ch);
|
|
|
|
|
|
|
|
//! \brief The following are computed from the edfHdr data
|
|
QString serialnumber;
|
|
qint64 dur_data_record;
|
|
qint64 startdate;
|
|
qint64 enddate;
|
|
|
|
};
|
|
|
|
class EDFduration
|
|
{
|
|
public:
|
|
EDFduration() { start = end = 0; type = EDF_UNKNOWN; }
|
|
EDFduration(quint32 start, quint32 end, QString path) :
|
|
start(start), end(end), path(path) {}
|
|
|
|
quint32 start;
|
|
quint32 end;
|
|
QString path;
|
|
QString filename;
|
|
EDFType type;
|
|
};
|
|
|
|
|
|
class STRRecord
|
|
{
|
|
public:
|
|
STRRecord() {
|
|
maskon.clear();
|
|
maskoff.clear();
|
|
maskdur = 0;
|
|
maskevents = -1;
|
|
mode = -1;
|
|
rms9_mode = -1;
|
|
set_pressure = -1;
|
|
epap = -1;
|
|
max_pressure = -1;
|
|
min_pressure = -1;
|
|
max_epap = -1;
|
|
min_epap = -1;
|
|
max_ps = -1;
|
|
min_ps = -1;
|
|
ps = -1;
|
|
ipap = -1;
|
|
max_ipap = -1;
|
|
min_ipap = -1;
|
|
epr = -1;
|
|
epr_level = -1;
|
|
sessionid = 0;
|
|
|
|
ahi = -1;
|
|
oai = -1;
|
|
ai = -1;
|
|
hi = -1;
|
|
uai = -1;
|
|
cai = -1;
|
|
csr = -1;
|
|
|
|
leak50 = -1;
|
|
leak95 = -1;
|
|
leakmax = -1;
|
|
|
|
rr50 = -1;
|
|
rr95 = -1;
|
|
rrmax = -1;
|
|
|
|
mv50 = -1;
|
|
mv95 = -1;
|
|
mvmax = -1;
|
|
|
|
ie50 = -1;
|
|
ie95 = -1;
|
|
iemax = -1;
|
|
|
|
tv50 = -1;
|
|
tv95 = -1;
|
|
tvmax = -1;
|
|
|
|
mp50 = -1;
|
|
mp95 = -1;
|
|
mpmax = -1;
|
|
|
|
tgtepap50 = -1;
|
|
tgtepap95 = -1;
|
|
tgtepapmax = -1;
|
|
|
|
tgtipap50 = -1;
|
|
tgtipap95 = -1;
|
|
tgtipapmax = -1;
|
|
|
|
s_RampTime = -1;
|
|
s_RampEnable = -1;
|
|
s_EPR_ClinEnable = -1;
|
|
s_EPREnable = -1;
|
|
|
|
s_PtAccess = -1;
|
|
s_ABFilter = -1;
|
|
s_Mask = -1;
|
|
s_Tube = -1;
|
|
s_ClimateControl = -1;
|
|
s_HumEnable = -1;
|
|
s_HumLevel = -1;
|
|
s_TempEnable = -1;
|
|
s_Temp = -1;
|
|
s_SmartStart = -1;
|
|
|
|
ramp_pressure = -1;
|
|
|
|
date=QDate();
|
|
}
|
|
|
|
// All the data members
|
|
QVector<quint32> maskon;
|
|
QVector<quint32> maskoff;
|
|
|
|
EventDataType maskdur;
|
|
EventDataType maskevents;
|
|
EventDataType mode;
|
|
EventDataType rms9_mode;
|
|
EventDataType set_pressure;
|
|
EventDataType max_pressure;
|
|
EventDataType min_pressure;
|
|
EventDataType epap;
|
|
EventDataType max_ps;
|
|
EventDataType min_ps;
|
|
EventDataType ps;
|
|
EventDataType max_epap;
|
|
EventDataType min_epap;
|
|
EventDataType ipap;
|
|
EventDataType max_ipap;
|
|
EventDataType min_ipap;
|
|
EventDataType epr;
|
|
EventDataType epr_level;
|
|
quint32 sessionid;
|
|
EventDataType ahi;
|
|
EventDataType oai;
|
|
EventDataType ai;
|
|
EventDataType hi;
|
|
EventDataType uai;
|
|
EventDataType cai;
|
|
EventDataType csr;
|
|
EventDataType leak50;
|
|
EventDataType leak95;
|
|
EventDataType leakmax;
|
|
EventDataType rr50;
|
|
EventDataType rr95;
|
|
EventDataType rrmax;
|
|
EventDataType mv50;
|
|
EventDataType mv95;
|
|
EventDataType mvmax;
|
|
EventDataType tv50;
|
|
EventDataType tv95;
|
|
EventDataType tvmax;
|
|
EventDataType mp50;
|
|
EventDataType mp95;
|
|
EventDataType mpmax;
|
|
EventDataType ie50;
|
|
EventDataType ie95;
|
|
EventDataType iemax;
|
|
EventDataType tgtepap50;
|
|
EventDataType tgtepap95;
|
|
EventDataType tgtepapmax;
|
|
EventDataType tgtipap50;
|
|
EventDataType tgtipap95;
|
|
EventDataType tgtipapmax;
|
|
|
|
EventDataType ramp_pressure;
|
|
QDate date;
|
|
|
|
EventDataType s_RampTime;
|
|
int s_RampEnable;
|
|
int s_EPR_ClinEnable;
|
|
int s_EPREnable;
|
|
|
|
int s_PtAccess;
|
|
int s_ABFilter;
|
|
int s_Mask;
|
|
int s_Tube;
|
|
int s_ClimateControl;
|
|
int s_HumEnable;
|
|
EventDataType s_HumLevel;
|
|
int s_TempEnable;
|
|
EventDataType s_Temp;
|
|
int s_SmartStart;
|
|
|
|
};
|
|
|
|
|
|
class ResmedLoader;
|
|
|
|
struct ResMedDay {
|
|
QDate date;
|
|
STRRecord str;
|
|
QHash<QString, QString> files;
|
|
// QHash<QString, EDFduration> durations;
|
|
|
|
};
|
|
|
|
class ResDayTask:public ImportTask
|
|
{
|
|
public:
|
|
ResDayTask(ResmedLoader * l, Machine * m, ResMedDay * d): reimporting(false), loader(l), mach(m), resday(d) {}
|
|
virtual ~ResDayTask() {}
|
|
virtual void run();
|
|
bool reimporting;
|
|
|
|
protected:
|
|
ResmedLoader * loader;
|
|
Machine * mach;
|
|
ResMedDay * resday;
|
|
};
|
|
|
|
class STRFile
|
|
{
|
|
public:
|
|
STRFile() :
|
|
filename(QString()), edf(nullptr) {}
|
|
STRFile(QString name, ResMedEDFInfo *str) :
|
|
filename(name), edf(str) {}
|
|
virtual ~STRFile() {}
|
|
|
|
QString filename;
|
|
ResMedEDFInfo * edf;
|
|
};
|
|
|
|
|
|
|
|
/*! \class ResmedLoader
|
|
\brief Importer for ResMed S9 Data
|
|
*/
|
|
class ResmedLoader : public CPAPLoader
|
|
{
|
|
Q_OBJECT
|
|
friend class ResmedImport;
|
|
friend class ResmedImportStage2;
|
|
public:
|
|
ResmedLoader();
|
|
virtual ~ResmedLoader();
|
|
|
|
//! \brief Detect if the given path contains a valid Folder structure
|
|
virtual bool Detect(const QString & path);
|
|
|
|
//! \brief Look up machine model information of ResMed file structure stored at path
|
|
virtual MachineInfo PeekInfo(const QString & path);
|
|
|
|
virtual void checkSummaryDay( ResMedDay & resday, QDate date, Machine * mach );
|
|
|
|
//! \brief Scans for ResMed SD folder structure signature, and loads any new data if found
|
|
virtual int Open(const QString &);
|
|
|
|
//! \brief Returns the version number of this ResMed loader
|
|
virtual int Version() { return resmed_data_version; }
|
|
|
|
//! \brief Returns the Machine class name of this loader. ("ResMed")
|
|
virtual const QString &loaderName() { return resmed_class_name; }
|
|
|
|
//! \brief Converts EDFSignal data to time delta packed EventList, and adds to Session
|
|
void ToTimeDelta(Session *sess, ResMedEDFInfo &edf, EDFSignal &es, ChannelID code, long recs,
|
|
qint64 duration, EventDataType min = 0, EventDataType max = 0, bool square = false);
|
|
|
|
//! \brief Register the ResmedLoader with the list of other machine loaders
|
|
static void Register();
|
|
|
|
//! \brief Parse the EVE Event annotation data, and save to Session * sess
|
|
//! This contains all Hypopnea, Obstructive Apnea, Central and Apnea codes
|
|
bool LoadEVE(Session *sess, const QString & path);
|
|
|
|
//! \brief Parse the CSL Event annotation data, and save to Session * sess
|
|
//! This contains Cheyne Stokes Respiration flagging on the AirSense 10
|
|
bool LoadCSL(Session *sess, const QString & path);
|
|
|
|
//! \brief Parse the BRP High Resolution data, and save to Session * sess
|
|
//! This contains Flow Rate, Mask Pressure, and Resp. Event data
|
|
bool LoadBRP(Session *sess, const QString & path);
|
|
|
|
//! \brief Parse the SAD Pulse oximetry attachment data, and save to Session * sess
|
|
//! This contains Pulse Rate and SpO2 Oxygen saturation data
|
|
bool LoadSAD(Session *sess, const QString & path);
|
|
|
|
//! \brief Parse the PRD low resolution data, and save to Session * sess
|
|
//! This contains the Pressure, Leak, Respiratory Rate, Minute Ventilation, Tidal Volume, etc..
|
|
bool LoadPLD(Session *sess, const QString & path);
|
|
|
|
virtual MachineInfo newInfo() {
|
|
return MachineInfo(MT_CPAP, 0, resmed_class_name, QObject::tr("ResMed"), QString(),
|
|
QString(), QString(), QObject::tr("S9"), QDateTime::currentDateTime(), resmed_data_version);
|
|
}
|
|
|
|
virtual void initChannels();
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Now for some CPAPLoader overrides
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
virtual QString PresReliefLabel() { return QObject::tr("EPR: "); }
|
|
|
|
virtual ChannelID PresReliefMode();
|
|
virtual ChannelID PresReliefLevel();
|
|
virtual ChannelID CPAPModeChannel();
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
volatile int sessionCount;
|
|
|
|
protected:
|
|
//! \brief The STR.edf file is a unique edf file with many signals
|
|
void ParseSTR(Machine *, QMap<QDate, STRFile> &, QDate);
|
|
|
|
//! \brief Scan for new files to import, group into sessions and add to task que
|
|
int scanFiles(Machine * mach, const QString & datalog_path, QDate firstImport);
|
|
|
|
//! \brief Write a backup copy to the backup path
|
|
QString backup(const QString & file, const QString & backup_path);
|
|
|
|
// The data members
|
|
// QMap<SessionID, QStringList> sessfiles;
|
|
// QMap<quint32, STRRecord> strsess;
|
|
// QMap<QDate, QList<STRRecord *> > strdate;
|
|
|
|
QMap<QDate, ResMedDay> resdayList;
|
|
|
|
#ifdef DEBUG_EFFICIENCY
|
|
QHash<ChannelID, qint64> channel_efficiency;
|
|
QHash<ChannelID, qint64> channel_time;
|
|
volatile qint64 timeInLoadBRP;
|
|
volatile qint64 timeInLoadPLD;
|
|
volatile qint64 timeInLoadEVE;
|
|
volatile qint64 timeInLoadCSL;
|
|
volatile qint64 timeInLoadSAD;
|
|
volatile qint64 timeInEDFOpen;
|
|
volatile qint64 timeInEDFInfo;
|
|
volatile qint64 timeInAddWaveform;
|
|
volatile qint64 timeInTimeDelta;
|
|
QMutex timeMutex;
|
|
|
|
|
|
#endif
|
|
};
|
|
|
|
#endif // RESMED_LOADER_H
|