00001 #ifndef artdaq_core_Core_MonitoredQuantity_hh 00002 #define artdaq_core_Core_MonitoredQuantity_hh 00003 00004 #include <boost/thread/mutex.hpp> 00005 00006 #include <math.h> 00007 #include <stdint.h> 00008 #include <vector> 00009 00010 namespace artdaq 00011 { 00015 struct MonitoredQuantityStats 00016 { 00017 typedef double DURATION_T; 00018 typedef double TIME_POINT_T; 00019 00023 enum class DataSetType 00024 { 00025 FULL = 0, 00026 RECENT = 1 00027 }; 00028 00029 long long fullSampleCount; 00030 double fullSampleRate; 00031 double fullValueSum; 00032 double fullValueSumOfSquares; 00033 double fullValueAverage; 00034 double fullValueRMS; 00035 double fullValueMin; 00036 double fullValueMax; 00037 double fullValueRate; 00038 DURATION_T fullDuration; 00039 00040 long long recentSampleCount; 00041 double recentSampleRate; 00042 double recentValueSum; 00043 double recentValueSumOfSquares; 00044 double recentValueAverage; 00045 double recentValueRMS; 00046 double recentValueMin; 00047 double recentValueMax; 00048 double recentValueRate; 00049 DURATION_T recentDuration; 00050 00051 std::vector<long long> recentBinnedSampleCounts; 00052 std::vector<double> recentBinnedValueSums; 00053 std::vector<DURATION_T> recentBinnedDurations; 00054 std::vector<TIME_POINT_T> recentBinnedEndTimes; 00055 00056 double lastSampleValue; 00057 double lastValueRate; 00058 TIME_POINT_T lastCalculationTime; 00059 bool enabled; 00060 00066 long long getSampleCount(DataSetType t = DataSetType::FULL) const { return t == DataSetType::RECENT ? recentSampleCount : fullSampleCount; } 00067 00073 double getValueSum(DataSetType t = DataSetType::FULL) const { return t == DataSetType::RECENT ? recentValueSum : fullValueSum; } 00074 00080 double getValueAverage(DataSetType t = DataSetType::FULL) const { return t == DataSetType::RECENT ? recentValueAverage : fullValueAverage; } 00081 00087 double getValueRate(DataSetType t = DataSetType::FULL) const { return t == DataSetType::RECENT ? recentValueRate : fullValueRate; } 00088 00094 double getValueRMS(DataSetType t = DataSetType::FULL) const { return t == DataSetType::RECENT ? recentValueRMS : fullValueRMS; } 00095 00101 double getValueMin(DataSetType t = DataSetType::FULL) const { return t == DataSetType::RECENT ? recentValueMin : fullValueMin; } 00102 00108 double getValueMax(DataSetType t = DataSetType::FULL) const { return t == DataSetType::RECENT ? recentValueMax : fullValueMax; } 00109 00115 DURATION_T getDuration(DataSetType t = DataSetType::FULL) const { return t == DataSetType::RECENT ? recentDuration : fullDuration; } 00116 00122 double getSampleRate(DataSetType t = DataSetType::FULL) const { return t == DataSetType::RECENT ? recentSampleRate : fullSampleRate; } 00123 00129 double getSampleLatency(DataSetType t = DataSetType::FULL) const 00130 { 00131 auto v = getSampleRate(t); 00132 return v ? 1e6 / v : INFINITY; 00133 } 00134 00139 double getLastSampleValue() const { return lastSampleValue; } 00140 00145 double getLastValueRate() const { return lastValueRate; } 00146 00151 bool isEnabled() const { return enabled; } 00152 }; 00153 00158 class MonitoredQuantity : MonitoredQuantityStats 00159 { 00160 public: 00161 00167 explicit MonitoredQuantity 00168 ( 00169 DURATION_T expectedCalculationInterval, 00170 DURATION_T timeWindowForRecentResults 00171 ); 00172 00177 void addSample(const double value = 1.0); 00178 00183 void addSample(const int value = 1); 00184 00189 void addSample(const uint32_t value = 1); 00190 00195 void addSample(const uint64_t value = 1); 00196 00208 bool calculateStatistics(TIME_POINT_T currentTime = 00209 getCurrentTime()); 00210 00214 void reset(); 00215 00219 void enable(); 00220 00224 void disable(); 00225 00230 bool isEnabled() const { return enabled; } 00231 00236 void setNewTimeWindowForRecentResults(DURATION_T interval); 00237 00250 DURATION_T getTimeWindowForRecentResults() const 00251 { 00252 return _intervalForRecentStats; 00253 } 00254 00259 DURATION_T ExpectedCalculationInterval() const 00260 { 00261 return _expectedCalculationInterval; 00262 } 00263 00269 bool waitUntilAccumulatorsHaveBeenFlushed(DURATION_T timeout) const; 00270 00275 void getStats(MonitoredQuantityStats& stats) const; 00276 00285 static TIME_POINT_T getCurrentTime(); 00286 00287 // accessors for particular statistics values (more efficient when 00288 // only a single value is needed) 00289 TIME_POINT_T getLastCalculationTime() const; 00290 DURATION_T getFullDuration() const; 00291 double getRecentValueSum() const; 00292 double getRecentValueAverage() const; 00293 long long getFullSampleCount() const; 00294 00295 private: 00296 00297 // Prevent copying of the MonitoredQuantity 00298 MonitoredQuantity(MonitoredQuantity const&) = delete; 00299 00300 MonitoredQuantity& operator=(MonitoredQuantity const&) = delete; 00301 00302 // Helper functions. 00303 void _reset_accumulators(); 00304 00305 void _reset_results(); 00306 00307 TIME_POINT_T _lastCalculationTime; 00308 long long _workingSampleCount; 00309 double _workingValueSum; 00310 double _workingValueSumOfSquares; 00311 double _workingValueMin; 00312 double _workingValueMax; 00313 double _workingLastSampleValue; 00314 00315 mutable boost::mutex _accumulationMutex; 00316 00317 unsigned int _binCount; 00318 unsigned int _workingBinId; 00319 std::vector<double> _binValueSumOfSquares; 00320 std::vector<double> _binValueMin; 00321 std::vector<double> _binValueMax; 00322 00323 mutable boost::mutex _resultsMutex; 00324 00325 DURATION_T _intervalForRecentStats; // seconds 00326 const DURATION_T _expectedCalculationInterval; // seconds 00327 }; 00328 } // namespace artdaq 00329 00330 #endif /* artdaq_core_Core_MonitoredQuantity_hh */