Still work in progress

This commit is contained in:
Phil Olynyk 2019-08-27 23:59:51 -04:00
parent 4c121cc53a
commit 5ee8feb37c
4 changed files with 128 additions and 32 deletions

View File

@ -3,6 +3,7 @@
#include <QApplication>
// #include <iostream>
#include <QDebug>
#include <QThread>
typedef float EventDataType;
@ -154,5 +155,8 @@ int main(int argc, char *argv[]) {
}
}
}
qDebug() << "Deleting the edf object";
delete &str;
QThread::sleep(1);
qDebug() << "Done";
}

View File

@ -19,8 +19,15 @@
#include "edfparser.h"
//EDFSignal::~EDFSignal()
//{
// delete [] dataArray;
//}
EDFInfo::EDFInfo()
{
filename = QString();
edfsignals.clear();
filesize = 0;
datasize = 0;
signalPtr = nullptr;
@ -30,6 +37,9 @@ EDFInfo::EDFInfo()
EDFInfo::~EDFInfo()
{
if ( fileData )
delete fileData;
for (auto & s : edfsignals) {
if (s.dataArray)
delete [] s.dataArray;
@ -68,27 +78,16 @@ QByteArray * EDFInfo::Open(const QString & name)
return fileData;
}
bool EDFInfo::Parse(QByteArray * fileData )
bool EDFInfo::parseHeader( EDFHeaderRaw *hdrPtr )
{
bool ok;
if (fileData == nullptr) {
qWarning() << "EDFInfo::Parse() called without valid EDF data " << filename;
sleep(1);
return false;
}
hdrPtr = (EDFHeaderRaw *)(*fileData).constData();
signalPtr = (char *)(*fileData).constData() + EDFHeaderSize;
filesize = (*fileData).size();
datasize = filesize - EDFHeaderSize;
pos = 0;
eof = false;
edfHdr.version = QString::fromLatin1(hdrPtr->version, 8).toLong(&ok);
if (!ok) {
qWarning() << "EDFInfo::Parse() Bad Version " << filename;
sleep(1);
delete fileData;
fileData = nullptr;
return false;
}
@ -107,6 +106,8 @@ bool EDFInfo::Parse(QByteArray * fileData )
if (!ok) {
qWarning() << "EDFInfo::Parse() Bad header byte count " << filename;
sleep(1);
delete fileData;
fileData = nullptr;
return false;
}
edfHdr.reserved44=QString::fromLatin1(hdrPtr->reserved, 44).trimmed();
@ -114,20 +115,49 @@ bool EDFInfo::Parse(QByteArray * fileData )
if (!ok) {
qWarning() << "EDFInfo::Parse() Bad data record count " << filename;
sleep(1);
delete fileData;
fileData = nullptr;
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;
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;
return false;
}
return true;
}
bool EDFInfo::Parse(QByteArray * fileData )
{
bool ok;
if (fileData == nullptr) {
qWarning() << "EDFInfo::Parse() called without valid EDF data " << filename;
sleep(1);
return false;
}
hdrPtr = (EDFHeaderRaw *)(*fileData).constData();
signalPtr = (char *)(*fileData).constData() + EDFHeaderSize;
filesize = (*fileData).size();
datasize = filesize - EDFHeaderSize;
pos = 0;
eof = false;
if ( ! parseHeader( hdrPtr ) )
return false;
// Initialize fixed-size signal list.
edfsignals.resize(edfHdr.num_signals);
@ -142,6 +172,8 @@ bool EDFInfo::Parse(QByteArray * fileData )
if (eof) {
qWarning() << "EDFInfo::Parse() Early end of file " << filename;
sleep(1);
delete fileData;
fileData = nullptr;
return false;
}
}
@ -179,6 +211,8 @@ bool EDFInfo::Parse(QByteArray * fileData )
if (eof) {
qWarning() << "EDFInfo::Parse() Early end of file " << filename;
sleep(1);
delete fileData;
fileData = nullptr;
return false;
}
@ -194,6 +228,8 @@ 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;
return false;
}
@ -220,9 +256,35 @@ bool EDFInfo::Parse(QByteArray * fileData )
}
}
}
delete fileData;
fileData = nullptr;
return true;
}
EDFHeaderQT * EDFInfo::GetHeader( const QString & name)
{
QFile fi(name);
if (!fi.open(QFile::ReadOnly)) {
qDebug() << "EDFInfo::Open() Couldn't open file " << name;
sleep(1);
return nullptr;
}
fileData = new QByteArray();
if (name.endsWith(STR_ext_gz)) {
*fileData = gUncompress(fi.read(sizeof(EDFHeaderRaw))); // Open and decompress file
} else {
*fileData = fi.read(sizeof(EDFHeaderRaw)); // Open and read uncompressed file
}
fi.close();
filename = name;
hdrPtr = (EDFHeaderRaw *)(*fileData).constData();
if ( ! parseHeader( hdrPtr ) )
return nullptr;
return & edfHdr;
}
// Parse the EDF file to get the annotations out of it.
QVector<Annotation> EDFInfo::ReadAnnotations(const char * data, int charLen)
{

View File

@ -67,6 +67,8 @@ struct EDFHeaderQT {
*/
struct EDFSignal {
public:
// virtual ~EDFSignal();
QString label; //! \brief Name of this Signal
QString transducer_type; //! \brief Tranducer Type (source of the data, usually blank)
QString physical_dimension; //! \brief The units of measurements represented by this signal
@ -122,8 +124,12 @@ class EDFInfo
virtual bool Parse(QByteArray * fileData); //! \brief Parse the EDF+ file into the EDFheaderQT. Must call Open(..) first.
virtual bool parseHeader( EDFHeaderRaw * hdrPtr ); //! \brief parse just the edf header for duration, etc
virtual EDFSignal * lookupLabel(const QString & name, int index=0); //! \brief Return a ptr to the i'th signal with that name
virtual EDFHeaderQT * GetHeader( const QString & name); //! \brief returna pointer to the header block
virtual long GetNumSignals() { return edfHdr.num_signals; } //! \brief Returns the number of signals contained in this EDF file
virtual long GetNumDataRecords() { return edfHdr.num_data_records; } //! \brief Returns the number of data records contained per signal.

View File

@ -166,8 +166,10 @@ void ResmedLoader::ParseSTR(Machine *mach, QMap<QDate, STRFile> & STRmap)
ResMedEDFInfo & str = *file.edf;
QDate date = str.edfHdr.startdate_orig.date(); // each STR.edf record starts at 12 noon
int size = str.GetNumDataRecords();
qDebug() << "Parsing" << strfile << date << str.GetNumDataRecords() << str.GetNumSignals();
qDebug() << "Parsing" << strfile << date.toString() << size << str.GetNumSignals();
qDebug() << "Last day is" << date.addDays(size-1).toString();
sleep(1);
// ResMed and their consistent naming and spacing... :/
@ -182,8 +184,6 @@ void ResmedLoader::ParseSTR(Machine *mach, QMap<QDate, STRFile> & STRmap)
EDFSignal *sig = nullptr;
int size = str.GetNumDataRecords();
// For each data record, representing 1 day each
for (int rec = 0; rec < size; ++rec, date = date.addDays(1)) {
emit setProgressValue(++currentRec);
@ -191,6 +191,7 @@ void ResmedLoader::ParseSTR(Machine *mach, QMap<QDate, STRFile> & STRmap)
if (ignoreOldSessions) {
if (date < ignoreBefore.date()) {
qDebug() << "Skipping" << date.toString() << "Before" << ignoreBefore.date().toString();
continue;
}
}
@ -198,6 +199,7 @@ void ResmedLoader::ParseSTR(Machine *mach, QMap<QDate, STRFile> & STRmap)
auto rit = resdayList.find(date);
if (rit != resdayList.end()) {
// Already seen this record.. should check if the data is the same, but meh.
qDebug() << "Skipping" << date.toString() << "Already saw this one";
continue;
}
@ -213,11 +215,14 @@ void ResmedLoader::ParseSTR(Machine *mach, QMap<QDate, STRFile> & STRmap)
}
if (!validday) {
// There are no mask on/off events, so this STR day is useless.
qDebug() << "Skipping" << date.toString() << "No mask events";
continue;
}
rit = resdayList.insert(date, ResMedDay());
qDebug() << "Setting up STRRecord for" << date.toString();
sleep(1);
STRRecord &R = rit.value().str;
uint timestamp = QDateTime(date,QTime(12,0,0)).toTime_t();
@ -586,8 +591,12 @@ void ResmedLoader::ParseSTR(Machine *mach, QMap<QDate, STRFile> & 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 ParseSTR";
sleep(3);
}
ResmedLoader::ResmedLoader() {
@ -1606,7 +1615,7 @@ void ResDayTask::run()
///////////////////////////////////////////////////////////////////////////////////
// Parse Identification.tgt file (containing serial number and machine information)
///////////////////////////////////////////////////////////////////////////////////
bool parseIdentTGT( QString path, MachineInfo info, QHash<QString, QString> idmap ) {
bool parseIdentTGT( QString path, MachineInfo * info, QHash<QString, QString> & idmap ) {
QString filename = path + RMS9_STR_idfile + STR_ext_TGT;
QFile f(filename);
@ -1627,7 +1636,8 @@ bool parseIdentTGT( QString path, MachineInfo info, QHash<QString, QString> id
QString value = line.section(" ", 1);
if (key == "SRN") { // Serial Number
info.serial = value;
info->serial = value;
qDebug() << "Serial # is >" << value << "<";
continue;
} else if (key == "PNA") { // Product Name
@ -1635,13 +1645,13 @@ bool parseIdentTGT( QString path, MachineInfo info, QHash<QString, QString> id
value.replace("_"," ");
if (value.contains(STR_ResMed_S9)) {
value.replace(STR_ResMed_S9, "");
info.series = 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;
info->series = STR_ResMed_AirSense10;
} else if (value.contains(STR_ResMed_AirCurve10)) {
value.replace(STR_ResMed_AirCurve10, "");
info.series = STR_ResMed_AirCurve10;
info->series = STR_ResMed_AirCurve10;
}
value.replace("(","");
value.replace(")","");
@ -1651,12 +1661,12 @@ bool parseIdentTGT( QString path, MachineInfo info, QHash<QString, QString> id
value.replace("Adapt", QObject::tr("VPAP Adapt"));
}
}
info.model = value.trimmed();
info->model = value.trimmed();
continue;
} else if (key == "PCD") { // Product Code
qDebug() << "Prouct Code is >" << value << "<";
info.modelnumber = value;
info->modelnumber = value;
continue;
}
@ -1822,9 +1832,15 @@ int ResmedLoader::Open(const QString & dirpath)
m_abort = false;
MachineInfo info = newInfo();
if ( ! parseIdentTGT(path, info, idmap) )
if ( ! parseIdentTGT(path, & info, idmap) )
return -1;
qDebug() << "Info:" << info.series << info.model << info.modelnumber << info.serial;
qDebug() << "IdMap size:" << idmap.size();
foreach ( QString st , idmap.keys() ) {
qDebug() << "Key" << st << "Value" << idmap[st];
}
// Abort if no serial number
if (info.serial.isEmpty()) {
qDebug() << "ResMed Data card has no valid serial number in Indentification.tgt";
@ -1849,13 +1865,13 @@ int ResmedLoader::Open(const QString & dirpath)
// Create machine object (unless it's already registered)
///////////////////////////////////////////////////////////////////////////////////
QDateTime firstImportDay = QDateTime("2010January01T00:01:00"); // Before Series 8 machines (I think)
QDate firstImportDay = QDate().fromString("2010-01-01", "yyyy-MM-dd"); // Before Series 8 machines (I think)
Machine *mach = p_profile->lookupMachine(info.serial, info.loadername);
if ( mach ) { // we have seen this machine
qDebug() << "We have seen this machime";
QDate lastDate = p_profile->LastDay(MT_CPAP);
firstImportDay = lastDate.addDay(-1);
firstImportDay = lastDate.addDays(-1);
} else { // Starting from new beginnings - new or purged
qDebug() << "New machine or just purged";
QDateTime ignoreBefore = p_profile->session->ignoreOlderSessionsDate();
@ -1863,7 +1879,7 @@ int ResmedLoader::Open(const QString & dirpath)
mach = p_profile->CreateMachine( info );
if (ignoreOldSessions)
firstImportDay = ignoreBefore;
firstImportDay = ignoreBefore.date();
}
qDebug() << "First day to import: " << firstImportDay.toString();
@ -1957,12 +1973,16 @@ 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) {
qDebug() << "Deleting edf of" << it.value().filename;
sleep(1);
delete it.value().edf;
}
qDebug() << "Finished STRmap cleanup";
sleep(1);
///////////////////////////////////////////////////////////////////////////////////
// Create the backup folder for storing a copy of everything in..
@ -2004,10 +2024,14 @@ int ResmedLoader::Open(const QString & dirpath)
if (isAborted())
return 0;
scanFiles(mach, datalogPath, firstImportDay);
qDebug() << "Starting scan of DATALOG";
sleep(1);
scanFiles(mach, datalogPath ); // , firstImportDay);
if (isAborted())
return 0;
qDebug() << "Fisnished DATALOG scan";
sleep(1);
// Now at this point we have resdayList populated with processable summary and EDF files data
// that can be processed in threads..