mirror of
https://gitlab.com/pholy/OSCAR-code.git
synced 2025-04-07 03:30:44 +00:00
Re-arrange edf-parser code - and fix it
This commit is contained in:
parent
4ad282768c
commit
8c11751b2b
@ -1,5 +1,6 @@
|
|||||||
/* EDF Parser Implementation
|
/* EDF Parser Implementation
|
||||||
*
|
*
|
||||||
|
* Copyright (c) 2019 The OSCAR Team
|
||||||
* Copyright (c) 2011-2018 Mark Watkins <mark@jedimark.net>
|
* Copyright (c) 2011-2018 Mark Watkins <mark@jedimark.net>
|
||||||
*
|
*
|
||||||
* This file is subject to the terms and conditions of the GNU General Public
|
* This file is subject to the terms and conditions of the GNU General Public
|
||||||
@ -20,16 +21,226 @@
|
|||||||
|
|
||||||
EDFParser::EDFParser(QString name)
|
EDFParser::EDFParser(QString name)
|
||||||
{
|
{
|
||||||
buffer = nullptr;
|
filesize = 0;
|
||||||
|
datasize = 0;
|
||||||
|
signalPtr = nullptr;
|
||||||
|
hdrPtr = nullptr;
|
||||||
|
fileData.clear();
|
||||||
if (!name.isEmpty())
|
if (!name.isEmpty())
|
||||||
Open(name);
|
Open(name);
|
||||||
}
|
}
|
||||||
EDFParser::~EDFParser()
|
EDFParser::~EDFParser()
|
||||||
{
|
{
|
||||||
for (auto & s : edfsignals) {
|
for (auto & s : edfsignals) {
|
||||||
if (s.data) { delete [] s.data; }
|
if (s.value)
|
||||||
|
delete [] s.value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool EDFParser::Open(const QString & name)
|
||||||
|
{
|
||||||
|
if (hdrPtr != nullptr) {
|
||||||
|
qWarning() << "EDFParser::Open() called with file already open" << name;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
QFile fi(name);
|
||||||
|
if (!fi.open(QFile::ReadOnly)) {
|
||||||
|
qDebug() << "EDFParser::Open() Couldn't open file" << name;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (name.endsWith(STR_ext_gz)) {
|
||||||
|
fileData = gUncompress(fi.readAll()); // Open and decompress file
|
||||||
|
} else {
|
||||||
|
fileData = fi.readAll(); // Open and read uncompressed file
|
||||||
|
}
|
||||||
|
fi.close();
|
||||||
|
if (fileData.size() <= EDFHeaderSize) {
|
||||||
|
qDebug() << "EDFParser::Open() File too short" << name;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
hdrPtr = (EDFHeaderRaw *)fileData.constData();
|
||||||
|
signalPtr = (char *)fileData.constData() + EDFHeaderSize;
|
||||||
|
filename = name;
|
||||||
|
filesize = fileData.size();
|
||||||
|
datasize = filesize - EDFHeaderSize;
|
||||||
|
pos = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EDFParser::Parse()
|
||||||
|
{
|
||||||
|
bool ok;
|
||||||
|
|
||||||
|
if (hdrPtr == nullptr) {
|
||||||
|
qWarning() << "EDFParser::Parse() called without valid EDF data" << filename;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
eof = false;
|
||||||
|
edfHdr.version = QString::fromLatin1(hdrPtr->version, 8).toLong(&ok);
|
||||||
|
if (!ok) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//patientident=QString::fromLatin1(header.patientident,80);
|
||||||
|
edfHdr.recordingident = QString::fromLatin1(hdrPtr->recordingident, 80); // Serial number is in here..
|
||||||
|
int snp = edfHdr.recordingident.indexOf("SRN=");
|
||||||
|
serialnumber.clear();
|
||||||
|
|
||||||
|
for (int i = snp + 4; i < edfHdr.recordingident.length(); i++) {
|
||||||
|
if (edfHdr.recordingident[i] == ' ') {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
serialnumber += edfHdr.recordingident[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
edfHdr.startdate_orig = QDateTime::fromString(QString::fromLatin1(hdrPtr->datetime, 16), "dd.MM.yyHH.mm.ss");
|
||||||
|
|
||||||
|
QDate d2 = edfHdr.startdate_orig.date();
|
||||||
|
|
||||||
|
if (d2.year() < 2000) {
|
||||||
|
d2.setDate(d2.year() + 100, d2.month(), d2.day());
|
||||||
|
edfHdr.startdate_orig.setDate(d2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!edfHdr.startdate_orig.isValid()) {
|
||||||
|
qDebug() << "Invalid date time retreieved parsing EDF File" << filename;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
startdate = qint64(edfHdr.startdate_orig.toTime_t()) * 1000L;
|
||||||
|
//startdate-=timezoneOffset();
|
||||||
|
if (startdate == 0) {
|
||||||
|
qDebug() << "Invalid startdate = 0 in EDF File" << filename;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug() << edfHdr.startdate_orig.toString("yyyy-MMM-dd HH:mm:ss") << "in" << filename;
|
||||||
|
|
||||||
|
edfHdr.num_header_bytes = QString::fromLatin1(hdrPtr->num_header_bytes, 8).toLong(&ok);
|
||||||
|
|
||||||
|
if (!ok) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
edfHdr.reserved44=QString::fromLatin1(hdrPtr->reserved, 44);
|
||||||
|
edfHdr.num_data_records = QString::fromLatin1(hdrPtr->num_data_records, 8).toLong(&ok);
|
||||||
|
|
||||||
|
if (!ok) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
edfHdr.duration_Seconds = QString::fromLatin1(hdrPtr->dur_data_records, 8).toLong(&ok);
|
||||||
|
|
||||||
|
if (!ok) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
dur_data_record = (edfHdr.duration_Seconds * 1000.0L);
|
||||||
|
|
||||||
|
edfHdr.num_signals = QString::fromLatin1(hdrPtr->num_signals, 4).toLong(&ok);
|
||||||
|
|
||||||
|
if (!ok) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
enddate = startdate + dur_data_record * qint64(edfHdr.num_data_records);
|
||||||
|
// if (dur_data_record==0)
|
||||||
|
// return false;
|
||||||
|
|
||||||
|
// this could be loaded quicker by transducer_type[signal] etc..
|
||||||
|
|
||||||
|
// Initialize fixed-size signal list.
|
||||||
|
edfsignals.resize(edfHdr.num_signals);
|
||||||
|
|
||||||
|
for (auto & sig : edfsignals) {
|
||||||
|
sig.value = nullptr;
|
||||||
|
sig.label = Read(16);
|
||||||
|
|
||||||
|
signal_labels.push_back(sig.label);
|
||||||
|
signalList[sig.label].push_back(&sig);
|
||||||
|
if (eof)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto & sig : edfsignals) {
|
||||||
|
sig.transducer_type = Read(80);
|
||||||
|
}
|
||||||
|
for (auto & sig : edfsignals) {
|
||||||
|
sig.physical_dimension = Read(8);
|
||||||
|
}
|
||||||
|
for (auto & sig : edfsignals) {
|
||||||
|
sig.physical_minimum = Read(8).toDouble(&ok);
|
||||||
|
}
|
||||||
|
for (auto & sig : edfsignals) {
|
||||||
|
sig.physical_maximum = Read(8).toDouble(&ok);
|
||||||
|
}
|
||||||
|
for (auto & sig : edfsignals) {
|
||||||
|
sig.digital_minimum = Read(8).toDouble(&ok);
|
||||||
|
}
|
||||||
|
for (auto & sig : edfsignals) {
|
||||||
|
sig.digital_maximum = Read(8).toDouble(&ok);
|
||||||
|
sig.gain = (sig.physical_maximum - sig.physical_minimum) / (sig.digital_maximum - sig.digital_minimum);
|
||||||
|
sig.offset = 0;
|
||||||
|
}
|
||||||
|
for (auto & sig : edfsignals) {
|
||||||
|
sig.prefiltering = Read(80);
|
||||||
|
}
|
||||||
|
for (auto & sig : edfsignals) {
|
||||||
|
sig.nr = Read(8).toLong(&ok);
|
||||||
|
}
|
||||||
|
for (auto & sig : edfsignals) {
|
||||||
|
sig.reserved = Read(32);
|
||||||
|
}
|
||||||
|
|
||||||
|
// could do it earlier, but it won't crash from > EOF Reads
|
||||||
|
if (eof)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// Now check the file isn't truncated before allocating all the memory
|
||||||
|
long allocsize = 0;
|
||||||
|
for (auto & sig : edfsignals) {
|
||||||
|
if (edfHdr.num_data_records > 0) {
|
||||||
|
allocsize += sig.nr * edfHdr.num_data_records * 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (allocsize > (datasize - pos)) {
|
||||||
|
// Space required more than the remainder left to read,
|
||||||
|
// so abort and let the user clean up the corrupted file themselves
|
||||||
|
qWarning() << "EDFParser::Parse():" << filename << " is too short!";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// allocate the buffers for the signal values
|
||||||
|
for (auto & sig : edfsignals) {
|
||||||
|
long recs = sig.nr * edfHdr.num_data_records;
|
||||||
|
if (edfHdr.num_data_records <= 0) {
|
||||||
|
sig.value = nullptr;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
sig.value = new qint16 [recs];
|
||||||
|
sig.pos = 0;
|
||||||
|
}
|
||||||
|
for (int x = 0; x < edfHdr.num_data_records; x++) {
|
||||||
|
for (auto & sig : edfsignals) {
|
||||||
|
#ifdef Q_LITTLE_ENDIAN
|
||||||
|
// Intel x86, etc..
|
||||||
|
memcpy((char *)&sig.value[sig.pos], (char *)&signalPtr[pos], sig.nr * 2);
|
||||||
|
sig.pos += sig.nr;
|
||||||
|
pos += sig.nr * 2;
|
||||||
|
#else
|
||||||
|
// Big endian safe
|
||||||
|
for (int j=0;j<sig.nr;j++) {
|
||||||
|
qint16 t=Read16();
|
||||||
|
sig.value[sig.pos++]=t;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// Read a 16 bits integer
|
// Read a 16 bits integer
|
||||||
qint16 EDFParser::Read16()
|
qint16 EDFParser::Read16()
|
||||||
{
|
{
|
||||||
@ -37,15 +248,11 @@ qint16 EDFParser::Read16()
|
|||||||
eof = true;
|
eof = true;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#ifdef Q_LITTLE_ENDIAN // Intel, etc...
|
||||||
#ifdef Q_LITTLE_ENDIAN
|
qint16 res = *(qint16 *)&signalPtr[pos];
|
||||||
// Intel, etc...
|
#else // ARM, PPC, etc..
|
||||||
qint16 res = *(qint16 *)&buffer[pos];
|
qint16 res = quint8(signalPtr[pos]) | (qint8(signalPtr[pos+1]) << 8);
|
||||||
#else
|
|
||||||
// ARM, PPC, etc..
|
|
||||||
qint16 res = quint8(buffer[pos]) | (qint8(buffer[pos+1]) << 8);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
pos += 2;
|
pos += 2;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@ -56,225 +263,20 @@ QString EDFParser::Read(unsigned n)
|
|||||||
eof = true;
|
eof = true;
|
||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
QByteArray buf(&signalPtr[pos], n);
|
||||||
QByteArray buf(&buffer[pos], n);
|
|
||||||
pos+=n;
|
pos+=n;
|
||||||
|
|
||||||
return buf.trimmed();
|
return buf.trimmed();
|
||||||
}
|
}
|
||||||
bool EDFParser::Parse()
|
|
||||||
{
|
|
||||||
bool ok;
|
|
||||||
|
|
||||||
if (header == nullptr) {
|
|
||||||
qWarning() << "EDFParser::Parse() called without valid EDF data" << filename;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
eof = false;
|
|
||||||
version = QString::fromLatin1(header->version, 8).toLong(&ok);
|
|
||||||
if (!ok) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//patientident=QString::fromLatin1(header.patientident,80);
|
|
||||||
recordingident = QString::fromLatin1(header->recordingident, 80); // Serial number is in here..
|
|
||||||
int snp = recordingident.indexOf("SRN=");
|
|
||||||
serialnumber.clear();
|
|
||||||
|
|
||||||
for (int i = snp + 4; i < recordingident.length(); i++) {
|
|
||||||
if (recordingident[i] == ' ') {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
serialnumber += recordingident[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
startdate_orig = QDateTime::fromString(QString::fromLatin1(header->datetime, 16), "dd.MM.yyHH.mm.ss");
|
|
||||||
|
|
||||||
QDate d2 = startdate_orig.date();
|
|
||||||
|
|
||||||
if (d2.year() < 2000) {
|
|
||||||
d2.setDate(d2.year() + 100, d2.month(), d2.day());
|
|
||||||
startdate_orig.setDate(d2);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!startdate_orig.isValid()) {
|
|
||||||
qDebug() << "Invalid date time retreieved parsing EDF File" << filename;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
startdate = qint64(startdate_orig.toTime_t()) * 1000L;
|
|
||||||
//startdate-=timezoneOffset();
|
|
||||||
if (startdate == 0) {
|
|
||||||
qDebug() << "Invalid startdate = 0 in EDF File" << filename;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//qDebug() << startDate.toString("yyyy-MM-dd HH:mm:ss");
|
|
||||||
|
|
||||||
num_header_bytes = QString::fromLatin1(header->num_header_bytes, 8).toLong(&ok);
|
|
||||||
|
|
||||||
if (!ok) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//reserved44=QString::fromLatin1(header.reserved,44);
|
|
||||||
num_data_records = QString::fromLatin1(header->num_data_records, 8).toLong(&ok);
|
|
||||||
|
|
||||||
if (!ok) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
dur_data_record = (QString::fromLatin1(header->dur_data_records, 8).toDouble(&ok) * 1000.0L);
|
|
||||||
|
|
||||||
if (!ok) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
num_signals = QString::fromLatin1(header->num_signals, 4).toLong(&ok);
|
|
||||||
|
|
||||||
if (!ok) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
enddate = startdate + dur_data_record * qint64(num_data_records);
|
|
||||||
// if (dur_data_record==0)
|
|
||||||
// return false;
|
|
||||||
|
|
||||||
// this could be loaded quicker by transducer_type[signal] etc..
|
|
||||||
|
|
||||||
// Initialize fixed-size signal list.
|
|
||||||
edfsignals.resize(num_signals);
|
|
||||||
|
|
||||||
for (auto & sig : edfsignals) {
|
|
||||||
sig.data = nullptr;
|
|
||||||
sig.label = Read(16);
|
|
||||||
|
|
||||||
signal_labels.push_back(sig.label);
|
|
||||||
signalList[sig.label].push_back(&sig);
|
|
||||||
if (eof) return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto & sig : edfsignals) { sig.transducer_type = Read(80); }
|
|
||||||
for (auto & sig : edfsignals) { sig.physical_dimension = Read(8); }
|
|
||||||
for (auto & sig : edfsignals) { sig.physical_minimum = Read(8).toDouble(&ok); }
|
|
||||||
for (auto & sig : edfsignals) { sig.physical_maximum = Read(8).toDouble(&ok); }
|
|
||||||
for (auto & sig : edfsignals) { sig.digital_minimum = Read(8).toDouble(&ok); }
|
|
||||||
for (auto & sig : edfsignals) { sig.digital_maximum = Read(8).toDouble(&ok);
|
|
||||||
sig.gain = (sig.physical_maximum - sig.physical_minimum) / (sig.digital_maximum - sig.digital_minimum);
|
|
||||||
sig.offset = 0;
|
|
||||||
}
|
|
||||||
for (auto & sig : edfsignals) { sig.prefiltering = Read(80); }
|
|
||||||
for (auto & sig : edfsignals) { sig.nr = Read(8).toLong(&ok); }
|
|
||||||
for (auto & sig : edfsignals) { sig.reserved = Read(32); }
|
|
||||||
|
|
||||||
// could do it earlier, but it won't crash from > EOF Reads
|
|
||||||
if (eof) return false;
|
|
||||||
|
|
||||||
// Now check the file isn't truncated before allocating all the memory
|
|
||||||
long allocsize = 0;
|
|
||||||
for (auto & sig : edfsignals) {
|
|
||||||
if (num_data_records > 0) {
|
|
||||||
allocsize += sig.nr * num_data_records * 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (allocsize > (datasize - pos)) {
|
|
||||||
// Space required more than the remainder left to read,
|
|
||||||
// so abort and let the user clean up the corrupted file themselves
|
|
||||||
qWarning() << "EDFParser::Parse():" << filename << " is truncated!";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// allocate the buffers
|
|
||||||
for (auto & sig : edfsignals) {
|
|
||||||
long recs = sig.nr * num_data_records;
|
|
||||||
|
|
||||||
if (num_data_records <= 0) {
|
|
||||||
sig.data = nullptr;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
sig.data = new qint16 [recs];
|
|
||||||
sig.pos = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
for (int x = 0; x < num_data_records; x++) {
|
|
||||||
for (auto & sig : edfsignals) {
|
|
||||||
#ifdef Q_LITTLE_ENDIAN
|
|
||||||
// Intel x86, etc..
|
|
||||||
memcpy((char *)&sig.data[sig.pos], (char *)&buffer[pos], sig.nr * 2);
|
|
||||||
sig.pos += sig.nr;
|
|
||||||
pos += sig.nr * 2;
|
|
||||||
#else
|
|
||||||
// Big endian safe
|
|
||||||
for (int j=0;j<sig.nr;j++) {
|
|
||||||
qint16 t=Read16();
|
|
||||||
sig.data[sig.pos++]=t;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
QByteArray gUncompress(const QByteArray &data);
|
|
||||||
|
|
||||||
bool EDFParser::Open(const QString & name)
|
|
||||||
{
|
|
||||||
if (buffer != nullptr) {
|
|
||||||
qWarning() << "EDFParser::Open() called with file already open" << name;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
QFile fi(name);
|
|
||||||
if (!fi.open(QFile::ReadOnly)) {
|
|
||||||
goto badfile;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (name.endsWith(STR_ext_gz)) {
|
|
||||||
filename = name; //name.mid(0, -3); // DoubleCheck: why am I cropping the extension? this is used for debugging
|
|
||||||
|
|
||||||
// Open and decempress file
|
|
||||||
data = gUncompress(fi.readAll());
|
|
||||||
} else {
|
|
||||||
// Open and read uncompressed file
|
|
||||||
filename = name;
|
|
||||||
data = fi.readAll();
|
|
||||||
}
|
|
||||||
fi.close();
|
|
||||||
|
|
||||||
filesize = data.size();
|
|
||||||
|
|
||||||
if (filesize > EDFHeaderSize) {
|
|
||||||
header = (EDFHeader *)data.constData();
|
|
||||||
buffer = (char *)data.constData() + EDFHeaderSize;
|
|
||||||
datasize = filesize - EDFHeaderSize;
|
|
||||||
} else goto badfile;
|
|
||||||
|
|
||||||
pos = 0;
|
|
||||||
return true;
|
|
||||||
|
|
||||||
badfile:
|
|
||||||
filesize = 0;
|
|
||||||
datasize = 0;
|
|
||||||
buffer = nullptr;
|
|
||||||
header = nullptr;
|
|
||||||
data.clear();
|
|
||||||
qDebug() << "EDFParser::Open() Couldn't open file" << name;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
EDFSignal *EDFParser::lookupLabel(const QString & name, int index)
|
EDFSignal *EDFParser::lookupLabel(const QString & name, int index)
|
||||||
{
|
{
|
||||||
auto it = signalList.find(name);
|
auto it = signalList.find(name);
|
||||||
if (it == signalList.end()) return nullptr;
|
if (it == signalList.end())
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
if (index >= it.value().size()) return nullptr;
|
if (index >= it.value().size())
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
return it.value()[index];
|
return it.value()[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
//QMutex EDFParser::EDFMutex;
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
/* EDF Parser Header
|
/* EDF Parser Header
|
||||||
*
|
*
|
||||||
|
* Copyright (c) 2019 The OSCAR Team
|
||||||
* Copyright (c) 2011-2018 Mark Watkins <mark@jedimark.net>
|
* Copyright (c) 2011-2018 Mark Watkins <mark@jedimark.net>
|
||||||
*
|
*
|
||||||
* This file is subject to the terms and conditions of the GNU General Public
|
* This file is subject to the terms and conditions of the GNU General Public
|
||||||
@ -13,7 +14,6 @@
|
|||||||
#include <QVector>
|
#include <QVector>
|
||||||
#include <QHash>
|
#include <QHash>
|
||||||
#include <QList>
|
#include <QList>
|
||||||
#include <QMutex>
|
|
||||||
|
|
||||||
#include "SleepLib/common.h"
|
#include "SleepLib/common.h"
|
||||||
|
|
||||||
@ -24,7 +24,7 @@ const QString STR_ext_gz = ".gz";
|
|||||||
\brief Represents the EDF+ header structure, used as a place holder while processing the text data.
|
\brief Represents the EDF+ header structure, used as a place holder while processing the text data.
|
||||||
\note More information on the EDF+ file format can be obtained from http://edfplus.info
|
\note More information on the EDF+ file format can be obtained from http://edfplus.info
|
||||||
*/
|
*/
|
||||||
struct EDFHeader {
|
struct EDFHeaderRaw {
|
||||||
char version[8];
|
char version[8];
|
||||||
char patientident[80];
|
char patientident[80];
|
||||||
char recordingident[80];
|
char recordingident[80];
|
||||||
@ -39,8 +39,23 @@ struct EDFHeader {
|
|||||||
__attribute__((packed))
|
__attribute__((packed))
|
||||||
#endif
|
#endif
|
||||||
;
|
;
|
||||||
|
const int EDFHeaderSize = sizeof(EDFHeaderRaw);
|
||||||
|
|
||||||
const int EDFHeaderSize = sizeof(EDFHeader);
|
/*! \struct EDFHeaderQT
|
||||||
|
\brief Contains the QT version of the EDF header information
|
||||||
|
*/
|
||||||
|
struct EDFHeaderQT {
|
||||||
|
public:
|
||||||
|
long version;
|
||||||
|
QString patientident;
|
||||||
|
QString recordingident;
|
||||||
|
QDateTime startdate_orig;
|
||||||
|
long num_header_bytes;
|
||||||
|
QString reserved44;
|
||||||
|
long num_data_records;
|
||||||
|
long duration_Seconds;
|
||||||
|
long num_signals;
|
||||||
|
};
|
||||||
|
|
||||||
/*! \struct EDFSignal
|
/*! \struct EDFSignal
|
||||||
\brief Contains information about a single EDF+ Signal
|
\brief Contains information about a single EDF+ Signal
|
||||||
@ -48,47 +63,20 @@ const int EDFHeaderSize = sizeof(EDFHeader);
|
|||||||
*/
|
*/
|
||||||
struct EDFSignal {
|
struct EDFSignal {
|
||||||
public:
|
public:
|
||||||
//! \brief Name of this Signal
|
QString label; //! \brief Name of this Signal
|
||||||
QString label;
|
QString transducer_type; //! \brief Tranducer Type (source of the data, usually blank)
|
||||||
|
QString physical_dimension; //! \brief The units of measurements represented by this signal
|
||||||
//! \brief Tranducer Type (source of the data, usually blank)
|
EventDataType physical_minimum; //! \brief The minimum limits of the ungained data
|
||||||
QString transducer_type;
|
EventDataType physical_maximum; //! \brief The maximum limits of the ungained data
|
||||||
|
EventDataType digital_minimum; //! \brief The minimum limits of the data with gain and offset applied
|
||||||
//! \brief The units of measurements represented by this signal
|
EventDataType digital_maximum; //! \brief The maximum limits of the data with gain and offset applied
|
||||||
QString physical_dimension;
|
EventDataType gain; //! \brief Raw integer data is multiplied by this value
|
||||||
|
EventDataType offset; //! \brief This value is added to the raw data
|
||||||
//! \brief The minimum limits of the ungained data
|
QString prefiltering; //! \brief Any prefiltering methods used (usually blank)
|
||||||
EventDataType physical_minimum;
|
long nr; //! \brief Number of records
|
||||||
|
QString reserved; //! \brief Reserved (usually blank)
|
||||||
//! \brief The maximum limits of the ungained data
|
qint16 *value; //! \brief Pointer to the signals sample data
|
||||||
EventDataType physical_maximum;
|
int pos; //! \brief a non-EDF extra used internally to count the signal data
|
||||||
|
|
||||||
//! \brief The minimum limits of the data with gain and offset applied
|
|
||||||
EventDataType digital_minimum;
|
|
||||||
|
|
||||||
//! \brief The maximum limits of the data with gain and offset applied
|
|
||||||
EventDataType digital_maximum;
|
|
||||||
|
|
||||||
//! \brief Raw integer data is multiplied by this value
|
|
||||||
EventDataType gain;
|
|
||||||
|
|
||||||
//! \brief This value is added to the raw data
|
|
||||||
EventDataType offset;
|
|
||||||
|
|
||||||
//! \brief Any prefiltering methods used (usually blank)
|
|
||||||
QString prefiltering;
|
|
||||||
|
|
||||||
//! \brief Number of records
|
|
||||||
long nr;
|
|
||||||
|
|
||||||
//! \brief Reserved (usually blank)
|
|
||||||
QString reserved;
|
|
||||||
|
|
||||||
//! \brief Pointer to the signals sample data
|
|
||||||
qint16 *data;
|
|
||||||
|
|
||||||
//! \brief a non-EDF extra used internally to count the signal data
|
|
||||||
int pos;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -108,62 +96,62 @@ class EDFParser
|
|||||||
//! \brief Open the EDF+ file, and read it's header
|
//! \brief Open the EDF+ file, and read it's header
|
||||||
bool Open(const QString & name);
|
bool Open(const QString & name);
|
||||||
|
|
||||||
|
//! \brief Parse the EDF+ file into the list of EDFSignals.. Must be call Open(..) first.
|
||||||
|
bool Parse();
|
||||||
|
|
||||||
//! \brief Read n bytes of 8 bit data from the EDF+ data stream
|
//! \brief Read n bytes of 8 bit data from the EDF+ data stream
|
||||||
QString Read(unsigned n);
|
QString Read(unsigned n);
|
||||||
|
|
||||||
//! \brief Read 16 bit word of data from the EDF+ data stream
|
//! \brief Read 16 bit word of data from the EDF+ data stream
|
||||||
qint16 Read16();
|
qint16 Read16();
|
||||||
|
|
||||||
|
//! \brief Return a ptr to the i'th signal with the given name (if multiple signal with the same name(?!))
|
||||||
|
EDFSignal *lookupLabel(const QString & name, int index=0);
|
||||||
|
|
||||||
|
//! \brief Returns the number of signals contained in this EDF file
|
||||||
|
long GetNumSignals() { return edfHdr.num_signals; }
|
||||||
|
|
||||||
|
//! \brief Returns the number of data records contained per signal.
|
||||||
|
long GetNumDataRecords() { return edfHdr.num_data_records; }
|
||||||
|
|
||||||
|
//! \brief Returns the duration represented by this EDF file (in milliseconds)
|
||||||
|
qint64 GetDuration() { return dur_data_record; }
|
||||||
|
|
||||||
|
//! \brief Returns the patientid field from the EDF header
|
||||||
|
QString GetPatient() { return edfHdr.patientident; }
|
||||||
|
|
||||||
|
// The data members follow
|
||||||
|
|
||||||
|
//! \brief The header in a QT friendly form
|
||||||
|
EDFHeaderQT edfHdr;
|
||||||
|
|
||||||
//! \brief Vector containing the list of EDFSignals contained in this edf file
|
//! \brief Vector containing the list of EDFSignals contained in this edf file
|
||||||
QVector<EDFSignal> edfsignals;
|
QVector<EDFSignal> edfsignals;
|
||||||
|
|
||||||
//! \brief An by-name indexed into the EDFSignal data
|
//! \brief An by-name indexed into the EDFSignal data
|
||||||
QStringList signal_labels;
|
QStringList signal_labels;
|
||||||
|
|
||||||
//! \brief ResMed likes to use the SAME signal name
|
//! \brief ResMed sometimes re-uses the SAME signal name
|
||||||
QHash<QString, QList<EDFSignal *> > signalList;
|
QHash<QString, QList<EDFSignal *> > signalList;
|
||||||
|
|
||||||
EDFSignal *lookupLabel(const QString & name, int index=0);
|
//! \brief The following are computed from the edfHdr data
|
||||||
|
QString serialnumber;
|
||||||
//! \brief Returns the number of signals contained in this EDF file
|
qint64 dur_data_record;
|
||||||
long GetNumSignals() { return num_signals; }
|
qint64 startdate;
|
||||||
|
qint64 enddate;
|
||||||
//! \brief Returns the number of data records contained per signal.
|
|
||||||
long GetNumDataRecords() { return num_data_records; }
|
|
||||||
|
|
||||||
//! \brief Returns the duration represented by this EDF file (in milliseconds)
|
|
||||||
qint64 GetDuration() { return dur_data_record; }
|
|
||||||
|
|
||||||
//! \brief Returns the patientid field from the EDF header
|
|
||||||
QString GetPatient() { return patientident; }
|
|
||||||
|
|
||||||
//! \brief Parse the EDF+ file into the list of EDFSignals.. Must be call Open(..) first.
|
|
||||||
bool Parse();
|
|
||||||
char *buffer;
|
|
||||||
|
|
||||||
|
// the following could be private
|
||||||
|
//! \brief This is the array holding the EDF file data
|
||||||
|
QByteArray fileData;
|
||||||
//! \brief The EDF+ files header structure, used as a place holder while processing the text data.
|
//! \brief The EDF+ files header structure, used as a place holder while processing the text data.
|
||||||
EDFHeader *header;
|
EDFHeaderRaw *hdrPtr;
|
||||||
QByteArray data;
|
//! \brief This is the array of signal descriptors and values
|
||||||
|
char *signalPtr;
|
||||||
|
|
||||||
QString filename;
|
QString filename;
|
||||||
long filesize;
|
long filesize;
|
||||||
long datasize;
|
long datasize;
|
||||||
long pos;
|
long pos;
|
||||||
|
|
||||||
long version;
|
|
||||||
long num_header_bytes;
|
|
||||||
long num_data_records;
|
|
||||||
qint64 dur_data_record;
|
|
||||||
long num_signals;
|
|
||||||
|
|
||||||
QString patientident;
|
|
||||||
QString recordingident;
|
|
||||||
QString serialnumber;
|
|
||||||
QDateTime startdate_orig;
|
|
||||||
qint64 startdate;
|
|
||||||
qint64 enddate;
|
|
||||||
QString reserved44;
|
|
||||||
// static QMutex EDFMutex;
|
|
||||||
bool eof;
|
bool eof;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -132,7 +132,7 @@ void ResmedLoader::ParseSTR(Machine *mach, QMap<QDate, STRFile> & STRmap)
|
|||||||
QString & strfile = file.filename;
|
QString & strfile = file.filename;
|
||||||
ResMedEDFParser & str = *file.edf;
|
ResMedEDFParser & str = *file.edf;
|
||||||
|
|
||||||
QDate date = str.startdate_orig.date(); // each STR.edf record starts at 12 noon
|
QDate date = str.edfHdr.startdate_orig.date(); // each STR.edf record starts at 12 noon
|
||||||
|
|
||||||
qDebug() << "Parsing" << strfile << date << str.GetNumDataRecords() << str.GetNumSignals();
|
qDebug() << "Parsing" << strfile << date << str.GetNumDataRecords() << str.GetNumSignals();
|
||||||
|
|
||||||
@ -171,8 +171,8 @@ void ResmedLoader::ParseSTR(Machine *mach, QMap<QDate, STRFile> & STRmap)
|
|||||||
|
|
||||||
bool validday = false;
|
bool validday = false;
|
||||||
for (int s = 0; s < maskon->nr; ++s) {
|
for (int s = 0; s < maskon->nr; ++s) {
|
||||||
qint32 on = maskon->data[recstart + s];
|
qint32 on = maskon->value[recstart + s];
|
||||||
qint32 off = maskoff->data[recstart + s];
|
qint32 off = maskoff->value[recstart + s];
|
||||||
|
|
||||||
if ((on >= 0) && (off >= 0)) validday=true;
|
if ((on >= 0) && (off >= 0)) validday=true;
|
||||||
}
|
}
|
||||||
@ -196,8 +196,8 @@ void ResmedLoader::ParseSTR(Machine *mach, QMap<QDate, STRFile> & STRmap)
|
|||||||
R.maskon.resize(maskon->nr);
|
R.maskon.resize(maskon->nr);
|
||||||
R.maskoff.resize(maskoff->nr);
|
R.maskoff.resize(maskoff->nr);
|
||||||
for (int s = 0; s < maskon->nr; ++s) {
|
for (int s = 0; s < maskon->nr; ++s) {
|
||||||
qint32 on = maskon->data[recstart + s];
|
qint32 on = maskon->value[recstart + s];
|
||||||
qint32 off = maskoff->data[recstart + s];
|
qint32 off = maskoff->value[recstart + s];
|
||||||
|
|
||||||
R.maskon[s] = (on>0) ? (timestamp + (on * 60)) : 0;
|
R.maskon[s] = (on>0) ? (timestamp + (on * 60)) : 0;
|
||||||
R.maskoff[s] = (off>0) ? (timestamp + (off * 60)) : 0;
|
R.maskoff[s] = (off>0) ? (timestamp + (off * 60)) : 0;
|
||||||
@ -216,7 +216,7 @@ void ResmedLoader::ParseSTR(Machine *mach, QMap<QDate, STRFile> & STRmap)
|
|||||||
CPAPMode mode = MODE_UNKNOWN;
|
CPAPMode mode = MODE_UNKNOWN;
|
||||||
|
|
||||||
if ((sig = str.lookupSignal(CPAP_Mode))) {
|
if ((sig = str.lookupSignal(CPAP_Mode))) {
|
||||||
int mod = EventDataType(sig->data[rec]) * sig->gain + sig->offset;
|
int mod = EventDataType(sig->value[rec]) * sig->gain + sig->offset;
|
||||||
R.rms9_mode = mod;
|
R.rms9_mode = mod;
|
||||||
|
|
||||||
if (mod == 11) {
|
if (mod == 11) {
|
||||||
@ -241,184 +241,184 @@ void ResmedLoader::ParseSTR(Machine *mach, QMap<QDate, STRFile> & STRmap)
|
|||||||
|
|
||||||
// Settings.CPAP.Starting Pressure
|
// Settings.CPAP.Starting Pressure
|
||||||
if ((mod == 0) && (sig = str.lookupLabel("S.C.StartPress"))) {
|
if ((mod == 0) && (sig = str.lookupLabel("S.C.StartPress"))) {
|
||||||
R.ramp_pressure = EventDataType(sig->data[rec]) * sig->gain + sig->offset;
|
R.ramp_pressure = EventDataType(sig->value[rec]) * sig->gain + sig->offset;
|
||||||
}
|
}
|
||||||
// Settings.Adaptive Starting Pressure? // mode 11 = APAP for her?
|
// Settings.Adaptive Starting Pressure? // mode 11 = APAP for her?
|
||||||
if (((mod == 1) || (mod == 11)) && (sig = str.lookupLabel("S.AS.StartPress"))) {
|
if (((mod == 1) || (mod == 11)) && (sig = str.lookupLabel("S.AS.StartPress"))) {
|
||||||
R.ramp_pressure = EventDataType(sig->data[rec]) * sig->gain + sig->offset;
|
R.ramp_pressure = EventDataType(sig->value[rec]) * sig->gain + sig->offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((R.mode == MODE_BILEVEL_FIXED) && (sig = str.lookupLabel("S.BL.StartPress"))) {
|
if ((R.mode == MODE_BILEVEL_FIXED) && (sig = str.lookupLabel("S.BL.StartPress"))) {
|
||||||
// Bilevel Starting Pressure
|
// Bilevel Starting Pressure
|
||||||
R.ramp_pressure = EventDataType(sig->data[rec]) * sig->gain + sig->offset;
|
R.ramp_pressure = EventDataType(sig->value[rec]) * sig->gain + sig->offset;
|
||||||
}
|
}
|
||||||
if (((R.mode == MODE_ASV) || (R.mode == MODE_ASV_VARIABLE_EPAP)) && (sig = str.lookupLabel("S.VA.StartPress"))) {
|
if (((R.mode == MODE_ASV) || (R.mode == MODE_ASV_VARIABLE_EPAP)) && (sig = str.lookupLabel("S.VA.StartPress"))) {
|
||||||
// Bilevel Starting Pressure
|
// Bilevel Starting Pressure
|
||||||
R.ramp_pressure = EventDataType(sig->data[rec]) * sig->gain + sig->offset;
|
R.ramp_pressure = EventDataType(sig->value[rec]) * sig->gain + sig->offset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((sig = str.lookupLabel("Mask Dur"))) {
|
if ((sig = str.lookupLabel("Mask Dur"))) {
|
||||||
R.maskdur = EventDataType(sig->data[rec]) * sig->gain + sig->offset;
|
R.maskdur = EventDataType(sig->value[rec]) * sig->gain + sig->offset;
|
||||||
}
|
}
|
||||||
if ((sig = str.lookupLabel("Leak Med")) || (sig = str.lookupLabel("Leak.50"))) {
|
if ((sig = str.lookupLabel("Leak Med")) || (sig = str.lookupLabel("Leak.50"))) {
|
||||||
float gain = sig->gain * 60.0;
|
float gain = sig->gain * 60.0;
|
||||||
R.leak50 = EventDataType(sig->data[rec]) * gain;
|
R.leak50 = EventDataType(sig->value[rec]) * gain;
|
||||||
}
|
}
|
||||||
if ((sig = str.lookupLabel("Leak Max"))|| (sig = str.lookupLabel("Leak.Max"))) {
|
if ((sig = str.lookupLabel("Leak Max"))|| (sig = str.lookupLabel("Leak.Max"))) {
|
||||||
float gain = sig->gain * 60.0;
|
float gain = sig->gain * 60.0;
|
||||||
R.leakmax = EventDataType(sig->data[rec]) * gain;
|
R.leakmax = EventDataType(sig->value[rec]) * gain;
|
||||||
}
|
}
|
||||||
if ((sig = str.lookupLabel("Leak 95")) || (sig = str.lookupLabel("Leak.95"))) {
|
if ((sig = str.lookupLabel("Leak 95")) || (sig = str.lookupLabel("Leak.95"))) {
|
||||||
float gain = sig->gain * 60.0;
|
float gain = sig->gain * 60.0;
|
||||||
R.leak95 = EventDataType(sig->data[rec]) * gain;
|
R.leak95 = EventDataType(sig->value[rec]) * gain;
|
||||||
}
|
}
|
||||||
if ((sig = str.lookupLabel("RespRate.50")) || (sig = str.lookupLabel("RR Med"))) {
|
if ((sig = str.lookupLabel("RespRate.50")) || (sig = str.lookupLabel("RR Med"))) {
|
||||||
R.rr50 = EventDataType(sig->data[rec]) * sig->gain;
|
R.rr50 = EventDataType(sig->value[rec]) * sig->gain;
|
||||||
}
|
}
|
||||||
if ((sig = str.lookupLabel("RespRate.Max")) || (sig = str.lookupLabel("RR Max"))) {
|
if ((sig = str.lookupLabel("RespRate.Max")) || (sig = str.lookupLabel("RR Max"))) {
|
||||||
R.rrmax = EventDataType(sig->data[rec]) * sig->gain;
|
R.rrmax = EventDataType(sig->value[rec]) * sig->gain;
|
||||||
}
|
}
|
||||||
if ((sig = str.lookupLabel("RespRate.95")) || (sig = str.lookupLabel("RR 95"))) {
|
if ((sig = str.lookupLabel("RespRate.95")) || (sig = str.lookupLabel("RR 95"))) {
|
||||||
R.rr95 = EventDataType(sig->data[rec]) * sig->gain;
|
R.rr95 = EventDataType(sig->value[rec]) * sig->gain;
|
||||||
}
|
}
|
||||||
if ((sig = str.lookupLabel("MinVent.50")) || (sig = str.lookupLabel("Min Vent Med"))) {
|
if ((sig = str.lookupLabel("MinVent.50")) || (sig = str.lookupLabel("Min Vent Med"))) {
|
||||||
R.mv50 = EventDataType(sig->data[rec]) * sig->gain;
|
R.mv50 = EventDataType(sig->value[rec]) * sig->gain;
|
||||||
}
|
}
|
||||||
if ((sig = str.lookupLabel("MinVent.Max")) || (sig = str.lookupLabel("Min Vent Max"))) {
|
if ((sig = str.lookupLabel("MinVent.Max")) || (sig = str.lookupLabel("Min Vent Max"))) {
|
||||||
R.mvmax = EventDataType(sig->data[rec]) * sig->gain;
|
R.mvmax = EventDataType(sig->value[rec]) * sig->gain;
|
||||||
}
|
}
|
||||||
if ((sig = str.lookupLabel("MinVent.95")) || (sig = str.lookupLabel("Min Vent 95"))) {
|
if ((sig = str.lookupLabel("MinVent.95")) || (sig = str.lookupLabel("Min Vent 95"))) {
|
||||||
R.mv95 = EventDataType(sig->data[rec]) * sig->gain;
|
R.mv95 = EventDataType(sig->value[rec]) * sig->gain;
|
||||||
}
|
}
|
||||||
if ((sig = str.lookupLabel("TidVol.50")) || (sig = str.lookupLabel("Tid Vol Med"))) {
|
if ((sig = str.lookupLabel("TidVol.50")) || (sig = str.lookupLabel("Tid Vol Med"))) {
|
||||||
R.tv50 = EventDataType(sig->data[rec]) * (sig->gain*1000.0);
|
R.tv50 = EventDataType(sig->value[rec]) * (sig->gain*1000.0);
|
||||||
}
|
}
|
||||||
if ((sig = str.lookupLabel("TidVol.Max")) || (sig = str.lookupLabel("Tid Vol Max"))) {
|
if ((sig = str.lookupLabel("TidVol.Max")) || (sig = str.lookupLabel("Tid Vol Max"))) {
|
||||||
R.tvmax = EventDataType(sig->data[rec]) * (sig->gain*1000.0);
|
R.tvmax = EventDataType(sig->value[rec]) * (sig->gain*1000.0);
|
||||||
}
|
}
|
||||||
if ((sig = str.lookupLabel("TidVol.95")) || (sig = str.lookupLabel("Tid Vol 95"))) {
|
if ((sig = str.lookupLabel("TidVol.95")) || (sig = str.lookupLabel("Tid Vol 95"))) {
|
||||||
R.tv95 = EventDataType(sig->data[rec]) * (sig->gain*1000.0);
|
R.tv95 = EventDataType(sig->value[rec]) * (sig->gain*1000.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((sig = str.lookupLabel("MaskPress.50")) || (sig = str.lookupLabel("Mask Pres Med"))) {
|
if ((sig = str.lookupLabel("MaskPress.50")) || (sig = str.lookupLabel("Mask Pres Med"))) {
|
||||||
R.mp50 = EventDataType(sig->data[rec]) * sig->gain;
|
R.mp50 = EventDataType(sig->value[rec]) * sig->gain;
|
||||||
}
|
}
|
||||||
if ((sig = str.lookupLabel("MaskPress.Max")) || (sig = str.lookupLabel("Mask Pres Max"))) {
|
if ((sig = str.lookupLabel("MaskPress.Max")) || (sig = str.lookupLabel("Mask Pres Max"))) {
|
||||||
R.mpmax = EventDataType(sig->data[rec]) * sig->gain ;
|
R.mpmax = EventDataType(sig->value[rec]) * sig->gain ;
|
||||||
}
|
}
|
||||||
if ((sig = str.lookupLabel("MaskPress.95")) || (sig = str.lookupLabel("Mask Pres 95"))) {
|
if ((sig = str.lookupLabel("MaskPress.95")) || (sig = str.lookupLabel("Mask Pres 95"))) {
|
||||||
R.mp95 = EventDataType(sig->data[rec]) * sig->gain ;
|
R.mp95 = EventDataType(sig->value[rec]) * sig->gain ;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((sig = str.lookupLabel("TgtEPAP.50")) || (sig = str.lookupLabel("Exp Pres Med"))) {
|
if ((sig = str.lookupLabel("TgtEPAP.50")) || (sig = str.lookupLabel("Exp Pres Med"))) {
|
||||||
R.tgtepap50 = EventDataType(sig->data[rec]) * sig->gain;
|
R.tgtepap50 = EventDataType(sig->value[rec]) * sig->gain;
|
||||||
}
|
}
|
||||||
if ((sig = str.lookupLabel("TgtEPAP.Max")) || (sig = str.lookupLabel("Exp Pres Max"))) {
|
if ((sig = str.lookupLabel("TgtEPAP.Max")) || (sig = str.lookupLabel("Exp Pres Max"))) {
|
||||||
R.tgtepapmax = EventDataType(sig->data[rec]) * sig->gain;
|
R.tgtepapmax = EventDataType(sig->value[rec]) * sig->gain;
|
||||||
}
|
}
|
||||||
if ((sig = str.lookupLabel("TgtEPAP.95")) || (sig = str.lookupLabel("Exp Pres 95"))) {
|
if ((sig = str.lookupLabel("TgtEPAP.95")) || (sig = str.lookupLabel("Exp Pres 95"))) {
|
||||||
R.tgtepap95 = EventDataType(sig->data[rec]) * sig->gain;
|
R.tgtepap95 = EventDataType(sig->value[rec]) * sig->gain;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((sig = str.lookupLabel("TgtIPAP.50")) || (sig = str.lookupLabel("Insp Pres Med"))) {
|
if ((sig = str.lookupLabel("TgtIPAP.50")) || (sig = str.lookupLabel("Insp Pres Med"))) {
|
||||||
R.tgtipap50 = EventDataType(sig->data[rec]) * sig->gain;
|
R.tgtipap50 = EventDataType(sig->value[rec]) * sig->gain;
|
||||||
}
|
}
|
||||||
if ((sig = str.lookupLabel("TgtIPAP.Max")) || (sig = str.lookupLabel("Insp Pres Max"))) {
|
if ((sig = str.lookupLabel("TgtIPAP.Max")) || (sig = str.lookupLabel("Insp Pres Max"))) {
|
||||||
R.tgtipapmax = EventDataType(sig->data[rec]) * sig->gain;
|
R.tgtipapmax = EventDataType(sig->value[rec]) * sig->gain;
|
||||||
}
|
}
|
||||||
if ((sig = str.lookupLabel("TgtIPAP.95")) || (sig = str.lookupLabel("Insp Pres 95"))) {
|
if ((sig = str.lookupLabel("TgtIPAP.95")) || (sig = str.lookupLabel("Insp Pres 95"))) {
|
||||||
R.tgtipap95 = EventDataType(sig->data[rec]) * sig->gain;
|
R.tgtipap95 = EventDataType(sig->value[rec]) * sig->gain;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((sig = str.lookupLabel("I:E Med"))) {
|
if ((sig = str.lookupLabel("I:E Med"))) {
|
||||||
R.ie50 = EventDataType(sig->data[rec]) * sig->gain;
|
R.ie50 = EventDataType(sig->value[rec]) * sig->gain;
|
||||||
}
|
}
|
||||||
if ((sig = str.lookupLabel("I:E Max"))) {
|
if ((sig = str.lookupLabel("I:E Max"))) {
|
||||||
R.iemax = EventDataType(sig->data[rec]) * sig->gain;
|
R.iemax = EventDataType(sig->value[rec]) * sig->gain;
|
||||||
}
|
}
|
||||||
if ((sig = str.lookupLabel("I:E 95"))) {
|
if ((sig = str.lookupLabel("I:E 95"))) {
|
||||||
R.ie95 = EventDataType(sig->data[rec]) * sig->gain;
|
R.ie95 = EventDataType(sig->value[rec]) * sig->gain;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool haveipap = false;
|
bool haveipap = false;
|
||||||
// if (R.mode == MODE_BILEVEL_FIXED) {
|
// if (R.mode == MODE_BILEVEL_FIXED) {
|
||||||
if ((sig = str.lookupSignal(CPAP_IPAP))) {
|
if ((sig = str.lookupSignal(CPAP_IPAP))) {
|
||||||
R.ipap = EventDataType(sig->data[rec]) * sig->gain + sig->offset;
|
R.ipap = EventDataType(sig->value[rec]) * sig->gain + sig->offset;
|
||||||
haveipap = true;
|
haveipap = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((sig = str.lookupSignal(CPAP_EPAP))) {
|
if ((sig = str.lookupSignal(CPAP_EPAP))) {
|
||||||
R.epap = EventDataType(sig->data[rec]) * sig->gain + sig->offset;
|
R.epap = EventDataType(sig->value[rec]) * sig->gain + sig->offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (R.mode == MODE_ASV) {
|
if (R.mode == MODE_ASV) {
|
||||||
if ((sig = str.lookupLabel("S.AV.StartPress"))) {
|
if ((sig = str.lookupLabel("S.AV.StartPress"))) {
|
||||||
EventDataType sp = EventDataType(sig->data[rec]) * sig->gain + sig->offset;
|
EventDataType sp = EventDataType(sig->value[rec]) * sig->gain + sig->offset;
|
||||||
R.ramp_pressure = sp;
|
R.ramp_pressure = sp;
|
||||||
}
|
}
|
||||||
if ((sig = str.lookupLabel("S.AV.EPAP"))) {
|
if ((sig = str.lookupLabel("S.AV.EPAP"))) {
|
||||||
R.min_epap = R.max_epap = R.epap = EventDataType(sig->data[rec]) * sig->gain + sig->offset;
|
R.min_epap = R.max_epap = R.epap = EventDataType(sig->value[rec]) * sig->gain + sig->offset;
|
||||||
|
|
||||||
}
|
}
|
||||||
if ((sig = str.lookupLabel("S.AV.MinPS"))) {
|
if ((sig = str.lookupLabel("S.AV.MinPS"))) {
|
||||||
R.min_ps = EventDataType(sig->data[rec]) * sig->gain + sig->offset;
|
R.min_ps = EventDataType(sig->value[rec]) * sig->gain + sig->offset;
|
||||||
}
|
}
|
||||||
if ((sig = str.lookupLabel("S.AV.MaxPS"))) {
|
if ((sig = str.lookupLabel("S.AV.MaxPS"))) {
|
||||||
R.max_ps = EventDataType(sig->data[rec]) * sig->gain + sig->offset;
|
R.max_ps = EventDataType(sig->value[rec]) * sig->gain + sig->offset;
|
||||||
R.max_ipap = R.epap + R.max_ps;
|
R.max_ipap = R.epap + R.max_ps;
|
||||||
R.min_ipap = R.epap + R.min_ps;
|
R.min_ipap = R.epap + R.min_ps;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (R.mode == MODE_ASV_VARIABLE_EPAP) {
|
if (R.mode == MODE_ASV_VARIABLE_EPAP) {
|
||||||
if ((sig = str.lookupLabel("S.AA.StartPress"))) {
|
if ((sig = str.lookupLabel("S.AA.StartPress"))) {
|
||||||
EventDataType sp = EventDataType(sig->data[rec]) * sig->gain + sig->offset;
|
EventDataType sp = EventDataType(sig->value[rec]) * sig->gain + sig->offset;
|
||||||
R.ramp_pressure = sp;
|
R.ramp_pressure = sp;
|
||||||
}
|
}
|
||||||
if ((sig = str.lookupLabel("S.AA.MinEPAP"))) {
|
if ((sig = str.lookupLabel("S.AA.MinEPAP"))) {
|
||||||
R.min_epap = EventDataType(sig->data[rec]) * sig->gain + sig->offset;
|
R.min_epap = EventDataType(sig->value[rec]) * sig->gain + sig->offset;
|
||||||
}
|
}
|
||||||
if ((sig = str.lookupLabel("S.AA.MaxEPAP"))) {
|
if ((sig = str.lookupLabel("S.AA.MaxEPAP"))) {
|
||||||
R.max_epap = EventDataType(sig->data[rec]) * sig->gain + sig->offset;
|
R.max_epap = EventDataType(sig->value[rec]) * sig->gain + sig->offset;
|
||||||
}
|
}
|
||||||
if ((sig = str.lookupLabel("S.AA.MinPS"))) {
|
if ((sig = str.lookupLabel("S.AA.MinPS"))) {
|
||||||
R.min_ps = EventDataType(sig->data[rec]) * sig->gain + sig->offset;
|
R.min_ps = EventDataType(sig->value[rec]) * sig->gain + sig->offset;
|
||||||
}
|
}
|
||||||
if ((sig = str.lookupLabel("S.AA.MaxPS"))) {
|
if ((sig = str.lookupLabel("S.AA.MaxPS"))) {
|
||||||
R.max_ps = EventDataType(sig->data[rec]) * sig->gain + sig->offset;
|
R.max_ps = EventDataType(sig->value[rec]) * sig->gain + sig->offset;
|
||||||
R.max_ipap = R.max_epap + R.max_ps;
|
R.max_ipap = R.max_epap + R.max_ps;
|
||||||
R.min_ipap = R.min_epap + R.min_ps;
|
R.min_ipap = R.min_epap + R.min_ps;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((sig = str.lookupSignal(CPAP_PressureMax))) {
|
if ((sig = str.lookupSignal(CPAP_PressureMax))) {
|
||||||
R.max_pressure = EventDataType(sig->data[rec]) * sig->gain + sig->offset;
|
R.max_pressure = EventDataType(sig->value[rec]) * sig->gain + sig->offset;
|
||||||
}
|
}
|
||||||
if ((sig = str.lookupSignal(CPAP_PressureMin))) {
|
if ((sig = str.lookupSignal(CPAP_PressureMin))) {
|
||||||
R.min_pressure = EventDataType(sig->data[rec]) * sig->gain + sig->offset;
|
R.min_pressure = EventDataType(sig->value[rec]) * sig->gain + sig->offset;
|
||||||
}
|
}
|
||||||
if ((sig = str.lookupSignal(RMS9_SetPressure))) {
|
if ((sig = str.lookupSignal(RMS9_SetPressure))) {
|
||||||
R.set_pressure = EventDataType(sig->data[rec]) * sig->gain + sig->offset;
|
R.set_pressure = EventDataType(sig->value[rec]) * sig->gain + sig->offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((sig = str.lookupSignal(CPAP_EPAPHi))) {
|
if ((sig = str.lookupSignal(CPAP_EPAPHi))) {
|
||||||
R.max_epap = EventDataType(sig->data[rec]) * sig->gain + sig->offset;
|
R.max_epap = EventDataType(sig->value[rec]) * sig->gain + sig->offset;
|
||||||
}
|
}
|
||||||
if ((sig = str.lookupSignal(CPAP_EPAPLo))) {
|
if ((sig = str.lookupSignal(CPAP_EPAPLo))) {
|
||||||
R.min_epap = EventDataType(sig->data[rec]) * sig->gain + sig->offset;
|
R.min_epap = EventDataType(sig->value[rec]) * sig->gain + sig->offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((sig = str.lookupSignal(CPAP_IPAPHi))) {
|
if ((sig = str.lookupSignal(CPAP_IPAPHi))) {
|
||||||
R.max_ipap = EventDataType(sig->data[rec]) * sig->gain + sig->offset;
|
R.max_ipap = EventDataType(sig->value[rec]) * sig->gain + sig->offset;
|
||||||
haveipap = true;
|
haveipap = true;
|
||||||
}
|
}
|
||||||
if ((sig = str.lookupSignal(CPAP_IPAPLo))) {
|
if ((sig = str.lookupSignal(CPAP_IPAPLo))) {
|
||||||
R.min_ipap = EventDataType(sig->data[rec]) * sig->gain + sig->offset;
|
R.min_ipap = EventDataType(sig->value[rec]) * sig->gain + sig->offset;
|
||||||
haveipap = true;
|
haveipap = true;
|
||||||
}
|
}
|
||||||
if ((sig = str.lookupSignal(CPAP_PS))) {
|
if ((sig = str.lookupSignal(CPAP_PS))) {
|
||||||
R.ps = EventDataType(sig->data[rec]) * sig->gain + sig->offset;
|
R.ps = EventDataType(sig->value[rec]) * sig->gain + sig->offset;
|
||||||
}
|
}
|
||||||
// }
|
// }
|
||||||
|
|
||||||
@ -428,10 +428,10 @@ void ResmedLoader::ParseSTR(Machine *mach, QMap<QDate, STRFile> & STRmap)
|
|||||||
int psvar = (mode == MODE_ASV_VARIABLE_EPAP) ? 1 : 0;
|
int psvar = (mode == MODE_ASV_VARIABLE_EPAP) ? 1 : 0;
|
||||||
|
|
||||||
if ((sig = str.lookupLabel("Max PS", psvar))) {
|
if ((sig = str.lookupLabel("Max PS", psvar))) {
|
||||||
R.max_ps = EventDataType(sig->data[rec]) * sig->gain + sig->offset;
|
R.max_ps = EventDataType(sig->value[rec]) * sig->gain + sig->offset;
|
||||||
}
|
}
|
||||||
if ((sig = str.lookupLabel("Min PS", psvar))) {
|
if ((sig = str.lookupLabel("Min PS", psvar))) {
|
||||||
R.min_ps = EventDataType(sig->data[rec]) * sig->gain + sig->offset;
|
R.min_ps = EventDataType(sig->value[rec]) * sig->gain + sig->offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!haveipap) {
|
if (!haveipap) {
|
||||||
@ -449,25 +449,25 @@ void ResmedLoader::ParseSTR(Machine *mach, QMap<QDate, STRFile> & STRmap)
|
|||||||
bool a10 = false;
|
bool a10 = false;
|
||||||
if ((mode == MODE_CPAP) || (mode == MODE_APAP)) {
|
if ((mode == MODE_CPAP) || (mode == MODE_APAP)) {
|
||||||
if ((sig = str.lookupSignal(RMS9_EPR))) {
|
if ((sig = str.lookupSignal(RMS9_EPR))) {
|
||||||
epr= EventDataType(sig->data[rec]) * sig->gain + sig->offset;
|
epr= EventDataType(sig->value[rec]) * sig->gain + sig->offset;
|
||||||
}
|
}
|
||||||
if ((sig = str.lookupSignal(RMS9_EPRLevel))) {
|
if ((sig = str.lookupSignal(RMS9_EPRLevel))) {
|
||||||
epr_level= EventDataType(sig->data[rec]) * sig->gain + sig->offset;
|
epr_level= EventDataType(sig->value[rec]) * sig->gain + sig->offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((sig = str.lookupLabel("S.EPR.EPRType"))) {
|
if ((sig = str.lookupLabel("S.EPR.EPRType"))) {
|
||||||
a10 = true;
|
a10 = true;
|
||||||
epr = EventDataType(sig->data[rec]) * sig->gain + sig->offset;
|
epr = EventDataType(sig->value[rec]) * sig->gain + sig->offset;
|
||||||
epr += 1;
|
epr += 1;
|
||||||
}
|
}
|
||||||
int epr_on=0, clin_epr_on=0;
|
int epr_on=0, clin_epr_on=0;
|
||||||
if ((sig = str.lookupLabel("S.EPR.EPREnable"))) { // first check machines opinion
|
if ((sig = str.lookupLabel("S.EPR.EPREnable"))) { // first check machines opinion
|
||||||
a10 = true;
|
a10 = true;
|
||||||
epr_on = EventDataType(sig->data[rec]) * sig->gain + sig->offset;
|
epr_on = EventDataType(sig->value[rec]) * sig->gain + sig->offset;
|
||||||
}
|
}
|
||||||
if (epr_on && (sig = str.lookupLabel("S.EPR.ClinEnable"))) {
|
if (epr_on && (sig = str.lookupLabel("S.EPR.ClinEnable"))) {
|
||||||
a10 = true;
|
a10 = true;
|
||||||
clin_epr_on = EventDataType(sig->data[rec]) * sig->gain + sig->offset;
|
clin_epr_on = EventDataType(sig->value[rec]) * sig->gain + sig->offset;
|
||||||
}
|
}
|
||||||
if (a10 && !(epr_on && clin_epr_on)) {
|
if (a10 && !(epr_on && clin_epr_on)) {
|
||||||
epr = 0;
|
epr = 0;
|
||||||
@ -495,71 +495,71 @@ void ResmedLoader::ParseSTR(Machine *mach, QMap<QDate, STRFile> & STRmap)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ((sig = str.lookupLabel("AHI"))) {
|
if ((sig = str.lookupLabel("AHI"))) {
|
||||||
R.ahi = EventDataType(sig->data[rec]) * sig->gain + sig->offset;
|
R.ahi = EventDataType(sig->value[rec]) * sig->gain + sig->offset;
|
||||||
}
|
}
|
||||||
if ((sig = str.lookupLabel("AI"))) {
|
if ((sig = str.lookupLabel("AI"))) {
|
||||||
R.ai = EventDataType(sig->data[rec]) * sig->gain + sig->offset;
|
R.ai = EventDataType(sig->value[rec]) * sig->gain + sig->offset;
|
||||||
}
|
}
|
||||||
if ((sig = str.lookupLabel("HI"))) {
|
if ((sig = str.lookupLabel("HI"))) {
|
||||||
R.hi = EventDataType(sig->data[rec]) * sig->gain + sig->offset;
|
R.hi = EventDataType(sig->value[rec]) * sig->gain + sig->offset;
|
||||||
}
|
}
|
||||||
if ((sig = str.lookupLabel("UAI"))) {
|
if ((sig = str.lookupLabel("UAI"))) {
|
||||||
R.uai = EventDataType(sig->data[rec]) * sig->gain + sig->offset;
|
R.uai = EventDataType(sig->value[rec]) * sig->gain + sig->offset;
|
||||||
}
|
}
|
||||||
if ((sig = str.lookupLabel("CAI"))) {
|
if ((sig = str.lookupLabel("CAI"))) {
|
||||||
R.cai = EventDataType(sig->data[rec]) * sig->gain + sig->offset;
|
R.cai = EventDataType(sig->value[rec]) * sig->gain + sig->offset;
|
||||||
}
|
}
|
||||||
if ((sig = str.lookupLabel("OAI"))) {
|
if ((sig = str.lookupLabel("OAI"))) {
|
||||||
R.oai = EventDataType(sig->data[rec]) * sig->gain + sig->offset;
|
R.oai = EventDataType(sig->value[rec]) * sig->gain + sig->offset;
|
||||||
}
|
}
|
||||||
if ((sig = str.lookupLabel("CSR"))) {
|
if ((sig = str.lookupLabel("CSR"))) {
|
||||||
R.csr = EventDataType(sig->data[rec]) * sig->gain + sig->offset;
|
R.csr = EventDataType(sig->value[rec]) * sig->gain + sig->offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((sig = str.lookupLabel("S.RampTime"))) {
|
if ((sig = str.lookupLabel("S.RampTime"))) {
|
||||||
R.s_RampTime = EventDataType(sig->data[rec]) * sig->gain + sig->offset;
|
R.s_RampTime = EventDataType(sig->value[rec]) * sig->gain + sig->offset;
|
||||||
}
|
}
|
||||||
if ((sig = str.lookupLabel("S.RampEnable"))) {
|
if ((sig = str.lookupLabel("S.RampEnable"))) {
|
||||||
R.s_RampEnable = EventDataType(sig->data[rec]) * sig->gain + sig->offset;
|
R.s_RampEnable = EventDataType(sig->value[rec]) * sig->gain + sig->offset;
|
||||||
}
|
}
|
||||||
if ((sig = str.lookupLabel("S.EPR.ClinEnable"))) {
|
if ((sig = str.lookupLabel("S.EPR.ClinEnable"))) {
|
||||||
R.s_EPR_ClinEnable = EventDataType(sig->data[rec]) * sig->gain + sig->offset;
|
R.s_EPR_ClinEnable = EventDataType(sig->value[rec]) * sig->gain + sig->offset;
|
||||||
}
|
}
|
||||||
if ((sig = str.lookupLabel("S.EPR.EPREnable"))) {
|
if ((sig = str.lookupLabel("S.EPR.EPREnable"))) {
|
||||||
R.s_EPREnable = EventDataType(sig->data[rec]) * sig->gain + sig->offset;
|
R.s_EPREnable = EventDataType(sig->value[rec]) * sig->gain + sig->offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((sig = str.lookupLabel("S.ABFilter"))) {
|
if ((sig = str.lookupLabel("S.ABFilter"))) {
|
||||||
R.s_ABFilter = EventDataType(sig->data[rec]) * sig->gain + sig->offset;
|
R.s_ABFilter = EventDataType(sig->value[rec]) * sig->gain + sig->offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((sig = str.lookupLabel("S.ClimateControl"))) {
|
if ((sig = str.lookupLabel("S.ClimateControl"))) {
|
||||||
R.s_ClimateControl = EventDataType(sig->data[rec]) * sig->gain + sig->offset;
|
R.s_ClimateControl = EventDataType(sig->value[rec]) * sig->gain + sig->offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((sig = str.lookupLabel("S.Mask"))) {
|
if ((sig = str.lookupLabel("S.Mask"))) {
|
||||||
R.s_Mask = EventDataType(sig->data[rec]) * sig->gain + sig->offset;
|
R.s_Mask = EventDataType(sig->value[rec]) * sig->gain + sig->offset;
|
||||||
}
|
}
|
||||||
if ((sig = str.lookupLabel("S.PtAccess"))) {
|
if ((sig = str.lookupLabel("S.PtAccess"))) {
|
||||||
R.s_PtAccess = EventDataType(sig->data[rec]) * sig->gain + sig->offset;
|
R.s_PtAccess = EventDataType(sig->value[rec]) * sig->gain + sig->offset;
|
||||||
}
|
}
|
||||||
if ((sig = str.lookupLabel("S.SmartStart"))) {
|
if ((sig = str.lookupLabel("S.SmartStart"))) {
|
||||||
R.s_SmartStart = EventDataType(sig->data[rec]) * sig->gain + sig->offset;
|
R.s_SmartStart = EventDataType(sig->value[rec]) * sig->gain + sig->offset;
|
||||||
}
|
}
|
||||||
if ((sig = str.lookupLabel("S.HumEnable"))) {
|
if ((sig = str.lookupLabel("S.HumEnable"))) {
|
||||||
R.s_HumEnable = EventDataType(sig->data[rec]) * sig->gain + sig->offset;
|
R.s_HumEnable = EventDataType(sig->value[rec]) * sig->gain + sig->offset;
|
||||||
}
|
}
|
||||||
if ((sig = str.lookupLabel("S.HumLevel"))) {
|
if ((sig = str.lookupLabel("S.HumLevel"))) {
|
||||||
R.s_HumLevel = EventDataType(sig->data[rec]) * sig->gain + sig->offset;
|
R.s_HumLevel = EventDataType(sig->value[rec]) * sig->gain + sig->offset;
|
||||||
}
|
}
|
||||||
if ((sig = str.lookupLabel("S.TempEnable"))) {
|
if ((sig = str.lookupLabel("S.TempEnable"))) {
|
||||||
R.s_TempEnable = EventDataType(sig->data[rec]) * sig->gain + sig->offset;
|
R.s_TempEnable = EventDataType(sig->value[rec]) * sig->gain + sig->offset;
|
||||||
}
|
}
|
||||||
if ((sig = str.lookupLabel("S.Temp"))) {
|
if ((sig = str.lookupLabel("S.Temp"))) {
|
||||||
R.s_Temp = EventDataType(sig->data[rec]) * sig->gain + sig->offset;
|
R.s_Temp = EventDataType(sig->value[rec]) * sig->gain + sig->offset;
|
||||||
}
|
}
|
||||||
if ((sig = str.lookupLabel("S.Tube"))) {
|
if ((sig = str.lookupLabel("S.Tube"))) {
|
||||||
R.s_Tube = EventDataType(sig->data[rec]) * sig->gain + sig->offset;
|
R.s_Tube = EventDataType(sig->value[rec]) * sig->gain + sig->offset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -715,7 +715,7 @@ int PeekAnnotations(const QString & path, quint32 &start, quint32 &end)
|
|||||||
for (int s = 0; s < edf.GetNumSignals(); s++) {
|
for (int s = 0; s < edf.GetNumSignals(); s++) {
|
||||||
recs = edf.edfsignals[s].nr * edf.GetNumDataRecords() * 2;
|
recs = edf.edfsignals[s].nr * edf.GetNumDataRecords() * 2;
|
||||||
|
|
||||||
data = (char *)edf.edfsignals[s].data;
|
data = (char *)edf.edfsignals[s].value;
|
||||||
pos = 0;
|
pos = 0;
|
||||||
tt = edf.startdate;
|
tt = edf.startdate;
|
||||||
//duration = 0;
|
//duration = 0;
|
||||||
@ -1791,7 +1791,7 @@ int ResmedLoader::Open(const QString & dirpath)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
QDate date = stredf->startdate_orig.date();
|
QDate date = stredf->edfHdr.startdate_orig.date();
|
||||||
date = QDate(date.year(), date.month(), 1);
|
date = QDate(date.year(), date.month(), 1);
|
||||||
if (STRmap.contains(date)) {
|
if (STRmap.contains(date)) {
|
||||||
delete stredf;
|
delete stredf;
|
||||||
@ -1869,7 +1869,7 @@ int ResmedLoader::Open(const QString & dirpath)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Don't trust the filename date, pick the one inside the STR...
|
// Don't trust the filename date, pick the one inside the STR...
|
||||||
date = stredf->startdate_orig.date();
|
date = stredf->edfHdr.startdate_orig.date();
|
||||||
date = QDate(date.year(), date.month(), 1);
|
date = QDate(date.year(), date.month(), 1);
|
||||||
|
|
||||||
STRmap[date] = STRFile(fi.canonicalFilePath(), stredf);
|
STRmap[date] = STRFile(fi.canonicalFilePath(), stredf);
|
||||||
@ -2145,7 +2145,7 @@ bool ResmedLoader::LoadCSL(Session *sess, const QString & path)
|
|||||||
for (int s = 0; s < edf.GetNumSignals(); s++) {
|
for (int s = 0; s < edf.GetNumSignals(); s++) {
|
||||||
recs = edf.edfsignals[s].nr * edf.GetNumDataRecords() * 2;
|
recs = edf.edfsignals[s].nr * edf.GetNumDataRecords() * 2;
|
||||||
|
|
||||||
data = (char *)edf.edfsignals[s].data;
|
data = (char *)edf.edfsignals[s].value;
|
||||||
pos = 0;
|
pos = 0;
|
||||||
tt = edf.startdate;
|
tt = edf.startdate;
|
||||||
// sess->updateFirst(tt);
|
// sess->updateFirst(tt);
|
||||||
@ -2312,7 +2312,7 @@ bool ResmedLoader::LoadEVE(Session *sess, const QString & path)
|
|||||||
for (int s = 0; s < edf.GetNumSignals(); s++) {
|
for (int s = 0; s < edf.GetNumSignals(); s++) {
|
||||||
recs = edf.edfsignals[s].nr * edf.GetNumDataRecords() * 2;
|
recs = edf.edfsignals[s].nr * edf.GetNumDataRecords() * 2;
|
||||||
|
|
||||||
data = (char *)edf.edfsignals[s].data;
|
data = (char *)edf.edfsignals[s].value;
|
||||||
pos = 0;
|
pos = 0;
|
||||||
tt = edf.startdate;
|
tt = edf.startdate;
|
||||||
|
|
||||||
@ -2495,7 +2495,7 @@ bool ResmedLoader::LoadBRP(Session *sess, const QString & path)
|
|||||||
#ifdef DEBUG_EFFICIENCY
|
#ifdef DEBUG_EFFICIENCY
|
||||||
time2.start();
|
time2.start();
|
||||||
#endif
|
#endif
|
||||||
a->AddWaveform(edf.startdate, es.data, recs, duration);
|
a->AddWaveform(edf.startdate, es.value, recs, duration);
|
||||||
#ifdef DEBUG_EFFICIENCY
|
#ifdef DEBUG_EFFICIENCY
|
||||||
AddWavetime+= time2.elapsed();
|
AddWavetime+= time2.elapsed();
|
||||||
#endif
|
#endif
|
||||||
@ -2552,7 +2552,7 @@ void ResmedLoader::ToTimeDelta(Session *sess, ResMedEDFParser &edf, EDFSignal &e
|
|||||||
tt += rate * startpos;
|
tt += rate * startpos;
|
||||||
}
|
}
|
||||||
|
|
||||||
qint16 *sptr = es.data;
|
qint16 *sptr = es.value;
|
||||||
qint16 *eptr = sptr + recs;
|
qint16 *eptr = sptr + recs;
|
||||||
sptr += startpos;
|
sptr += startpos;
|
||||||
|
|
||||||
@ -2709,7 +2709,7 @@ bool ResmedLoader::LoadSAD(Session *sess, const QString & path)
|
|||||||
bool hasdata = false;
|
bool hasdata = false;
|
||||||
|
|
||||||
for (int i = 0; i < recs; ++i) {
|
for (int i = 0; i < recs; ++i) {
|
||||||
if (es.data[i] != -1) {
|
if (es.value[i] != -1) {
|
||||||
hasdata = true;
|
hasdata = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2810,7 +2810,7 @@ bool ResmedLoader::LoadPLD(Session *sess, const QString & path)
|
|||||||
} else if (matchSignal(CPAP_RespRate, es.label)) {
|
} else if (matchSignal(CPAP_RespRate, es.label)) {
|
||||||
code = CPAP_RespRate;
|
code = CPAP_RespRate;
|
||||||
a = sess->AddEventList(code, EVL_Waveform, es.gain, es.offset, 0, 0, rate);
|
a = sess->AddEventList(code, EVL_Waveform, es.gain, es.offset, 0, 0, rate);
|
||||||
a->AddWaveform(edf.startdate, es.data, recs, duration);
|
a->AddWaveform(edf.startdate, es.value, recs, duration);
|
||||||
} else if (matchSignal(CPAP_TidalVolume, es.label)) {
|
} else if (matchSignal(CPAP_TidalVolume, es.label)) {
|
||||||
code = CPAP_TidalVolume;
|
code = CPAP_TidalVolume;
|
||||||
es.gain *= 1000.0;
|
es.gain *= 1000.0;
|
||||||
@ -2845,9 +2845,9 @@ bool ResmedLoader::LoadPLD(Session *sess, const QString & path)
|
|||||||
// es.physical_maximum /= 100.0;
|
// es.physical_maximum /= 100.0;
|
||||||
// es.physical_minimum /= 100.0;
|
// es.physical_minimum /= 100.0;
|
||||||
// qDebug() << "IE Gain, Max, Min" << es.gain << es.physical_maximum << es.physical_minimum;
|
// qDebug() << "IE Gain, Max, Min" << es.gain << es.physical_maximum << es.physical_minimum;
|
||||||
// qDebug() << "IE count, data..." << es.nr << es.data[0] << es.data[1] << es.data[2] << es.data[3] << es.data[4];
|
// qDebug() << "IE count, data..." << es.nr << es.value[0] << es.value[1] << es.value[2] << es.value[3] << es.value[4];
|
||||||
a = sess->AddEventList(code, EVL_Waveform, es.gain, es.offset, 0, 0, rate);
|
a = sess->AddEventList(code, EVL_Waveform, es.gain, es.offset, 0, 0, rate);
|
||||||
a->AddWaveform(edf.startdate, es.data, recs, duration);
|
a->AddWaveform(edf.startdate, es.value, recs, duration);
|
||||||
//a=ToTimeDelta(sess,edf,es, code,recs,duration,0,0);
|
//a=ToTimeDelta(sess,edf,es, code,recs,duration,0,0);
|
||||||
} else if (matchSignal(CPAP_Ti, es.label)) {
|
} else if (matchSignal(CPAP_Ti, es.label)) {
|
||||||
code = CPAP_Ti;
|
code = CPAP_Ti;
|
||||||
@ -2857,7 +2857,7 @@ bool ResmedLoader::LoadPLD(Session *sess, const QString & path)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
a = sess->AddEventList(code, EVL_Waveform, es.gain, es.offset, 0, 0, rate);
|
a = sess->AddEventList(code, EVL_Waveform, es.gain, es.offset, 0, 0, rate);
|
||||||
a->AddWaveform(edf.startdate, es.data, recs, duration);
|
a->AddWaveform(edf.startdate, es.value, recs, duration);
|
||||||
//a=ToTimeDelta(sess,edf,es, code,recs,duration,0,0);
|
//a=ToTimeDelta(sess,edf,es, code,recs,duration,0,0);
|
||||||
} else if (matchSignal(CPAP_Te, es.label)) {
|
} else if (matchSignal(CPAP_Te, es.label)) {
|
||||||
code = CPAP_Te;
|
code = CPAP_Te;
|
||||||
@ -2866,12 +2866,12 @@ bool ResmedLoader::LoadPLD(Session *sess, const QString & path)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
a = sess->AddEventList(code, EVL_Waveform, es.gain, es.offset, 0, 0, rate);
|
a = sess->AddEventList(code, EVL_Waveform, es.gain, es.offset, 0, 0, rate);
|
||||||
a->AddWaveform(edf.startdate, es.data, recs, duration);
|
a->AddWaveform(edf.startdate, es.value, recs, duration);
|
||||||
//a=ToTimeDelta(sess,edf,es, code,recs,duration,0,0);
|
//a=ToTimeDelta(sess,edf,es, code,recs,duration,0,0);
|
||||||
} else if (matchSignal(CPAP_TgMV, es.label)) {
|
} else if (matchSignal(CPAP_TgMV, es.label)) {
|
||||||
code = CPAP_TgMV;
|
code = CPAP_TgMV;
|
||||||
a = sess->AddEventList(code, EVL_Waveform, es.gain, es.offset, 0, 0, rate);
|
a = sess->AddEventList(code, EVL_Waveform, es.gain, es.offset, 0, 0, rate);
|
||||||
a->AddWaveform(edf.startdate, es.data, recs, duration);
|
a->AddWaveform(edf.startdate, es.value, recs, duration);
|
||||||
//a=ToTimeDelta(sess,edf,es, code,recs,duration,0,0);
|
//a=ToTimeDelta(sess,edf,es, code,recs,duration,0,0);
|
||||||
} else if (es.label == "") { // What the hell resmed??
|
} else if (es.label == "") { // What the hell resmed??
|
||||||
if (emptycnt == 0) {
|
if (emptycnt == 0) {
|
||||||
|
@ -459,7 +459,13 @@ test {
|
|||||||
CONFIG -= app_bundle
|
CONFIG -= app_bundle
|
||||||
!win32 { # add memory checking on Linux and macOS test builds
|
!win32 { # add memory checking on Linux and macOS test builds
|
||||||
QMAKE_CFLAGS += -Werror -fsanitize=address -fno-omit-frame-pointer -fno-common -fsanitize-address-use-after-scope
|
QMAKE_CFLAGS += -Werror -fsanitize=address -fno-omit-frame-pointer -fno-common -fsanitize-address-use-after-scope
|
||||||
|
lessThan(QT_MAJOR_VERSION,5)|lessThan(QT_MINOR_VERSION,9) {
|
||||||
|
QMAKE_CFLAGS -= -fsanitize-address-use-after-scope
|
||||||
|
}
|
||||||
QMAKE_CXXFLAGS += -Werror -fsanitize=address -fno-omit-frame-pointer -fno-common -fsanitize-address-use-after-scope
|
QMAKE_CXXFLAGS += -Werror -fsanitize=address -fno-omit-frame-pointer -fno-common -fsanitize-address-use-after-scope
|
||||||
|
lessThan(QT_MAJOR_VERSION,5)|lessThan(QT_MINOR_VERSION,9) {
|
||||||
|
QMAKE_CXXFLAGS -= -fsanitize-address-use-after-scope
|
||||||
|
}
|
||||||
QMAKE_LFLAGS += -fsanitize=address
|
QMAKE_LFLAGS += -fsanitize=address
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user