From 20a5fbd5e26c10819d6bedd6dffca2ab1e941eb5 Mon Sep 17 00:00:00 2001 From: Mark Watkins Date: Sat, 30 Jul 2011 00:58:44 +1000 Subject: [PATCH] Start of Oximetry rework --- Graphs/gLineChart.cpp | 8 +- Graphs/gLineChart.h | 6 +- Graphs/gSegmentChart.cpp | 31 +++- Graphs/gSegmentChart.h | 2 +- Graphs/graphlayer.h | 5 +- Graphs/graphwindow.cpp | 4 +- Graphs/graphwindow.h | 20 +-- SleepLib/day.h | 3 + SleepLib/event.cpp | 5 +- SleepLib/event.h | 7 +- SleepyHeadQT.pro | 18 +- daily.cpp | 41 +++-- daily.h | 14 +- mainwindow.cpp | 10 +- mainwindow.h | 2 +- oximetry.cpp | 360 ++++++++++++++++----------------------- oximetry.h | 24 ++- 17 files changed, 279 insertions(+), 281 deletions(-) diff --git a/Graphs/gLineChart.cpp b/Graphs/gLineChart.cpp index a04c1d5b..bfd9a7ec 100644 --- a/Graphs/gLineChart.cpp +++ b/Graphs/gLineChart.cpp @@ -11,8 +11,8 @@ #include "gLineChart.h" #define EXTRA_ASSERTS 1 -gLineChart::gLineChart(MachineCode code,QColor col,bool _square_plot) -:gLayer(code),m_square_plot(_square_plot) +gLineChart::gLineChart(MachineCode code,QColor col,bool square_plot, bool disable_accel) +:gLayer(code),m_square_plot(square_plot),m_disable_accel(disable_accel) { color.clear(); color.push_back(col); @@ -135,7 +135,8 @@ void gLineChart::Plot(gGraphWindow & w,float scrx,float scry) for (unsigned n=0;n500) { // Don't square plot if too many points or waveform @@ -166,7 +167,6 @@ void gLineChart::Plot(gGraphWindow & w,float scrx,float scry) //assert(x1last(); return m_maxx; } virtual EventDataType Miny() { return m_miny; } virtual EventDataType Maxy() { return m_maxy; } - + virtual void setMinY(EventDataType val) { m_miny=val; } + virtual void setMaxY(EventDataType val) { m_maxy=val; } + virtual void setMinX(qint64 val) { m_minx=val; } + virtual void setMaxX(qint64 val) { m_maxx=val; } virtual void setVisible(bool v) { m_visible=v; } virtual bool isVisible() { return m_visible; } virtual bool isEmpty(); diff --git a/Graphs/graphwindow.cpp b/Graphs/graphwindow.cpp index a93aca3a..beb39181 100644 --- a/Graphs/graphwindow.cpp +++ b/Graphs/graphwindow.cpp @@ -45,7 +45,7 @@ gGraphWindow::gGraphWindow(QWidget *parent, const QString & title, QGLWidget * s min_x=max_x=0; } -gGraphWindow::gGraphWindow(QWidget *parent, const QString & title, QGLContext * context,Qt::WindowFlags f) +/*gGraphWindow::gGraphWindow(QWidget *parent, const QString & title, QGLContext * context,Qt::WindowFlags f) : QGLWidget((QGLContext *)context, parent, 0, f ) { gl_context=context; @@ -69,7 +69,7 @@ gGraphWindow::gGraphWindow(QWidget *parent, const QString & title, QGLContext * //setAcceptDrops(true); setMouseTracking(true); setFocusPolicy(Qt::StrongFocus); -} +}*/ gGraphWindow::~gGraphWindow() { diff --git a/Graphs/graphwindow.h b/Graphs/graphwindow.h index a94e7f08..342adc93 100644 --- a/Graphs/graphwindow.h +++ b/Graphs/graphwindow.h @@ -1,8 +1,8 @@ -/******************************************************************** +/* gGraphWindow Headers Copyright (c)2011 Mark Watkins License: GPL -*********************************************************************/ +*/ #ifndef GRAPHWINDOW_H #define GRAPHWINDOW_H @@ -26,7 +26,7 @@ class gGraphWindow : public QGLWidget { Q_OBJECT public: - explicit gGraphWindow(QWidget *parent, const QString & title, QGLContext * context,Qt::WindowFlags f=0); + //explicit gGraphWindow(QWidget *parent, const QString & title, QGLContext * context,Qt::WindowFlags f=0); explicit gGraphWindow(QWidget *parent, const QString & title, QGLWidget * shared,Qt::WindowFlags f=0); virtual ~gGraphWindow(); @@ -72,18 +72,12 @@ public: inline int Height() { return m_scrY-m_marginTop-m_marginBottom; } // Height of ""... void LinkZoom(gGraphWindow *g) { link_zoom.push_back(g); } // Linking graphs changes zoom behaviour.. - //void LinkMove(gGraphWindow *g) { link_move.push_back(g); } // Linking graphs changes zoom behaviour.. virtual qint64 MinX(); virtual qint64 MaxX(); virtual EventDataType MinY(); virtual EventDataType MaxY(); - /* virtual double RealMinX(); - virtual double RealMaxX(); - virtual double RealMinY(); - virtual double RealMaxY();*/ - virtual void SetMinX(qint64 v); virtual void SetMaxX(qint64 v); virtual void SetMinY(EventDataType v); @@ -125,20 +119,14 @@ public: void Render(int scrx,int scry); - //virtual void Update(); - //virtual void Update(); void AddLayer(gLayer *l); - //virtual void DataChanged(gLayer *layer); - qint64 max_x,min_x,max_y,min_y; qint64 rmax_x,rmin_x,rmax_y,rmin_y; void SetBlockZoom(bool b) { m_block_zoom=b; } - //void SetBlockMove(bool b) { m_block_move=b; } bool BlockZoom() { return m_block_zoom; } QGLContext *gl_context; - //FTFont *texfont; void SetGradientBackground(bool b) { m_gradient_background=b; } bool GradientBackground() { return m_gradient_background; } bool isEmpty(); @@ -150,9 +138,7 @@ public: void initializeGL(); QSplitter *splitter; listlink_zoom; - //listlink_move; - //bool m_block_move; bool m_block_zoom; bool m_drag_foobar; bool m_dragGraph; diff --git a/SleepLib/day.h b/SleepLib/day.h index 3591f7d5..ba13551c 100644 --- a/SleepLib/day.h +++ b/SleepLib/day.h @@ -41,6 +41,8 @@ public: qint64 first() { return d_first; } qint64 last() { return d_last; } + void setFirst(qint64 val) { d_first=val; } + void setLast(qint64 val) { d_last=val; } qint64 first(MachineCode code); qint64 last(MachineCode code); EventDataType min(MachineCode code); @@ -60,6 +62,7 @@ public: Machine *machine; void OpenEvents(); + vector & getSessions() { return sessions; } protected: vector sessions; diff --git a/SleepLib/event.cpp b/SleepLib/event.cpp index 458ee56c..19b35f6d 100644 --- a/SleepLib/event.cpp +++ b/SleepLib/event.cpp @@ -1,8 +1,8 @@ -/******************************************************************** +/* SleepLib Event Class Implementation Copyright (c)2011 Mark Watkins License: GPL -*********************************************************************/ +*/ #include #include "event.h" @@ -73,7 +73,6 @@ void EventList::AddWaveform(qint64 start, qint16 * data, int recs, qint64 durati qWarning() << "Attempted to add waveform without setting sample rate"; return; } - // duration=recs*rate; qint64 last=start+duration; if (!m_first) { m_first=start; diff --git a/SleepLib/event.h b/SleepLib/event.h index 5c4d999d..4352c974 100644 --- a/SleepLib/event.h +++ b/SleepLib/event.h @@ -27,6 +27,8 @@ public: void AddWaveform(qint64 start, char * data, int recs, qint64 duration); inline const int & count() { return m_count; } + void setCount(int count) { m_count=count; } + inline EventStoreType raw(int i) { return m_data[i]; } EventDataType data(int i); @@ -34,6 +36,8 @@ public: inline const qint64 & first() { return m_first; } inline const qint64 & last() { return m_last; } inline qint64 duration() { return m_last-m_first; } + void setFirst(qint64 val) { m_first=val; } + void setLast(qint64 val) { m_last=val; } void setGain(EventDataType v) { m_gain=v; } void setOffset(EventDataType v) { m_offset=v; } @@ -48,10 +52,11 @@ public: inline const EventListType & type() { return m_type; } inline const MachineCode & code() { return m_code; } inline const bool & update_minmax() { return m_update_minmax; } + vector & getData() { return m_data; } vector & getTime() { return m_time; } protected: - vector m_time; + vector m_time; // 32bitalize this.. add offsets to m_first vector m_data; MachineCode m_code; EventListType m_type; diff --git a/SleepyHeadQT.pro b/SleepyHeadQT.pro index 3d644cb5..1881fa4f 100644 --- a/SleepyHeadQT.pro +++ b/SleepyHeadQT.pro @@ -31,7 +31,10 @@ SOURCES += main.cpp\ SleepLib/loader_plugins/cms50_loader.cpp \ SleepLib/loader_plugins/prs1_loader.cpp \ SleepLib/loader_plugins/zeo_loader.cpp \ + SleepLib/loader_plugins/resmed_loader.cpp \ + SleepLib/loader_plugins/sleep_database.cpp \ daily.cpp \ + oximetry.cpp \ overview.cpp \ mainwindow.cpp \ SleepLib/event.cpp \ @@ -51,12 +54,9 @@ SOURCES += main.cpp\ Graphs/gTitle.cpp \ Graphs/gCandleStick.cpp \ Graphs/gBarChart.cpp \ - SleepLib/loader_plugins/resmed_loader.cpp \ - SleepLib/loader_plugins/sleep_database.cpp \ + Graphs/gSegmentChart.cpp \ Graphs/gSessionTime.cpp \ - qextserialport/qextserialport.cpp \ - oximetry.cpp \ - Graphs/gSegmentChart.cpp + qextserialport/qextserialport.cpp unix:SOURCES += qextserialport/posix_qextserialport.cpp unix:!macx:SOURCES += qextserialport/qextserialenumerator_unix.cpp @@ -80,6 +80,7 @@ HEADERS += \ SleepLib/loader_plugins/cms50_loader.h \ SleepLib/loader_plugins/prs1_loader.h \ SleepLib/loader_plugins/zeo_loader.h \ + oximetry.h \ daily.h \ overview.h \ mainwindow.h \ @@ -99,14 +100,13 @@ HEADERS += \ Graphs/gTitle.h \ Graphs/gCandleStick.h \ Graphs/gBarChart.h \ + Graphs/gSegmentChart.h\ + Graphs/gSessionTime.h \ SleepLib/loader_plugins/resmed_loader.h \ SleepLib/loader_plugins/sleep_database.h \ - Graphs/gSessionTime.h \ qextserialport/qextserialport_global.h \ qextserialport/qextserialport.h \ - qextserialport/qextserialenumerator.h \ - oximetry.h \ - Graphs/gSegmentChart.h + qextserialport/qextserialenumerator.h FORMS += \ diff --git a/daily.cpp b/daily.cpp index 4a80d6be..f14c0449 100644 --- a/daily.cpp +++ b/daily.cpp @@ -29,6 +29,16 @@ const int min_height=100; const int default_height=150; +MyScrollArea::MyScrollArea(Daily * parent) +{ +} +MyScrollArea::~MyScrollArea() +{ +} +void MyScrollArea::scrollContentsBy(int dx, int dy) +{ +} + Daily::Daily(QWidget *parent,QGLWidget * shared) : QWidget(parent), ui(new Ui::Daily) @@ -42,12 +52,15 @@ Daily::Daily(QWidget *parent,QGLWidget * shared) : exit(-1); } + //scrollArea=new MyScrollArea(this); + gSplitter=new QSplitter(Qt::Vertical,ui->scrollArea); gSplitter->setStyleSheet("QSplitter::handle { background-color: 'light grey'; }"); gSplitter->setHandleWidth(3); ui->scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn); ui->scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); ui->scrollArea->setWidget(gSplitter); + //this->connect(ui->scrollArea, //ui->graphSizer->addWidget(gSplitter); ui->scrollArea->setAutoFillBackground(false); gSplitter->setAutoFillBackground(false); @@ -196,26 +209,32 @@ Daily::Daily(QWidget *parent,QGLWidget * shared) : // SPO2->hide(); PULSE->hide(); + gSegmentChart *seg; + TAP_EAP->SetMargins(0,0,0,0); - TAP_EAP->AddLayer(AddCPAP(new gTAPGraph(CPAP_EAP))); + TAP_EAP->AddLayer(AddCPAP(seg=new gTAPGraph(CPAP_EAP))); + TAP_EAP->hide(); + TAP_EAP->SetGradientBackground(false); TAP_IAP->SetMargins(0,0,0,0); - TAP_IAP->AddLayer(AddCPAP(new gTAPGraph(CPAP_IAP))); + TAP_IAP->AddLayer(AddCPAP(seg=new gTAPGraph(CPAP_IAP))); TAP_IAP->hide(); + TAP_IAP->SetGradientBackground(false); TAP->SetMargins(0,0,0,0); - TAP->AddLayer(AddCPAP(new gTAPGraph(CPAP_Pressure))); + TAP->AddLayer(AddCPAP(seg=new gTAPGraph(CPAP_Pressure,GST_Line))); TAP->hide(); + TAP->SetGradientBackground(false); G_AHI->SetMargins(0,0,0,0); - gSegmentChart *l=new gSegmentChart(GST_Pie); - l->AddSlice(CPAP_Hypopnea,QColor(0x40,0x40,0xff,0xff),"H"); - l->AddSlice(CPAP_Obstructive,QColor(0x40,0xaf,0xbf,0xff),"OA"); - l->AddSlice(CPAP_ClearAirway,QColor(0xb2,0x54,0xcd,0xff),"CA"); - l->AddSlice(CPAP_RERA,QColor(0xff,0xff,0x80,0xff),"RE"); - l->AddSlice(CPAP_FlowLimit,QColor(0x40,0x40,0x40,0xff),"FL"); - G_AHI->AddLayer(AddCPAP(l)); + seg=new gSegmentChart(GST_Pie); + seg->AddSlice(CPAP_Hypopnea,QColor(0x40,0x40,0xff,0xff),"H"); + seg->AddSlice(CPAP_Obstructive,QColor(0x40,0xaf,0xbf,0xff),"OA"); + seg->AddSlice(CPAP_ClearAirway,QColor(0xb2,0x54,0xcd,0xff),"CA"); + seg->AddSlice(CPAP_RERA,QColor(0xff,0xff,0x80,0xff),"RE"); + seg->AddSlice(CPAP_FlowLimit,QColor(0x40,0x40,0x40,0xff),"FL"); + G_AHI->AddLayer(AddCPAP(seg)); G_AHI->SetGradientBackground(false); G_AHI->hide(); @@ -449,7 +468,7 @@ void Daily::Load(QDate date) "\n"; QString tmp; const int gwwidth=240; - const int gwheight=25; + const int gwheight=100; UpdateOXIGraphs(oxi); UpdateCPAPGraphs(cpap); UpdateEventsTree(ui->treeWidget,cpap); diff --git a/daily.h b/daily.h index 49f28ad7..7fc6158e 100644 --- a/daily.h +++ b/daily.h @@ -24,6 +24,18 @@ namespace Ui { class Daily; } +class Daily; +class MyScrollArea:public QScrollArea +{ +public: + MyScrollArea(Daily * parent); + virtual ~MyScrollArea(); +protected: + virtual void scrollContentsBy(int dx, int dy); + Daily *daily; +}; + + class Daily : public QWidget { Q_OBJECT @@ -83,7 +95,7 @@ private: Ui::Daily *ui; Profile *profile; QDate previous_date; - QScrollArea *scrollArea; + MyScrollArea *scrollArea; QSplitter *gSplitter; QLabel *NoData; QWidget *spacer; diff --git a/mainwindow.cpp b/mainwindow.cpp index 8109aa49..3091fe91 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -19,8 +19,6 @@ #include "SleepLib/loader_plugins/resmed_loader.h" -#include "daily.h" -#include "overview.h" #include "Graphs/glcommon.h" QProgressBar *qprogress; @@ -119,8 +117,8 @@ MainWindow::MainWindow(QWidget *parent) : //overview=new Overview(ui->tabWidget,daily->SharedWidget()); //ui->tabWidget->insertTab(2,overview,tr("Overview")); - //oximetry=new Oximetry(ui->tabWidget,daily->SharedWidget()); - //ui->tabWidget->insertTab(3,oximetry,tr("Oximetry")); + oximetry=new Oximetry(ui->tabWidget,daily->SharedWidget()); + ui->tabWidget->insertTab(3,oximetry,tr("Oximetry")); ui->tabWidget->setCurrentWidget(ui->welcome); @@ -135,11 +133,11 @@ MainWindow::~MainWindow() /*if (overview) { overview->close(); delete overview; - } + } */ if (oximetry) { oximetry->close(); delete oximetry; - }*/ + } DoneGraphs(); Profiles::Done(); mainwin=NULL; diff --git a/mainwindow.h b/mainwindow.h index ac0640d2..01968a32 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -82,7 +82,7 @@ private: Ui::MainWindow *ui; Daily * daily; //Overview * overview; - //Oximetry * oximetry; + Oximetry * oximetry; bool first_load; Profile *profile; }; diff --git a/oximetry.cpp b/oximetry.cpp index 93593452..dcd1599f 100644 --- a/oximetry.cpp +++ b/oximetry.cpp @@ -2,10 +2,11 @@ #include #include -/*#include "oximetry.h" +#include "oximetry.h" #include "ui_oximetry.h" #include "qextserialport/qextserialenumerator.h" #include "SleepLib/loader_plugins/cms50_loader.h" +#include "SleepLib/event.h" #include "Graphs/gXAxis.h" #include "Graphs/gBarChart.h" #include "Graphs/gLineChart.h" @@ -23,34 +24,48 @@ Oximetry::Oximetry(QWidget *parent,QGLWidget * shared) : profile=Profiles::Get(prof); if (!profile) { qWarning("Couldn't get profile.. Have to abort!"); - abort(); + exit(-1); } + mach=profile->GetMachine(MT_OXIMETER); + if (!mach) { + CMS50Loader *l=dynamic_cast(GetLoader("CMS50")); + if (l) { + mach=l->CreateMachine(profile); + } + qDebug() << "Create Oximeter device"; + } + + // Create dummy day & session for holding eventlists. + day=new Day(mach); + session=new Session(mach,0); + day->AddSession(session); gSplitter=new QSplitter(Qt::Vertical,ui->scrollArea); gSplitter->setStyleSheet("QSplitter::handle { background-color: 'dark grey'; }"); gSplitter->setHandleWidth(2); ui->graphLayout->addWidget(gSplitter); - AddData(plethy=new WaveData(OXI_Plethy)); + // Create the Event Lists to store / import data + ev_plethy=new EventList(OXI_Plethy,EVL_Event,1,0,0,0,1000.0/50.0); + session->eventlist[OXI_Plethy].push_back(ev_plethy); + + ev_pulse=new EventList(OXI_Pulse,EVL_Event,1); + session->eventlist[OXI_Pulse].push_back(ev_pulse); + + ev_spo2=new EventList(OXI_SPO2,EVL_Event,1); + session->eventlist[OXI_SPO2].push_back(ev_spo2); + + plethy=new gLineChart(OXI_Plethy,Qt::black,false,true); AddGraph(PLETHY=new gGraphWindow(gSplitter,tr("Plethysomogram"),shared)); + plethy->SetDay(day); - AddData(pulse=new EventData(OXI_Pulse)); - AddGraph(PULSE=new gGraphWindow(gSplitter,tr("Pulse Rate"),PLETHY)); + pulse=new gLineChart(OXI_Pulse,Qt::red,true); + AddGraph(PULSE=new gGraphWindow(gSplitter,tr("Pulse Rate"),shared)); + pulse->SetDay(day); - AddData(spo2=new EventData(OXI_SPO2)); - AddGraph(SPO2=new gGraphWindow(gSplitter,tr("SPO2"),PLETHY)); - - plethy->SetRealMaxY(128); - pulse->SetRealMaxY(130); - spo2->SetRealMaxY(100); - - for (unsigned i=0;iAddSegment(1000000); - Data[i]->np.push_back(0); - Data[i]->SetRealMinY(0); - Data[i]->SetMinY(0); - Data[i]->SetMaxY(Data[i]->RealMaxY()); - } + spo2=new gLineChart(OXI_SPO2,Qt::blue,true); + AddGraph(SPO2=new gGraphWindow(gSplitter,tr("SPO2"),shared)); + spo2->SetDay(day); for (unsigned i=0;iaddWidget(Graphs[i]); } - SPO2->AddLayer(new gLineChart(spo2,Qt::blue,65536,false,false,false)); - PULSE->AddLayer(new gLineChart(pulse,Qt::red,65536,false,false,false)); - PLETHY->AddLayer(new gLineChart(plethy,Qt::black,65536,true,false,false)); + PLETHY->AddLayer(plethy); + PULSE->AddLayer(pulse); + SPO2->AddLayer(spo2); for (unsigned i=0;isetMinimumHeight(150); Graphs[i]->SetSplitter(gSplitter); - Graphs[i]->RealMinY(); - Graphs[i]->RealMaxY(); - Graphs[i]->MinY(); - Graphs[i]->MaxY(); } on_RefreshPortsButton_clicked(); @@ -92,6 +103,8 @@ void Oximetry::on_RefreshPortsButton_clicked() int z=0; QString firstport; bool current_found=false; + + // Windows build mixes these up #ifdef Q_WS_WIN32 #define qesPORTNAME portName #else @@ -131,46 +144,40 @@ void Oximetry::on_RunButton_toggled(bool checked) lasttime=0; lastpulse=-1; lastspo2=-1; - plethy->np[0]=0; + + // Wipe any current data + ev_plethy->getData().clear(); + ev_plethy->getTime().clear(); + ev_plethy->setCount(0); + ev_pulse->getData().clear(); + ev_pulse->getTime().clear(); + ev_pulse->setCount(0); + ev_spo2->getData().clear(); + ev_spo2->getTime().clear(); + ev_spo2->setCount(0); + lasttime=QDateTime::currentMSecsSinceEpoch(); starttime=lasttime; - plethy->SetRealMinX(double(lasttime)/86400000.0); - plethy->SetRealMaxX(double(lasttime+60000)/86400000.0); - plethy->SetMinX(double(lasttime)/86400000.0); - plethy->SetMaxX(double(lasttime+30000)/86400000.0); - PLETHY->RealMinX(); - PLETHY->RealMaxX(); - PLETHY->MinX(); - PLETHY->MaxX(); - plethy->SetReady(true); - plethy->SetVC(1); - plethy->np[0]=0; + day->setFirst(lasttime); + day->setLast(lasttime+30000); + session->set_first(lasttime); + session->set_last(lasttime+30000); + ev_plethy->setFirst(lasttime); + ev_plethy->setLast(lasttime+3600000); + PLETHY->SetMinX(lasttime); + PLETHY->SetMaxX(lasttime+30000); - pulse->SetRealMinX(double(lasttime)/86400000.0); - pulse->SetRealMaxX(double(lasttime)/86400000.0+(1.0/24.0)); - pulse->SetMinX(double(lasttime)/86400000.0); - pulse->SetMaxX(double(lasttime)/86400000.0+(1.0/24.0)); - pulse->np[0]=0; - pulse->SetReady(true); - pulse->SetVC(1); - PULSE->RealMinX(); - PULSE->RealMaxX(); - PULSE->MinX(); - PULSE->MaxX(); + ev_pulse->setFirst(lasttime); + ev_pulse->setLast(lasttime+3600000); + PULSE->SetMinX(lasttime); + PULSE->SetMaxX(lasttime+30000); - spo2->SetRealMinX(double(lasttime)/86400000.0); - spo2->SetRealMaxX(double(lasttime)/86400000.0+(1.0/24.0)); - spo2->SetMinX(double(lasttime)/86400000.0); - spo2->SetMaxX(double(lasttime)/86400000.0+(1.0/24.0)); - spo2->np[0]=0; - spo2->SetReady(true); - spo2->SetVC(1); - SPO2->RealMinX(); - SPO2->RealMaxX(); - SPO2->MinX(); - SPO2->MaxX(); + ev_spo2->setFirst(lasttime); + ev_spo2->setLast(lasttime+3600000); + SPO2->SetMinX(lasttime); + SPO2->SetMaxX(lasttime+30000); ui->RunButton->setText("&Stop"); ui->SerialPortsCombo->setEnabled(false); @@ -198,29 +205,18 @@ void Oximetry::on_RunButton_toggled(bool checked) delete port; port=NULL; - spo2->point[0][spo2->np[0]].setX(lasttime/86400000.0); - spo2->point[0][spo2->np[0]++].setY(lastspo2); - pulse->point[0][pulse->np[0]].setX(lasttime/86400000.0); - pulse->point[0][pulse->np[0]++].setY(lastpulse); - - pulse->SetRealMaxX(plethy->RealMaxX()); - spo2->SetRealMaxX(plethy->RealMaxX()); - - spo2->SetMinX(plethy->RealMinX()); - spo2->SetMaxX(plethy->RealMaxX()); - pulse->SetMinX(plethy->RealMinX()); - pulse->SetMaxX(plethy->RealMaxX()); - plethy->SetMinX(plethy->RealMinX()); - - PULSE->RealMaxX(); - PULSE->MaxX(); - PULSE->MinX(); - SPO2->RealMaxX(); - SPO2->MaxX(); - SPO2->MinX(); - PLETHY->MinX(); - PLETHY->MaxX(); + ev_spo2->setLast(lasttime); + ev_pulse->setLast(lasttime); + ev_plethy->setLast(lasttime); + day->setLast(lasttime); + session->set_last(lasttime); + SPO2->SetMinX(ev_spo2->first()); + SPO2->SetMaxX(lasttime); + PULSE->SetMinX(ev_pulse->first()); + PULSE->SetMaxX(lasttime); + PLETHY->SetMinX(ev_plethy->first()); + PLETHY->SetMaxX(lasttime); PLETHY->updateGL(); SPO2->updateGL(); @@ -234,31 +230,40 @@ void Oximetry::on_SerialPortsCombo_activated(const QString &arg1) } void Oximetry::UpdatePlethy(qint8 d) { - plethy->point[0][plethy->np[0]].setX(double(lasttime)/86400000.0); - plethy->point[0][plethy->np[0]++].setY(d); - lasttime+=20; // 50 samples per second? - plethy->SetRealMaxX(lasttime/86400000.0); - if (plethy->RealMaxX()-plethy->RealMinX()>(1.0/(24.0*120.0))) { - plethy->SetMinX(lasttime/86400000.0-(1.0/(24.0*120.0))); - plethy->SetMaxX(lasttime/86400000.0); + ev_plethy->AddEvent(lasttime,d); + lasttime+=20; // 50 samples per second + //ev_plethy->setLast(lasttime); + //if (plethy->RealMaxX()-plethy->RealMinX()>(1.0/(24.0*120.0))) { + // plethy->SetMinX(lasttime/86400000.0-(1.0/(24.0*120.0))); + // plethy->SetMaxX(lasttime/86400000.0); + //} + + if (d==55) { + int i=0; } + //plethy->setMinY(ev_plethy->min()); + //plethy->setMaxY(ev_plethy->max()); + //plethy->setMinY(ev_plethy->min()); + //plethy->setMaxY(ev_plethy->max()); PLETHY->MinX(); PLETHY->MaxX(); - PLETHY->RealMaxX(); - pulse->SetRealMaxX(PLETHY->RealMaxX()); - spo2->SetRealMaxX(PLETHY->RealMaxX()); - PULSE->SetMinX(PLETHY->MinX()); - SPO2->SetMinX(PLETHY->MinX()); - PULSE->SetMaxX(PLETHY->MaxX()); - SPO2->SetMaxX(PLETHY->MaxX()); - if (plethy->np[0]>max_data_points) { - //TODO: Stop Serial recording.. - - // for now overwrite.. - plethy->np[0]=0; - lasttime=0; - } - //PLETHY->updateGL(); // Move this to a timer. + //PLETHY->MinY(); + //PLETHY->MaxY(); + PLETHY->SetMinY(ev_plethy->min()); + PLETHY->SetMaxY(ev_plethy->max()); + PULSE->SetMinY(ev_pulse->min()); + PULSE->SetMaxY(ev_pulse->max()); + SPO2->SetMinY(ev_spo2->min()); + SPO2->SetMaxY(ev_spo2->max()); + //PLETHY->MaxY(); + PLETHY->SetMaxX(lasttime); + PLETHY->SetMinX(lasttime-30000); + PULSE->SetMaxX(lasttime); + PULSE->SetMinX(lasttime-30000); + SPO2->SetMaxX(lasttime); + SPO2->SetMinX(lasttime-30000); + session->set_last(lasttime); + day->setLast(lasttime); } bool Oximetry::UpdatePulse(qint8 pul) { @@ -268,35 +273,7 @@ bool Oximetry::UpdatePulse(qint8 pul) // Can make the graph can skip them. if (lastpulse!=pul) { - pulse->point[0][pulse->np[0]].setX(double(lasttime)/86400000.0); - pulse->point[0][pulse->np[0]++].setY(pul); - if (pul!=0) { - if (pulse->MinY()==0) { - pulse->SetMinY((pul/10) * 10); - pulse->SetMaxY((pul/10+1) * 10); - PULSE->MinY(); - PULSE->MaxY(); - } else { - if (pulMinY()) { - pulse->SetMinY((pul/10) * 10); - PULSE->MinY(); - } - if (pul>pulse->MaxY()) { - pulse->SetMaxY((pul/10+1) * 10); - PULSE->MaxY(); - } - - } - } - - // PULSE->updateGL(); - if (pulse->np[0]>max_data_points) { - //TODO: Stop Serial recording.. - - // for now overwrite.. - pulse->np[0]=0; - lasttime=0; - } + ev_pulse->AddEvent(lasttime,pul); ret=true; //qDebug() << "Pulse=" << int(bytes[0]); } @@ -309,36 +286,7 @@ bool Oximetry::UpdateSPO2(qint8 sp) if (lastspo2!=sp) { - spo2->point[0][spo2->np[0]].setX(double(lasttime)/86400000.0); - spo2->point[0][spo2->np[0]++].setY(sp); - - if (sp!=0) { - if (spo2->MinY()==0) { - spo2->SetMinY((sp/10) * 10); - spo2->SetMaxY((sp/10+1) * 10); - SPO2->MinY(); - SPO2->MaxY(); - } else { - if (spMinY()) { - spo2->SetMinY((sp/10) * 10); - SPO2->MinY(); - } - if (sp>spo2->MaxY()) { - spo2->SetMaxY((sp/10+1) * 10); - SPO2->MaxY(); - } - - } - } - - //SPO2->updateGL(); - if (spo2->np[0]>max_data_points) { - //TODO: Stop Serial recording.. - - // for now overwrite.. - spo2->np[0]=0; - lasttime=0; - } + ev_spo2->AddEvent(lasttime,sp); ret=true; //qDebug() << "SpO2=" << int(bytes[1]); } @@ -361,6 +309,7 @@ void Oximetry::onReadyRead() if (bytes[i]&0x80) { EventDataType d=bytes[i+1] & 0x7f; UpdatePlethy(d); + //qDebug() << d; i+=3; } else { if (UpdatePulse(bytes[i])) redraw_pulse=true; @@ -374,27 +323,15 @@ void Oximetry::onReadyRead() if (redraw_spo2) SPO2->updateGL(); - //if (bytes.size()==3) { - //} else if (bytes.size()==2) { // Data bytes in live mode - // Plethy data - //} else { - //qDebug() << "Got " << bytes.size() << " bytes"; - //} - //QString aa=QString::number(bytes.size(),16)+"bytes: "; - //for (int i=0;iGetMachine(MT_OXIMETER); - if (!mach) { - CMS50Loader *l=dynamic_cast(GetLoader("CMS50")); - if (l) { - mach=l->CreateMachine(profile); - } - - qDebug() << "Needed to create Oximeter device"; - } const int rb_size=0x200; static unsigned char b1[2]={0xf5,0xf5}; static unsigned char b2[3]={0xf6,0xf6,0xf6}; static unsigned char rb[rb_size]; - //b1[0]=0xf5; - //b1[1]=0xf5; - //b2[0]=0xf6; - //b2[1]=0xf6; - //b2[2]=0xf6; + unsigned char * buffer=NULL; ui->SerialPortsCombo->setEnabled(false); ui->RunButton->setText("&Start"); ui->RunButton->setChecked(false); - // port->write((char *)b1,2); - // return; if (port) { port->close(); delete port; @@ -565,14 +487,16 @@ void Oximetry::on_ImportButton_clicked() QDateTime date=QDateTime::currentDateTimeUtc(); SessionID sid=date.toTime_t(); - Session *sess=new Session(mach,sid); + session->SetSessionID(sid); qDebug() << "Read " << bytes << "Bytes"; qDebug() << "Creating session " << sid; char pulse,spo2,lastpulse=-1,lastspo2=-1; qint64 tt=sid-(bytes/3); tt*=1000; - sess->set_first(tt); + session->set_first(tt); + ev_pulse->setFirst(tt); + ev_spo2->setFirst(tt); EventDataType data; unsigned i=0; while (iAddEvent(new Event(tt,OXI_Pulse,0,&data,1)); + ev_pulse->AddEvent(tt,data); //qDebug() << "Pulse: " << int(pulse); } if (spo2 != 0 && spo2!=lastspo2) { data=spo2; - sess->AddEvent(new Event(tt,OXI_SPO2,0,&data,1)); + ev_spo2->AddEvent(tt,data); //qDebug() << "SpO2: " << int(spo2); } @@ -597,22 +521,38 @@ void Oximetry::on_ImportButton_clicked() lastspo2=spo2; tt+=1000; } - data=pulse; - sess->AddEvent(new Event(tt,OXI_Pulse,0,&data,1)); - data=spo2; - sess->AddEvent(new Event(tt,OXI_SPO2,0,&data,1)); - sess->summary[OXI_PulseMin]=sess->min_event_field(OXI_Pulse,0); - sess->summary[OXI_PulseMax]=sess->max_event_field(OXI_Pulse,0); - sess->summary[OXI_PulseAverage]=sess->weighted_avg_event_field(OXI_Pulse,0); - sess->summary[OXI_SPO2Min]=sess->min_event_field(OXI_SPO2,0); - sess->summary[OXI_SPO2Max]=sess->max_event_field(OXI_SPO2,0); - sess->summary[OXI_SPO2Average]=sess->weighted_avg_event_field(OXI_SPO2,0); - sess->SetChanged(true); - mach->AddSession(sess,profile); + ev_pulse->AddEvent(tt,pulse); + ev_spo2->AddEvent(tt,spo2); + + session->summary[OXI_PulseMin]=ev_pulse->min(); + session->summary[OXI_PulseMax]=ev_pulse->max(); + session->summary[OXI_PulseAverage]=session->weighted_avg(OXI_Pulse); + + session->summary[OXI_SPO2Min]=ev_spo2->min(); + session->summary[OXI_SPO2Max]=ev_spo2->max(); + session->summary[OXI_SPO2Average]=session->weighted_avg(OXI_SPO2); + + session->SetChanged(true); + mach->AddSession(session,profile); mach->Save(); // Output Pulse & SPO2 here.. delete [] buffer; port->write((char *)b2,3); + + // Need to create a new session as this one got pinched. + session=new Session(mach,0); + day->getSessions().clear(); + day->AddSession(session); + + // As did these + ev_plethy=new EventList(OXI_Plethy,EVL_Waveform,1,0,0,0,1.0/50.0); + session->eventlist[OXI_Plethy].push_back(ev_plethy); + + ev_pulse=new EventList(OXI_Pulse,EVL_Event,1); + session->eventlist[OXI_Pulse].push_back(ev_pulse); + + ev_spo2=new EventList(OXI_SPO2,EVL_Event,1); + session->eventlist[OXI_SPO2].push_back(ev_spo2); } delete port; port=NULL; @@ -621,4 +561,4 @@ void Oximetry::on_ImportButton_clicked() ui->SerialPortsCombo->setEnabled(true); qstatus->setText("Ready"); } -*/ + diff --git a/oximetry.h b/oximetry.h index 1d981409..91fe9a87 100644 --- a/oximetry.h +++ b/oximetry.h @@ -1,6 +1,6 @@ #ifndef OXIMETRY_H #define OXIMETRY_H -/* + #include #include @@ -8,8 +8,11 @@ #include #include "SleepLib/profiles.h" +#include "SleepLib/day.h" +#include "SleepLib/session.h" + #include "Graphs/graphwindow.h" -#include "Graphs/graphdata_custom.h" +#include "Graphs/gLineChart.h" namespace Ui { class Oximetry; @@ -26,13 +29,11 @@ public: explicit Oximetry(QWidget *parent,QGLWidget * shared=NULL); ~Oximetry(); - void AddData(gPointData *d) { Data.push_back(d); } void AddGraph(gGraphWindow *w) { Graphs.push_back(w); } void RedrawGraphs(); private slots: void on_RefreshPortsButton_clicked(); - void on_RunButton_toggled(bool checked); void on_SerialPortsCombo_activated(const QString &arg1); @@ -46,20 +47,27 @@ private: bool UpdateSPO2(qint8 spo2); void UpdatePlethy(qint8 plethy); - Ui::Oximetry *ui; Profile *profile; QSplitter *gSplitter; - gPointData *pulse,*spo2,*plethy; + gLineChart *pulse,*spo2,*plethy; gGraphWindow *PULSE,*SPO2,*PLETHY; + vector Graphs; - vector Data; + vector Data; + QextSerialPort *port; QString portname; PORTMODE portmode; qint64 lasttime,starttime; int lastpulse, lastspo2; + Machine * mach; + Day * day; + Session * session; + EventList * ev_pulse; + EventList * ev_spo2; + EventList * ev_plethy; }; -*/ + #endif // OXIMETRY_H