ATLAS Offline Software
Loading...
Searching...
No Matches
TRTAvgEventSizeCheck.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
3*/
4
5#ifdef ONLINE // can only be built in an online environment
6
9
10#include "dqm_core/AlgorithmManager.h"
11#include "dqm_core/AlgorithmRegistrator.h"
12#include "dqm_core/AlgorithmConfig.h"
13#include "ers/ers.h"
14
15#include "ipc/partition.h"
16#include "is/inforeceiver.h"
17#include "is/callbackinfo.h"
18#include "is/infoT.h"
19
20#include <limits>
21#include <cmath>
22
23namespace /* anonymous */ {
24
25class TRTBeamConditions : public ISInfoReceiver
26{
27public:
28 static TRTBeamConditions &instance();
29 float get();
30 virtual ~TRTBeamConditions() {}
31
32private:
33 TRTBeamConditions();
34 void callback(ISCallbackInfo *info);
35
36private:
37 static const char *m_name;
38 boost::mutex m_mutex; // not really required here because m_value is of primitive type float
39 float m_value;
40};
41
42const char *TRTBeamConditions::m_name("beamconditions.hitfractionTRT_longToT");
43
44TRTBeamConditions &TRTBeamConditions::instance()
45{
46 static TRTBeamConditions s_instance;
47 return s_instance;
48}
49
50float TRTBeamConditions::get()
51{
52 boost::mutex::scoped_lock lock(m_mutex);
53 return m_value;
54}
55
56TRTBeamConditions::TRTBeamConditions() : ISInfoReceiver(IPCPartition("initial")), m_mutex(), m_value(0)
57{
58 try {
59 subscribe(m_name, &TRTBeamConditions::callback, this);
60 } catch (daq::is::Exception &ex) {
61 ERS_LOG("Subscribing to " << m_name << " IS Info failed: " << ex);
62 }
63}
64
65void TRTBeamConditions::callback(ISCallbackInfo *info)
66{
67 try {
68 ISInfoFloat hitfraction;
69 info->value(hitfraction);
70
71 const long long timestamp = info->time().total_mksec_utc();
72 const long long now = OWLTime().total_mksec_utc();
73 const long long maxAge = 5 * 60 * 1000000; // five minutes
74
75 boost::mutex::scoped_lock lock(m_mutex);
76 if (now - timestamp < maxAge) {
77 m_value = hitfraction.getValue();
78 } else {
79 m_value = 0; // reject old values
80 }
81 } catch (daq::is::Exception &ex) {
82 ERS_LOG("Receiving " << m_name << " IS Info failed: " << ex);
83 }
84}
85
86dqm_core::AlgorithmRegistrator<dqm_algorithms::TRTAvgEventSizeCheck> __ii__("TRTAvgEventSizeCheck");
87
88} // namespace
89
90
91
92dqm_algorithms::TRTAvgEventSizeCheck::TRTAvgEventSizeCheck() : lastCollisionsSeen_(boost::posix_time::min_date_time) // never
93{
94 (void)TRTBeamConditions::instance(); // already initiate the subscription
95}
96
97dqm_algorithms::TRTAvgEventSizeCheck *dqm_algorithms::TRTAvgEventSizeCheck::clone()
98{
99 return new TRTAvgEventSizeCheck();
100}
101
102dqm_core::Result *dqm_algorithms::TRTAvgEventSizeCheck::execute(const std::string &name, const TObject &object, const dqm_core::AlgorithmConfig &config)
103{
104 if (!object.IsA()->InheritsFrom("TH1")) {
105 throw dqm_core::BadConfig(ERS_HERE, name, "histogram does not inherit from TH1");
106 }
107 const TH1 &histogram = dynamic_cast<const TH1 &>(object); // should be safe after the previous check
108 if (histogram.GetDimension() > 1) {
109 throw dqm_core::BadConfig(ERS_HERE, name, "histogram has more than one dimension");
110 }
111
112 const double noiseLimit = dqm_algorithms::tools::GetFirstFromMap("NoiseLimit", config.getParameters());
113 const double delaySeconds = dqm_algorithms::tools::GetFirstFromMap("DelayTime", config.getParameters(), 60);
114 const boost::posix_time::time_duration delayTime = boost::posix_time::seconds(delaySeconds); // same value
115
116 const double hitFraction = TRTBeamConditions::instance().get();
117 const bool collisions = (hitFraction > noiseLimit);
118 const bool unknown = (hitFraction == 0); // the beam monitoring is just starting or the published value is too old
119
120 const boost::posix_time::ptime now = boost::posix_time::microsec_clock::universal_time();
121 if (collisions) lastCollisionsSeen_ = now;
122 const bool acceptLargeEvents = (now <= (lastCollisionsSeen_ + delayTime) || unknown); // also accept large events if the beam monitoring is not working
123
124 const char *avgThresholdName = acceptLargeEvents ? "Avg_Collisions" : "Avg_Noise"; // select which set of thresholds to use
125 const double avgG = dqm_algorithms::tools::GetFromMap(avgThresholdName, config.getGreenThresholds());
126 const double avgR = dqm_algorithms::tools::GetFromMap(avgThresholdName, config.getRedThresholds());
127
128 double sum = 0;
129 double sum2 = 0;
130 int spyReadoutEnabled = 0;
131 int spyReadoutDisabled = 0;
132
133 for (int i = 1; i <= histogram.GetNbinsX(); ++i) {
134 const double binContent = histogram.GetBinContent(i);
135 if (binContent) { // skip zero bins
136 sum += binContent;
137 sum2 += binContent * binContent;
138 ++spyReadoutEnabled;
139 } else {
140 ++spyReadoutDisabled;
141 }
142 }
143
144 const int &N = spyReadoutEnabled; // just a shorter name for this
145 const double avg = N ? sum / N : 0; // protect against division by zero
146 const double rms = N ? std::sqrt(sum2 / N - avg * avg) : 0; // protect against division by zero
147
148 dqm_core::Result *result = new dqm_core::Result;
149
150 if (avg <= 0) result->status_ = dqm_core::Result::Undefined; // negative values should never appear
151 else if (avg <= avgG) result->status_ = dqm_core::Result::Green;
152 else if (avg < avgR) result->status_ = dqm_core::Result::Yellow;
153 else result->status_ = dqm_core::Result::Red;
154
155 result->tags_["Avg"] = avg;
156 result->tags_["RMS"] = rms;
157 result->tags_["SpyReadoutDisabled"] = spyReadoutDisabled;
158 result->tags_["_HitFraction_"] = hitFraction;
159 result->tags_["_Collisions_"] = collisions;
160 result->tags_["_AcceptLargeEvents_"] = acceptLargeEvents;
161 return result;
162}
163
164void dqm_algorithms::TRTAvgEventSizeCheck::printDescription(std::ostream& out)
165{
166 out << "TRTAvgEventSizeCheck: checks the average event size from the TRT RODs.\n"
167 "The algorithm applies two different sets of thresholds, depending on whether we have collisions or not.\n"
168 "Mandatory parameters:\n"
169 " NoiseLimit: if \"hitfractionTRT_longToT\" is above this value, the algorithm assumes we are having collisions.\n"
170 "Optional parameters:\n"
171 " DelayTime: how long after collisions the algorithm still accepts large events (in seconds, default = 60).\n"
172 "Mandatory thresholds:\n"
173 " Avg_Collisions: the allowed average event size when we are having collisions.\n"
174 " Avg_Noise: the allowed average event size when we are not having collisions.\n"
175 "Results:\n"
176 " Avg: the average event size, averaged over all RODs in the histogram, excluding the ones with disabled spy readout.\n"
177 " RMS: the RMS of the average event size distribution, excluding the ones with disabled spy readout.\n"
178 " SpyReadoutDisabled: the number of RODs with disabled spy readout.\n"
179 " _HitFraction_: the value of \"hitfractionTRT_longToT\", mirrored as a DQMF result.\n"
180 " _Collisions_: is \"hitfractionTRT_longToT\" currently above the NoiseLimit?\n"
181 " _AcceptLargeEvents_: are we still in the DelayTime after collisions?" << std::endl;
182}
183
184#endif // ONLINE
std::map< std::string, double > instance
std::string histogram
Definition chains.cxx:52
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
Definition hcg.cxx:130
avg(a, b)
Definition Recovery.py:79
double GetFirstFromMap(const std::string &paramName, const std::map< std::string, double > &params)
const T & GetFromMap(const std::string &pname, const std::map< std::string, T > &params)
#define IsA
Declare the TObject style functions.