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