Added Percentile calculations

This commit is contained in:
Mark Watkins 2011-05-30 01:40:34 +10:00
parent 191d498573
commit 37cdc5a25b
8 changed files with 92 additions and 28 deletions

View File

@ -7835,7 +7835,7 @@
"sleeplib/machine.h" "sleeplib/machine.h"
"graphs/graph.h" "graphs/graph.h"
1306667662 /home/mark/projects/git/sleepyhead/libs/sleeplib/machine.h 1306682653 /home/mark/projects/git/sleepyhead/libs/sleeplib/machine.h
<wx/string.h> <wx/string.h>
<wx/variant.h> <wx/variant.h>
<wx/dir.h> <wx/dir.h>
@ -7873,7 +7873,7 @@
<sleeplib/machine.h> <sleeplib/machine.h>
<list> <list>
1306667877 /home/mark/projects/git/sleepyhead/version.h 1306683584 /home/mark/projects/git/sleepyhead/version.h
1306549105 /home/mark/projects/git/sleepyhead/libs/sleeplib/prs1_loader.h 1306549105 /home/mark/projects/git/sleepyhead/libs/sleeplib/prs1_loader.h
"machine.h" "machine.h"
@ -7890,7 +7890,7 @@
"preferences.h" "preferences.h"
"tinyxml/tinyxml.h" "tinyxml/tinyxml.h"
1306667876 source:/home/mark/projects/git/sleepyhead/SleepyHeadMain.cpp 1306683142 source:/home/mark/projects/git/sleepyhead/SleepyHeadMain.cpp
"wx_pch.h" "wx_pch.h"
"version.h" "version.h"
<wx/app.h> <wx/app.h>
@ -7919,7 +7919,7 @@
<wx/ffile.h> <wx/ffile.h>
<wx/utils.h> <wx/utils.h>
1306667681 source:/home/mark/projects/git/sleepyhead/libs/sleeplib/machine.cpp 1306683485 source:/home/mark/projects/git/sleepyhead/libs/sleeplib/machine.cpp
<tr1/random> <tr1/random>
<wx/colour.h> <wx/colour.h>
<wx/log.h> <wx/log.h>
@ -7927,6 +7927,7 @@
"binary_file.h" "binary_file.h"
"machine.h" "machine.h"
"profiles.h" "profiles.h"
<algorithm>
1306414968 source:/home/mark/projects/git/sleepyhead/libs/sleeplib/machine_loader.cpp 1306414968 source:/home/mark/projects/git/sleepyhead/libs/sleeplib/machine_loader.cpp
"machine_loader.h" "machine_loader.h"
@ -7939,7 +7940,7 @@
<wx/stdpaths.h> <wx/stdpaths.h>
"preferences.h" "preferences.h"
1306414968 source:/home/mark/projects/git/sleepyhead/libs/sleeplib/profiles.cpp 1306673434 source:/home/mark/projects/git/sleepyhead/libs/sleeplib/profiles.cpp
<wx/filefn.h> <wx/filefn.h>
<wx/filename.h> <wx/filename.h>
<wx/utils.h> <wx/utils.h>
@ -7951,7 +7952,7 @@
"machine_loader.h" "machine_loader.h"
"tinyxml/tinyxml.h" "tinyxml/tinyxml.h"
1306667633 source:/home/mark/projects/git/sleepyhead/libs/sleeplib/prs1_loader.cpp 1306681892 source:/home/mark/projects/git/sleepyhead/libs/sleeplib/prs1_loader.cpp
<wx/dir.h> <wx/dir.h>
<wx/filename.h> <wx/filename.h>
<wx/ffile.h> <wx/ffile.h>

View File

@ -4,11 +4,11 @@
<File name="GUIFrame.cpp" open="0" top="0" tabpos="7"> <File name="GUIFrame.cpp" open="0" top="0" tabpos="7">
<Cursor position="1774" topLine="0" /> <Cursor position="1774" topLine="0" />
</File> </File>
<File name="SleepyHeadApp.cpp" open="1" top="1" tabpos="9"> <File name="SleepyHeadApp.cpp" open="0" top="0" tabpos="9">
<Cursor position="1346" topLine="14" /> <Cursor position="1346" topLine="14" />
</File> </File>
<File name="SleepyHeadMain.cpp" open="1" top="0" tabpos="3"> <File name="SleepyHeadMain.cpp" open="1" top="0" tabpos="3">
<Cursor position="14754" topLine="408" /> <Cursor position="16541" topLine="457" />
</File> </File>
<File name="SleepyHeadMain.h" open="1" top="0" tabpos="4"> <File name="SleepyHeadMain.h" open="1" top="0" tabpos="4">
<Cursor position="2066" topLine="34" /> <Cursor position="2066" topLine="34" />
@ -26,10 +26,10 @@
<Cursor position="0" topLine="0" /> <Cursor position="0" topLine="0" />
</File> </File>
<File name="libs/sleeplib/machine.cpp" open="1" top="0" tabpos="1"> <File name="libs/sleeplib/machine.cpp" open="1" top="0" tabpos="1">
<Cursor position="4755" topLine="129" /> <Cursor position="20308" topLine="691" />
</File> </File>
<File name="libs/sleeplib/machine.h" open="1" top="0" tabpos="2"> <File name="libs/sleeplib/machine.h" open="1" top="0" tabpos="2">
<Cursor position="6107" topLine="197" /> <Cursor position="2173" topLine="55" />
</File> </File>
<File name="libs/sleeplib/machine_loader.cpp" open="0" top="0" tabpos="8"> <File name="libs/sleeplib/machine_loader.cpp" open="0" top="0" tabpos="8">
<Cursor position="0" topLine="0" /> <Cursor position="0" topLine="0" />
@ -37,20 +37,20 @@
<File name="libs/sleeplib/machine_loader.h" open="0" top="0" tabpos="15"> <File name="libs/sleeplib/machine_loader.h" open="0" top="0" tabpos="15">
<Cursor position="0" topLine="0" /> <Cursor position="0" topLine="0" />
</File> </File>
<File name="libs/sleeplib/preferences.cpp" open="0" top="0" tabpos="9"> <File name="libs/sleeplib/preferences.cpp" open="1" top="0" tabpos="9">
<Cursor position="0" topLine="0" /> <Cursor position="5120" topLine="160" />
</File> </File>
<File name="libs/sleeplib/preferences.h" open="0" top="0" tabpos="16"> <File name="libs/sleeplib/preferences.h" open="0" top="0" tabpos="16">
<Cursor position="31" topLine="0" /> <Cursor position="31" topLine="0" />
</File> </File>
<File name="libs/sleeplib/profiles.cpp" open="0" top="0" tabpos="10"> <File name="libs/sleeplib/profiles.cpp" open="1" top="0" tabpos="10">
<Cursor position="22" topLine="0" /> <Cursor position="1342" topLine="38" />
</File> </File>
<File name="libs/sleeplib/profiles.h" open="0" top="0" tabpos="17"> <File name="libs/sleeplib/profiles.h" open="0" top="0" tabpos="17">
<Cursor position="28" topLine="0" /> <Cursor position="28" topLine="0" />
</File> </File>
<File name="libs/sleeplib/prs1_loader.cpp" open="1" top="0" tabpos="7"> <File name="libs/sleeplib/prs1_loader.cpp" open="1" top="1" tabpos="7">
<Cursor position="15901" topLine="250" /> <Cursor position="22943" topLine="679" />
</File> </File>
<File name="libs/sleeplib/prs1_loader.h" open="1" top="0" tabpos="8"> <File name="libs/sleeplib/prs1_loader.h" open="1" top="0" tabpos="8">
<Cursor position="1115" topLine="0" /> <Cursor position="1115" topLine="0" />

View File

@ -599,6 +599,9 @@ void Daily::OnCalendarDay( wxCalendarEvent& event )
float rei=d->count(CPAP_RERA)/d->hours(); float rei=d->count(CPAP_RERA)/d->hours();
float vsi=d->count(CPAP_VSnore)/d->hours(); float vsi=d->count(CPAP_VSnore)/d->hours();
float fli=d->count(CPAP_FlowLimit)/d->hours(); float fli=d->count(CPAP_FlowLimit)/d->hours();
float p90=d->percentile(CPAP_Pressure,0,0.9);
float eap90=d->percentile(CPAP_EAP,0,0.9);
float iap90=d->percentile(CPAP_IAP,0,0.9);
wxString submodel=_("Unknown Model"); wxString submodel=_("Unknown Model");
@ -637,7 +640,7 @@ void Daily::OnCalendarDay( wxCalendarEvent& event )
html=html+wxT("<tr><td><b>")+_("Avg&nbsp;Pressure")+wxT("</b></td><td>")+wxString::Format(wxT("%.2fcmH2O"),d->summary_avg(CPAP_PressureAverage))+wxT("</td></tr>\n"); html=html+wxT("<tr><td><b>")+_("Avg&nbsp;Pressure")+wxT("</b></td><td>")+wxString::Format(wxT("%.2fcmH2O"),d->summary_avg(CPAP_PressureAverage))+wxT("</td></tr>\n");
html=html+wxT("<tr><td><b>")+_("Min&nbsp;Reached")+wxT("</b></td><td>")+wxString::Format(wxT("%.1fcmH2O"),d->summary_min(CPAP_PressureMinAchieved))+wxT("</td></tr>\n"); html=html+wxT("<tr><td><b>")+_("Min&nbsp;Reached")+wxT("</b></td><td>")+wxString::Format(wxT("%.1fcmH2O"),d->summary_min(CPAP_PressureMinAchieved))+wxT("</td></tr>\n");
html=html+wxT("<tr><td><b>")+_("Max&nbsp;Reached")+wxT("</b></td><td>")+wxString::Format(wxT("%.1fcmH2O"),d->summary_max(CPAP_PressureMaxAchieved))+wxT("</td></tr>\n"); html=html+wxT("<tr><td><b>")+_("Max&nbsp;Reached")+wxT("</b></td><td>")+wxString::Format(wxT("%.1fcmH2O"),d->summary_max(CPAP_PressureMaxAchieved))+wxT("</td></tr>\n");
html=html+wxT("<tr><td><b>")+_("90%&nbsp;Pressure?")+wxT("</b></td><td>")+wxString::Format(wxT("%.1fcmH2O"),d->summary_avg(CPAP_PressurePercentValue))+wxT("</td></tr>\n"); html=html+wxT("<tr><td><b>")+_("90%&nbsp;Pressure")+wxT("</b></td><td>")+wxString::Format(wxT("%.1fcmH2O"),p90)+wxT("</td></tr>\n");
} else if (mode==MODE_BIPAP) { } else if (mode==MODE_BIPAP) {
html=html+wxT("<tr><td><b>")+_("Avg IPAP")+wxT("</b></td><td>")+wxString::Format(wxT("%.2fcmH2O"),d->summary_avg(BIPAP_IAPAverage))+wxT("</td></tr>\n"); html=html+wxT("<tr><td><b>")+_("Avg IPAP")+wxT("</b></td><td>")+wxString::Format(wxT("%.2fcmH2O"),d->summary_avg(BIPAP_IAPAverage))+wxT("</td></tr>\n");
html=html+wxT("<tr><td><b>")+_("Avg EPAP")+wxT("</b></td><td>")+wxString::Format(wxT("%.1fcmH2O"),d->summary_avg(BIPAP_EAPAverage))+wxT("</td></tr>\n"); html=html+wxT("<tr><td><b>")+_("Avg EPAP")+wxT("</b></td><td>")+wxString::Format(wxT("%.1fcmH2O"),d->summary_avg(BIPAP_EAPAverage))+wxT("</td></tr>\n");
@ -645,6 +648,8 @@ void Daily::OnCalendarDay( wxCalendarEvent& event )
html=html+wxT("<tr><td><b>")+_("Max IPAP")+wxT("</b></td><td>")+wxString::Format(wxT("%.1fcmH2O"),d->summary_max(BIPAP_IAPMax))+wxT("</td></tr>\n"); html=html+wxT("<tr><td><b>")+_("Max IPAP")+wxT("</b></td><td>")+wxString::Format(wxT("%.1fcmH2O"),d->summary_max(BIPAP_IAPMax))+wxT("</td></tr>\n");
html=html+wxT("<tr><td><b>")+_("Min EPAP")+wxT("</b></td><td>")+wxString::Format(wxT("%.1fcmH2O"),d->summary_min(BIPAP_EAPMin))+wxT("</td></tr>\n"); html=html+wxT("<tr><td><b>")+_("Min EPAP")+wxT("</b></td><td>")+wxString::Format(wxT("%.1fcmH2O"),d->summary_min(BIPAP_EAPMin))+wxT("</td></tr>\n");
html=html+wxT("<tr><td><b>")+_("Max EPAP")+wxT("</b></td><td>")+wxString::Format(wxT("%.1fcmH2O"),d->summary_max(BIPAP_EAPMax))+wxT("</td></tr>\n"); html=html+wxT("<tr><td><b>")+_("Max EPAP")+wxT("</b></td><td>")+wxString::Format(wxT("%.1fcmH2O"),d->summary_max(BIPAP_EAPMax))+wxT("</td></tr>\n");
html=html+wxT("<tr><td><b>")+_("90%&nbsp;IPAP")+wxT("</b></td><td>")+wxString::Format(wxT("%.1fcmH2O"),iap90)+wxT("</td></tr>\n");
html=html+wxT("<tr><td><b>")+_("90%&nbsp;EPAP")+wxT("</b></td><td>")+wxString::Format(wxT("%.1fcmH2O"),eap90)+wxT("</td></tr>\n");
} }
html=html+wxT("<tr><td><b>")+_("Avg Leak")+wxT("</b></td><td>")+wxString::Format(wxT("%.2f"),d->summary_avg(CPAP_LeakAverage))+wxT("</td></tr>\n"); html=html+wxT("<tr><td><b>")+_("Avg Leak")+wxT("</b></td><td>")+wxString::Format(wxT("%.2f"),d->summary_avg(CPAP_LeakAverage))+wxT("</td></tr>\n");

View File

@ -5,7 +5,7 @@
#include "binary_file.h" #include "binary_file.h"
#include "machine.h" #include "machine.h"
#include "profiles.h" #include "profiles.h"
#include <algorithm>
extern wxProgressDialog *loader_progress; extern wxProgressDialog *loader_progress;
@ -457,6 +457,23 @@ wxTimeSpan Day::total_time()
} }
return d_totaltime; return d_totaltime;
} }
EventDataType Day::percentile(MachineCode code,int field,double percent)
{
double val=0;
// Cache this?
int cnt=0;
// Don't assume sessions are in order.
for (auto s=sessions.begin();s!=sessions.end();s++) {
Session & sess=*(*s);
if (sess.events.find(code)!=sess.events.end()) {
val+=sess.percentile(code,field,percent);
cnt++;
}
}
if (cnt==0) return 0;
return EventDataType(val/cnt);
}
const wxDateTime & Day::first(MachineCode code) const wxDateTime & Day::first(MachineCode code)
{ {
@ -656,6 +673,35 @@ double Session::avg_event_field(MachineCode mc,int field)
return sum/cnt; return sum/cnt;
} }
bool sortfunction (double i,double j) { return (i<j); }
double Session::percentile(MachineCode mc,int field,double percent)
{
if (events.find(mc)==events.end()) return 0;
vector<EventDataType> array;
for (auto e=events[mc].begin(); e!=events[mc].end(); e++) {
Event & ev = *(*e);
array.push_back(ev[0]);
}
std::sort(array.begin(),array.end(),sortfunction);
int size=array.size();
double i=size*percent;
double t;
double q=modf(i,&t);
int j=t;
if (j>=size-1) return array[j];
double a=array[j-1];
double b=array[j];
if (a==b) return a;
double c=(b-a);
double d=c*q;
return array[j]+q;
}
double Session::weighted_avg_event_field(MachineCode mc,int field) double Session::weighted_avg_event_field(MachineCode mc,int field)
{ {
if (events.find(mc)==events.end()) return 0; if (events.find(mc)==events.end()) return 0;
@ -720,6 +766,9 @@ void Session::AddWaveform(Waveform *w)
waveforms[w->code()].push_back(w); waveforms[w->code()].push_back(w);
//wxLogMessage(w->start().Format(wxT("%Y-%m-%d %H:%M:%S"))+wxT(" ")+w->end().Format(wxT("%Y-%m-%d %H:%M:%S"))+wxString::Format(wxT(" %i %.1f"),w->samples(), w->duration())); //wxLogMessage(w->start().Format(wxT("%Y-%m-%d %H:%M:%S"))+wxT(" ")+w->end().Format(wxT("%Y-%m-%d %H:%M:%S"))+wxString::Format(wxT(" %i %.1f"),w->samples(), w->duration()));
// Could parse the flow data for Breaths per minute info here..
} }
void Session::TrashEvents() void Session::TrashEvents()
// Trash this sessions Events and release memory. // Trash this sessions Events and release memory.

View File

@ -39,6 +39,7 @@ wxInt16 {
// General Event Codes // General Event Codes
CPAP_Obstructive=0, CPAP_Hypopnea, CPAP_ClearAirway, CPAP_RERA, CPAP_VSnore, CPAP_FlowLimit, CPAP_Obstructive=0, CPAP_Hypopnea, CPAP_ClearAirway, CPAP_RERA, CPAP_VSnore, CPAP_FlowLimit,
CPAP_Leak, CPAP_Pressure, CPAP_EAP, CPAP_IAP, CPAP_CSR, CPAP_FlowRate, CPAP_Leak, CPAP_Pressure, CPAP_EAP, CPAP_IAP, CPAP_CSR, CPAP_FlowRate,
CPAP_BreathsPerMinute,
// General CPAP Summary Information // General CPAP Summary Information
CPAP_PressureMin=0x80, CPAP_PressureMax, CPAP_RampTime, CPAP_RampStartingPressure, CPAP_Mode, CPAP_PressureReliefType, CPAP_PressureMin=0x80, CPAP_PressureMax, CPAP_RampTime, CPAP_RampStartingPressure, CPAP_Mode, CPAP_PressureReliefType,
@ -95,6 +96,7 @@ public:
EventDataType sum(MachineCode code,int field=0); EventDataType sum(MachineCode code,int field=0);
EventDataType count(MachineCode code); EventDataType count(MachineCode code);
EventDataType weighted_avg(MachineCode code,int field=0); EventDataType weighted_avg(MachineCode code,int field=0);
EventDataType percentile(MachineCode mc,int field,double percent);
// Note, the following convert to doubles without considering the consequences fully. // Note, the following convert to doubles without considering the consequences fully.
EventDataType summary_avg(MachineCode code); EventDataType summary_avg(MachineCode code);
@ -305,6 +307,7 @@ public:
double sum_event_field(MachineCode mc,int field); double sum_event_field(MachineCode mc,int field);
double avg_event_field(MachineCode mc,int field); double avg_event_field(MachineCode mc,int field);
double weighted_avg_event_field(MachineCode mc,int field); double weighted_avg_event_field(MachineCode mc,int field);
double percentile(MachineCode mc,int field,double percentile);
map<MachineCode,wxVariant> summary; map<MachineCode,wxVariant> summary;
void SetChanged(bool val) { void SetChanged(bool val) {

View File

@ -62,7 +62,7 @@ void Profile::ExtraLoad(TiXmlHandle *root)
TiXmlElement *elem; TiXmlElement *elem;
elem=root->FirstChild("Machines").FirstChild().Element(); elem=root->FirstChild("Machines").FirstChild().Element();
if (!elem) { if (!elem) {
wxLogError(wxT("ExtraLoad: Elem is empty!!!")); wxLogDebug(wxT("ExtraLoad: Elem is empty!!!"));
} }
for(; elem; elem=elem->NextSiblingElement()) { for(; elem; elem=elem->NextSiblingElement()) {
wxString pKey(elem->Value(),wxConvUTF8); wxString pKey(elem->Value(),wxConvUTF8);

View File

@ -681,9 +681,11 @@ bool PRS1Loader::OpenWaveforms(Session *session,wxString filename)
SampleFormat min,max; SampleFormat min,max;
bool first=true; bool first=true;
SampleFormat c;
for (long i=0;i<samples;i++) { for (long i=0;i<samples;i++) {
data[i]=buffer[i]; data[i]=buffer[i];
SampleFormat &c=data[i]; c=data[i];
if (first) { if (first) {
min=max=c; min=max=c;
first=false; first=false;
@ -691,10 +693,14 @@ bool PRS1Loader::OpenWaveforms(Session *session,wxString filename)
if (min>c) min=c; if (min>c) min=c;
if (max<c) max=c; if (max<c) max=c;
} }
//wxLogMessage(wxT("Samples Per Breath: ")+wxString::Format(wxT("%.2f"),double(breath_total)/double(breaths)));
Waveform *w=new Waveform(start,CPAP_FlowRate,data,samples,duration,min,max); Waveform *w=new Waveform(start,CPAP_FlowRate,data,samples,duration,min,max);
//wxLogMessage(wxString::Format(wxT("%i %i %i %i %i"),start,samples,duration,min,max)); //wxLogMessage(wxString::Format(wxT("%i %i %i %i %i"),start,samples,duration,min,max));
session->AddWaveform(w); session->AddWaveform(w);
//wxLogMessage(wxT("Done PRS1 Waveforms ")+filename); //wxLogMessage(wxT("Done PRS1 Waveforms ")+filename);
return true; return true;
} }

View File

@ -4,7 +4,7 @@
namespace AutoVersion{ namespace AutoVersion{
//Date Version Types //Date Version Types
static const char DATE[] = "29"; static const char DATE[] = "30";
static const char MONTH[] = "05"; static const char MONTH[] = "05";
static const char YEAR[] = "2011"; static const char YEAR[] = "2011";
static const char UBUNTU_VERSION_STYLE[] = "11.05"; static const char UBUNTU_VERSION_STYLE[] = "11.05";
@ -16,14 +16,14 @@ namespace AutoVersion{
//Standard Version Type //Standard Version Type
static const long MAJOR = 0; static const long MAJOR = 0;
static const long MINOR = 7; static const long MINOR = 7;
static const long BUILD = 1878; static const long BUILD = 1951;
static const long REVISION = 4819; static const long REVISION = 5273;
//Miscellaneous Version Types //Miscellaneous Version Types
static const long BUILDS_COUNT = 6282; static const long BUILDS_COUNT = 6389;
#define RC_FILEVERSION 0,7,1878,4819 #define RC_FILEVERSION 0,7,1951,5273
#define RC_FILEVERSION_STRING "0, 7, 1878, 4819\0" #define RC_FILEVERSION_STRING "0, 7, 1951, 5273\0"
static const char FULLVERSION_STRING[] = "0.7.1878.4819"; static const char FULLVERSION_STRING[] = "0.7.1951.5273";
//These values are to keep track of your versioning state, don't modify them. //These values are to keep track of your versioning state, don't modify them.
static const long BUILD_HISTORY = 62; static const long BUILD_HISTORY = 62;