00001 #ifndef STATS_HPP
00002 #define STATS_HPP
00003
00004
00005 #include "base.hpp"
00006 #include "xmltraversal.h"
00007
00008
00009
00010 class UTILITYSHARED_EXPORT Statistics
00011 {
00012 double lastValue;
00013 unsigned numberSamples;
00014 double sum;
00015 double sumSquares;
00016 double minimum;
00017 double maximum;
00018
00019
00020
00021 bool trackSpc;
00022 double upperControl;
00023 double lowerControl;
00024
00025 unsigned trendCount;
00026 unsigned meanCrowding;
00027 unsigned triggerCount;
00028 bool dirTrendUp;
00029 bool dirTrendDown;
00030
00031 QDateTime updateTime;
00032 bool upperControlEnabled;
00033 bool lowerControlEnabled;
00034 QDateTime lowerControlTriggerTime;
00035 QDateTime upperControlTriggerTime;
00036
00037 public:
00038 Statistics() : lastValue(0),numberSamples(0),sum(0),
00039 sumSquares(0),minimum(0),maximum(0),
00040 trackSpc(false),upperControl(0),lowerControl(0),
00041 trendCount(0),meanCrowding(0),
00042 triggerCount(0),dirTrendUp(false),
00043 dirTrendDown(false),
00044 upperControlEnabled(false),
00045 lowerControlEnabled(false)
00046 {
00047 };
00048 Statistics(const Statistics &s) : lastValue(s.lastValue),numberSamples(s.numberSamples),sum(s.sum),
00049 sumSquares(s.sumSquares),minimum(s.minimum),maximum(s.maximum),
00050 trackSpc(s.trackSpc),upperControl(s.upperControl),lowerControl(s.lowerControl),
00051 trendCount(s.trendCount),meanCrowding(s.meanCrowding),triggerCount(s.triggerCount),
00052 dirTrendUp(false),dirTrendDown(false),updateTime(s.updateTime),
00053 upperControlEnabled(s.upperControlEnabled),
00054 lowerControlEnabled(s.lowerControlEnabled),
00055 lowerControlTriggerTime(s.lowerControlTriggerTime),
00056 upperControlTriggerTime(s.upperControlTriggerTime)
00057 {
00058 };
00059 virtual void clear()
00060 {
00061 lastValue = sum = sumSquares = minimum = maximum = 0;
00062 numberSamples = trendCount = meanCrowding = triggerCount = 0;
00063 dirTrendUp = dirTrendDown = false;
00064 };
00065 virtual void setValue(double v);
00066 double getLastValue() const { return lastValue;};
00067 unsigned getNumberSamples() const { return numberSamples;};
00068 double getMinimum() const { return minimum;};
00069 double getMaximum() const { return maximum;};
00070 double getRange() const { return maximum - minimum;};
00071 static double tval(double p, int df);
00072 double getSum() const { return sum;};
00073 double getUpperControl() const { return upperControl;}
00074 double getLowerControl() const {return lowerControl;}
00075 bool getUpperControlEnabled() const { return upperControlEnabled;}
00076 bool getLowerControlEnabled() const { return lowerControlEnabled;}
00077 void setUpperControlEnabled(bool f) { upperControlEnabled = f;}
00078 void setLowerControlEnabled(bool f) { lowerControlEnabled = f;}
00079 QDateTime getUpdateTime() const { return updateTime;}
00080 QDateTime getUpperControlTriggerTime() const { return upperControlTriggerTime;}
00081 QDateTime getLowerControlTriggerTime() const { return lowerControlTriggerTime;}
00082 double variance() const
00083 {
00084 if ( getNumberSamples() > 1)
00085 {
00086 return(( sumSquares - ((sum * sum) / getNumberSamples())) / ( getNumberSamples() - 1));
00087 }
00088 else
00089 {
00090 return ( 0.0 );
00091 }
00092 };
00093
00094 double getStdDev() const
00095 {
00096 if ( getNumberSamples() <= 0 || variance() <= 0)
00097 {
00098 return(0);
00099 }
00100 else
00101 {
00102 return( (double) sqrt( variance() ) );
00103 }
00104 };
00105
00106 double confidence(int interval) const
00107 {
00108 int df = getNumberSamples() - 1;
00109 if (df <= 0) return HUGE_VAL;
00110 double t = tval(double(100 + interval) * 0.005, df);
00111 if (t == HUGE_VAL)
00112 return t;
00113 else
00114 return (t * getStdDev()) / sqrt(double(getNumberSamples()));
00115 };
00116
00117 double confidence(double p_value) const
00118 {
00119 int df = getNumberSamples() - 1;
00120 if (df <= 0) return HUGE_VAL;
00121 double t = tval((1.0 + p_value) * 0.5, df);
00122 if (t == HUGE_VAL)
00123 return t;
00124 else
00125 return (t * getStdDev()) / sqrt(double(getNumberSamples()));
00126 }
00127 double getMean() const
00128 {
00129 if(numberSamples > 0)
00130 {
00131 return sum / (double)numberSamples;
00132 };
00133 return 0;
00134 };
00135
00136 unsigned getTrendCount() const { return trendCount;};
00137 unsigned getTriggerCount() const { return triggerCount;};
00138 unsigned getMeanCrowding() const { return meanCrowding;};
00139 bool getTrackSpc() const { return trackSpc;};
00140 void setTrackSpc(bool f) { trackSpc = f;};
00141 XMLTraversal & toXML(XMLTraversal &x)
00142 {
00143 x.push();
00144 XMLSET(x,lastValue);
00145 XMLSET(x,numberSamples);
00146 XMLSET(x,sum);
00147 XMLSET(x,sumSquares);
00148 XMLSET(x,minimum);
00149 XMLSET(x,maximum);
00150
00151
00152
00153 XMLSET(x,trackSpc);
00154 XMLSET(x,upperControl);
00155 XMLSET(x,lowerControl);
00156 XMLSET(x,upperControlEnabled);
00157 XMLSET(x,lowerControlEnabled);
00158
00159 XMLSET(x,trendCount);
00160 XMLSET(x,meanCrowding);
00161 XMLSET(x,triggerCount);
00162 XMLSET(x,dirTrendUp);
00163 XMLSET(x,dirTrendDown);
00164
00165 XMLSET(x,updateTime);
00166 XMLSET(x,upperControlTriggerTime);
00167 XMLSET(x,lowerControlTriggerTime);
00168
00169 x.pop();
00170 return x;
00171 };
00172
00173 XMLTraversal & fromXML(XMLTraversal &x)
00174 {
00175 x.push();
00176
00177 XMLGET(x,lastValue);
00178 XMLGET(x,numberSamples);
00179 XMLGET(x,sum);
00180 XMLGET(x,sumSquares);
00181 XMLGET(x,minimum);
00182 XMLGET(x,maximum);
00183
00184
00185
00186 XMLGET(x,trackSpc);
00187 XMLGET(x,upperControl);
00188 XMLGET(x,lowerControl);
00189 XMLGET(x,upperControlEnabled);
00190 XMLGET(x,lowerControlEnabled);
00191
00192 XMLGET(x,trendCount);
00193 XMLGET(x,meanCrowding);
00194 XMLGET(x,triggerCount);
00195 XMLGET(x,dirTrendUp);
00196 XMLGET(x,dirTrendDown);
00197 XMLGET(x,updateTime);
00198 XMLGET(x,upperControlTriggerTime);
00199 XMLGET(x,lowerControlTriggerTime);
00200 x.pop();
00201 return x;
00202 };
00203
00204
00205 friend QDataStream & operator >> (QDataStream &is, Statistics &r);
00206 friend QDataStream & operator << (QDataStream &os, const Statistics &r);
00207 };
00208
00209 inline QDataStream & operator >> (QDataStream &is, Statistics &r)
00210 {
00211 is >> r.lastValue;
00212 is >> r.numberSamples;
00213 is >> r.sum;
00214 is >> r.sumSquares;
00215 is >> r.minimum;
00216 is >> r.maximum;
00217
00218
00219
00220 is >> r.trackSpc;
00221 is >> r.upperControl;
00222 is >> r.lowerControl;
00223
00224 is >> r.trendCount;
00225 is >> r.meanCrowding;
00226 is >> r.triggerCount;
00227 is >> r.dirTrendUp;
00228 is >> r.dirTrendDown;
00229 is >> r.updateTime;
00230 is >> r.upperControlTriggerTime;
00231 is >> r.lowerControlTriggerTime;
00232 return is;
00233 };
00234
00235 inline QDataStream & operator << (QDataStream &is, const Statistics &r)
00236 {
00237 is << r.lastValue;
00238 is << r.numberSamples;
00239 is << r.sum;
00240 is << r.sumSquares;
00241 is << r.minimum;
00242 is << r.maximum;
00243
00244
00245
00246 is << r.trackSpc;
00247 is << r.upperControl;
00248 is << r.lowerControl;
00249
00250 is << r.trendCount;
00251 is << r.meanCrowding;
00252 is << r.triggerCount;
00253 is << r.dirTrendUp;
00254 is << r.dirTrendDown;
00255 is << r.updateTime;
00256 is << r.upperControlTriggerTime;
00257 is << r.lowerControlTriggerTime;
00258 return is;
00259 };
00260
00261
00262
00263
00264 class StatisticsThreshold
00265 {
00266 double _threshold;
00267 int _triggerCount;
00268 bool _enabled;
00269 bool _triggered;
00270 public:
00271
00272 typedef enum
00273 {
00274 None = 0,
00275 HiHi,
00276 HiLo,
00277 LoHi,
00278 LoLo,
00279 NumberThresholds
00280 } ThresholdTypes;
00281
00282
00283 StatisticsThreshold(double t = 0) :
00284 _threshold(t),
00285 _triggerCount(0),
00286 _enabled(false),
00287 _triggered(false) {}
00288 StatisticsThreshold( const StatisticsThreshold &s) :
00289 _threshold(s._threshold),
00290 _triggerCount(s._triggerCount),
00291 _enabled(s._enabled),
00292 _triggered(s._triggered){}
00293
00294 double threshold() const { return _threshold;}
00295 void setThreshold(double t, bool e = true) { _threshold = t; _enabled = e;}
00296 int triggerCount() const { return _triggerCount;}
00297 void clear() { _triggerCount = 0; _triggered = false;}
00298
00299 bool compareHi(double v)
00300 {
00301 _triggered = ( v >= _threshold) && _enabled;
00302 if( _triggered)_triggerCount++;
00303 return _triggered;
00304 }
00305
00306 bool compareLo(double v)
00307 {
00308 _triggered = ( v <= _threshold) && _enabled;
00309 if(_triggered)_triggerCount++;
00310 return _triggered;
00311 }
00312
00313 void increment() { _triggerCount++;}
00314 bool enabled() { return _enabled;}
00315 void setEnabled(bool f) { _enabled = f;}
00316 bool triggered() const { return _triggered;}
00317
00318 };
00319
00320
00321 class StatisticsThresholdSet : public Statistics
00322 {
00323 QVector<StatisticsThreshold> _thresholds;
00324
00325 bool _triggered;
00326 bool _hihilolo;
00327 bool _hilolohi;
00328
00329 public:
00330 StatisticsThresholdSet() :
00331 _thresholds(StatisticsThreshold::NumberThresholds),
00332 _triggered(false),_hihilolo(false),_hilolohi(false) {};
00333
00334 StatisticsThresholdSet(const StatisticsThresholdSet &s) :
00335 Statistics(s),_thresholds(s._thresholds),
00336 _triggered(s._triggered),
00337 _hihilolo(s._hihilolo),
00338 _hilolohi(s._hilolohi)
00339 {
00340
00341 }
00342
00343 StatisticsThreshold & thresholds(int i) { return _thresholds[i];};
00344
00345 void setThresholds(double lolo, double lohi, double hilo, double hihi,
00346 bool loloEnable = true, bool lohiEnable = true, bool hiloEnable = true, bool hihiEnable = true)
00347 {
00348 _thresholds[StatisticsThreshold::HiHi].setThreshold(hihi,hihiEnable);
00349 _thresholds[StatisticsThreshold::HiLo].setThreshold(hilo,hiloEnable);
00350 _thresholds[StatisticsThreshold::LoHi].setThreshold(lohi,lohiEnable);
00351 _thresholds[StatisticsThreshold::LoLo].setThreshold(lolo,loloEnable);
00352 }
00353
00354 bool triggered() const { return _triggered;}
00355 bool triggeredHiHiLoLo() const { return _hihilolo;}
00356 bool triggeredHiLoLoHi() const { return _hilolohi;}
00357
00358
00359 StatisticsThreshold::ThresholdTypes maxState()
00360 {
00361 if(triggered())
00362 {
00363 if(_thresholds[StatisticsThreshold::HiHi].triggered()) return StatisticsThreshold::HiHi;
00364 if(_thresholds[StatisticsThreshold::LoLo].triggered()) return StatisticsThreshold::LoLo;
00365 if(_thresholds[StatisticsThreshold::HiLo].triggered()) return StatisticsThreshold::HiLo;
00366 if(_thresholds[StatisticsThreshold::LoHi].triggered()) return StatisticsThreshold::LoHi;
00367 }
00368 return StatisticsThreshold::None;
00369 }
00370
00371
00372 void setValue(double v)
00373 {
00374 _hihilolo = _thresholds[StatisticsThreshold::LoLo].compareLo(v) || _thresholds[StatisticsThreshold::HiHi].compareHi(v);
00375 _hilolohi = _thresholds[StatisticsThreshold::HiLo].compareHi(v) || _thresholds[StatisticsThreshold::LoHi].compareLo(v);
00376 _triggered = _hihilolo || _hilolohi;
00377 if(!triggered()) _thresholds[StatisticsThreshold::None].increment();
00378 Statistics::setValue(v);
00379 }
00380
00381 void clear()
00382 {
00383 for(int i = 0; i < StatisticsThreshold::NumberThresholds; i++) _thresholds[i].clear();
00384 Statistics::clear();
00385 _triggered = _hihilolo = _hilolohi = false;
00386 }
00387
00388 };
00389 #endif