Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Class Members | File Members

MonitorDataset.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   SpikeStream Application                                               *
00003  *   Copyright (C) 2007 by David Gamez                                     *
00004  *   david@davidgamez.eu                                                   *
00005  *   Version 0.1                                                           *
00006  *                                                                         *
00007  *   This program is free software; you can redistribute it and/or modify  *
00008  *   it under the terms of the GNU General Public License as published by  *
00009  *   the Free Software Foundation; either version 2 of the License, or     *
00010  *   (at your option) any later version.                                   *
00011  *                                                                         *
00012  *   This program is distributed in the hope that it will be useful,       *
00013  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00014  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00015  *   GNU General Public License for more details.                          *
00016  *                                                                         *
00017  *   You should have received a copy of the GNU General Public License     *
00018  *   along with this program; if not, write to the                         *
00019  *   Free Software Foundation, Inc.,                                       *
00020  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00021  ***************************************************************************/
00022 
00023 //SpikeStream includes
00024 #include "MonitorDataset.h"
00025 #include "Debug.h"
00026 
00027 //Other includes
00028 #include <iostream>
00029 using namespace std;
00030 
00031 
00032 /*! Standard constructor that initialises everything. */
00033 MonitorDataset::MonitorDataset(int bufSize, double rangeL, double rangeH) : QwtData(){
00034         /* Initialise the data used in this class. These are all pointers so need to be
00035                 allocated on the heap. */
00036         //Dataset starts inserting at zero and starts reading at zero   
00037         insertPos = new int;
00038         *insertPos = 0;
00039 
00040         //Store buffer size
00041         bufferSize = new int;
00042         *bufferSize = bufSize;
00043 
00044         //Initialise parameters that will be used to learn the range once the buffer is full
00045         xIncrement = new double;
00046         *xIncrement = 0.0;
00047         xOld =new double;
00048         *xOld = 0.0;
00049         yMin = new double;
00050         *yMin = 0.0;
00051         yMax = new double;
00052         *yMax = 0.0;
00053         bufferFull = new bool;
00054         *bufferFull = false;
00055 
00056         //Initialise bounds rectangle to the default range
00057     //QwtDoubleRect(double left, double top, double width, double height);
00058         bndRect = new QwtDoubleRect(0.0, rangeL, *bufferSize, rangeH - rangeL);
00059 
00060         //Create arrays to hold the x and y values
00061         xArray = new double[*bufferSize];
00062         yArray = new double[*bufferSize];
00063 
00064         //Initialise arrays to zero
00065         for(int i=0; i<*bufferSize; ++i){
00066                 xArray[i] = 0.0;
00067                 yArray[i] = 0.0;
00068         }
00069 }
00070 
00071 
00072 /*! Constructor that does not initialise - used by copy(). */
00073 MonitorDataset::MonitorDataset(){
00074 }
00075 
00076 
00077 /*! Destructor. This does not do any cleaning up because a reference copy is made of this
00078         class and so cleaning up might entail this destructor being called twice. Need to 
00079         call cleanUp() explicitly to delete the data structures. */
00080 MonitorDataset::~MonitorDataset(){
00081         #ifdef MEMORY_DEBUG
00082                 cout<<"DESTROYING MONITOR DATASET"<<endl;
00083         #endif//MEMORY_DEBUG
00084 }
00085 
00086 
00087 //-----------------------------------------------------------------------
00088 //--------------------------- PUBLIC METHODS ----------------------------
00089 //-----------------------------------------------------------------------
00090 
00091 /*! Adds a point to the dataset. This is added at insertPos, which is rotated so that 
00092         the oldest point is overwritten. */
00093 void MonitorDataset::addPoint(double xVal, double yVal){
00094         //Store points
00095         xArray[*insertPos] = xVal;
00096         yArray[*insertPos] = yVal;
00097 
00098         //Work out how fast we are advancing with each additional point
00099         *xIncrement = xVal - *xOld;
00100         *xOld = xVal;
00101 
00102         //Store y range
00103         if(yVal > *yMax)
00104                 *yMax = yVal;
00105         else if(yVal < *yMin)
00106                 *yMin = yVal;
00107 
00108         //Advance insert position
00109         ++(*insertPos);
00110         *insertPos %= *bufferSize;
00111         if(*insertPos == 0)
00112                 //Record that buffer has been filled up, so we can now start advancing the window
00113                 *bufferFull = true;
00114 
00115         //If we have enough data points.
00116         if(*bufferFull){
00117                 /* Check that xVal is visible. It can vanish when the monitoring is stopped
00118                         whilst the simulation is running. */
00119                 if(xVal < bndRect->left() || xVal > (bndRect->left() + bndRect->width())){
00120                         //Reposition drawing point 19/20 of the way along the bound rectangle
00121                         double leftPos = xVal - ( ((double)*bufferSize * 19.0 ) / 20.0) * (*xIncrement);
00122                         bndRect->setLeft(leftPos);//(
00123                 }
00124 
00125                 /*Adjust position of the rectangle based on the ranges
00126                  We have advanced bufferWidth times, each time with increment xIncrement
00127                         so width of window should be bufferWidth * xIncrement. */
00128                 bndRect->setRect(bndRect->left() + *xIncrement, *yMin, *bufferSize * (*xIncrement), *yMax - *yMin);
00129         }
00130         else{
00131                 //Want to start adjusting the width straight away
00132                 bndRect->setWidth(*bufferSize * (*xIncrement));
00133         }
00134 }
00135 
00136 
00137 /*! Returns the bounding rectangle of the dataset. */
00138 QwtDoubleRect MonitorDataset::boundingRect() const{
00139     return *bndRect;
00140 }
00141 
00142 
00143 /*! Returns a reference to the bounding rectangle of the dataset. */
00144 QwtDoubleRect* MonitorDataset::boundingRectRef() const{
00145    return bndRect;
00146 }
00147 
00148 
00149 /*! Deletes everything in the class.
00150         Carry this out here instead of the destructor because copy() returns a copy
00151         of the references and so the destructor could be invoked twice on the same
00152         objects. */
00153 void MonitorDataset::cleanUp(){
00154         #ifdef MEMORY_DEBUG
00155                 cout<<"CLEANING UP MONITOR DATASET"<<endl;
00156         #endif//MEMORY_DEBUG
00157 
00158         //Delete everything allocated on the stack.
00159         delete [] xArray;
00160         delete [] yArray;
00161         delete insertPos;
00162         delete bufferSize;
00163         delete xIncrement;
00164         delete xOld;
00165         delete yMin;
00166         delete yMax;
00167         delete bufferFull;
00168         delete bndRect;
00169 }
00170 
00171 
00172 /*! Copies references so that new class updates in sync with old.
00173         Copy all the references to data and arrays and the rectangle. Do it this way
00174         because QwtPlot uses a copy of this dataset and invokes methods on the copy. */
00175 MonitorDataset* MonitorDataset::copy() const{
00176         MonitorDataset* tempMonitorData = new MonitorDataset();
00177         tempMonitorData->bufferSize = bufferSize;
00178         tempMonitorData->xIncrement = xIncrement;
00179         tempMonitorData->xOld = xOld;
00180         tempMonitorData->yMin = yMin;
00181         tempMonitorData->yMax = yMax;
00182         tempMonitorData->bndRect = bndRect;
00183         tempMonitorData->xArray = xArray;
00184         tempMonitorData->yArray = yArray;
00185         tempMonitorData->insertPos = insertPos;
00186         tempMonitorData->bufferFull = bufferFull;
00187 
00188         return tempMonitorData;
00189 }
00190 
00191 
00192 /*! Returns the number of data points held by this class. */
00193 size_t MonitorDataset::size() const{
00194         return *bufferSize;
00195 }
00196 
00197 
00198 /*! Returns the x value at position i. */
00199 double MonitorDataset::x(size_t i) const{
00200 //      cout<<"READING X: bufferSize="<<*bufferSize<<"; i="<<i<<"; insertPos="<<*insertPos<<"; VALUE = "<<xArray[(i + *insertPos) % *bufferSize]<<endl;
00201         return xArray[(i + *insertPos) % *bufferSize];
00202 }
00203 
00204 
00205 /*! Returns the y value at position i. */
00206 double MonitorDataset::y(size_t i) const{
00207         return yArray[(i + *insertPos) % *bufferSize];
00208 }
00209 
00210 

Generated on Mon Sep 3 22:29:04 2007 for SpikeStream Application by  doxygen 1.4.4