mirror of
https://gitlab.com/pholy/OSCAR-code.git
synced 2025-04-05 10:40:42 +00:00
QDateTime was slowing the importers down, changed to qint64. This change is guaranteed to introduce some bugs
This commit is contained in:
parent
454934b246
commit
9cc50bee94
@ -22,8 +22,8 @@ void WaveData::Reload(Day *day)
|
||||
m_ready=false;
|
||||
return;
|
||||
}
|
||||
min_x=day->first().toMSecsSinceEpoch()/86400000.0;
|
||||
max_x=day->last().toMSecsSinceEpoch()/86400000.0;
|
||||
min_x=day->first()/86400000.0;
|
||||
max_x=day->last()/86400000.0;
|
||||
if (max_x<min_x) {
|
||||
min_y=max_y=0;
|
||||
m_ready=false;
|
||||
@ -43,8 +43,8 @@ void WaveData::Reload(Day *day)
|
||||
int t=0;
|
||||
|
||||
Waveform *w=(*l);
|
||||
double st=w->start().toMSecsSinceEpoch()/86400000.0;
|
||||
double rate=(w->duration()/w->samples())/86400.0;
|
||||
double st=w->start()/86400000.0;
|
||||
double rate=(w->duration()/w->samples())/86400000.0;
|
||||
//qDebug() << "Waveform Chunk contains " << w->samples() << " samples";
|
||||
for (int i=0;i<w->samples();i++) {
|
||||
QPointD r(st,(*w)[i]);
|
||||
@ -114,8 +114,8 @@ void EventData::Reload(Day *day)
|
||||
return;
|
||||
}
|
||||
|
||||
min_x=day->first().toMSecsSinceEpoch()/86400000.0;
|
||||
max_x=day->last().toMSecsSinceEpoch()/86400000.0;
|
||||
min_x=day->first()/86400000.0;
|
||||
max_x=day->last()/86400000.0;
|
||||
if (min_x>max_x) {
|
||||
//int a=5;
|
||||
assert(min_x<max_x);
|
||||
@ -135,7 +135,7 @@ void EventData::Reload(Day *day)
|
||||
for (vector<Event *>::iterator ev=(*s)->events[code].begin(); ev!=(*s)->events[code].end(); ev++) {
|
||||
p=(*(*ev))[field];
|
||||
if (((p!=0) && skipzero) || !skipzero) {
|
||||
QPointD r((*ev)->time().toMSecsSinceEpoch()/86400000.0,p);
|
||||
QPointD r((*ev)->time()/86400000.0,p);
|
||||
point[vc][t++]=r;
|
||||
assert(t<max_points);
|
||||
if (first) {
|
||||
@ -208,7 +208,7 @@ void TAPData::Reload(Day *day)
|
||||
int cnt=0;
|
||||
|
||||
bool first;
|
||||
QDateTime last;
|
||||
qint64 last;
|
||||
int lastval=0,val;
|
||||
|
||||
int field=0;
|
||||
@ -224,7 +224,7 @@ void TAPData::Reload(Day *day)
|
||||
if (first) {
|
||||
first=false; // only bother setting lastval (below) this time.
|
||||
} else {
|
||||
double d=last.msecsTo(ev.time())/1000.0;
|
||||
double d=(ev.time()-last)/1000.0;
|
||||
|
||||
assert(lastval<max_slots);
|
||||
pTime[lastval]+=d;
|
||||
@ -301,15 +301,15 @@ void FlagData::Reload(Day *day)
|
||||
vc=0;
|
||||
double v1,v2;
|
||||
bool first;
|
||||
min_x=day->first().toMSecsSinceEpoch()/86400000.0;
|
||||
max_x=day->last().toMSecsSinceEpoch()/86400000.0;
|
||||
min_x=day->first()/86400000.0;
|
||||
max_x=day->last()/86400000.0;
|
||||
|
||||
for (vector<Session *>::iterator s=day->begin();s!=day->end();s++) {
|
||||
if ((*s)->events.find(code)==(*s)->events.end()) continue;
|
||||
first=true;
|
||||
for (vector<Event *>::iterator e=(*s)->events[code].begin(); e!=(*s)->events[code].end(); e++) {
|
||||
Event & ev =(*(*e));
|
||||
v2=v1=ev.time().toMSecsSinceEpoch()/86400000.0;
|
||||
v2=v1=ev.time()/86400000.0;
|
||||
if (offset>=0)
|
||||
v1-=ev[offset]/86400.0;
|
||||
point[vc][c].setX(v1);
|
||||
@ -467,8 +467,8 @@ double HistoryData::GetAverage()
|
||||
}
|
||||
void HistoryData::SetDateRange(QDate start,QDate end)
|
||||
{
|
||||
double x1=QDateTime(start).toMSecsSinceEpoch()/86400000.0; // -0.5;
|
||||
double x2=QDateTime(end.addDays(1)).toMSecsSinceEpoch()/86400000.0;
|
||||
qint64 x1=QDateTime(start).toMSecsSinceEpoch()/86400000.0;
|
||||
qint64 x2=QDateTime(end.addDays(1)).toMSecsSinceEpoch()/86400000.0;
|
||||
if (x1 < real_min_x) x1=real_min_x;
|
||||
if (x2 > (real_max_x)) x2=(real_max_x);
|
||||
min_x=x1;
|
||||
@ -500,22 +500,33 @@ UsageHistoryData::~UsageHistoryData()
|
||||
}
|
||||
double UsageHistoryData::Calc(Day *day)
|
||||
{
|
||||
double d;
|
||||
qint64 d;
|
||||
double h;
|
||||
if (uhd==UHD_Bedtime) {
|
||||
d=day->first().time().hour();
|
||||
if (d<12) d+=24;
|
||||
d+=(day->first().time().minute()/60.0);
|
||||
d+=(day->first().time().second()/3600.0);
|
||||
return d;
|
||||
d=day->first()/1000;
|
||||
d%=86400;
|
||||
|
||||
h=d/3600;
|
||||
if (h<12) h+=24;
|
||||
h+=1.0/float(d%3600);
|
||||
//d+=(day->first().time().minute()/60.0);
|
||||
//d+=(day->first().time().second()/3600.0);
|
||||
return h;
|
||||
}
|
||||
else if (uhd==UHD_Waketime) {
|
||||
d=day->last().time().hour();
|
||||
d+=(day->last().time().minute()/60.0);
|
||||
d+=(day->last().time().second()/3600.0);
|
||||
return d;
|
||||
d=day->first()/1000;
|
||||
d%=86400;
|
||||
h=d/3600;
|
||||
h+=1.0/float(d%3600);
|
||||
|
||||
//d=day->last().time().hour();
|
||||
//d+=(day->last().time().minute()/60.0);
|
||||
//d+=(day->last().time().second()/3600.0);
|
||||
return h;
|
||||
}
|
||||
else if (uhd==UHD_Hours) return day->hours();
|
||||
else
|
||||
else if (uhd==UHD_Hours) {
|
||||
return day->hours();
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -230,12 +230,12 @@ EventDataType Day::weighted_avg(MachineCode code,int field)
|
||||
if (s2==0) return 0;
|
||||
return (s1/s2);
|
||||
}
|
||||
float Day::total_time()
|
||||
qint64 Day::total_time()
|
||||
{
|
||||
d_totaltime=0;
|
||||
for (vector<Session *>::iterator s=sessions.begin();s!=sessions.end();s++) {
|
||||
Session & sess=*(*s);
|
||||
d_totaltime+=sess.last().toTime_t()-sess.first().toTime_t();
|
||||
d_totaltime+=sess.last()-sess.first();
|
||||
}
|
||||
return d_totaltime;
|
||||
}
|
||||
@ -256,19 +256,17 @@ EventDataType Day::percentile(MachineCode code,int field,double percent)
|
||||
|
||||
}
|
||||
|
||||
const QDateTime & Day::first(MachineCode code)
|
||||
qint64 Day::first(MachineCode code)
|
||||
{
|
||||
static QDateTime date;
|
||||
QDateTime tmp;
|
||||
bool fir=true;
|
||||
qint64 date=0;
|
||||
qint64 tmp;
|
||||
|
||||
for (vector<Session *>::iterator s=sessions.begin();s!=sessions.end();s++) {
|
||||
Session & sess=*(*s);
|
||||
if (sess.events.find(code)!=sess.events.end()) {
|
||||
tmp=sess.events[code][0]->time();
|
||||
if (fir) {
|
||||
if (!date) {
|
||||
date=tmp;
|
||||
fir=false;
|
||||
} else {
|
||||
if (tmp<date) date=tmp;
|
||||
}
|
||||
@ -277,11 +275,10 @@ const QDateTime & Day::first(MachineCode code)
|
||||
return date;
|
||||
}
|
||||
|
||||
const QDateTime & Day::last(MachineCode code)
|
||||
qint64 Day::last(MachineCode code)
|
||||
{
|
||||
static QDateTime date;
|
||||
QDateTime tmp;
|
||||
bool fir=true;
|
||||
qint64 date=0;
|
||||
qint64 tmp;
|
||||
|
||||
for (vector<Session *>::iterator s=sessions.begin();s!=sessions.end();s++) {
|
||||
Session & sess=*(*s);
|
||||
@ -289,9 +286,8 @@ const QDateTime & Day::last(MachineCode code)
|
||||
vector<Event *>::reverse_iterator i=sess.events[code].rbegin();
|
||||
assert(i!=sess.events[code].rend());
|
||||
tmp=(*i)->time();
|
||||
if (fir) {
|
||||
if (!date) {
|
||||
date=tmp;
|
||||
fir=false;
|
||||
} else {
|
||||
if (tmp>date) date=tmp;
|
||||
}
|
||||
|
@ -40,13 +40,13 @@ public:
|
||||
EventDataType summary_min(MachineCode code);
|
||||
EventDataType summary_max(MachineCode code);
|
||||
|
||||
const QDateTime & first(MachineCode code);
|
||||
const QDateTime & last(MachineCode code);
|
||||
const QDateTime & first() { return d_first; };
|
||||
const QDateTime & last() { return d_last; };
|
||||
qint64 first(MachineCode code);
|
||||
qint64 last(MachineCode code);
|
||||
qint64 first() { return d_first; };
|
||||
qint64 last() { return d_last; };
|
||||
|
||||
float total_time(); // in seconds
|
||||
float hours() { return total_time()/3600.0; };
|
||||
qint64 total_time(); // in milliseconds
|
||||
float hours() { return total_time()/3600000.0; };
|
||||
|
||||
Session *operator [](int i) { return sessions[i]; };
|
||||
|
||||
@ -61,8 +61,8 @@ public:
|
||||
|
||||
protected:
|
||||
vector<Session *> sessions;
|
||||
QDateTime d_first,d_last;
|
||||
double d_totaltime;
|
||||
qint64 d_first,d_last;
|
||||
qint64 d_totaltime;
|
||||
private:
|
||||
bool d_firstsession;
|
||||
};
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
#include "event.h"
|
||||
|
||||
Event::Event(QDateTime time,MachineCode code, EventDataType * data, int fields)
|
||||
Event::Event(qint64 time,MachineCode code, EventDataType * data, int fields)
|
||||
:e_time(time),e_code(code)
|
||||
{
|
||||
e_fields=fields;
|
||||
|
@ -16,13 +16,13 @@ class Event
|
||||
{
|
||||
friend class Session;
|
||||
public:
|
||||
Event(QDateTime time,MachineCode code,EventDataType * data,int fields);
|
||||
Event(qint64 time,MachineCode code,EventDataType * data,int fields);
|
||||
~Event();
|
||||
EventDataType operator[](short i) {
|
||||
if (i<e_fields) return e_data[i];
|
||||
else return 0;
|
||||
};
|
||||
const QDateTime & time() {
|
||||
const qint64 & time() {
|
||||
return e_time;
|
||||
};
|
||||
MachineCode code() {
|
||||
@ -32,7 +32,7 @@ public:
|
||||
return e_fields;
|
||||
};
|
||||
protected:
|
||||
QDateTime e_time;
|
||||
qint64 e_time;
|
||||
MachineCode e_code;
|
||||
short e_fields;
|
||||
vector<EventDataType> e_data;
|
||||
|
@ -173,6 +173,7 @@ bool CMS50Loader::OpenSPORFile(QString path,Machine *mach,Profile *profile)
|
||||
qDebug() << "Invalid date time retreieved in CMS50::OpenSPORFile";
|
||||
return false;
|
||||
}
|
||||
qint64 starttime=date.toMSecsSinceEpoch();
|
||||
|
||||
f.seek(data_starts);
|
||||
|
||||
@ -192,15 +193,15 @@ bool CMS50Loader::OpenSPORFile(QString path,Machine *mach,Profile *profile)
|
||||
EventDataType cp,cs;
|
||||
|
||||
Session *sess=new Session(mach,sessid);
|
||||
sess->set_first(date);
|
||||
sess->AddEvent(new Event(date,OXI_Pulse,&last_pulse,1));
|
||||
sess->AddEvent(new Event(date,OXI_SPO2,&last_spo2,1));
|
||||
sess->set_first(starttime);
|
||||
sess->AddEvent(new Event(starttime,OXI_Pulse,&last_pulse,1));
|
||||
sess->AddEvent(new Event(starttime,OXI_SPO2,&last_spo2,1));
|
||||
|
||||
EventDataType PMin=0,PMax=0,SMin=0,SMax=0,PAvg=0,SAvg=0;
|
||||
int PCnt=0,SCnt=0;
|
||||
//wxDateTime
|
||||
QDateTime tt=date;
|
||||
QDateTime lasttime=date;
|
||||
qint64 tt=starttime;
|
||||
qint64 lasttime=starttime;
|
||||
bool first_p=true,first_s=true;
|
||||
|
||||
for (int i=2;i<num_records;i+=2) {
|
||||
@ -238,16 +239,15 @@ bool CMS50Loader::OpenSPORFile(QString path,Machine *mach,Profile *profile)
|
||||
last_spo2=cs;
|
||||
if (PMax<cp) PMax=cp;
|
||||
if (SMax<cs) SMax=cs;
|
||||
tt=tt.addSecs(1); // An educated guess. Verified by gcz@cpaptalk
|
||||
tt+=1000; // An educated guess of 1 second. Verified by gcz@cpaptalk
|
||||
}
|
||||
if (cp) sess->AddEvent(new Event(tt,OXI_Pulse,&cp,1));
|
||||
if (cs) sess->AddEvent(new Event(tt,OXI_SPO2,&cs,1));
|
||||
|
||||
sess->set_last(lasttime);
|
||||
double t=sess->last().toTime_t()-sess->first().toTime_t();
|
||||
|
||||
double hours=(t/3600.0);
|
||||
sess->set_hours(hours);
|
||||
//double t=sess->last()-sess->first().toTime_t();
|
||||
//double hours=(t/3600.0);
|
||||
//sess->set_hours(hours);
|
||||
|
||||
EventDataType pa=0,sa=0;
|
||||
if (PCnt>0) pa=PAvg/double(PCnt);
|
||||
|
@ -378,7 +378,7 @@ int PRS1Loader::OpenMachine(Machine *m,QString path,Profile *profile)
|
||||
bool PRS1Loader::OpenSummary(Session *session,QString filename)
|
||||
{
|
||||
int size,sequence,seconds,br;
|
||||
time_t timestamp;
|
||||
qint64 timestamp;
|
||||
unsigned char header[24];
|
||||
unsigned char ext,sum;
|
||||
|
||||
@ -420,12 +420,7 @@ bool PRS1Loader::OpenSummary(Session *session,QString filename)
|
||||
return false;
|
||||
}
|
||||
|
||||
QDateTime date=QDateTime::fromTime_t(timestamp);
|
||||
//QDateTime tmpdate=date;
|
||||
//int ticks=date.GetTicks();
|
||||
|
||||
if (!date.isValid())
|
||||
return false;
|
||||
qint64 date=timestamp*1000;
|
||||
|
||||
memset(m_buffer,0,size);
|
||||
unsigned char * buffer=m_buffer;
|
||||
@ -472,12 +467,10 @@ bool PRS1Loader::OpenSummary(Session *session,QString filename)
|
||||
unsigned duration=bb;// | (buffer[0x15] << 8);
|
||||
session->summary[CPAP_Duration]=(int)duration;
|
||||
//qDebug() << "ID: " << session->session() << " " << duration;
|
||||
float hours=float(duration)/3600.0;
|
||||
session->set_hours(hours);
|
||||
//float hours=float(duration)/3600.0;
|
||||
//session->set_hours(hours);
|
||||
|
||||
QDateTime st=session->first();
|
||||
st=st.addSecs(duration);
|
||||
session->set_last(st);
|
||||
session->set_last(date+(duration*1000));
|
||||
|
||||
session->summary[CPAP_PressureMinAchieved]=buffer[0x16]/10.0;
|
||||
session->summary[CPAP_PressureMaxAchieved]=buffer[0x17]/10.0;
|
||||
@ -499,7 +492,7 @@ bool PRS1Loader::OpenSummary(Session *session,QString filename)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PRS1Loader::Parse002(Session *session,unsigned char *buffer,int size,time_t timestamp)
|
||||
bool PRS1Loader::Parse002(Session *session,unsigned char *buffer,int size,qint64 timestamp)
|
||||
{
|
||||
MachineCode Codes[]={
|
||||
PRS1_Unknown00, PRS1_Unknown01, CPAP_Pressure, CPAP_EAP, PRS1_PressurePulse, CPAP_RERA, CPAP_Obstructive, CPAP_ClearAirway,
|
||||
@ -510,9 +503,9 @@ bool PRS1Loader::Parse002(Session *session,unsigned char *buffer,int size,time_t
|
||||
|
||||
EventDataType data[4];
|
||||
|
||||
QDateTime start=QDateTime::fromTime_t(timestamp);
|
||||
QDateTime t=start;
|
||||
//t.Set(timestamp);
|
||||
qint64 start=timestamp;
|
||||
qint64 t=timestamp;
|
||||
qint64 tt;
|
||||
int pos=0;
|
||||
int cnt=0;
|
||||
short delta;
|
||||
@ -522,11 +515,11 @@ bool PRS1Loader::Parse002(Session *session,unsigned char *buffer,int size,time_t
|
||||
if (code!=0x12) {
|
||||
delta=buffer[pos] | buffer[pos+1] << 8;
|
||||
pos+=2;
|
||||
t=t.addSecs(delta);
|
||||
t+=delta*1000;
|
||||
}
|
||||
// float data0,data1,data2;
|
||||
MachineCode cpapcode=Codes[(int)code];
|
||||
QDateTime tt=t;
|
||||
tt=t;
|
||||
cnt++;
|
||||
switch (code) {
|
||||
case 0x00: // Unknown
|
||||
@ -546,7 +539,9 @@ bool PRS1Loader::Parse002(Session *session,unsigned char *buffer,int size,time_t
|
||||
case 0x0a: // Hypopnea
|
||||
case 0x0c: // Flow Limitation
|
||||
data[0]=buffer[pos];
|
||||
tt=tt.addSecs(-(buffer[pos++])); // Subtract Time Offset
|
||||
|
||||
tt-=buffer[pos++]*1000; // Subtract Time Offset
|
||||
|
||||
session->AddEvent(new Event(tt,cpapcode,data,1));
|
||||
break;
|
||||
case 0x0d: // Vibratory Snore
|
||||
@ -575,18 +570,15 @@ bool PRS1Loader::Parse002(Session *session,unsigned char *buffer,int size,time_t
|
||||
case 0x0e: // Unknown
|
||||
case 0x10: // Unknown
|
||||
data[0]=buffer[pos++]; // << 8) | buffer[pos];
|
||||
//pos+=2;
|
||||
data[1]=buffer[pos++];
|
||||
data[2]=buffer[pos++];
|
||||
//tt-=wxTimeSpan::Seconds(data[0]);
|
||||
session->AddEvent(new Event(t,cpapcode, data, 3));
|
||||
//wxLogMessage(tt.FormatTime()+QString::Format(wxT(" %i: %.2f %.2f %.2f"),code,data[0],data[1],data[2]));
|
||||
break;
|
||||
case 0x0f: // Cheyne Stokes Respiration
|
||||
data[0]=buffer[pos+1]<<8 | buffer[pos];
|
||||
pos+=2;
|
||||
data[1]=buffer[pos++];
|
||||
tt=tt.addSecs(-data[1]);
|
||||
tt-=data[1]*1000;
|
||||
session->AddEvent(new Event(tt,cpapcode, data, 2));
|
||||
break;
|
||||
case 0x12: // Summary
|
||||
@ -608,7 +600,7 @@ bool PRS1Loader::Parse002(Session *session,unsigned char *buffer,int size,time_t
|
||||
bool PRS1Loader::OpenEvents(Session *session,QString filename)
|
||||
{
|
||||
int size,sequence,seconds,br;
|
||||
time_t timestamp;
|
||||
qint64 timestamp;
|
||||
unsigned char header[24]; // use m_buffer?
|
||||
unsigned char ext;
|
||||
|
||||
@ -646,7 +638,7 @@ bool PRS1Loader::OpenEvents(Session *session,QString filename)
|
||||
if (br<size) {
|
||||
return false;
|
||||
}
|
||||
Parse002(session,buffer,size,timestamp);
|
||||
Parse002(session,buffer,size,timestamp*1000L);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -658,9 +650,9 @@ bool PRS1Loader::OpenWaveforms(Session *session,QString filename)
|
||||
|
||||
int size,sequence,seconds,br;
|
||||
unsigned cnt=0;
|
||||
time_t timestamp;
|
||||
qint64 timestamp;
|
||||
|
||||
time_t start=0;
|
||||
qint64 start=0;
|
||||
unsigned char header[24];
|
||||
unsigned char ext;
|
||||
|
||||
@ -671,7 +663,7 @@ bool PRS1Loader::OpenWaveforms(Session *session,QString filename)
|
||||
|
||||
int hl=24;
|
||||
long samples=0;
|
||||
int duration=0;
|
||||
qint64 duration=0;
|
||||
char * buffer=(char *)m_buffer;
|
||||
|
||||
while (true) {
|
||||
@ -698,7 +690,7 @@ bool PRS1Loader::OpenWaveforms(Session *session,QString filename)
|
||||
if (sequence==328) {
|
||||
seconds=0;
|
||||
}
|
||||
if (!start) start=timestamp;
|
||||
if (!start) start=timestamp*1000;
|
||||
seconds=(header[16] << 8) | header[15];
|
||||
|
||||
size-=(hl+2);
|
||||
@ -754,6 +746,7 @@ bool PRS1Loader::OpenWaveforms(Session *session,QString filename)
|
||||
bool first=true;
|
||||
|
||||
SampleFormat c;
|
||||
duration*=1000;
|
||||
|
||||
for (long i=0;i<samples;i++) {
|
||||
data[i]=buffer[i];
|
||||
@ -765,8 +758,7 @@ bool PRS1Loader::OpenWaveforms(Session *session,QString filename)
|
||||
if (min>c) min=c;
|
||||
if (max<c) max=c;
|
||||
}
|
||||
QDateTime dt=QDateTime::fromTime_t(start);
|
||||
Waveform *w=new Waveform(dt,CPAP_FlowRate,data,samples,duration,min,max);
|
||||
Waveform *w=new Waveform(start,CPAP_FlowRate,data,samples,duration,min,max);
|
||||
session->AddWaveform(w);
|
||||
|
||||
return true;
|
||||
|
@ -57,7 +57,7 @@ protected:
|
||||
bool OpenSummary(Session *session,QString filename);
|
||||
bool OpenEvents(Session *session,QString filename);
|
||||
bool OpenWaveforms(Session *session,QString filename);
|
||||
bool Parse002(Session *session,unsigned char *buffer,int size,time_t timestamp);
|
||||
bool Parse002(Session *session,unsigned char *buffer,int size,qint64 timestamp);
|
||||
unsigned char * m_buffer;
|
||||
};
|
||||
|
||||
|
@ -56,50 +56,59 @@ bool EDFParser::Parse()
|
||||
{
|
||||
bool ok;
|
||||
QString temp,temp2;
|
||||
version=Read(8).toLong(&ok);
|
||||
|
||||
version=QString::fromAscii(header.version,8).toLong(&ok);
|
||||
if (!ok)
|
||||
return false;
|
||||
|
||||
patientident=Read(80);
|
||||
recordingident=Read(80); // Serial number is in here..
|
||||
int snp=recordingident.indexOf("SRN=");
|
||||
|
||||
for (int i=snp+4;i<recordingident.length();i++) {
|
||||
if (recordingident[i]==' ')
|
||||
break;
|
||||
serialnumber+=recordingident[i];
|
||||
//patientident=QString::fromAscii(header.patientident,80);
|
||||
//recordingident=QString::fromAscii(header.recordingident,80); // Serial number is in here..
|
||||
//int snp=recordingident.indexOf("SRN=");
|
||||
char * idx=index(header.recordingident,'=');
|
||||
idx++;
|
||||
serialnumber.clear();
|
||||
for (int i=0;i<16;++i) {
|
||||
if (*idx==0x20) break;
|
||||
serialnumber+=*idx;
|
||||
++idx;
|
||||
}
|
||||
temp=Read(8);
|
||||
temp+=" "+Read(8);
|
||||
startdate=QDateTime::fromString(temp,"dd.MM.yy HH.mm.ss");
|
||||
QDate d2=startdate.date();
|
||||
|
||||
// for (int i=snp+4;i<recordingident.length();i++) {
|
||||
// if (recordingident[i]==' ')
|
||||
// break;
|
||||
//serialnumber+=recordingident[i];
|
||||
//}
|
||||
QDateTime startDate=QDateTime::fromString(QString::fromAscii(header.datetime,16),"dd.MM.yyHH.mm.ss");
|
||||
QDate d2=startDate.date();
|
||||
if (d2.year()<2000) {
|
||||
d2.setYMD(d2.year()+100,d2.month(),d2.day());
|
||||
startdate.setDate(d2);
|
||||
startDate.setDate(d2);
|
||||
}
|
||||
if (!startdate.isValid()) {
|
||||
if (!startDate.isValid()) {
|
||||
qDebug() << "Invalid date time retreieved parsing EDF File " << filename;
|
||||
return false;
|
||||
}
|
||||
startdate=startDate.toMSecsSinceEpoch();
|
||||
|
||||
//qDebug() << startdate.toString("yyyy-MM-dd HH:mm:ss");
|
||||
//qDebug() << startDate.toString("yyyy-MM-dd HH:mm:ss");
|
||||
|
||||
num_header_bytes=Read(8).toLong(&ok);
|
||||
num_header_bytes=QString::fromAscii(header.num_header_bytes,8).toLong(&ok);
|
||||
if (!ok)
|
||||
return false;
|
||||
reserved44=Read(44);
|
||||
num_data_records=Read(8).toLong(&ok);
|
||||
//reserved44=QString::fromAscii(header.reserved,44);
|
||||
num_data_records=QString::fromAscii(header.num_data_records,8).toLong(&ok);
|
||||
if (!ok)
|
||||
return false;
|
||||
temp=Read(8);
|
||||
// temp="0.00";
|
||||
dur_data_record=temp.toDouble(&ok);
|
||||
dur_data_record=QString::fromAscii(header.dur_data_records,8).toDouble(&ok)*1000.0;
|
||||
if (!ok)
|
||||
return false;
|
||||
num_signals=Read(4).toLong(&ok);
|
||||
num_signals=QString::fromAscii(header.num_signals,4).toLong(&ok);
|
||||
if (!ok)
|
||||
return false;
|
||||
|
||||
|
||||
// this could be loaded quicker by transducer_type[signal] etc..
|
||||
|
||||
for (int i=0;i<num_signals;i++) {
|
||||
EDFSignal *signal=new EDFSignal;
|
||||
edfsignals.push_back(signal);
|
||||
@ -135,6 +144,7 @@ bool EDFParser::Parse()
|
||||
memcpy((char *)&sig.data[sig.pos],(char *)&buffer[pos],sig.nr*2);
|
||||
sig.pos+=sig.nr;
|
||||
pos+=sig.nr*2;
|
||||
// big endian will screw up without this..
|
||||
/*for (int j=0;j<sig.nr;j++) {
|
||||
qint16 t=Read16();
|
||||
sig.data[sig.pos++]=t;
|
||||
@ -151,9 +161,12 @@ bool EDFParser::Open(QString name)
|
||||
if (!f.isReadable()) return false;
|
||||
filename=name;
|
||||
filesize=f.size();
|
||||
datasize=filesize-EDFHeaderSize;
|
||||
if (datasize<0) return false;
|
||||
f.read((char *)&header,EDFHeaderSize);
|
||||
//qDebug() << "Opening " << name;
|
||||
buffer=new char [filesize];
|
||||
f.read(buffer,filesize);
|
||||
buffer=new char [datasize];
|
||||
f.read(buffer,datasize);
|
||||
f.close();
|
||||
pos=0;
|
||||
return true;
|
||||
@ -194,6 +207,8 @@ Machine *ResmedLoader::CreateMachine(QString serial,Profile *profile)
|
||||
|
||||
}
|
||||
|
||||
long event_cnt=0;
|
||||
|
||||
bool ResmedLoader::Open(QString & path,Profile *profile)
|
||||
{
|
||||
|
||||
@ -303,14 +318,15 @@ bool ResmedLoader::Open(QString & path,Profile *profile)
|
||||
else if (fn=="pld.edf") LoadPLD(sess,edf);
|
||||
else if (fn=="brp.edf") LoadBRP(sess,edf);
|
||||
else if (fn=="sad.edf") LoadSAD(sess,edf);
|
||||
}
|
||||
|
||||
if (first) {
|
||||
sess->SetChanged(true);
|
||||
m->AddSession(sess,profile); // Adding earlier than I really like here..
|
||||
first=false;
|
||||
}
|
||||
}
|
||||
if (sess) {
|
||||
}
|
||||
if (!done && sess) {
|
||||
sess->summary[CPAP_PressureMedian]=sess->avg_event_field(CPAP_Pressure,0);
|
||||
sess->summary[CPAP_PressureAverage]=sess->weighted_avg_event_field(CPAP_Pressure,0);
|
||||
sess->summary[CPAP_PressureMinAchieved]=sess->min_event_field(CPAP_Pressure,0);
|
||||
@ -338,6 +354,7 @@ bool ResmedLoader::Open(QString & path,Profile *profile)
|
||||
}
|
||||
//m->Save();
|
||||
if (qprogress) qprogress->setValue(100);
|
||||
qDebug() << "Total Events " << event_cnt;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -351,20 +368,20 @@ bool ResmedLoader::LoadEVE(Session *sess,EDFParser &edf)
|
||||
long pos;
|
||||
bool sign,ok;
|
||||
double d;
|
||||
QDateTime tt;
|
||||
qint64 tt;
|
||||
EventDataType fields[3];
|
||||
MachineCode code;
|
||||
//Event *e;
|
||||
totaldur=edf.GetNumDataRecords()*edf.GetDuration();
|
||||
|
||||
for (int s=0;s<edf.GetNumSignals();s++) {
|
||||
recs=edf.edfsignals[s]->nr*edf.GetNumDataRecords()*2;
|
||||
|
||||
if (!sess->first().isValid()) {
|
||||
if (!sess->first()) {
|
||||
sess->set_first(edf.startdate);
|
||||
|
||||
totaldur=edf.GetNumDataRecords()*edf.GetDuration();
|
||||
if (totaldur>0) {
|
||||
sess->set_last(edf.startdate.addMSecs(totaldur*1000.0));
|
||||
sess->set_hours(totaldur/3600.0);
|
||||
sess->set_last(edf.startdate+totaldur);
|
||||
//sess->set_hours(totaldur/3600.0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -394,7 +411,7 @@ bool ResmedLoader::LoadEVE(Session *sess,EDFParser &edf)
|
||||
}
|
||||
if (!sign) d=-d;
|
||||
|
||||
tt=edf.startdate.addMSecs(d*1000.0);
|
||||
tt+=d*1000.0;
|
||||
duration=0;
|
||||
// First entry
|
||||
|
||||
@ -406,7 +423,7 @@ bool ResmedLoader::LoadEVE(Session *sess,EDFParser &edf)
|
||||
t+=data[pos];
|
||||
pos++;
|
||||
} while ((data[pos]!=20) && (pos<recs)); // start code
|
||||
duration=t.toDouble(&ok);
|
||||
duration=t.toDouble(&ok)*1000.0;
|
||||
if (!ok) {
|
||||
qDebug() << "Faulty EDF EVE file (at %" << pos << ") " << edf.filename;
|
||||
break;
|
||||
@ -431,7 +448,7 @@ bool ResmedLoader::LoadEVE(Session *sess,EDFParser &edf)
|
||||
else if (t=="hypopnea") code=CPAP_Hypopnea;
|
||||
else if (t=="central apnea") code=CPAP_ClearAirway;
|
||||
if (code!=MC_UNKNOWN) {
|
||||
fields[0]=duration;
|
||||
fields[0]=duration/1000.0;
|
||||
sess->AddEvent(new Event(tt,code,fields,1));
|
||||
} else {
|
||||
if (t!="recording starts") {
|
||||
@ -458,7 +475,7 @@ bool ResmedLoader::LoadBRP(Session *sess,EDFParser &edf)
|
||||
QString t;
|
||||
for (int s=0;s<edf.GetNumSignals();s++) {
|
||||
long recs=edf.edfsignals[s]->nr*edf.GetNumDataRecords();
|
||||
double duration=edf.GetNumDataRecords()*edf.GetDuration();
|
||||
qint64 duration=edf.GetNumDataRecords()*edf.GetDuration();
|
||||
MachineCode code;
|
||||
if (edf.edfsignals[s]->label=="Flow") code=CPAP_FlowRate;
|
||||
else if (edf.edfsignals[s]->label=="Mask Pres") code=CPAP_MaskPressure;
|
||||
@ -466,10 +483,10 @@ bool ResmedLoader::LoadBRP(Session *sess,EDFParser &edf)
|
||||
qDebug() << "Unknown Signal " << edf.edfsignals[s]->label;
|
||||
continue;
|
||||
}
|
||||
if (!sess->first().isValid()) {
|
||||
if (!sess->first()) {
|
||||
sess->set_first(edf.startdate);
|
||||
sess->set_last(edf.startdate.addMSecs(duration*1000.0));
|
||||
sess->set_hours(duration/3600.0);
|
||||
sess->set_last(edf.startdate+duration);
|
||||
//sess->set_hours(duration/3600.0);
|
||||
}
|
||||
Waveform *w=new Waveform(edf.startdate,code,edf.edfsignals[s]->data,recs,duration,edf.edfsignals[s]->digital_minimum,edf.edfsignals[s]->digital_maximum);
|
||||
edf.edfsignals[s]->data=NULL; // so it doesn't get deleted when edf gets trashed.
|
||||
@ -479,29 +496,37 @@ bool ResmedLoader::LoadBRP(Session *sess,EDFParser &edf)
|
||||
}
|
||||
return true;
|
||||
}
|
||||
void ResmedLoader::ToTimeDelta(Session *sess,EDFParser &edf, qint16 *data, MachineCode code, long recs, double duration,EventDataType divisor)
|
||||
void ResmedLoader::ToTimeDelta(Session *sess,EDFParser &edf, qint16 *data, MachineCode code, long recs, qint64 duration,EventDataType divisor)
|
||||
{
|
||||
bool first=true;
|
||||
double rate=(duration/recs)*1000.0;
|
||||
QDateTime tt=edf.startdate;
|
||||
double rate=(duration/recs); // milliseconds per record
|
||||
qint64 tt=edf.startdate;
|
||||
EventDataType c,last;
|
||||
//return;
|
||||
Event *e=new Event(tt,code,&c,1);
|
||||
for (int i=0;i<recs;i++) {
|
||||
c=data[i]/divisor;
|
||||
//c=EventDataType(q)/2.0; //data[i]/divisor;
|
||||
|
||||
if (first) {
|
||||
sess->AddEvent(new Event(tt,code,&c,1));
|
||||
e=new Event(tt,code,&c,1);
|
||||
sess->AddEvent(e);
|
||||
event_cnt++;
|
||||
first=false;
|
||||
} else {
|
||||
if (last!=c) {
|
||||
sess->AddEvent(new Event(tt,code,&c,1));
|
||||
e=new Event(tt,code,&c,1);
|
||||
sess->AddEvent(e);
|
||||
event_cnt++;
|
||||
|
||||
}
|
||||
}
|
||||
tt=tt.addMSecs(rate);
|
||||
tt+=rate;
|
||||
|
||||
last=c;
|
||||
}
|
||||
sess->AddEvent(new Event(tt,code,&c,1)); // add one at the end..
|
||||
e=new Event(tt,code,&c,1);
|
||||
sess->AddEvent(e); // add one at the end..
|
||||
event_cnt++;
|
||||
}
|
||||
bool ResmedLoader::LoadSAD(Session *sess,EDFParser &edf)
|
||||
{
|
||||
@ -521,11 +546,11 @@ bool ResmedLoader::LoadPLD(Session *sess,EDFParser &edf)
|
||||
QString t;
|
||||
for (int s=0;s<edf.GetNumSignals();s++) {
|
||||
long recs=edf.edfsignals[s]->nr*edf.GetNumDataRecords();
|
||||
double duration=edf.GetNumDataRecords()*edf.GetDuration();
|
||||
if (!sess->first().isValid()) {
|
||||
qint64 duration=edf.GetNumDataRecords()*edf.GetDuration();
|
||||
if (!sess->first()) {
|
||||
sess->set_first(edf.startdate);
|
||||
sess->set_last(edf.startdate.addMSecs(duration*1000.0));
|
||||
sess->set_hours(duration/3600.0);
|
||||
sess->set_last(edf.startdate+duration);
|
||||
//sess->set_hours(duration/3600.0);
|
||||
}
|
||||
MachineCode code;
|
||||
// if (s==TherapyPres) {
|
||||
|
@ -26,6 +26,20 @@ const int resmed_data_version=0;
|
||||
|
||||
const QString resmed_class_name="ResMed";
|
||||
|
||||
struct EDFHeader {
|
||||
char version[8];
|
||||
char patientident[80];
|
||||
char recordingident[80];
|
||||
char datetime[16];
|
||||
char num_header_bytes[8];
|
||||
char reserved[44];
|
||||
char num_data_records[8];
|
||||
char dur_data_records[8];
|
||||
char num_signals[4];
|
||||
} __attribute__ ((packed));
|
||||
|
||||
const int EDFHeaderSize=sizeof(EDFHeader);
|
||||
|
||||
struct EDFSignal {
|
||||
public:
|
||||
QString label;
|
||||
@ -60,20 +74,22 @@ public:
|
||||
QString GetPatient() { return patientident; };
|
||||
bool Parse();
|
||||
char *buffer;
|
||||
EDFHeader header;
|
||||
QString filename;
|
||||
int filesize;
|
||||
int pos;
|
||||
long filesize;
|
||||
long datasize;
|
||||
long pos;
|
||||
|
||||
long version;
|
||||
long num_header_bytes;
|
||||
long num_data_records;
|
||||
double dur_data_record;
|
||||
qint64 dur_data_record;
|
||||
long num_signals;
|
||||
|
||||
QString patientident;
|
||||
QString recordingident;
|
||||
QString serialnumber;
|
||||
QDateTime startdate;
|
||||
qint64 startdate;
|
||||
QString reserved44;
|
||||
};
|
||||
|
||||
@ -86,7 +102,7 @@ public:
|
||||
|
||||
virtual int Version() { return resmed_data_version; };
|
||||
virtual const QString & ClassName() { return resmed_class_name; };
|
||||
void ToTimeDelta(Session *sess,EDFParser &edf, qint16 *data, MachineCode code, long recs,double duration,EventDataType divisor=1);
|
||||
void ToTimeDelta(Session *sess,EDFParser &edf, qint16 *data, MachineCode code, long recs,qint64 duration,EventDataType divisor=1);
|
||||
|
||||
Machine *CreateMachine(QString serial,Profile *profile);
|
||||
|
||||
|
@ -211,7 +211,7 @@ Machine::Machine(Profile *p,MachineID id)
|
||||
Machine::~Machine()
|
||||
{
|
||||
qDebug() << "Destroy Machine";
|
||||
map<QDateTime,Day *>::iterator d;
|
||||
map<qint64,Day *>::iterator d;
|
||||
for (d=day.begin();d!=day.end();d++) {
|
||||
delete d->second;
|
||||
}
|
||||
@ -233,9 +233,9 @@ Day *Machine::AddSession(Session *s,Profile *p)
|
||||
if (s->session()>highest_sessionid)
|
||||
highest_sessionid=s->session();
|
||||
|
||||
QDateTime date=s->first();
|
||||
date=date.addDays(-1);
|
||||
date.setTime(QTime(0,0));
|
||||
qint64 date=s->first()/86400000;
|
||||
date--; //=date.addDays(-1);
|
||||
date*=86400000;
|
||||
|
||||
const int hours_since_last_session=4;
|
||||
const int hours_since_midnight=12;
|
||||
@ -246,7 +246,7 @@ Day *Machine::AddSession(Session *s,Profile *p)
|
||||
// Previous day record exists...
|
||||
|
||||
// Calculate time since end of previous days last session
|
||||
span=(s->first().toTime_t() - day[date]->last().toTime_t())/3600.0;
|
||||
span=(s->first() - day[date]->last())/3600000.0;
|
||||
|
||||
// less than n hours since last session yesterday?
|
||||
if (span < hours_since_last_session) {
|
||||
@ -256,9 +256,10 @@ Day *Machine::AddSession(Session *s,Profile *p)
|
||||
|
||||
if (!previous) {
|
||||
// Calculate Hours since midnight.
|
||||
QDateTime t=s->first();
|
||||
t.setTime(QTime(0,0));
|
||||
span=(s->first().toTime_t() - t.toTime_t())/3600.0;
|
||||
qint64 t=s->first()/86400000;
|
||||
t*=86400000;
|
||||
//t.setTime(QTime(0,0));
|
||||
span=(s->first() - t)/3600000.0;
|
||||
|
||||
// Bedtime was late last night.
|
||||
if (span < hours_since_midnight) {
|
||||
@ -268,7 +269,7 @@ Day *Machine::AddSession(Session *s,Profile *p)
|
||||
|
||||
if (!previous) {
|
||||
// Revert to sessions original day.
|
||||
date=date.addDays(1);
|
||||
date+=86400000;
|
||||
}
|
||||
|
||||
sessionlist[s->session()]=s;
|
||||
@ -281,11 +282,12 @@ Day *Machine::AddSession(Session *s,Profile *p)
|
||||
firstsession=false;
|
||||
}
|
||||
if (day.find(date)==day.end()) {
|
||||
QString dstr=date.toString("yyyyMMdd");
|
||||
//QString dstr=date.toString("yyyyMMdd");
|
||||
//qDebug("Adding Profile Day %s",dstr.toAscii().data());
|
||||
day[date]=new Day(this);
|
||||
// Add this Day record to profile
|
||||
p->AddDay(date.date(),day[date],m_type);
|
||||
QDateTime d=QDateTime::fromMSecsSinceEpoch(date);
|
||||
p->AddDay(d.date(),day[date],m_type);
|
||||
}
|
||||
|
||||
day[date]->AddSession(s);
|
||||
@ -402,7 +404,7 @@ bool Machine::SaveSession(Session *sess)
|
||||
}
|
||||
bool Machine::Save()
|
||||
{
|
||||
map<QDateTime,Day *>::iterator d;
|
||||
map<qint64,Day *>::iterator d;
|
||||
vector<Session *>::iterator s;
|
||||
int size=0;
|
||||
int cnt=0;
|
||||
@ -417,7 +419,7 @@ bool Machine::Save()
|
||||
|
||||
for (s=d->second->begin(); s!=d->second->end(); s++) {
|
||||
cnt++;
|
||||
if (qprogress) qprogress->setValue(66+(float(cnt)/float(size)*33));
|
||||
if (qprogress) qprogress->setValue(66.0+(float(cnt)/float(size)*33.0));
|
||||
if ((*s)->IsChanged()) (*s)->Store(path);
|
||||
}
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ public:
|
||||
bool SaveSession(Session *sess);
|
||||
bool Purge(int secret);
|
||||
|
||||
map<QDateTime,Day *> day;
|
||||
map<qint64,Day *> day;
|
||||
map<SessionID,Session *> sessionlist;
|
||||
map<QString,QString> properties;
|
||||
|
||||
@ -69,11 +69,11 @@ public:
|
||||
};
|
||||
SessionID CreateSessionID() { return highest_sessionid+1; };
|
||||
const MachineID & id() { return m_id; };
|
||||
const QDateTime & FirstDay() { return firstday; };
|
||||
const QDateTime & LastDay() { return lastday; };
|
||||
const qint64 & FirstDay() { return firstday; };
|
||||
const qint64 & LastDay() { return lastday; };
|
||||
|
||||
protected:
|
||||
QDateTime firstday,lastday;
|
||||
qint64 firstday,lastday;
|
||||
SessionID highest_sessionid;
|
||||
MachineID m_id;
|
||||
QString m_class;
|
||||
|
@ -27,6 +27,7 @@ Session::Session(Machine * m,SessionID session)
|
||||
s_waves_loaded=false;
|
||||
_first_session=true;
|
||||
|
||||
s_first=s_last=0;
|
||||
s_wavefile="";
|
||||
s_eventfile="";
|
||||
}
|
||||
@ -139,10 +140,10 @@ double Session::weighted_avg_event_field(MachineCode mc,int field)
|
||||
int cnt=0;
|
||||
|
||||
bool first=true;
|
||||
QDateTime last;
|
||||
qint64 last;
|
||||
int lastval=0,val;
|
||||
const int max_slots=2600;
|
||||
double vtime[max_slots]={0};
|
||||
qint64 vtime[max_slots]={0};
|
||||
|
||||
|
||||
double mult;
|
||||
@ -160,7 +161,7 @@ double Session::weighted_avg_event_field(MachineCode mc,int field)
|
||||
if (first) {
|
||||
first=false;
|
||||
} else {
|
||||
int d=e.e_time.toTime_t()-last.toTime_t();
|
||||
int d=(e.e_time-last)/1000;
|
||||
if (lastval>max_slots) {
|
||||
qWarning("max_slots to small in Session::weighted_avg_event_fied()");
|
||||
return 0;
|
||||
@ -174,7 +175,7 @@ double Session::weighted_avg_event_field(MachineCode mc,int field)
|
||||
lastval=val;
|
||||
}
|
||||
|
||||
double total;
|
||||
qint64 total;
|
||||
for (int i=0; i<max_slots; i++) total+=vtime[i];
|
||||
//double hours=total.GetSeconds().GetLo()/3600.0;
|
||||
|
||||
@ -194,7 +195,7 @@ double Session::weighted_avg_event_field(MachineCode mc,int field)
|
||||
void Session::AddEvent(Event * e)
|
||||
{
|
||||
events[e->code()].push_back(e);
|
||||
if (s_first.isValid()) {
|
||||
if (s_first) {
|
||||
if (e->time()<s_first) s_first=e->time();
|
||||
if (e->time()>s_last) s_last=e->time();
|
||||
} else {
|
||||
@ -299,11 +300,12 @@ bool Session::StoreSummary(QString filename)
|
||||
f.Pack((quint16)0); // File Type 0 == Summary File
|
||||
f.Pack((quint16)0); // File Version
|
||||
|
||||
time_t starttime=s_first.toTime_t();
|
||||
time_t duration=s_last.toTime_t()-starttime;
|
||||
quint32 starttime=s_first/1000;
|
||||
quint32 duration=(s_last-s_first)/1000;
|
||||
|
||||
f.Pack(starttime); // Session Start Time
|
||||
f.Pack(duration); // Duration of sesion in seconds.
|
||||
|
||||
f.Pack(s_first); // Session Start Time
|
||||
f.Pack((quint16)duration); // Duration of sesion in seconds.
|
||||
f.Pack((quint16)summary.size());
|
||||
|
||||
map<MachineCode,MCDataType> mctype;
|
||||
@ -352,14 +354,15 @@ bool Session::StoreSummary(QString filename)
|
||||
}
|
||||
}
|
||||
f.Close();
|
||||
// wxFFile j;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Session::LoadSummary(QString filename)
|
||||
{
|
||||
if (filename.isEmpty()) return false;
|
||||
//qDebug(("Loading Summary "+filename).toLatin1());
|
||||
BinaryFile f;
|
||||
|
||||
if (!f.Open(filename,BF_READ)) {
|
||||
qDebug() << "Couldn't open file" << filename;
|
||||
return false;
|
||||
@ -388,11 +391,12 @@ bool Session::LoadSummary(QString filename)
|
||||
if (!f.Unpack(t16)) throw UnpackError(); // File Version
|
||||
// dont care yet
|
||||
|
||||
if (!f.Unpack(s_first)) throw UnpackError(); // Start time
|
||||
if (!f.Unpack(t16)) throw UnpackError(); // Duration // (16bit==Limited to 18 hours)
|
||||
|
||||
s_last=s_first.addSecs(t16);
|
||||
s_hours=t16/3600.0;
|
||||
if (!f.Unpack(t32)) throw UnpackError(); // Start time
|
||||
s_first=qint64(t32)*1000;
|
||||
|
||||
if (!f.Unpack(t32)) throw UnpackError(); // Duration // (16bit==Limited to 18 hours)
|
||||
s_last=s_first+qint64(t32)*1000;
|
||||
|
||||
if (!f.Unpack(sumsize)) throw UnpackError(); // Summary size (number of Machine Code lists)
|
||||
|
||||
@ -445,11 +449,11 @@ bool Session::StoreEvents(QString filename)
|
||||
f.Pack((quint16)1); // File type 1 == Event
|
||||
f.Pack((quint16)0); // File Version
|
||||
|
||||
time_t starttime=s_first.toTime_t();
|
||||
time_t duration=s_last.toTime_t()-starttime;
|
||||
quint32 starttime=s_first/1000;
|
||||
quint32 duration=(s_last-s_first)/1000;
|
||||
|
||||
f.Pack(s_first);
|
||||
f.Pack((qint16)duration);
|
||||
f.Pack(starttime);
|
||||
f.Pack(duration);
|
||||
|
||||
f.Pack((qint16)events.size()); // Number of event categories
|
||||
|
||||
@ -465,22 +469,22 @@ bool Session::StoreEvents(QString filename)
|
||||
}
|
||||
bool first;
|
||||
float tf;
|
||||
time_t last=0,eventtime,delta;
|
||||
qint64 last=0,eventtime,delta;
|
||||
|
||||
for (i=events.begin(); i!=events.end(); i++) {
|
||||
first=true;
|
||||
for (j=i->second.begin(); j!=i->second.end(); j++) {
|
||||
eventtime=(*j)->time().toTime_t();
|
||||
eventtime=(*j)->time();
|
||||
if (first) {
|
||||
f.Pack((*j)->time());
|
||||
first=false;
|
||||
} else {
|
||||
delta=eventtime-last;
|
||||
if (delta>0xffff) {
|
||||
if (delta>0xffffffff) {
|
||||
qDebug("StoreEvent: Delta too big.. needed to use bigger value");
|
||||
exit(1);
|
||||
}
|
||||
f.Pack((quint16)delta);
|
||||
f.Pack((quint32)delta);
|
||||
}
|
||||
for (int k=0; k<(*j)->fields(); k++) {
|
||||
tf=(*(*j))[k];
|
||||
@ -522,11 +526,10 @@ bool Session::LoadEvents(QString filename)
|
||||
if (!f.Unpack(t16)) throw UnpackError(); // File Version
|
||||
// dont give a crap yet..
|
||||
|
||||
if (!f.Unpack(s_first)) throw UnpackError(); // Start time
|
||||
if (!f.Unpack(t16)) throw UnpackError(); // Duration // (16bit==Limited to 18 hours)
|
||||
|
||||
s_last=s_first.addSecs(t16);
|
||||
s_hours=t16/3600.0;
|
||||
if (!f.Unpack(t32)) throw UnpackError(); // Start time
|
||||
s_first=qint64(t32)*1000;
|
||||
if (!f.Unpack(t32)) throw UnpackError(); // Duration // (16bit==Limited to 18 hours)
|
||||
s_last=s_first+qint64(t32)*1000;
|
||||
|
||||
qint16 evsize;
|
||||
if (!f.Unpack(evsize)) throw UnpackError(); // Summary size (number of Machine Code lists)
|
||||
@ -549,7 +552,7 @@ bool Session::LoadEvents(QString filename)
|
||||
for (int i=0; i<evsize; i++) {
|
||||
mc=mcorder[i];
|
||||
bool first=true;
|
||||
QDateTime d;
|
||||
qint64 d;
|
||||
float fl;
|
||||
events[mc].clear();
|
||||
for (int e=0; e<mcsize[mc]; e++) {
|
||||
@ -557,8 +560,8 @@ bool Session::LoadEvents(QString filename)
|
||||
if (!f.Unpack(d)) throw UnpackError(); // Timestamp
|
||||
first=false;
|
||||
} else {
|
||||
if (!f.Unpack(t16)) throw UnpackError(); // Time Delta
|
||||
d=d.addSecs(t16);
|
||||
if (!f.Unpack(t32)) throw UnpackError(); // Time Delta
|
||||
d=d+t32;
|
||||
}
|
||||
EventDataType ED[max_number_event_fields];
|
||||
for (int c=0; c<mcfields[mc]; c++) {
|
||||
@ -587,11 +590,11 @@ bool Session::StoreWaveforms(QString filename)
|
||||
f.Pack((quint16)2); // File type 2 == Waveform
|
||||
f.Pack((quint16)0); // File Version
|
||||
|
||||
time_t starttime=s_first.toTime_t();
|
||||
time_t duration=s_last.toTime_t()-starttime;
|
||||
quint32 starttime=s_first/1000;
|
||||
quint32 duration=(s_last-s_first)/1000;
|
||||
|
||||
f.Pack(s_first);
|
||||
f.Pack((qint16)duration);
|
||||
f.Pack(starttime);
|
||||
f.Pack(duration);
|
||||
|
||||
f.Pack((qint16)waveforms.size()); // Number of different waveforms
|
||||
|
||||
@ -605,13 +608,14 @@ bool Session::StoreWaveforms(QString filename)
|
||||
for (j=i->second.begin(); j!=i->second.end(); j++) {
|
||||
|
||||
Waveform &w=*(*j);
|
||||
// 64bit number..
|
||||
f.Pack(w.start()); // Start time of first waveform chunk
|
||||
|
||||
//qint32 samples;
|
||||
//double seconds;
|
||||
|
||||
f.Pack((qint32)w.samples()); // Total number of samples
|
||||
f.Pack((float)w.duration()); // Total number of seconds
|
||||
f.Pack((qint64)w.duration()); // Total number of seconds
|
||||
f.Pack((qint16)w.min());
|
||||
f.Pack((qint16)w.max());
|
||||
f.Pack((qint8)sizeof(SampleFormat)); // Bytes per sample
|
||||
@ -658,18 +662,18 @@ bool Session::LoadWaveforms(QString filename)
|
||||
if (!f.Unpack(t16)) throw UnpackError(); // File Version
|
||||
// dont give a crap yet..
|
||||
|
||||
if (!f.Unpack(s_first)) throw UnpackError(); // Start time
|
||||
if (!f.Unpack(t16)) throw UnpackError(); // Duration // (16bit==Limited to 18 hours)
|
||||
if (!f.Unpack(t32)) throw UnpackError(); // Start time
|
||||
s_first=qint64(t32)*1000;
|
||||
|
||||
s_last=s_first.addSecs(t16);
|
||||
s_hours=t16/3600.0;
|
||||
if (!f.Unpack(t32)) throw UnpackError(); // Duration // (16bit==Limited to 18 hours)
|
||||
s_last=s_first+qint64(t32)*1000;
|
||||
|
||||
qint16 wvsize;
|
||||
if (!f.Unpack(wvsize)) throw UnpackError(); // Summary size (number of Machine Code lists)
|
||||
|
||||
MachineCode mc;
|
||||
QDateTime date;
|
||||
float seconds;
|
||||
qint64 date;
|
||||
qint64 seconds;
|
||||
qint32 samples;
|
||||
int chunks;
|
||||
SampleFormat min,max;
|
||||
|
@ -50,30 +50,25 @@ public:
|
||||
const SessionID & session() {
|
||||
return s_session;
|
||||
};
|
||||
const QDateTime & first() {
|
||||
const qint64 & first() {
|
||||
return s_first;
|
||||
};
|
||||
const QDateTime & last() {
|
||||
const qint64 & last() {
|
||||
return s_last;
|
||||
};
|
||||
void SetSessionID(SessionID s) {
|
||||
s_session=s;
|
||||
};
|
||||
void set_first(QDateTime d) {
|
||||
void set_first(qint64 d) {
|
||||
s_first=d;
|
||||
};
|
||||
void set_last(QDateTime d) {
|
||||
void set_last(qint64 d) {
|
||||
s_last=d;
|
||||
};
|
||||
void set_hours(float h) {
|
||||
if (h<=0) {
|
||||
h=0.000001;
|
||||
}
|
||||
s_hours=h;
|
||||
};
|
||||
|
||||
const float & hours() {
|
||||
return s_hours;
|
||||
float hours() {
|
||||
double t=(s_last-s_first)/3600000.0;
|
||||
return t;
|
||||
};
|
||||
int count_events(MachineCode mc) {
|
||||
if (events.find(mc)==events.end()) return 0;
|
||||
@ -107,9 +102,8 @@ protected:
|
||||
SessionID s_session;
|
||||
|
||||
Machine *s_machine;
|
||||
QDateTime s_first;
|
||||
QDateTime s_last;
|
||||
float s_hours;
|
||||
qint64 s_first;
|
||||
qint64 s_last;
|
||||
bool s_changed;
|
||||
bool s_lonesession;
|
||||
bool _first_session;
|
||||
|
@ -6,12 +6,11 @@
|
||||
|
||||
#include "waveform.h"
|
||||
|
||||
Waveform::Waveform(QDateTime time,MachineCode code, SampleFormat *data,int samples,float duration,SampleFormat min, SampleFormat max)
|
||||
Waveform::Waveform(qint64 time,MachineCode code, SampleFormat *data,int samples,qint64 duration,SampleFormat min, SampleFormat max)
|
||||
:w_time(time),w_code(code),w_data(data),w_samples(samples),w_duration(duration)
|
||||
{
|
||||
w_totalspan=duration;
|
||||
double rate=duration/samples;
|
||||
w_samplespan=rate;
|
||||
w_samplespan=duration/samples;
|
||||
Min=min;
|
||||
Max=max;
|
||||
}
|
||||
|
@ -17,17 +17,17 @@ class Waveform
|
||||
{
|
||||
friend class Session;
|
||||
public:
|
||||
Waveform(QDateTime time,MachineCode code,SampleFormat * data,int samples,float duration,SampleFormat min, SampleFormat max);
|
||||
Waveform(qint64 time,MachineCode code,SampleFormat * data,int samples,qint64 duration,SampleFormat min, SampleFormat max);
|
||||
~Waveform();
|
||||
SampleFormat operator[](int i) {
|
||||
if (i<w_samples) return w_data[i];
|
||||
else return 0;
|
||||
};
|
||||
const QDateTime & start() {
|
||||
qint64 start() {
|
||||
return w_time;
|
||||
};
|
||||
const QDateTime end() {
|
||||
return w_time.addSecs(w_totalspan);
|
||||
qint64 end() {
|
||||
return w_time+w_totalspan;
|
||||
};
|
||||
MachineCode code() {
|
||||
return w_code;
|
||||
@ -35,7 +35,7 @@ public:
|
||||
int samples() {
|
||||
return w_samples;
|
||||
};
|
||||
float duration() {
|
||||
qint64 duration() {
|
||||
return w_duration;
|
||||
};
|
||||
SampleFormat min() {
|
||||
@ -47,14 +47,14 @@ public:
|
||||
SampleFormat *GetBuffer() { return w_data; };
|
||||
|
||||
protected:
|
||||
QDateTime w_time;
|
||||
qint64 w_time;
|
||||
MachineCode w_code;
|
||||
SampleFormat * w_data;
|
||||
qint32 w_samples;
|
||||
float w_duration;
|
||||
qint64 w_duration;
|
||||
SampleFormat Min,Max;
|
||||
double w_totalspan;
|
||||
double w_samplespan;
|
||||
qint64 w_totalspan;
|
||||
qint64 w_samplespan;
|
||||
};
|
||||
|
||||
|
||||
|
28
daily.cpp
28
daily.cpp
@ -437,21 +437,22 @@ void Daily::UpdateEventsTree(QTreeWidget *tree,Day *day)
|
||||
mcr=mcroot[code];
|
||||
}
|
||||
for (vector<Event *>::iterator e=(*s)->events[code].begin();e!=(*s)->events[code].end();e++) {
|
||||
QDateTime t=(*e)->time();
|
||||
qint64 t=(*e)->time();
|
||||
if (code==CPAP_CSR) {
|
||||
t=t.addSecs(-((*(*e))[0]/2));
|
||||
t-=((*(*e))[0]/2)*1000;
|
||||
}
|
||||
QStringList a;
|
||||
QString c,b;
|
||||
c.sprintf("#%03i: ",++mccnt[code]);
|
||||
c+=t.toString(" HH:mm:ss");
|
||||
QDateTime d=QDateTime::fromMSecsSinceEpoch(t);
|
||||
c+=d.toString(" HH:mm:ss");
|
||||
|
||||
//if ((*e)->fields()) { // Perhaps need a dedicated offset field
|
||||
//b.sprintf(" %02.0f",(*(*e))[0]);
|
||||
//c+=b;
|
||||
//}
|
||||
a.append(c);
|
||||
a.append(t.toString("yyyy-MM-dd HH:mm:ss"));
|
||||
a.append(d.toString("yyyy-MM-dd HH:mm:ss"));
|
||||
mcr->addChild(new QTreeWidgetItem(a));
|
||||
}
|
||||
}
|
||||
@ -510,8 +511,6 @@ void Daily::Load(QDate date)
|
||||
UpdateOXIGraphs(oxi);
|
||||
UpdateEventsTree(ui->treeWidget,cpap);
|
||||
|
||||
|
||||
|
||||
QString epr,modestr;
|
||||
float iap90,eap90;
|
||||
CPAPMode mode=MODE_UNKNOWN;
|
||||
@ -551,8 +550,11 @@ void Daily::Load(QDate date)
|
||||
}
|
||||
|
||||
html+="<tr><td align='center'><b>Date</b></td><td align='center'><b>"+tr("Sleep")+"</b></td><td align='center'><b>"+tr("Wake")+"</b></td><td align='center'><b>"+tr("Hours")+"</b></td></tr>";
|
||||
int tt=cpap->total_time();
|
||||
html+="<tr><td align='center'>"+cpap->first().date().toString(Qt::SystemLocaleShortDate)+"</td><td align='center'>"+cpap->first().toString("HH:mm")+"</td><td align='center'>"+cpap->last().toString("HH:mm")+"</td><td align='center'>"+a.sprintf("%02i:%02i",tt/3600,tt%60)+"</td></tr>\n";
|
||||
int tt=cpap->total_time()/1000;
|
||||
QDateTime date=QDateTime::fromMSecsSinceEpoch(cpap->first());
|
||||
QDateTime date2=QDateTime::fromMSecsSinceEpoch(cpap->last());
|
||||
|
||||
html+="<tr><td align='center'>"+date.toString(Qt::SystemLocaleShortDate)+"</td><td align='center'>"+date.toString("HH:mm")+"</td><td align='center'>"+date2.toString("HH:mm")+"</td><td align='center'>"+a.sprintf("%02i:%02i",tt/3600,tt%60)+"</td></tr>\n";
|
||||
html+="<tr><td colspan=4 align=center><hr></td></tr>\n";
|
||||
|
||||
QString cs;
|
||||
@ -699,9 +701,11 @@ void Daily::Load(QDate date)
|
||||
}
|
||||
html+="</table><hr height=2><table cellpadding=0 cellspacing=0 border=0 width=100%>";
|
||||
html+="<tr><td align=center>SessionID</td><td align=center>Date</td><td align=center>Start</td><td align=center>End</td></tr>";
|
||||
QDateTime fd,ld;
|
||||
for (vector<Session *>::iterator s=cpap->begin();s!=cpap->end();s++) {
|
||||
|
||||
tmp.sprintf(("<tr><td align=center>%08x</td><td align=center>"+(*s)->first().toString("yyyy-MM-dd")+"</td><td align=center>"+(*s)->first().toString("HH:mm ")+"</td><td align=center>"+(*s)->last().toString("HH:mm")+"</td></tr>").toLatin1(),(*s)->session());
|
||||
fd=QDateTime::fromMSecsSinceEpoch((*s)->first());
|
||||
ld=QDateTime::fromMSecsSinceEpoch((*s)->last());
|
||||
tmp.sprintf(("<tr><td align=center>%08x</td><td align=center>"+fd.toString("yyyy-MM-dd")+"</td><td align=center>"+fd.toString("HH:mm ")+"</td><td align=center>"+ld.toString("HH:mm")+"</td></tr>").toLatin1(),(*s)->session());
|
||||
html+=tmp;
|
||||
}
|
||||
html+="</table>";
|
||||
@ -832,9 +836,9 @@ Session * Daily::CreateJournalSession(QDate date)
|
||||
QDateTime dt;
|
||||
dt.setDate(date);
|
||||
dt.setTime(QTime(17,0)); //5pm to make sure it goes in the right day
|
||||
sess->set_first(dt);
|
||||
sess->set_first(dt.toMSecsSinceEpoch());
|
||||
dt=dt.addSecs(3600);
|
||||
sess->set_last(dt);
|
||||
sess->set_last(dt.toMSecsSinceEpoch());
|
||||
sess->SetChanged(true);
|
||||
m->AddSession(sess,profile);
|
||||
return sess;
|
||||
|
Loading…
Reference in New Issue
Block a user