diff --git a/oscar/SleepLib/loader_plugins/edfparser.cpp b/oscar/SleepLib/loader_plugins/edfparser.cpp index 5efe560a..cea9e9a3 100644 --- a/oscar/SleepLib/loader_plugins/edfparser.cpp +++ b/oscar/SleepLib/loader_plugins/edfparser.cpp @@ -37,8 +37,8 @@ EDFInfo::EDFInfo() EDFInfo::~EDFInfo() { - if ( fileData ) - delete fileData; +// if ( fileData ) +// delete fileData; for (auto & s : edfsignals) { if (s.dataArray) @@ -69,7 +69,7 @@ QByteArray * EDFInfo::Open(const QString & name) } fi.close(); if (fileData->size() <= EDFHeaderSize) { - delete fileData; + fileData->clear();; qDebug() << "EDFInfo::Open() File too short " << name; sleep(1); return nullptr; @@ -86,8 +86,7 @@ bool EDFInfo::parseHeader( EDFHeaderRaw *hdrPtr ) if (!ok) { qWarning() << "EDFInfo::Parse() Bad Version " << filename; sleep(1); - delete fileData; - fileData = nullptr; + fileData->clear(); return false; } @@ -106,8 +105,7 @@ bool EDFInfo::parseHeader( EDFHeaderRaw *hdrPtr ) if (!ok) { qWarning() << "EDFInfo::Parse() Bad header byte count " << filename; sleep(1); - delete fileData; - fileData = nullptr; + fileData->clear(); return false; } edfHdr.reserved44=QString::fromLatin1(hdrPtr->reserved, 44).trimmed(); @@ -115,24 +113,21 @@ bool EDFInfo::parseHeader( EDFHeaderRaw *hdrPtr ) if (!ok) { qWarning() << "EDFInfo::Parse() Bad data record count " << filename; sleep(1); - delete fileData; - fileData = nullptr; + fileData->clear(); return false; } edfHdr.duration_Seconds = QString::fromLatin1(hdrPtr->dur_data_records, 8).toDouble(&ok); if (!ok) { qWarning() << "EDFInfo::Parse() Bad duration " << filename; sleep(1); - delete fileData; - fileData = nullptr; + fileData->clear(); return false; } edfHdr.num_signals = QString::fromLatin1(hdrPtr->num_signals, 4).toLong(&ok); if (!ok) { qWarning() << "EDFInfo::Parse() Bad number of signals " << filename; sleep(1); - delete fileData; - fileData = nullptr; + fileData->clear(); return false; } return true; @@ -172,8 +167,7 @@ bool EDFInfo::Parse(QByteArray * fileData ) if (eof) { qWarning() << "EDFInfo::Parse() Early end of file " << filename; sleep(1); - delete fileData; - fileData = nullptr; + fileData->clear(); return false; } } @@ -211,8 +205,7 @@ bool EDFInfo::Parse(QByteArray * fileData ) if (eof) { qWarning() << "EDFInfo::Parse() Early end of file " << filename; sleep(1); - delete fileData; - fileData = nullptr; + fileData->clear(); return false; } @@ -228,8 +221,7 @@ bool EDFInfo::Parse(QByteArray * fileData ) // so abort and let the user clean up the corrupted file themselves qWarning() << "EDFInfo::Parse(): " << filename << " is too short!"; sleep(1); - delete fileData; - fileData = nullptr; + fileData->clear(); return false; } @@ -256,8 +248,7 @@ bool EDFInfo::Parse(QByteArray * fileData ) } } } - delete fileData; - fileData = nullptr; + fileData->clear(); return true; } @@ -282,6 +273,7 @@ EDFHeaderQT * EDFInfo::GetHeader( const QString & name) if ( ! parseHeader( hdrPtr ) ) return nullptr; + fileData->clear(); return & edfHdr; } diff --git a/oscar/SleepLib/loader_plugins/resmed_loader.cpp b/oscar/SleepLib/loader_plugins/resmed_loader.cpp index 07b1167a..7eee8aef 100644 --- a/oscar/SleepLib/loader_plugins/resmed_loader.cpp +++ b/oscar/SleepLib/loader_plugins/resmed_loader.cpp @@ -140,12 +140,12 @@ bool matchSignal(ChannelID ch, const QString & name) } // This function parses a list of STR files and creates a date ordered map of individual records -void ResmedLoader::ParseSTR(Machine *mach, QMap & STRmap) +void ResmedLoader::ParseSTR(Machine *mach, QMap & STRmap, QDate firstImport) { Q_UNUSED(mach) - QDateTime ignoreBefore = p_profile->session->ignoreOlderSessionsDate(); - bool ignoreOldSessions = p_profile->session->ignoreOlderSessions(); +// QDateTime ignoreBefore = p_profile->session->ignoreOlderSessionsDate(); +// bool ignoreOldSessions = p_profile->session->ignoreOlderSessions(); int totalRecs = 0; for (auto it=STRmap.begin(), end=STRmap.end(); it != end; ++it) { @@ -167,10 +167,15 @@ void ResmedLoader::ParseSTR(Machine *mach, QMap & STRmap) QDate date = str.edfHdr.startdate_orig.date(); // each STR.edf record starts at 12 noon int size = str.GetNumDataRecords(); + QDate lastDay = date.addDays(size-1); qDebug() << "Parsing" << strfile << date.toString() << size << str.GetNumSignals(); - qDebug() << "Last day is" << date.addDays(size-1).toString(); - sleep(1); + qDebug() << "Last day is" << lastDay; + + if ( lastDay < firstImport ) { + qDebug() << "LastDay before firstImport, skipping" << file.filename; + continue; + } // ResMed and their consistent naming and spacing... :/ EDFSignal *maskon = str.lookupLabel("Mask On"); @@ -189,12 +194,12 @@ void ResmedLoader::ParseSTR(Machine *mach, QMap & STRmap) emit setProgressValue(++currentRec); QCoreApplication::processEvents(); - if (ignoreOldSessions) { - if (date < ignoreBefore.date()) { - qDebug() << "Skipping" << date.toString() << "Before" << ignoreBefore.date().toString(); + // if (ignoreOldSessions) { + if (date < firstImport) { +// qDebug() << "Skipping" << date.toString() << "Before" << ignoreBefore.date().toString(); continue; } - } + // } auto rit = resdayList.find(date); if (rit != resdayList.end()) { @@ -221,8 +226,8 @@ void ResmedLoader::ParseSTR(Machine *mach, QMap & STRmap) rit = resdayList.insert(date, ResMedDay()); - qDebug() << "Setting up STRRecord for" << date.toString(); - sleep(1); +// qDebug() << "Setting up STRRecord for" << date.toString(); +// sleep(1); STRRecord &R = rit.value().str; uint timestamp = QDateTime(date,QTime(12,0,0)).toTime_t(); @@ -591,12 +596,12 @@ void ResmedLoader::ParseSTR(Machine *mach, QMap & STRmap) if ((sig = str.lookupLabel("S.Tube"))) { R.s_Tube = EventDataType(sig->dataArray[rec]) * sig->gain + sig->offset; } - qDebug() << "Finished" << date.toString(); - sleep(1); +// qDebug() << "Finished" << date.toString(); +// sleep(1); } } - qDebug() << "Finished ParseSTR"; - sleep(3); +// qDebug() << "Finished ParseSTR"; +// sleep(3); } ResmedLoader::ResmedLoader() { @@ -648,6 +653,46 @@ bool ResmedLoader::Detect(const QString & givenpath) return true; } +QHash parseIdentLine( const QString line, MachineInfo * info) +{ + QHash hash; + + if (!line.isEmpty()) { + QString key = line.section(" ", 0, 0).section("#", 1); + QString value = line.section(" ", 1); + + if (key == "SRN") { // Serial Number + info->serial = value; + + } else if (key == "PNA") { // Product Name + value.replace("_"," "); + + if (value.contains(STR_ResMed_S9)) { + value.replace(STR_ResMed_S9, ""); + info->series = STR_ResMed_S9; + } else if (value.contains(STR_ResMed_AirSense10)) { + value.replace(STR_ResMed_AirSense10, ""); + info->series = STR_ResMed_AirSense10; + } else if (value.contains(STR_ResMed_AirCurve10)) { + value.replace(STR_ResMed_AirCurve10, ""); + info->series = STR_ResMed_AirCurve10; + } + value.replace("(",""); + value.replace(")",""); + if (value.contains("Adapt", Qt::CaseInsensitive)) { + if (!value.contains("VPAP")) { + value.replace("Adapt", QObject::tr("VPAP Adapt")); + } + } + info->model = value.trimmed(); + } else if (key == "PCD") { // Product Code + info->modelnumber = value; + } + hash[key] = value; + } + + return hash; +} MachineInfo ResmedLoader::PeekInfo(const QString & path) { @@ -665,39 +710,7 @@ MachineInfo ResmedLoader::PeekInfo(const QString & path) // Parse # entries into idmap. while (!f.atEnd()) { QString line = f.readLine().trimmed(); - - if (!line.isEmpty()) { - QString key = line.section(" ", 0, 0).section("#", 1); - QString value = line.section(" ", 1); - - if (key == "SRN") { // Serial Number - info.serial = value; - - } else if (key == "PNA") { // Product Name - value.replace("_"," "); - - if (value.contains(STR_ResMed_S9)) { - value.replace(STR_ResMed_S9, ""); - info.series = STR_ResMed_S9; - } else if (value.contains(STR_ResMed_AirSense10)) { - value.replace(STR_ResMed_AirSense10, ""); - info.series = STR_ResMed_AirSense10; - } else if (value.contains(STR_ResMed_AirCurve10)) { - value.replace(STR_ResMed_AirCurve10, ""); - info.series = STR_ResMed_AirCurve10; - } - value.replace("(",""); - value.replace(")",""); - if (value.contains("Adapt", Qt::CaseInsensitive)) { - if (!value.contains("VPAP")) { - value.replace("Adapt", QObject::tr("VPAP Adapt")); - } - } - info.model = value.trimmed(); - } else if (key == "PCD") { // Product Code - info.modelnumber = value; - } - } + QHash hash = parseIdentLine( line, & info ); } return info; @@ -948,7 +961,7 @@ EDFduration getEDFDuration(const QString & filename) /////////////////////////////////////////////////////////////////////////////////////////// // Sorted EDF files that need processing into date records according to ResMed noon split /////////////////////////////////////////////////////////////////////////////////////////// -int ResmedLoader::scanFiles(Machine * mach, const QString & datalog_path) +int ResmedLoader::scanFiles(Machine * mach, const QString & datalog_path, QDate firstImport) { QTime time; @@ -988,8 +1001,8 @@ int ResmedLoader::scanFiles(Machine * mach, const QString & datalog_path) QFileInfoList dirlist = dir.entryInfoList(); int dirlistSize = dirlist.size(); - QDateTime ignoreBefore = p_profile->session->ignoreOlderSessionsDate(); - bool ignoreOldSessions = p_profile->session->ignoreOlderSessions(); +// QDateTime ignoreBefore = p_profile->session->ignoreOlderSessionsDate(); +// bool ignoreOldSessions = p_profile->session->ignoreOlderSessions(); // Scan for any sub folders and create files lists for (int i = 0; i < dirlistSize ; i++) { @@ -1004,13 +1017,13 @@ int ResmedLoader::scanFiles(Machine * mach, const QString & datalog_path) continue; } } else if (len == 8) { // test directory date - if (ignoreOldSessions) { - QDateTime dirDate = QDateTime().fromString(filename, "yyyyMMdd"); - if (dirDate.date() < ignoreBefore.date()) { + // if (ignoreOldSessions) { + QDate dirDate = QDate().fromString(filename, "yyyyMMdd"); + if (dirDate < firstImport) { qDebug() << "Skipping directory - ignore before " << filename; continue; } - } + // } } else { qDebug() << "Skipping directory - bad name size " << filename; continue; @@ -1079,10 +1092,10 @@ int ResmedLoader::scanFiles(Machine * mach, const QString & datalog_path) date = date.addDays(-1); } - if (ignoreOldSessions) { - if (date < ignoreBefore.date()) +// if (ignoreOldSessions) { + if (date < firstImport) continue; - } +// } // Chop off the .gz component if it exists, it's not needed at this stage if (filename.endsWith(STR_ext_gz)) { @@ -1630,48 +1643,50 @@ bool parseIdentTGT( QString path, MachineInfo * info, QHash & // Parse # entries into idmap. while (!f.atEnd()) { QString line = f.readLine().trimmed(); + QHash hash = parseIdentLine( line, info ); + idmap.unite(hash); - if (!line.isEmpty()) { - QString key = line.section(" ", 0, 0).section("#", 1); - QString value = line.section(" ", 1); - - if (key == "SRN") { // Serial Number - info->serial = value; - qDebug() << "Serial # is >" << value << "<"; - continue; - - } else if (key == "PNA") { // Product Name - qDebug() << "Prouct Name is >" << value << "<"; - value.replace("_"," "); - if (value.contains(STR_ResMed_S9)) { - value.replace(STR_ResMed_S9, ""); - info->series = STR_ResMed_S9; - } else if (value.contains(STR_ResMed_AirSense10)) { - value.replace(STR_ResMed_AirSense10, ""); - info->series = STR_ResMed_AirSense10; - } else if (value.contains(STR_ResMed_AirCurve10)) { - value.replace(STR_ResMed_AirCurve10, ""); - info->series = STR_ResMed_AirCurve10; - } - value.replace("(",""); - value.replace(")",""); - - if (value.contains("Adapt", Qt::CaseInsensitive)) { - if (!value.contains("VPAP")) { - value.replace("Adapt", QObject::tr("VPAP Adapt")); - } - } - info->model = value.trimmed(); - continue; - - } else if (key == "PCD") { // Product Code - qDebug() << "Prouct Code is >" << value << "<"; - info->modelnumber = value; - continue; - } - - idmap[key] = value; - } +// if (!line.isEmpty()) { +// QString key = line.section(" ", 0, 0).section("#", 1); +// QString value = line.section(" ", 1); +// +// if (key == "SRN") { // Serial Number +// info->serial = value; +// qDebug() << "Serial # is >" << value << "<"; +// continue; +// +// } else if (key == "PNA") { // Product Name +// qDebug() << "Prouct Name is >" << value << "<"; +// value.replace("_"," "); +// if (value.contains(STR_ResMed_S9)) { +// value.replace(STR_ResMed_S9, ""); +// info->series = STR_ResMed_S9; +// } else if (value.contains(STR_ResMed_AirSense10)) { +// value.replace(STR_ResMed_AirSense10, ""); +// info->series = STR_ResMed_AirSense10; +// } else if (value.contains(STR_ResMed_AirCurve10)) { +// value.replace(STR_ResMed_AirCurve10, ""); +// info->series = STR_ResMed_AirCurve10; +// } +// value.replace("(",""); +// value.replace(")",""); +// +// if (value.contains("Adapt", Qt::CaseInsensitive)) { +// if (!value.contains("VPAP")) { +// value.replace("Adapt", QObject::tr("VPAP Adapt")); +// } +// } +// info->model = value.trimmed(); +// continue; +// +// } else if (key == "PCD") { // Product Code +// qDebug() << "Prouct Code is >" << value << "<"; +// info->modelnumber = value; +// continue; +// } +// +// idmap[key] = value; +// } } f.close(); @@ -1973,7 +1988,7 @@ int ResmedLoader::Open(const QString & dirpath) // Build a Date map of all records in STR.edf files, populating ResDayList /////////////////////////////////////////////////////////////////////////////////// - ParseSTR(mach, STRmap ); // , firstImportDay); + ParseSTR(mach, STRmap, firstImportDay); // We are done with the Parsed STR EDF objects, so delete them for (auto it=STRmap.begin(), end=STRmap.end(); it != end; ++it) { @@ -2026,7 +2041,7 @@ int ResmedLoader::Open(const QString & dirpath) qDebug() << "Starting scan of DATALOG"; sleep(1); - scanFiles(mach, datalogPath ); // , firstImportDay); + scanFiles(mach, datalogPath, firstImportDay); if (isAborted()) return 0; @@ -2206,11 +2221,11 @@ bool ResmedLoader::LoadCSL(Session *sess, const QString & path) // Process event annotation records qDebug() << "File has " << edf.annotations.size() << "annotation vectors"; - int vec = 1; +// int vec = 1; for (auto annoVec = edf.annotations.begin(); annoVec != edf.annotations.end(); annoVec++ ) { - qDebug() << "Vector " << vec++ << " has " << annoVec->size() << " annotations"; +// qDebug() << "Vector " << vec++ << " has " << annoVec->size() << " annotations"; for (auto anno = annoVec->begin(); anno != annoVec->end(); anno++ ) { - qDebug() << "Offset: " << anno->offset << " Duration: " << anno->duration << " Text: " << anno->text; +// qDebug() << "Offset: " << anno->offset << " Duration: " << anno->duration << " Text: " << anno->text; double tt = edf.startdate + qint64(anno->offset*1000.0); if ( ! anno->text.isEmpty()) { @@ -2228,7 +2243,7 @@ bool ResmedLoader::LoadCSL(Session *sess, const QString & path) } else { qDebug() << "Split csr event flag in " << edf.filename; } - } else if (anno->text != "recording starts") { + } else if (anno->text != "Recording starts") { qDebug() << "Unobserved ResMed CSL annotation field: " << anno->text; } } @@ -2283,11 +2298,11 @@ bool ResmedLoader::LoadEVE(Session *sess, const QString & path) // Process event annotation records qDebug() << "File has " << edf.annotations.size() << "annotation vectors"; - int vec = 1; +// int vec = 1; for (auto annoVec = edf.annotations.begin(); annoVec != edf.annotations.end(); annoVec++ ) { - qDebug() << "Vector " << vec++ << " has " << annoVec->size() << " annotations"; +// qDebug() << "Vector " << vec++ << " has " << annoVec->size() << " annotations"; for (auto anno = annoVec->begin(); anno != annoVec->end(); anno++ ) { - qDebug() << "Offset: " << anno->offset << " Duration: " << anno->duration << " Text: " << anno->text; +// qDebug() << "Offset: " << anno->offset << " Duration: " << anno->duration << " Text: " << anno->text; double tt = edf.startdate + qint64(anno->offset*1000.0); if ( ! anno->text.isEmpty()) { @@ -2317,7 +2332,7 @@ bool ResmedLoader::LoadEVE(Session *sess, const QString & path) if (sess->checkInside(tt)) CA->AddEvent(tt, anno->duration); } else { - if (anno->text != "recording starts") { + if (anno->text != "Recording starts") { qDebug() << "Unobserved ResMed annotation field: " << anno->text; } } diff --git a/oscar/SleepLib/loader_plugins/resmed_loader.h b/oscar/SleepLib/loader_plugins/resmed_loader.h index 0beb3989..94a16040 100644 --- a/oscar/SleepLib/loader_plugins/resmed_loader.h +++ b/oscar/SleepLib/loader_plugins/resmed_loader.h @@ -349,10 +349,10 @@ class ResmedLoader : public CPAPLoader protected: //! \brief The STR.edf file is a unique edf file with many signals - void ParseSTR(Machine *, QMap &); + void ParseSTR(Machine *, QMap &, QDate); //! \brief Scan for new files to import, group into sessions and add to task que - int scanFiles(Machine * mach, const QString & datalog_path); + 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);