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); GetTextExtent(str, textX, textY);
if (!draw_xticks_instead && (textY+6<barwidth)) { if (!draw_xticks_instead && (textY+6<barwidth)) {
glBegin(GL_LINE); glBegin(GL_LINE);
glVertex2f(start_px+px1+barwidth/2+textY/2,start_py); glVertex2f(start_px+px1+barwidth/2,start_py);
glVertex2f(start_px+px1+barwidth/2+textY/2,start_py-6); glVertex2f(start_px+px1+barwidth/2,start_py-6);
glEnd(); 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; } 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) { if (sess->count_events(CPAP_IAP)>0) {
//sess->summary[CPAP_Mode]!=MODE_ASV)
sess->summary[CPAP_Mode]=MODE_BIPAP; 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) { if (sess->summary[CPAP_PressureReliefType].toInt()!=PR_NONE) {
sess->summary[CPAP_PressureReliefType]=PR_BIFLEX; 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_IAPMin]=sess->min_event_field(CPAP_IAP,0);
sess->summary[BIPAP_IAPMax]=sess->max_event_field(CPAP_IAP,0); sess->summary[BIPAP_IAPMax]=sess->max_event_field(CPAP_IAP,0);
} else { } else {
sess->summary[CPAP_PressureMedian]=sess->avg_event_field(CPAP_Pressure,0); 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_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; data[0]=buffer[pos++]/10.0;
session->AddEvent(new Event(t,cpapcode, data,1)); session->AddEvent(new Event(t,cpapcode, data,1));
break; 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 case 0x04: // Pressure Pulse
data[0]=buffer[pos++]; data[0]=buffer[pos++];
session->AddEvent(new Event(t,cpapcode, data,1)); session->AddEvent(new Event(t,cpapcode, data,1));
break; break;
case 0x0a: // Hypopnea
case 0x05: // RERA case 0x05: // RERA
case 0x06: // Obstructive Apoanea case 0x06: // Obstructive Apoanea
case 0x07: // Clear Airway case 0x07: // Clear Airway
case 0x0a: // Hypopnea
case 0x0c: // Flow Limitation case 0x0c: // Flow Limitation
data[0]=buffer[pos++]; data[0]=buffer[pos++];
tt-=data[0]*1000; // Subtract Time Offset 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++]; data[1]=buffer[pos++];
session->AddEvent(new Event(tt,cpapcode,data,2)); session->AddEvent(new Event(tt,cpapcode,data,2));
break; 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 case 0x0d: // Vibratory Snore
session->AddEvent(new Event(t,cpapcode, data,0)); session->AddEvent(new Event(t,cpapcode, data,0));
break; 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 case 0x11: // Leak Rate
data[0]=buffer[pos++]; data[0]=buffer[pos++];
data[1]=buffer[pos++]; data[1]=buffer[pos++];
@ -609,13 +612,11 @@ bool PRS1Loader::Parse002(Session *session,unsigned char *buffer,int size,qint64
} }
break; break;
case 0x0e: // Unknown case 0x0e: // Unknown
data[0]=buffer[pos++]; // << 8) | buffer[pos]; data[0]=buffer[pos++]; // << 8) | buffer[pos];
data[1]=buffer[pos++]; data[1]=buffer[pos++];
data[2]=buffer[pos++]; data[2]=buffer[pos++];
session->AddEvent(new Event(t,cpapcode, data, 3)); session->AddEvent(new Event(t,cpapcode, data, 3));
break; break;
case 0x10: // Unknown case 0x10: // Unknown
data[0]=buffer[pos++]; // << 8) | buffer[pos]; data[0]=buffer[pos++]; // << 8) | buffer[pos];
data[1]=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 session->AddEvent(new Event(t,CPAP_IAPLO,&data[1],1)); //correct
data[2]=buffer[pos++]/10.0; // Hi IPAP data[2]=buffer[pos++]/10.0; // Hi IPAP
session->AddEvent(new Event(t,CPAP_IAPHI,&data[2],1)); //correct 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 data[3]=buffer[pos++];//Leak
session->AddEvent(new Event(t,CPAP_Leak,&data[3],1)); // correct session->AddEvent(new Event(t,CPAP_Leak,&data[3],1)); // correct
data[4]=buffer[pos++];//Breaths Per Minute 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) { if (data[8]>0) {
session->AddEvent(new Event(t,CPAP_VSnore,&data[8],1)); //correct 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 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]); 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; break;
case 0x03: // BIPAP Pressure case 0x03: // BIPAP Pressure

View File

@ -45,7 +45,10 @@ enum MachineCode//:qint16
CPAP_LeakMedian,CPAP_LeakMinimum,CPAP_LeakMaximum,CPAP_LeakAverage,CPAP_Duration, CPAP_LeakMedian,CPAP_LeakMinimum,CPAP_LeakMaximum,CPAP_LeakAverage,CPAP_Duration,
CPAP_SnoreMinimum, CPAP_SnoreMaximum, CPAP_SnoreAverage, CPAP_SnoreMedian, 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 Specific Codes
PRS1_PressurePulse=0x1000,PRS1_VSnore2, PRS1_PressurePulse=0x1000,PRS1_VSnore2,

View File

@ -147,7 +147,7 @@ double Session::weighted_avg_event_field(MachineCode mc,int field)
double mult; 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; mult=10.0;
} else mult=10.0; } else mult=10.0;
@ -175,21 +175,21 @@ double Session::weighted_avg_event_field(MachineCode mc,int field)
lastval=val; lastval=val;
} }
qint64 total; qint64 total=0;
for (int i=0; i<max_slots; i++) total+=vtime[i]; for (int i=0; i<max_slots; i++) total+=vtime[i];
//double hours=total.GetSeconds().GetLo()/3600.0; //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; if (total==0) return 0;
for (int i=0; i<max_slots; i++) { for (int i=0; i<max_slots; i++) {
if (vtime[i] > 0) { if (vtime[i] > 0) {
s0=(vtime[i]/3600.0); s0=vtime[i];
s1+=i*s0; s1+=i*s0;
s2+=s0; s2+=s0;
} }
} }
double j=double(s1)/double(total);
return (s1/total)/mult; return j/mult;
} }
void Session::AddEvent(Event * e) 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->AddLayer(new gLineChart(rr,Qt::gray,65536,false,false,true));
RR->setMinimumHeight(150); 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)); AddOXIData(pulse=new EventData(OXI_Pulse,0,65536,true));
//pulse->ForceMinY(40); //pulse->ForceMinY(40);
@ -276,6 +283,8 @@ Daily::Daily(QWidget *parent,QGLContext *context) :
FRW->LinkZoom(TV); FRW->LinkZoom(TV);
FRW->LinkZoom(RR); FRW->LinkZoom(RR);
FRW->LinkZoom(FLG); FRW->LinkZoom(FLG);
FRW->LinkZoom(PTB);
SF->LinkZoom(FRW); SF->LinkZoom(FRW);
SF->LinkZoom(MP); SF->LinkZoom(MP);
SF->LinkZoom(PRD); SF->LinkZoom(PRD);
@ -285,6 +294,8 @@ Daily::Daily(QWidget *parent,QGLContext *context) :
SF->LinkZoom(TV); SF->LinkZoom(TV);
SF->LinkZoom(RR); SF->LinkZoom(RR);
SF->LinkZoom(FLG); SF->LinkZoom(FLG);
SF->LinkZoom(PTB);
PRD->LinkZoom(SF); PRD->LinkZoom(SF);
PRD->LinkZoom(FRW); PRD->LinkZoom(FRW);
PRD->LinkZoom(MP); PRD->LinkZoom(MP);
@ -294,6 +305,18 @@ Daily::Daily(QWidget *parent,QGLContext *context) :
PRD->LinkZoom(TV); PRD->LinkZoom(TV);
PRD->LinkZoom(RR); PRD->LinkZoom(RR);
PRD->LinkZoom(FLG); 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(SF);
LEAK->LinkZoom(FRW); LEAK->LinkZoom(FRW);
@ -304,6 +327,7 @@ Daily::Daily(QWidget *parent,QGLContext *context) :
LEAK->LinkZoom(TV); LEAK->LinkZoom(TV);
LEAK->LinkZoom(RR); LEAK->LinkZoom(RR);
LEAK->LinkZoom(FLG); LEAK->LinkZoom(FLG);
LEAK->LinkZoom(PTB);
SNORE->LinkZoom(SF); SNORE->LinkZoom(SF);
SNORE->LinkZoom(FRW); SNORE->LinkZoom(FRW);
@ -314,6 +338,7 @@ Daily::Daily(QWidget *parent,QGLContext *context) :
SNORE->LinkZoom(TV); SNORE->LinkZoom(TV);
SNORE->LinkZoom(RR); SNORE->LinkZoom(RR);
SNORE->LinkZoom(FLG); SNORE->LinkZoom(FLG);
SNORE->LinkZoom(PTB);
MV->LinkZoom(SF); MV->LinkZoom(SF);
MV->LinkZoom(FRW); MV->LinkZoom(FRW);
@ -324,6 +349,7 @@ Daily::Daily(QWidget *parent,QGLContext *context) :
MV->LinkZoom(TV); MV->LinkZoom(TV);
MV->LinkZoom(RR); MV->LinkZoom(RR);
MV->LinkZoom(FLG); MV->LinkZoom(FLG);
MV->LinkZoom(PTB);
TV->LinkZoom(SF); TV->LinkZoom(SF);
TV->LinkZoom(FRW); TV->LinkZoom(FRW);
@ -334,6 +360,7 @@ Daily::Daily(QWidget *parent,QGLContext *context) :
TV->LinkZoom(MV); TV->LinkZoom(MV);
TV->LinkZoom(RR); TV->LinkZoom(RR);
TV->LinkZoom(FLG); TV->LinkZoom(FLG);
TV->LinkZoom(PTB);
RR->LinkZoom(SF); RR->LinkZoom(SF);
RR->LinkZoom(FRW); RR->LinkZoom(FRW);
@ -344,6 +371,7 @@ Daily::Daily(QWidget *parent,QGLContext *context) :
RR->LinkZoom(MV); RR->LinkZoom(MV);
RR->LinkZoom(TV); RR->LinkZoom(TV);
RR->LinkZoom(FLG); RR->LinkZoom(FLG);
RR->LinkZoom(PTB);
FLG->LinkZoom(SF); FLG->LinkZoom(SF);
FLG->LinkZoom(FRW); FLG->LinkZoom(FRW);
@ -354,6 +382,7 @@ Daily::Daily(QWidget *parent,QGLContext *context) :
FLG->LinkZoom(MV); FLG->LinkZoom(MV);
FLG->LinkZoom(TV); FLG->LinkZoom(TV);
FLG->LinkZoom(RR); FLG->LinkZoom(RR);
FLG->LinkZoom(PTB);
MP->LinkZoom(SF); MP->LinkZoom(SF);
MP->LinkZoom(FRW); MP->LinkZoom(FRW);
@ -364,6 +393,7 @@ Daily::Daily(QWidget *parent,QGLContext *context) :
MP->LinkZoom(MV); MP->LinkZoom(MV);
MP->LinkZoom(TV); MP->LinkZoom(TV);
MP->LinkZoom(RR); MP->LinkZoom(RR);
MP->LinkZoom(PTB);
gSplitter->addWidget(NoData); gSplitter->addWidget(NoData);
@ -372,6 +402,7 @@ Daily::Daily(QWidget *parent,QGLContext *context) :
AddGraph(MP); AddGraph(MP);
AddGraph(MV); AddGraph(MV);
AddGraph(TV); AddGraph(TV);
AddGraph(PTB);
AddGraph(RR); AddGraph(RR);
AddGraph(PRD); AddGraph(PRD);
AddGraph(LEAK); 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_weighted_avg(BIPAP_IAPAverage));
html+=("</td><td>")+a.sprintf("%.2f",cpap->summary_max(BIPAP_IAPMax))+("</td></tr>"); 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+="<tr><td align=left>"+tr("Leak:");
html+="</td><td>"+a.sprintf("%.2f",cpap->summary_min(CPAP_LeakMinimum)); 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(); prd->isEmpty() && pressure_iap->isEmpty() ? PRD->hide() : PRD->show();
leak->isEmpty() ? LEAK->hide() : LEAK->show(); leak->isEmpty() ? LEAK->hide() : LEAK->show();
snore->isEmpty() ? SNORE->hide() : SNORE->show(); snore->isEmpty() ? SNORE->hide() : SNORE->show();
ptb->isEmpty() ? PTB->hide() : PTB->show();
bool merge_oxi_graphs=true; bool merge_oxi_graphs=true;
if (!merge_oxi_graphs) { if (!merge_oxi_graphs) {

View File

@ -58,10 +58,10 @@ private:
void UpdateEventsTree(QTreeWidget * tree,Day *day); void UpdateEventsTree(QTreeWidget * tree,Day *day);
gPointData *tap,*tap_eap,*tap_iap,*g_ahi,*frw,*prd,*leak,*pressure_iap,*pressure_eap,*snore; 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; 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 *> OXIData;
list<gPointData *> CPAPData; list<gPointData *> CPAPData;

View File

@ -12,7 +12,7 @@ p,a,td,body { font-size: 14px }
<td valign="top" leftmargin=0 cellpadding=6> <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>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> <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>ResMed S9 models (AutoSet and lower)</li>
<li>Contec CMS50 Oximeters</li> <li>Contec CMS50 Oximeters</li>
<p><b>Project Website:</b> <a href='http://sleepyhead.sourceforge.net'>http://sleepyhead.sourceforge.net</a><br> <p><b>Project Website:</b> <a href='http://sleepyhead.sourceforge.net'>http://sleepyhead.sourceforge.net</a><br>