Weighted Average Fix

This commit is contained in:
Mark Watkins 2011-07-12 22:43:10 +10:00
parent e92eaf98a3
commit 7d0e5e60fe
7 changed files with 74 additions and 37 deletions

View File

@ -135,10 +135,10 @@ void gSessionTime::Plot(gGraphWindow & w,float scrx,float scry)
GetTextExtent(str, textX, textY);
if (!draw_xticks_instead && (textY+6<barwidth)) {
glBegin(GL_LINE);
glVertex2f(start_px+px1+barwidth/2+textY/2,start_py);
glVertex2f(start_px+px1+barwidth/2+textY/2,start_py-6);
glVertex2f(start_px+px1+barwidth/2,start_py);
glVertex2f(start_px+px1+barwidth/2,start_py-6);
glEnd();
DrawText(str,start_px+px1+barwidth/2+textY/2+textY,scry-(start_py-8-textX/2),90);
DrawText(str,start_px+px1+barwidth/2+textY,scry-(start_py-8-textX/2),90);
} else draw_xticks_instead=true;
}
}

View File

@ -323,7 +323,13 @@ int PRS1Loader::OpenMachine(Machine *m,QString path,Profile *profile)
if (sess->count_events(CPAP_IAP)>0) {
//sess->summary[CPAP_Mode]!=MODE_ASV)
sess->summary[CPAP_Mode]=MODE_BIPAP;
sess->summary[BIPAP_PSAverage]=sess->weighted_avg_event_field(CPAP_PS,0);
sess->summary[BIPAP_PSMin]=sess->min_event_field(CPAP_PS,0);
sess->summary[BIPAP_PSMax]=sess->max_event_field(CPAP_PS,0);
if (sess->summary[CPAP_PressureReliefType].toInt()!=PR_NONE) {
sess->summary[CPAP_PressureReliefType]=PR_BIFLEX;
}
@ -340,6 +346,8 @@ int PRS1Loader::OpenMachine(Machine *m,QString path,Profile *profile)
sess->summary[BIPAP_IAPMin]=sess->min_event_field(CPAP_IAP,0);
sess->summary[BIPAP_IAPMax]=sess->max_event_field(CPAP_IAP,0);
} else {
sess->summary[CPAP_PressureMedian]=sess->avg_event_field(CPAP_Pressure,0);
//sess->summary[CPAP_PressureAverage]=sess->weighted_avg_event_field(CPAP_Pressure,0);
@ -563,15 +571,24 @@ bool PRS1Loader::Parse002(Session *session,unsigned char *buffer,int size,qint64
data[0]=buffer[pos++]/10.0;
session->AddEvent(new Event(t,cpapcode, data,1));
break;
case 0x03: // BIPAP Pressure
data[0]=buffer[pos++];
data[1]=buffer[pos++];
data[0]/=10.0;
data[1]/=10.0;
session->AddEvent(new Event(t,CPAP_EAP, data, 1));
session->AddEvent(new Event(t,CPAP_IAP, &data[1], 1));
data[1]-=data[0];
session->AddEvent(new Event(t,CPAP_PS, &data[1], 1));
break;
case 0x04: // Pressure Pulse
data[0]=buffer[pos++];
session->AddEvent(new Event(t,cpapcode, data,1));
break;
case 0x0a: // Hypopnea
case 0x05: // RERA
case 0x06: // Obstructive Apoanea
case 0x07: // Clear Airway
case 0x0a: // Hypopnea
case 0x0c: // Flow Limitation
data[0]=buffer[pos++];
tt-=data[0]*1000; // Subtract Time Offset
@ -582,23 +599,9 @@ bool PRS1Loader::Parse002(Session *session,unsigned char *buffer,int size,qint64
data[1]=buffer[pos++];
session->AddEvent(new Event(tt,cpapcode,data,2));
break;
//case 0x08: // ASV Codes
//case 0x09: // ASV Codes
// data[0]=buffer[pos];
// tt-=buffer[pos++]*1000; // Subtract Time Offset
// session->AddEvent(new Event(tt,cpapcode,data,1));
// break;
case 0x0d: // Vibratory Snore
session->AddEvent(new Event(t,cpapcode, data,0));
break;
case 0x03: // BIPAP Pressure
data[0]=buffer[pos++];
data[1]=buffer[pos++];
data[0]/=10.0;
data[1]/=10.0;
session->AddEvent(new Event(t,CPAP_EAP, data, 1));
session->AddEvent(new Event(t,CPAP_IAP, &data[1], 1));
break;
case 0x11: // Leak Rate
data[0]=buffer[pos++];
data[1]=buffer[pos++];
@ -609,13 +612,11 @@ bool PRS1Loader::Parse002(Session *session,unsigned char *buffer,int size,qint64
}
break;
case 0x0e: // Unknown
data[0]=buffer[pos++]; // << 8) | buffer[pos];
data[1]=buffer[pos++];
data[2]=buffer[pos++];
session->AddEvent(new Event(t,cpapcode, data, 3));
break;
case 0x10: // Unknown
data[0]=buffer[pos++]; // << 8) | buffer[pos];
data[1]=buffer[pos++];
@ -750,11 +751,6 @@ bool PRS1Loader::Parse002ASV(Session *session,unsigned char *buffer,int size,qin
session->AddEvent(new Event(t,CPAP_IAPLO,&data[1],1)); //correct
data[2]=buffer[pos++]/10.0; // Hi IPAP
session->AddEvent(new Event(t,CPAP_IAPHI,&data[2],1)); //correct
// This may not be necessary.. Check: the average of IAPHI - average of IAPLO may equal the average of this.
data[2]-=data[1];
session->AddEvent(new Event(t,CPAP_PS,&data[2],1)); //correct
data[3]=buffer[pos++];//Leak
session->AddEvent(new Event(t,CPAP_Leak,&data[3],1)); // correct
data[4]=buffer[pos++];//Breaths Per Minute
@ -770,9 +766,11 @@ bool PRS1Loader::Parse002ASV(Session *session,unsigned char *buffer,int size,qin
if (data[8]>0) {
session->AddEvent(new Event(t,CPAP_VSnore,&data[8],1)); //correct
}
data[9]=buffer[pos++]/10.0; // This is a pressure value
data[9]=buffer[pos++]/10.0; // EPAP
session->AddEvent(new Event(t,CPAP_EAP,&data[9],1)); //correct
data[2]-=data[9]; // Pressure Support
session->AddEvent(new Event(t,CPAP_PS,&data[2],1)); //correct
qDebug()<< d.toString("yyyy-MM-dd HH:mm:ss") << hex << session->session() << pos+15 << hex << int(code) << ": " << hex << int(data[0]) << " " << int(data[1]) << " " << int(data[2]) << " " << int(data[3]) << " " << int(data[4]) << " " << int(data[5])<< " " << int(data[6]) << " " << int(data[7]) << " " << int(data[8]) << " " << int(data[9]);
break;
case 0x03: // BIPAP Pressure

View File

@ -45,7 +45,10 @@ enum MachineCode//:qint16
CPAP_LeakMedian,CPAP_LeakMinimum,CPAP_LeakMaximum,CPAP_LeakAverage,CPAP_Duration,
CPAP_SnoreMinimum, CPAP_SnoreMaximum, CPAP_SnoreAverage, CPAP_SnoreMedian,
BIPAP_EAPAverage,BIPAP_IAPAverage,BIPAP_EAPMin,BIPAP_EAPMax,BIPAP_IAPMin,BIPAP_IAPMax,CPAP_BrokenSummary,
BIPAP_EAPAverage,BIPAP_IAPAverage,BIPAP_EAPMin,BIPAP_EAPMax,BIPAP_IAPMin,BIPAP_IAPMax,
BIPAP_PSAverage,BIPAP_PSMin, BIPAP_PSMax,
CPAP_BrokenSummary,
// PRS1 Specific Codes
PRS1_PressurePulse=0x1000,PRS1_VSnore2,

View File

@ -147,7 +147,7 @@ double Session::weighted_avg_event_field(MachineCode mc,int field)
double mult;
if ((mc==CPAP_Pressure) || (mc==CPAP_EAP) || (mc==CPAP_IAP)) {
if ((mc==CPAP_Pressure) || (mc==CPAP_EAP) || (mc==CPAP_IAP) | (mc==CPAP_PS)) {
mult=10.0;
} else mult=10.0;
@ -175,21 +175,21 @@ double Session::weighted_avg_event_field(MachineCode mc,int field)
lastval=val;
}
qint64 total;
qint64 total=0;
for (int i=0; i<max_slots; i++) total+=vtime[i];
//double hours=total.GetSeconds().GetLo()/3600.0;
double s0=0,s1=0,s2=0;
qint64 s0=0,s1=0,s2=0;
if (total==0) return 0;
for (int i=0; i<max_slots; i++) {
if (vtime[i] > 0) {
s0=(vtime[i]/3600.0);
s0=vtime[i];
s1+=i*s0;
s2+=s0;
}
}
return (s1/total)/mult;
double j=double(s1)/double(total);
return j/mult;
}
void Session::AddEvent(Event * e)

View File

@ -188,6 +188,13 @@ Daily::Daily(QWidget *parent,QGLContext *context) :
RR->AddLayer(new gLineChart(rr,Qt::gray,65536,false,false,true));
RR->setMinimumHeight(150);
AddCPAPData(ptb=new EventData(CPAP_PatientTriggeredBreaths ));
PTB=new gGraphWindow(gSplitter,tr("Patient Trig Breaths"),SF);
PTB->AddLayer(new gXAxis());
PTB->AddLayer(new gYAxis());
PTB->AddLayer(new gLineChart(ptb,Qt::gray,65536,false,false,true));
PTB->setMinimumHeight(150);
AddOXIData(pulse=new EventData(OXI_Pulse,0,65536,true));
//pulse->ForceMinY(40);
@ -276,6 +283,8 @@ Daily::Daily(QWidget *parent,QGLContext *context) :
FRW->LinkZoom(TV);
FRW->LinkZoom(RR);
FRW->LinkZoom(FLG);
FRW->LinkZoom(PTB);
SF->LinkZoom(FRW);
SF->LinkZoom(MP);
SF->LinkZoom(PRD);
@ -285,6 +294,8 @@ Daily::Daily(QWidget *parent,QGLContext *context) :
SF->LinkZoom(TV);
SF->LinkZoom(RR);
SF->LinkZoom(FLG);
SF->LinkZoom(PTB);
PRD->LinkZoom(SF);
PRD->LinkZoom(FRW);
PRD->LinkZoom(MP);
@ -294,6 +305,18 @@ Daily::Daily(QWidget *parent,QGLContext *context) :
PRD->LinkZoom(TV);
PRD->LinkZoom(RR);
PRD->LinkZoom(FLG);
PRD->LinkZoom(PTB);
PTB->LinkZoom(SF);
PTB->LinkZoom(FRW);
PTB->LinkZoom(MP);
PTB->LinkZoom(LEAK);
PTB->LinkZoom(SNORE);
PTB->LinkZoom(MV);
PTB->LinkZoom(TV);
PTB->LinkZoom(RR);
PTB->LinkZoom(FLG);
PTB->LinkZoom(PRD);
LEAK->LinkZoom(SF);
LEAK->LinkZoom(FRW);
@ -304,6 +327,7 @@ Daily::Daily(QWidget *parent,QGLContext *context) :
LEAK->LinkZoom(TV);
LEAK->LinkZoom(RR);
LEAK->LinkZoom(FLG);
LEAK->LinkZoom(PTB);
SNORE->LinkZoom(SF);
SNORE->LinkZoom(FRW);
@ -314,6 +338,7 @@ Daily::Daily(QWidget *parent,QGLContext *context) :
SNORE->LinkZoom(TV);
SNORE->LinkZoom(RR);
SNORE->LinkZoom(FLG);
SNORE->LinkZoom(PTB);
MV->LinkZoom(SF);
MV->LinkZoom(FRW);
@ -324,6 +349,7 @@ Daily::Daily(QWidget *parent,QGLContext *context) :
MV->LinkZoom(TV);
MV->LinkZoom(RR);
MV->LinkZoom(FLG);
MV->LinkZoom(PTB);
TV->LinkZoom(SF);
TV->LinkZoom(FRW);
@ -334,6 +360,7 @@ Daily::Daily(QWidget *parent,QGLContext *context) :
TV->LinkZoom(MV);
TV->LinkZoom(RR);
TV->LinkZoom(FLG);
TV->LinkZoom(PTB);
RR->LinkZoom(SF);
RR->LinkZoom(FRW);
@ -344,6 +371,7 @@ Daily::Daily(QWidget *parent,QGLContext *context) :
RR->LinkZoom(MV);
RR->LinkZoom(TV);
RR->LinkZoom(FLG);
RR->LinkZoom(PTB);
FLG->LinkZoom(SF);
FLG->LinkZoom(FRW);
@ -354,6 +382,7 @@ Daily::Daily(QWidget *parent,QGLContext *context) :
FLG->LinkZoom(MV);
FLG->LinkZoom(TV);
FLG->LinkZoom(RR);
FLG->LinkZoom(PTB);
MP->LinkZoom(SF);
MP->LinkZoom(FRW);
@ -364,6 +393,7 @@ Daily::Daily(QWidget *parent,QGLContext *context) :
MP->LinkZoom(MV);
MP->LinkZoom(TV);
MP->LinkZoom(RR);
MP->LinkZoom(PTB);
gSplitter->addWidget(NoData);
@ -372,6 +402,7 @@ Daily::Daily(QWidget *parent,QGLContext *context) :
AddGraph(MP);
AddGraph(MV);
AddGraph(TV);
AddGraph(PTB);
AddGraph(RR);
AddGraph(PRD);
AddGraph(LEAK);
@ -664,6 +695,10 @@ void Daily::Load(QDate date)
html+=("</td><td>")+a.sprintf("%.2f",cpap->summary_weighted_avg(BIPAP_IAPAverage));
html+=("</td><td>")+a.sprintf("%.2f",cpap->summary_max(BIPAP_IAPMax))+("</td></tr>");
html+=("<tr><td align=left>"+tr("PS:")+"</td><td>")+a.sprintf("%.2f",cpap->summary_min(BIPAP_PSMin));
html+=("</td><td>")+a.sprintf("%.2f",cpap->summary_weighted_avg(BIPAP_PSAverage));
html+=("</td><td>")+a.sprintf("%.2f",cpap->summary_max(BIPAP_PSMax))+("</td></tr>");
}
html+="<tr><td align=left>"+tr("Leak:");
html+="</td><td>"+a.sprintf("%.2f",cpap->summary_min(CPAP_LeakMinimum));
@ -713,6 +748,7 @@ void Daily::Load(QDate date)
prd->isEmpty() && pressure_iap->isEmpty() ? PRD->hide() : PRD->show();
leak->isEmpty() ? LEAK->hide() : LEAK->show();
snore->isEmpty() ? SNORE->hide() : SNORE->show();
ptb->isEmpty() ? PTB->hide() : PTB->show();
bool merge_oxi_graphs=true;
if (!merge_oxi_graphs) {

View File

@ -58,10 +58,10 @@ private:
void UpdateEventsTree(QTreeWidget * tree,Day *day);
gPointData *tap,*tap_eap,*tap_iap,*g_ahi,*frw,*prd,*leak,*pressure_iap,*pressure_eap,*snore;
gPointData *pulse,*spo2,*rr,*mv,*tv,*mp,*flg;
gPointData *pulse,*spo2,*rr,*mv,*tv,*mp,*flg,*ptb;
gFlagsGroup *fg;
gGraphWindow *PRD,*FRW,*G_AHI,*TAP,*LEAK,*SF,*TAP_EAP,*TAP_IAP,*PULSE,*SPO2,*SNORE,*RR,*MP,*MV,*TV,*FLG;
gGraphWindow *PRD,*FRW,*G_AHI,*TAP,*LEAK,*SF,*TAP_EAP,*TAP_IAP,*PULSE,*SPO2,*SNORE,*RR,*MP,*MV,*TV,*FLG,*PTB;
list<gPointData *> OXIData;
list<gPointData *> CPAPData;

View File

@ -12,7 +12,7 @@ p,a,td,body { font-size: 14px }
<td valign="top" leftmargin=0 cellpadding=6>
<p>This software is designed to assist you in reviewing data for your CPAP Machine, Oximeter, and Sleep Stage monitors, as well as help you track general issues related to sleep health.</p>
<p>Currenly supports the following machines:</p>
<li>Philips Respironics System One (BIPAP and lower)</li>
<li>Philips Respironics System One (Including ASV models)</li>
<li>ResMed S9 models (AutoSet and lower)</li>
<li>Contec CMS50 Oximeters</li>
<p><b>Project Website:</b> <a href='http://sleepyhead.sourceforge.net'>http://sleepyhead.sourceforge.net</a><br>