ATLAS Offline Software
Loading...
Searching...
No Matches
AthMonitorAlgorithm.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
7
8AthMonitorAlgorithm::AthMonitorAlgorithm( const std::string& name, ISvcLocator* pSvcLocator )
9:AthReentrantAlgorithm(name,pSvcLocator)
10 // Put this here rather than in the header to allow forward-declaring
11 // TrigDecisionTool.
12,m_trigDecTool{this, "TrigDecisionTool",""}
16{}
17
18
20
21
23 StatusCode sc;
24
25 // ROOT global histogram flag: off (not thread-safe to have it on)
26 TH1::AddDirectory(kFALSE);
27
28 // Retrieve the generic monitoring tools (a ToolHandleArray)
29 if ( !m_tools.empty() ) {
30 ATH_CHECK( m_tools.retrieve() );
31 for (size_t idx = 0; idx < m_tools.size(); ++idx) {
32 if (m_tools[idx].empty()) {
33 ATH_MSG_FATAL("Encountered empty ToolHandle");
34 return StatusCode::FAILURE;
35 }
36 std::string name(m_tools[idx].name());
37 m_toolLookupMap[ name ] = idx;
38 }
39 }
40
41 // Retrieve the trigger decision tool if requested
42 if ( !m_trigDecTool.empty() ) {
43 ATH_CHECK( m_trigDecTool.retrieve() );
44 ATH_MSG_DEBUG( "TDT retrieved" );
46 // If the trigger chain is specified, parse it into a list.
47 if ( !m_triggerChainString.empty() ) {
49 if ( !sc.isSuccess() ) {
50 ATH_MSG_WARNING("Error parsing trigger chain list, using empty list instead.");
51 m_vTrigChainNames.clear();
52 }
53 }
54 } else sc = StatusCode::SUCCESS;
55
56 // Retrieve filters
57 ATH_CHECK( m_DQFilterTools.retrieve() );
58
59 // Convert the data type and environment strings from the python configuration into the
60 // enum class types DataType_t and Environment_t
63
64 ATH_CHECK( m_lumiDataKey.initialize (m_useLumi) );
67
68 // get event info key
69 ATH_CHECK( m_EventInfoKey.initialize() );
70
71 // end of initialization
72 ATH_MSG_DEBUG("Exiting AthMonitorAlgorithm::initialize() successfully.");
73 return sc;
74}
75
76
77StatusCode AthMonitorAlgorithm::execute( const EventContext& ctx ) const {
78
79 // Checks that all of the DQ filters are passed. If any one of the filters
80 // fails, return SUCCESS code and do not fill the histograms with the event.
81 for ( const auto& filterItr : m_DQFilterTools ) {
82 if (!filterItr->accept()) {
83 ATH_MSG_DEBUG("Event rejected due to filter tool.");
84 return StatusCode::SUCCESS;
85 }
86 }
87
88 // Trigger: If there is a decision tool and the chains fail, skip the event.
90 ATH_MSG_DEBUG("Event rejected due to trigger filter.");
91 return StatusCode::SUCCESS;
92 }
93
94 ATH_MSG_DEBUG("Event accepted!");
95 return fillHistograms(ctx);
96}
97
98
99void AthMonitorAlgorithm::fill( const ToolHandle<GenericMonitoringTool>& groupHandle,
100 MonVarVec_t&& variables ) const {
101 Monitored::Group(groupHandle,std::move(variables)).fill();
102}
103
104
105void AthMonitorAlgorithm::fill( const std::string& groupName,
106 MonVarVec_t&& variables ) const {
107 this->fill(getGroup(groupName),std::move(variables));
108}
109
110
114
115
117 // convert the string to all lowercase
118 std::string lowerCaseStr = str;
119 std::transform(lowerCaseStr.begin(), lowerCaseStr.end(), lowerCaseStr.begin(), ::tolower);
120
121 // check if it matches one of the enum choices
122 if( lowerCaseStr == "user" ) {
123 return Environment_t::user;
124 } else if( lowerCaseStr == "online" ) {
126 } else if( lowerCaseStr == "tier0" ) {
128 } else if( lowerCaseStr == "tier0raw" ) {
130 } else if( lowerCaseStr == "tier0esd" ) {
132 } else if( lowerCaseStr == "aod" ) {
133 return Environment_t::AOD;
134 } else if( lowerCaseStr == "altprod" ) {
136 } else { // otherwise, warn the user and return "user"
137 ATH_MSG_WARNING("AthMonitorAlgorithm::envStringToEnum(): Unknown environment "
138 <<str<<", returning user.");
139 return Environment_t::user;
140 }
141}
142
143
145 // convert the string to all lowercase
146 std::string lowerCaseStr = str;
147 std::transform(lowerCaseStr.begin(), lowerCaseStr.end(), lowerCaseStr.begin(), ::tolower);
148
149 // check if it matches one of the enum choices
150 if( lowerCaseStr == "userdefined" ) {
152 } else if( lowerCaseStr == "montecarlo" ) {
154 } else if( lowerCaseStr == "collisions" ) {
156 } else if( lowerCaseStr == "cosmics" ) {
157 return DataType_t::cosmics;
158 } else if( lowerCaseStr == "heavyioncollisions" ) {
160 } else { // otherwise, warn the user and return "userDefined"
161 ATH_MSG_WARNING("AthMonitorAlgorithm::dataTypeStringToEnum(): Unknown data type "
162 <<str<<", returning userDefined.");
164 }
165}
166
167
168const ToolHandle<GenericMonitoringTool>& AthMonitorAlgorithm::getGroup( const std::string& name ) const {
169 // get the pointer to the tool, and check that it exists
170 auto idx = m_toolLookupMap.find(name);
171 if (ATH_LIKELY(idx != m_toolLookupMap.end())) {
172 return m_tools[idx->second];
173 }
174 else {
175 // treat empty tool handle case as in Monitored::Group
176 if (m_toolLookupMap.empty()) {
177 return m_dummy;
178 }
179
180 if (!isInitialized()) {
182 "It seems that the AthMonitorAlgorithm::initialize was not called "
183 "in derived class initialize method");
184 } else {
185 std::string available = std::accumulate(
186 m_toolLookupMap.begin(), m_toolLookupMap.end(), std::string(""),
187 [](const std::string& s, auto h) { return s + "," + h.first; });
188 ATH_MSG_FATAL("The tool " << name << " could not be found in the tool array of the "
189 << "monitoring algorithm " << m_name << ". This probably reflects a discrepancy between "
190 << "your python configuration and c++ filling code. Note: your available groups are {"
191 << available << "}.");
192 }
193 }
194 return m_dummy;
195}
196
197
198const ToolHandle<Trig::TrigDecisionTool>& AthMonitorAlgorithm::getTrigDecisionTool() const {
199 return m_trigDecTool;
200}
201
202
203bool AthMonitorAlgorithm::trigChainsArePassed( const std::vector<std::string>& vTrigNames ) const {
204
205
206 // If no triggers were given, return true.
207 if (vTrigNames.empty()) return true;
208
209
210 // Trigger: Check if this Algorithm is being run as an Express Stream job.
211 // Events are entering the express stream are chosen randomly, and by chain,
212 // Hence an additional check should be aplied to see if the chain(s)
213 // monitored here are responsible for the event being selected for
214 // the express stream.
215
216 const auto group = m_trigDecTool->getChainGroup(vTrigNames);
218 const auto passedBits = m_trigDecTool->isPassedBits(group);
219 bool expressPass = passedBits & TrigDefs::Express_passed; //bitwise AND
220 if(!expressPass) {
221 return false;
222 }
223 }
224
225 // monitor the event if any of the chains in the chain group passes the event.
226 return group->isPassed();
227
228}
229
230
231float AthMonitorAlgorithm::lbAverageInteractionsPerCrossing (const EventContext& ctx /*= Gaudi::Hive::currentContext()*/) const
232{
233 if (!m_lumiDataKey.empty()) {
235 return lumi->lbAverageInteractionsPerCrossing();
236 } else {
237 ATH_MSG_DEBUG("AthMonitorAlgorithm::lbAverageInteractionsPerCrossing() - luminosity tools are not retrieved.");
238 return -1.0;
239 }
240}
241
242
243float AthMonitorAlgorithm::lbInteractionsPerCrossing (const EventContext& ctx /*= Gaudi::Hive::currentContext()*/) const
244{
245 if (!m_lumiDataKey.empty()) {
247 float muToLumi = lumi->muToLumi();
248 if (muToLumi > 0) {
249 return lumi->lbLuminosityPerBCIDVector().at (ctx.eventID().bunch_crossing_id()) / muToLumi;
250 }
251 return 0;
252 } else {
253 ATH_MSG_DEBUG("AthMonitorAlgorithm::lbInteractionsPerCrossing() - luminosity tools are not retrieved.");
254 return -1.0;
255 }
256}
257
258
259float AthMonitorAlgorithm::lbAverageLuminosity (const EventContext& ctx /*= Gaudi::Hive::currentContext()*/) const
260{
261 if (!m_lumiDataKey.empty()) {
263 return lumi->lbAverageLuminosity();
264 } else {
265 ATH_MSG_DEBUG("AthMonitorAlgorithm::lbAverageLuminosity() - luminosity tools are not retrieved.");
266 return -1.0;
267 }
268}
269
270
271float AthMonitorAlgorithm::lbLuminosityPerBCID (const EventContext& ctx /*= Gaudi::Hive::currentContext()*/) const
272{
273 if (!m_lumiDataKey.empty()) {
275 return lumi->lbLuminosityPerBCIDVector().at (ctx.eventID().bunch_crossing_id());
276 } else {
277 ATH_MSG_DEBUG("AthMonitorAlgorithm::lbLuminosityPerBCID() - luminosity tools are not retrieved.");
278 return -1.0;
279 }
280}
281
282
283float AthMonitorAlgorithm::lbAverageLivefraction (const EventContext& ctx /*= Gaudi::Hive::currentContext()*/) const
284{
287 return 1.0;
288 }
289
290 if (!m_trigLiveFractionDataKey.empty()) {
292 return live->lbAverageLiveFraction();
293 } else {
294 ATH_MSG_DEBUG("AthMonitorAlgorithm::lbAverageLivefraction() - luminosity not available.");
295 return -1.0;
296 }
297}
298
299
300float AthMonitorAlgorithm::livefractionPerBCID (const EventContext& ctx /*= Gaudi::Hive::currentContext()*/) const
301{
304 return 1.0;
305 }
306
307 if (!m_trigLiveFractionDataKey.empty()) {
309 return live->l1LiveFractionVector().at (ctx.eventID().bunch_crossing_id());
310 } else {
311 ATH_MSG_DEBUG("AthMonitorAlgorithm::livefractionPerBCID() - luminosity not available.");
312 return -1.0;
313 }
314}
315
316
317double AthMonitorAlgorithm::lbLumiWeight (const EventContext& ctx /*= Gaudi::Hive::currentContext()*/) const
318{
319 if (!m_lumiDataKey.empty()) {
321 } else {
322 ATH_MSG_DEBUG("AthMonitorAlgorithm::lbLumiWeight() - luminosity tools are not retrieved.");
323 return -1.0;
324 }
325}
326
327
328double AthMonitorAlgorithm::lbDuration (const EventContext& ctx /*= Gaudi::Hive::currentContext()*/) const
329{
332 return m_defaultLBDuration;
333 }
334
335 if (!m_lbDurationDataKey.empty()) {
337 return dur->lbDuration();
338 } else {
339 ATH_MSG_DEBUG("AthMonitorAlgorithm::lbDuration() - luminosity tools are not retrieved.");
340 return m_defaultLBDuration;
341 }
342}
343
344
345StatusCode AthMonitorAlgorithm::parseList(const std::string& line, std::vector<std::string>& result) const {
346 std::string item;
347 std::stringstream ss(line);
348
349 ATH_MSG_DEBUG( "AthMonitorAlgorithm::parseList()" );
350
351 while ( std::getline(ss, item, ',') ) {
352 std::stringstream iss(item); // remove whitespace
353 iss >> item;
354 result.push_back(item);
355 }
356
357 return StatusCode::SUCCESS;
358}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_FATAL(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
#define ATH_LIKELY(x)
void tolower(std::string &s)
static Double_t ss
static Double_t sc
static const Attributes_t empty
Header file for AthHistogramAlgorithm.
virtual StatusCode fillHistograms(const EventContext &ctx) const =0
adds event to the monitoring histograms
const ToolHandle< GenericMonitoringTool > & getGroup(const std::string &name) const
Get a specific monitoring tool from the tool handle array.
bool trigChainsArePassed(const std::vector< std::string > &vTrigNames) const
Check whether triggers are passed.
AthMonitorAlgorithm::DataType_t m_dataType
Instance of the DataType_t enum.
DataType_t dataTypeStringToEnum(const std::string &str) const
Convert the data type string from the python configuration to an enum object.
Environment_t envStringToEnum(const std::string &str) const
Convert the environment string from the python configuration to an enum object.
Gaudi::Property< std::string > m_triggerChainString
Trigger chain string pulled from the job option and parsed into a vector.
Gaudi::Property< bool > m_useLumi
Allows use of various luminosity functions.
std::unordered_map< std::string, size_t > m_toolLookupMap
virtual StatusCode parseList(const std::string &line, std::vector< std::string > &result) const
Parse a string into a vector.
virtual StatusCode initialize() override
initialize
Environment_t
Specifies the processing environment.
const ToolHandle< Trig::TrigDecisionTool > & getTrigDecisionTool() const
Get the trigger decision tool member.
std::vector< std::string > m_vTrigChainNames
Vector of trigger chain names parsed from trigger chain string.
Gaudi::Property< float > m_defaultLBDuration
Default duration of one lumi block.
SG::ReadHandle< xAOD::EventInfo > GetEventInfo(const EventContext &) const
Return a ReadHandle for an EventInfo object (get run/event numbers, etc.)
const ToolHandle< GenericMonitoringTool > m_dummy
PublicToolHandle< Trig::TrigDecisionTool > m_trigDecTool
Tool to tell whether a specific trigger is passed.
DataType_t
Specifies what type of input data is being monitored.
AthMonitorAlgorithm(const std::string &name, ISvcLocator *pSvcLocator)
Constructor.
SG::ReadCondHandleKey< TrigLiveFractionCondData > m_trigLiveFractionDataKey
virtual ~AthMonitorAlgorithm()
Destructor.
Gaudi::Property< bool > m_enforceExpressTriggers
ToolHandleArray< GenericMonitoringTool > m_tools
Array of Generic Monitoring Tools.
SG::ReadCondHandleKey< LBDurationCondData > m_lbDurationDataKey
std::vector< std::reference_wrapper< Monitored::IMonitoredVariable > > MonVarVec_t
ToolHandleArray< IDQFilterTool > m_DQFilterTools
Array of Data Quality filter tools.
SG::ReadHandleKey< xAOD::EventInfo > m_EventInfoKey
Key for retrieving EventInfo from StoreGate.
AthMonitorAlgorithm::Environment_t m_environment
Instance of the Environment_t enum.
Gaudi::Property< std::string > m_environmentStr
Environment string pulled from the job option and converted to enum.
Gaudi::Property< std::string > m_dataTypeStr
DataType string pulled from the job option and converted to enum.
SG::ReadCondHandleKey< LuminosityCondData > m_lumiDataKey
virtual StatusCode execute(const EventContext &ctx) const override
Applies filters and trigger requirements.
An algorithm that can be simultaneously executed in multiple threads.
Group of local monitoring quantities and retain correlation when filling histograms
void fill()
Explicitly fill the monitoring histograms and disable autoFill.
void fill(const ToolHandle< GenericMonitoringTool > &groupHandle, std::vector< std::reference_wrapper< Monitored::IMonitoredVariable > > &&variables) const
Fills a vector of variables to a group by reference.
virtual double lbLumiWeight(const EventContext &ctx=Gaudi::Hive::currentContext()) const
Calculate the average integrated luminosity multiplied by the live fraction.
virtual float lbInteractionsPerCrossing(const EventContext &ctx=Gaudi::Hive::currentContext()) const
Calculate instantaneous number of interactions, i.e.
virtual float lbLuminosityPerBCID(const EventContext &ctx=Gaudi::Hive::currentContext()) const
Calculate the instantaneous luminosity per bunch crossing.
virtual float livefractionPerBCID(const EventContext &ctx=Gaudi::Hive::currentContext()) const
Calculate the live fraction per bunch crossing ID.
virtual float lbAverageLuminosity(const EventContext &ctx=Gaudi::Hive::currentContext()) const
Calculate average luminosity (in ub-1 s-1 => 10^30 cm-2 s-1).
virtual float lbAverageInteractionsPerCrossing(const EventContext &ctx=Gaudi::Hive::currentContext()) const
Calculate the average mu, i.e.
virtual float lbAverageLivefraction(const EventContext &ctx=Gaudi::Hive::currentContext()) const
Calculate the average luminosity livefraction.
virtual double lbDuration(const EventContext &ctx=Gaudi::Hive::currentContext()) const
Calculate the duration of the luminosity block (in seconds)