ATLAS Offline Software
EnhancedBiasWeighter.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 // EnhancedBiasWeighter includes
7 
9 
10 #include "TXMLEngine.h"
11 #include "TObjString.h"
12 #include "TDOMParser.h"
13 #include "TXMLNode.h"
14 #include "TXMLDocument.h"
15 #include "TXMLAttr.h"
16 
17 #include <memory>
18 #include <filesystem>
19 
20 namespace {
21  template <typename T>
22  T stringToNum(const std::string& i) {
23  T ret;
24  std::istringstream( i ) >> ret;
25  return ret;
26  }
27 }
28 
30  : asg::AsgTool( name ),
31  m_deadtime(1.),
32  m_pairedBunches(0),
33  m_mcModifiedCrossSection(0.)
34 {}
35 
37 {
38  ATH_MSG_DEBUG ("Initializing " << name() << "...");
40 
41  if (m_isMC) {
42 
43  if (m_mcCrossSection == 0 || m_mcFilterEfficiency == 0) {
44  ATH_MSG_FATAL("For MC rates, a cross section and filter efficiency must be supplied.");
45  return StatusCode::FAILURE;
46  }
47  m_deadtime = 1.; // No deadtime for MC
48  m_pairedBunches = FULL_RING; // Assume full-ring
49  const float mcCrossSectionInSqCm = 1e-33 * m_mcCrossSection; // Convert nb -> cm^2
51  ATH_MSG_INFO ("Running over MC with xsec:" << m_mcCrossSection << " nb, filter efficiency:" << m_mcFilterEfficiency << ", k-factor:" << m_mcKFactor);
52 
53  } else { // isData
54 
55  if (m_runNumber == 0u) {
56  ATH_MSG_FATAL("calculateWeightingData is TRUE, but the RunNumber property has not been set. This must be set such that we can read in the correct data.");
57  return StatusCode::FAILURE;
58  }
59  ATH_MSG_INFO ("calculateWeightingData is TRUE. This job will read in EnhancedBias weighting data from CVMFS and COOL.");
61  ATH_CHECK( loadLumi() );
62 
63  } // end isData
64 
65 
66  return StatusCode::SUCCESS;
67 }
68 
70 {
71  ATH_MSG_DEBUG ("Finalizing " << name() << "...");
72  return StatusCode::SUCCESS;
73 }
74 
76 {
77  // Construct name
78  std::stringstream fileName;
79  const uint32_t runNumber = m_runNumber; // This is because Gaudi::Properties have special behaviour with the << operator
80  fileName << "EnhancedBiasWeights_" << runNumber << ".xml";
81  std::string weightingFile = (!m_weightsDirectory.empty()) ? findLocalFile(fileName.str()) : PathResolverFindCalibFile("TrigCostRootAnalysis/" + fileName.str() ); // Check standard area
82 
83  ATH_MSG_DEBUG("Using weighting file " << weightingFile);
84 
85  if (weightingFile == "") {
86  msg() << (m_errorOnMissingEBWeights ? MSG::ERROR : MSG::WARNING) << "Could not retrieve " << fileName.str() << ", cannot perform enhanced bias weighting." << endmsg;
87  return (m_errorOnMissingEBWeights ? StatusCode::FAILURE : StatusCode::SUCCESS);
88  }
89 
90  std::unique_ptr<TXMLEngine> xml(new TXMLEngine() );
91  XMLDocPointer_t xmlDoc = xml->ParseFile( weightingFile.c_str() );
92 
93  if (xmlDoc == nullptr) {
94  ATH_MSG_WARNING ("Could not parse " << fileName.str() << ", cannot perform enhanced bias weighting.");
95  return StatusCode::FAILURE;
96  }
97 
98  // Navigate XML
99  const XMLNodePointer_t mainNode = xml->DocGetRootElement(xmlDoc);
100  if ( xml->GetNodeName(mainNode) != std::string("run") ) {
101  ATH_MSG_ERROR ("Canot parse XML. Expected 'run' node, got " << xml->GetNodeName(mainNode));
102  return StatusCode::FAILURE;
103  }
104  const XMLNodePointer_t weightsNode = xml->GetChild( mainNode );
105  const XMLNodePointer_t eventsNode = xml->GetNext( weightsNode );
106 
107  XMLNodePointer_t weightNode = xml->GetChild( weightsNode );
108  XMLNodePointer_t eventNode = xml->GetChild( eventsNode );
109 
110  while ( weightNode != 0 ) { // Loop over all weight elements
111  if ( xml->GetNodeName(weightNode) != std::string("weight") ) {
112  ATH_MSG_ERROR ("Canot parse XML. Expected 'weight' node, got " << xml->GetNodeName(weightNode));
113  return StatusCode::FAILURE;
114  }
115 
116  const int32_t id = std::atoi(xml->GetAttr(weightNode, "id") );
117  const double weight = std::atof(xml->GetAttr(weightNode, "value") );
118  int32_t unbiased = 0;
119  if ( xml->HasAttr(weightNode, "unbiased") == true ) {
120  unbiased = std::atoi(xml->GetAttr(weightNode, "unbiased"));
121  }
122 
124  m_idToUnbiasedMap[id] = unbiased;
125 
126  weightNode = xml->GetNext(weightNode);
127  }
128 
129  while ( eventNode != 0 ) { // Loop over all event elements
130  if ( xml->GetNodeName(eventNode) != std::string("e") ) {
131  ATH_MSG_ERROR ("Canot parse XML. Expected 'e' (event) node, got " << xml->GetNodeName(eventNode));
132  return StatusCode::FAILURE;
133  }
134  const uint64_t eventNumber = std::strtoll(xml->GetAttr(eventNode, "n"), nullptr, 10); //Number
135  const int32_t eventWeightID = std::stoi(xml->GetAttr(eventNode, "w") ); //Weight ID
136 
137  m_eventNumberToIdMap[eventNumber] = eventWeightID;
138 
139  eventNode = xml->GetNext(eventNode);
140  }
141 
142  ATH_MSG_INFO ("Loaded " << m_eventNumberToIdMap.size() << " event weights for run " << runNumber);
143  return StatusCode::SUCCESS;
144 }
145 
147 {
148  // Fetch LB time from COOL for this run
150  if (m_readLumiBlock.updateLumiBlocks(runNumber, msg()) == false) {
151  ATH_MSG_FATAL("Unable to load this runs luminosity values from COOL.");
152  return StatusCode::FAILURE;
153  }
154 
155  // Read in number of events to expect
156  // Construct name
157  std::stringstream fileName;
158  fileName << "enhanced_bias_run_" << runNumber << ".xml";
159  std::string runFile = (!m_weightsDirectory.empty()) ? findLocalFile(fileName.str()) : PathResolverFindCalibFile("TrigCostRootAnalysis/" + fileName.str() ); // Check standard area
160 
161  ATH_MSG_DEBUG("Using run file " << runFile);
162  if (runFile == "") {
163  msg() << (m_errorOnMissingEBWeights ? MSG::ERROR : MSG::WARNING) << "Could not retrieve " << fileName.str() << ", cannot perform enhanced bias weighting." << endmsg;
164  return (m_errorOnMissingEBWeights ? StatusCode::FAILURE : StatusCode::SUCCESS);
165  }
166 
167  std::unique_ptr<TXMLEngine> xml(new TXMLEngine());
168  const XMLDocPointer_t xmlDoc = xml->ParseFile( runFile.c_str() );
169 
170  if (xmlDoc == nullptr) {
171  ATH_MSG_FATAL ("Could not parse " << fileName.str() << ", cannot perform enhanced bias weighting.");
172  return StatusCode::FAILURE;
173  }
174 
175  const XMLNodePointer_t mainNode = xml->DocGetRootElement(xmlDoc);
176  if ( xml->GetNodeName(mainNode) != std::string("trigger") ) {
177  ATH_MSG_ERROR ("Canot parse XML. Expected 'trigger' node, got " << xml->GetNodeName(mainNode));
178  return StatusCode::FAILURE;
179  }
180  XMLNodePointer_t listNode = xml->GetChild( mainNode );
181 
182  while ( listNode != 0 ) { // Loop over all menu elements
183  const std::string listName = xml->GetNodeName(listNode);
184 
185  if (listName == "lb_list") {
186 
187  XMLNodePointer_t node = xml->GetChild( listNode );
188  while( node != 0) {
189  if ( xml->GetNodeName(node) != std::string("lb") ) {
190  ATH_MSG_ERROR ("Canot parse XML. Expected 'lb' node, got " << xml->GetNodeName(node));
191  return StatusCode::FAILURE;
192  }
193  const uint32_t lb = std::atoi( xml->GetAttr(node, "id") );
194  const double lumi = std::atof( xml->GetAttr(node, "lumi") );
195  const uint32_t nEvents = std::atoi( xml->GetNodeContent(node) );
196  const std::string flag = xml->HasAttr(node, "flag") ? xml->GetAttr(node, "flag") : "";
197 
199  m_goodLB[lb] = (flag == "bad" ? 0 : 1);
200  m_lumiPerLB[lb] = lumi < 1e10 ? 1e30 * lumi : lumi;
201 
202  if (xml->HasAttr(node, "deadtime")) {
203  // Deadtime is a weight factor, the weight will be multiplied by deadtime + 1
204  m_deadtimePerLB[lb] = 1. + std::atof( xml->GetAttr(node, "deadtime") );
205  }
206 
207  node = xml->GetNext(node);
208  }
209 
210  } else if (listName == "lumivalues") {
211 
212  XMLNodePointer_t node = xml->GetChild( listNode );
213  while( node != 0) {
214  if ( xml->GetNodeName(node) == std::string("deadtime") ) {
215  m_deadtime = 1. + std::atof( xml->GetNodeContent(node) );
216  }
217  node = xml->GetNext(node);
218  }
219 
220  } else if (listName == "bunchgroups") {
221 
222  XMLNodePointer_t node = xml->GetChild( listNode );
223  while( node != 0) {
224  m_bunches.push_back( std::atoi( xml->GetNodeContent(node) ) );
225  if ( xml->GetNodeName(node) == std::string("bunchgroup") && xml->HasAttr(node, "name") &&
226  (std::string(xml->GetAttr(node, "name")) == "Paired" || std::string(xml->GetAttr(node, "name")) == "Filled")) {
227  m_pairedBunches = std::atoi( xml->GetNodeContent(node) );
228  }
229  node = xml->GetNext(node);
230  }
231 
232  } else if (listName == "filters") {
233 
234  ATH_MSG_DEBUG("Found filters section of enhanced bias XML. Unused by this application.");
235 
236  } else {
237 
238  ATH_MSG_INFO("Encountered unknown element in enhanced bias XML: " << listName << " ignoring it.");
239 
240  }
241 
242  listNode = xml->GetNext(listNode);
243  }
244 
245  ATH_MSG_INFO ("Loaded " << m_eventsPerLB.size() << " EnhancedBias lumi block's info for run " << runNumber);
246  return StatusCode::SUCCESS;
247 }
248 
249 std::unordered_map<std::string, ChainDetail> EnhancedBiasWeighter::parsePrescaleXML(const std::string& prescaleXML) const {
250  std::unordered_map<std::string, ChainDetail> result;
251 
252  std::string xmlFile = PathResolverFindDataFile( prescaleXML );
253  if (xmlFile == "") {
254  ATH_MSG_ERROR ("Could not retrieve " << prescaleXML << ", place it somewhere PathResolver can find it (such as the current directory).");
255  return result;
256  }
257 
258  std::unique_ptr<TXMLEngine> xml(new TXMLEngine());
259  const XMLDocPointer_t xmlDoc = xml->ParseFile( xmlFile.c_str() );
260 
261  if (xmlDoc == nullptr) {
262  ATH_MSG_WARNING ("Could not parse " << prescaleXML << ", please check that it is valid XML.");
263  return result;
264  }
265 
266  // Get access to main node
267  XMLNodePointer_t mainNode = xml->DocGetRootElement(xmlDoc);
268  if ( xml->GetNodeName(mainNode) != std::string("trigger") ) {
269  ATH_MSG_ERROR ("Canot parse XML. Expected 'trigger' node, got " << xml->GetNodeName(mainNode));
270  return result;
271  }
272  XMLNodePointer_t listNode = xml->GetChild( mainNode );
273 
274 
275  while ( listNode != nullptr) { // Loop over all menu elements
276  const std::string listName = xml->GetNodeName(listNode);
277 
278  // if (_listName == "PredictionLumi") {
279  // Float_t predictionLumi = stringToFloat( xml->GetNodeContent(listNode) );
280  // }
281  if (listName != "level") { // Find the "level" item
282  listNode = xml->GetNext(listNode);
283  continue;
284  }
285 
286  XMLNodePointer_t sigNode = xml->GetChild( listNode );
287  while( sigNode != nullptr) {
288  if (xml->GetNodeName(sigNode) != std::string("signature")) { // Find the "signature" items
289  sigNode = xml->GetNext(sigNode);
290  continue;
291  }
292 
293  XMLNodePointer_t sigDetailsNode = xml->GetChild( sigNode );
294  std::string chainName;
295  while( sigDetailsNode != nullptr) {
296 
297  if (xml->GetNodeContent(sigDetailsNode) == nullptr) {
298  sigDetailsNode = xml->GetNext(sigDetailsNode);
299  continue;
300  }
301 
302  const std::string detail = xml->GetNodeName(sigDetailsNode);
303  if (detail == "sig_name") {
304  chainName = xml->GetNodeContent(sigDetailsNode);
306  } else if (detail == "sig_counter") {
307  result[chainName].m_counter = std::stoi( xml->GetNodeContent(sigDetailsNode) );
308  } else if (detail == "prescale" || detail == "chain_prescale") { // This is an alternate name
309  result[chainName].m_prescale = std::stod( xml->GetNodeContent(sigDetailsNode) );
310  } else if (detail == "lower_chain_name") {
311  // Later processing here does not expect any spaces, so remove them now. Pure comma separated list
312  std::string lower = xml->GetNodeContent(sigDetailsNode);
313  while (lower.find(" ") != std::string::npos) lower.replace( lower.find(" "), 1, "");
314  result[chainName].m_lowerName = lower;
315  } else if (detail == "evts_passed") {
316  result[chainName].m_eventsPassed = std::stod( xml->GetNodeContent(sigDetailsNode) );
317  } else if (detail == "evts_passed_weighted") {
318  result[chainName].m_eventsPassedWeighted = std::stod( xml->GetNodeContent(sigDetailsNode) );
319  } else if (detail == "rate") {
320  result[chainName].m_rate = std::stod( xml->GetNodeContent(sigDetailsNode) );
321  } else if (detail == "rate_err") {
322  result[chainName].m_rateErr = std::stod( xml->GetNodeContent(sigDetailsNode) );
323  } else if (detail == "passthrough") {
324  result[chainName].m_passthroughPrescale = std::stod( xml->GetNodeContent(sigDetailsNode) );
325  } else if (detail == "rerun_prescale") {
326  result[chainName].m_rerunPrescale = std::stod( xml->GetNodeContent(sigDetailsNode) );
327  } else if (detail == "express_prescale") {
328  result[chainName].m_expressPrescale = std::stod( xml->GetNodeContent(sigDetailsNode) );
329  } else if (detail == "efficiency") {
330  result[chainName].m_efficiency = std::stod( xml->GetNodeContent(sigDetailsNode) );
331  } else if (detail == "efficiency_err") {
332  result[chainName].m_efficiencyErr = std::stod( xml->GetNodeContent(sigDetailsNode) );
333  } else if (detail == "prescaled_efficiency") {
334  result[chainName].m_prescaledEfficiency = std::stod( xml->GetNodeContent(sigDetailsNode) );
335  } else if (detail == "prescaled_efficiency_error") {
336  result[chainName].m_prescaledEfficiencyErr = std::stod( xml->GetNodeContent(sigDetailsNode) );
337  } else if (detail == "comment") {
338  result[chainName].m_comment = xml->GetNodeContent(sigDetailsNode);
339  } else {
340  ATH_MSG_DEBUG("Input prescales XML contains additional data which cannot be parsed at present:" << detail);
341  }
342 
343  sigDetailsNode = xml->GetNext(sigDetailsNode);
344  }
345  sigNode = xml->GetNext(sigNode);
346  }
347  listNode = xml->GetNext(listNode);
348  }
349 
350  return result;
351 }
352 
354 {
355  const uint64_t eventNumber = eventInfo->eventNumber();
356 
357  const auto mapIterator = m_eventNumberToIdMap.find(eventNumber);
358  if (mapIterator != m_eventNumberToIdMap.end()) {
359  return mapIterator->second;
360  }
361  // Unfortunately, earlier weighting XMLs have 32 bit signed event number. Hence we also have to try this option
362  const int32_t eventNumber32 = static_cast<int32_t>(eventNumber);
363  const auto mapIterator32 = m_eventNumberToIdMap.find(eventNumber32);
364  if (mapIterator32 != m_eventNumberToIdMap.end()) {
365  return mapIterator32->second;
366  } else {
367  ATH_MSG_ERROR( "Couldn't find enhanced bias info for event " << eventNumber);
368  return -1;
369  }
370 }
371 
372 int32_t EnhancedBiasWeighter::getEventEBID(const EventContext& context) const
373 {
374  const uint64_t eventNumber = context.eventID().event_number();
375 
376  const auto mapIterator = m_eventNumberToIdMap.find(eventNumber);
377  if (mapIterator != m_eventNumberToIdMap.end()) {
378  return mapIterator->second;
379  }
380  // Unfortunately, earlier weighting XMLs have 32 bit signed event number. Hence we also have to try this option
381  const int32_t eventNumber32 = static_cast<int32_t>(eventNumber);
382  const auto mapIterator32 = m_eventNumberToIdMap.find(eventNumber32);
383  if (mapIterator32 != m_eventNumberToIdMap.end()) {
384  return mapIterator32->second;
385  } else {
386  ATH_MSG_ERROR( "Couldn't find enhanced bias info for event " << eventNumber);
387  return -1;
388  }
389 }
390 
392 {
393  if (m_enforceEBGRL && !isGoodLB(eventInfo)) {
394  return 0;
395  }
396 
397  ATH_CHECK( trackAverages(eventInfo), 0 );
398 
399  if (m_isMC) {
400 
402  return 1.;
403  }
404 
405  const std::vector<float> weights = eventInfo->mcEventWeights();
406  if (weights.size() > 0) {
407  return weights[0];
408  }
409  return 1.;
410 
411  } else { // isData
412 
413  int32_t ebID = getEventEBID(eventInfo);
414  const auto mapIterator = m_idToWeightMap.find(ebID);
415  if (mapIterator == m_idToWeightMap.end() ) {
416  ATH_MSG_ERROR( "Couldn't find enhanced bias weight for event with ID " << ebID);
417  return 0;
418  }
419  return mapIterator->second;
420 
421  } // isData
422 }
423 
424 
425 double EnhancedBiasWeighter::getEBWeight(const EventContext& context) const
426 {
427 
428  if (m_enforceEBGRL && !isGoodLB(context)) {
429  return 0;
430  }
431 
432  ATH_CHECK( trackAverages(context), 0 );
433 
434  if (m_isMC) {
435 
436  ATH_MSG_ERROR( "Cannot use EventContext based getEBWeight with MC. Needs full EventInfo.");
437  return 0.;
438 
439  } else { // isData
440 
441  int32_t ebID = getEventEBID(context);
442  const auto mapIterator = m_idToWeightMap.find(ebID);
443  if (mapIterator == m_idToWeightMap.end() ) {
444  ATH_MSG_ERROR( "Couldn't find enhanced bias weight for event with ID " << ebID);
445  return 0;
446  }
447  return mapIterator->second;
448 
449  } // isData
450 }
451 
452 
453 StatusCode EnhancedBiasWeighter::trackAverages(const EventContext& context) const
454 {
455  m_lumiAverage += getLBLumi(context);
456  return StatusCode::SUCCESS;
457 }
458 
459 
461 {
462  m_muAverage += std::ceil( eventInfo->actualInteractionsPerCrossing() );
463  m_lumiAverage += getLBLumi(eventInfo);
464  return StatusCode::SUCCESS;
465 }
466 
468 {
469  if (m_isMC) {
470 
471  // Probability that a single pp interaction yields this MC process (ratio of xsec)
472  const double probOfProcess = m_mcModifiedCrossSection / m_inelasticCrossSection;
473  // Probability that a single bunch-crossing yeild this MC process. Binomial statistics (1 - Prob(exactly 0 interactions, given mu interactions)).
474  const double probOfBunchCrossing = 1. - std::pow( 1. - probOfProcess, std::ceil(eventInfo->actualInteractionsPerCrossing()) );
475  const double bunchCrossingRate = m_pairedBunches * LHC_FREQUENCY;
476  // How much wall-time does this event represent? This is the reciprocal of the rate, which is the % per crossing scaled by the crossing rate.
477  ATH_MSG_DEBUG("MC livetime debug: probOfProcess:" << probOfProcess << " probOfBunchCrossing:" << probOfBunchCrossing << " bunchCrossingRate:" << bunchCrossingRate << " time:" << (1. / (probOfBunchCrossing * bunchCrossingRate)));
478  return 1. / (probOfBunchCrossing * bunchCrossingRate);
479 
480  } else {
481 
482  uint32_t lumiBlock = eventInfo->lumiBlock();
483  std::lock_guard<std::mutex> scopeLock(m_mutex);
484 
485  // Check the cache
486  const auto inCacheIterator = m_eventLivetime.find( lumiBlock );
487  if (inCacheIterator != m_eventLivetime.end()) return inCacheIterator->second;
488 
489  // Else calculate
490  const auto mapIterator = m_eventsPerLB.find(lumiBlock);
491  if (mapIterator == m_eventsPerLB.end() ) {
493  ATH_MSG_ERROR( "Couldn't find LB info for LB: " << lumiBlock );
494  }
495  return 0;
496  }
497  const int32_t eventsInThisLB = mapIterator->second;
498  const double lbLength = m_readLumiBlock.getLumiBlockLength(lumiBlock, msg());
499  // This event is one in eventsInThisLB, so has an effective temporal contribution of:
500  double eventLivetime = 0;
501  if (eventsInThisLB > 0 && fabs(lbLength) > 1e-10) eventLivetime = (1. / static_cast<double>(eventsInThisLB)) * lbLength;
502  // Cache this (mutable)
503  m_eventLivetime[lumiBlock] = eventLivetime;
504  return eventLivetime;
505 
506  } // isData
507 }
508 
509 double EnhancedBiasWeighter::getEBLiveTime(const EventContext& context) const
510 {
511  if (m_isMC) {
512 
513  ATH_MSG_ERROR( "Cannot use EventContext based getEBLiveTime with MC. Needs full EventInfo.");
514  return 0.;
515 
516  } else {
517 
518  uint32_t lumiBlock = context.eventID().lumi_block();
519  std::lock_guard<std::mutex> scopeLock(m_mutex);
520 
521  // Check the cache
522  const auto inCacheIterator = m_eventLivetime.find( lumiBlock );
523  if (inCacheIterator != m_eventLivetime.end()) return inCacheIterator->second;
524 
525  // Else calculate
526  const auto mapIterator = m_eventsPerLB.find(lumiBlock);
527  if (mapIterator == m_eventsPerLB.end() ) {
529  ATH_MSG_ERROR( "Couldn't find LB info for LB: " << lumiBlock );
530  }
531  return 0.;
532  }
533  const int32_t eventsInThisLB = mapIterator->second;
534  const double lbLength = m_readLumiBlock.getLumiBlockLength(lumiBlock, msg());
535  // This event is one in eventsInThisLB, so has an effective temporal contribution of:
536  double eventLivetime = 0;
537  if (eventsInThisLB > 0 && fabs(lbLength) > 1e-10) eventLivetime = (1. / static_cast<double>(eventsInThisLB)) * lbLength;
538  // Cache this (mutable)
539  m_eventLivetime[lumiBlock] = eventLivetime;
540  return eventLivetime;
541 
542  } // isData
543 
544 }
545 
546 double EnhancedBiasWeighter::getLBLength(const xAOD::EventInfo* eventInfo) const {
547  if (m_isMC) {
548  ATH_MSG_ERROR( "getLBLength Does not work for MC.");
549  return 0.;
550  } else {
551  uint32_t lumiBlock = eventInfo->lumiBlock();
552  const double lbLength = m_readLumiBlock.getLumiBlockLength(lumiBlock, msg());
553  return lbLength;
554  } // isData
555 }
556 
557 
558 
559 double EnhancedBiasWeighter::getLBLength(const EventContext& context) const {
560  if (m_isMC) {
561  ATH_MSG_ERROR( "getLBLength Does not work for MC.");
562  return 0.;
563  } else {
564  uint32_t lumiBlock = context.eventID().lumi_block();
565  const double lbLength = m_readLumiBlock.getLumiBlockLength(lumiBlock, msg());
566  return lbLength;
567  } // isData
568 }
569 
570 
572 {
573  if (m_isMC) {
574 
575  return true;
576 
577  } else { //isData
578 
579  int32_t ebID = getEventEBID(eventInfo);
580  const auto mapIterator = m_idToUnbiasedMap.find(ebID);
581  if (mapIterator == m_idToUnbiasedMap.end() ) {
582  ATH_MSG_ERROR("Couldn't find isUnbiased information for event with ID " << ebID);
583  return false;
584  }
585  return mapIterator->second;
586 
587  } // isData
588 }
589 
591 {
592  if (m_isMC) {
593 
594  return true;
595 
596  } else { // isData
597 
598  uint32_t lumiBlock = eventInfo->lumiBlock();
599 
600  const auto mapIterator = m_goodLB.find(lumiBlock);
601  if (mapIterator == m_goodLB.end() ) {
602  ATH_MSG_ERROR( "Couldn't find LB good/bad info for LB: " << lumiBlock );
603  return false;
604  }
605  return static_cast<bool>(mapIterator->second);
606 
607  } // isData
608 }
609 
610 bool EnhancedBiasWeighter::isGoodLB(const EventContext& context) const
611 {
612  if (m_isMC) {
613 
614  return true;
615 
616  } else { // isData
617 
618  uint32_t lumiBlock = context.eventID().lumi_block();
619 
620  const auto mapIterator = m_goodLB.find(lumiBlock);
621  if (mapIterator == m_goodLB.end() ) {
622  ATH_MSG_ERROR( "Couldn't find LB good/bad info for LB: " << lumiBlock );
623  return false;
624  }
625  return static_cast<bool>(mapIterator->second);
626 
627  } // isData
628 }
629 
631  return m_isMC;
632 }
633 
635  return m_runNumber;
636 }
637 
638 double EnhancedBiasWeighter::getLBLumi(const xAOD::EventInfo* eventInfo) const
639 {
640  if (m_isMC) {
641 
642  const double mu = std::ceil( eventInfo->actualInteractionsPerCrossing() );
644 
645  } else { // isData
646 
647  uint32_t lumiBlock = eventInfo->lumiBlock();
648  const auto mapIterator = m_lumiPerLB.find(lumiBlock);
649  if (mapIterator == m_lumiPerLB.end() ) {
650  ATH_MSG_ERROR( "Couldn't find lumi info for LB: " << lumiBlock );
651  return 0.;
652  }
653  return mapIterator->second;
654 
655  } // isData
656 }
657 
658 double EnhancedBiasWeighter::getLBLumi(const EventContext& context) const
659 {
660  if (m_isMC) {
661 
662  ATH_MSG_ERROR( "Cannot use EventContext based getLBLumi with MC. Needs full EventInfo.");
663  return 0.;
664 
665  } else { // isData
666 
667  uint32_t lumiBlock = context.eventID().lumi_block();
668  const auto mapIterator = m_lumiPerLB.find(lumiBlock);
669  if (mapIterator == m_lumiPerLB.end() ) {
670  ATH_MSG_ERROR( "Couldn't find lumi info for LB: " << lumiBlock );
671  return 0.;
672  }
673  return mapIterator->second;
674 
675  } // isData
676 }
677 
679 {
680  if (m_isMC) {
681  return 1.;
682  }
683  else if (m_deadtimePerLB.count(lumiblock)) {
684  return m_deadtimePerLB.at(lumiblock);
685  }
686  return m_deadtime;
687 }
688 
690 {
691  return m_pairedBunches;
692 }
693 
695 {
696  if (!m_useBunchCrossingData) return StatusCode::SUCCESS;
697 
698  const EventContext& context = Gaudi::Hive::currentContext();
700  ATH_CHECK( bunchCrossingTool.isValid() );
701  distance = bunchCrossingTool->distanceFromFront( eventInfo->bcid(), BunchCrossingCondData::BunchDistanceType::BunchCrossings );
702 
703  return StatusCode::SUCCESS;
704 }
705 
707 {
708  return m_lumiAverage.mean();
709 }
710 
712 {
713  return m_muAverage.mean();
714 }
715 
716 
718 {
719  // Set up the decorator
720  SG::AuxElement::Decorator< double > decoratorEBWeight("EnhancedBiasWeight");
721  SG::AuxElement::Decorator< double > decoratorEBLivetime("EnhancedBiasLivetime");
722  SG::AuxElement::Decorator< double > decoratorLBLumi("LBLumi");
723  SG::AuxElement::Decorator< double > decoratorDeadtime("Deadtime");
724  SG::AuxElement::Decorator< uint32_t > decoratorBCIDDistanceFromFront("BCIDDistanceFromFront");
725  SG::AuxElement::Decorator< char > decoratorUnbiasedFlag("IsUnbiasedEventFlag");
726  SG::AuxElement::Decorator< char > decoratorGoodLBFlag("IsGoodLBFlag");
727 
728  const xAOD::EventInfo* eventInfo(nullptr);
729  uint32_t distance = 0;
730  ATH_CHECK( evtStore()->retrieve(eventInfo, "EventInfo") );
731  ATH_CHECK( getDistanceIntoTrain(eventInfo, distance) );
732 
733  decoratorEBWeight(*eventInfo) = getEBWeight(eventInfo);
734  decoratorEBLivetime(*eventInfo) = getEBLiveTime(eventInfo);
735  decoratorLBLumi(*eventInfo) = getLBLumi(eventInfo);
736  decoratorUnbiasedFlag(*eventInfo) = isUnbiasedEvent(eventInfo);
737  decoratorGoodLBFlag(*eventInfo) = isGoodLB(eventInfo);
738  decoratorDeadtime(*eventInfo) = getDeadtime(eventInfo->lumiBlock());
739  decoratorBCIDDistanceFromFront(*eventInfo) = distance;
740 
741  return StatusCode::SUCCESS;
742 }
743 
744 
745 std::string EnhancedBiasWeighter::findLocalFile (const std::string& fileName) const {
746 
747  if (m_weightsDirectory.empty()) {
748  ATH_MSG_ERROR("Local directory for EB xml not set!");
749  return "";
750  }
751 
752  std::string fullName = m_weightsDirectory+ "/" + fileName;
753 
755  ATH_MSG_ERROR("File " << fullName << " not found!");
756  return "";
757  }
758 
759  return fullName;
760 }
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
EnhancedBiasWeighter::getEBLiveTime
virtual double getEBLiveTime(const xAOD::EventInfo *eventInfo) const override
Definition: EnhancedBiasWeighter.cxx:467
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
EnhancedBiasWeighter::m_mcCrossSection
Gaudi::Property< double > m_mcCrossSection
Definition: EnhancedBiasWeighter.h:192
EnhancedBiasWeighter::initialize
virtual StatusCode initialize() override
Initialize is required by AsgTool base class.
Definition: EnhancedBiasWeighter.cxx:36
get_generator_info.result
result
Definition: get_generator_info.py:21
EnhancedBiasWeighter::m_runNumber
Gaudi::Property< uint32_t > m_runNumber
Definition: EnhancedBiasWeighter.h:187
SG::ReadCondHandle
Definition: ReadCondHandle.h:44
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
xAOD::EventInfo_v1::eventNumber
uint64_t eventNumber() const
The current event's event number.
python.MagFieldUtils.lumiblock
lumiblock
Definition: MagFieldUtils.py:188
EnhancedBiasWeighter::getDistanceIntoTrain
virtual StatusCode getDistanceIntoTrain(const xAOD::EventInfo *eventInfo, uint32_t &distance) const override
Definition: EnhancedBiasWeighter.cxx:694
xAOD::EventInfo_v1::mcEventWeights
const std::vector< float > & mcEventWeights() const
The weights of all the MC events used in the simulation.
xAOD::uint32_t
setEventNumber uint32_t
Definition: EventInfo_v1.cxx:127
EnhancedBiasWeighter::m_pairedBunches
uint32_t m_pairedBunches
Online number of paired bunches.
Definition: EnhancedBiasWeighter.h:201
EnhancedBiasWeighter::m_isMC
Gaudi::Property< bool > m_isMC
Definition: EnhancedBiasWeighter.h:191
EnhancedBiasWeighter::trackAverages
StatusCode trackAverages(const xAOD::EventInfo *eventInfo) const
Internal function to keep track of the mean instantaneous lumi & mean pileup of the EB/MC sample bein...
Definition: EnhancedBiasWeighter.cxx:460
EnhancedBiasWeighter::getLBLumi
virtual double getLBLumi(const xAOD::EventInfo *eventInfo) const override
Definition: EnhancedBiasWeighter.cxx:638
EnhancedBiasWeighter::m_mcIgnoreGeneratorWeights
Gaudi::Property< bool > m_mcIgnoreGeneratorWeights
Definition: EnhancedBiasWeighter.h:195
WriteCellNoiseToCool.fullName
fullName
Definition: WriteCellNoiseToCool.py:461
conifer::pow
constexpr int pow(int x)
Definition: conifer.h:20
EnhancedBiasWeighter::getLBLength
virtual double getLBLength(const xAOD::EventInfo *eventInfo) const override
Definition: EnhancedBiasWeighter.cxx:546
EnhancedBiasWeighter::m_idToUnbiasedMap
std::unordered_map< int32_t, uint8_t > m_idToUnbiasedMap
Map a weighting ID to a flag if this weight is from an unbiased (RD) trigger online.
Definition: EnhancedBiasWeighter.h:211
EnhancedBiasWeighter::m_deadtimePerLB
std::unordered_map< uint32_t, double > m_deadtimePerLB
Map of average deadtime per LB.
Definition: EnhancedBiasWeighter.h:215
EnhancedBiasWeighter::m_eventsPerLB
std::unordered_map< uint32_t, uint32_t > m_eventsPerLB
Map of how many EnhancedBias events were recorded per LB.
Definition: EnhancedBiasWeighter.h:212
asg
Definition: DataHandleTestTool.h:28
SG::ReadCondHandle::isValid
bool isValid()
Definition: ReadCondHandle.h:205
EnhancedBiasWeighter::getEventEBID
int32_t getEventEBID(const xAOD::EventInfo *eventInfo) const
Definition: EnhancedBiasWeighter.cxx:353
detail
Definition: extract_histogram_tag.cxx:14
EnhancedBiasWeighter::getDeadtime
virtual double getDeadtime(const int lumiblock=-1) const override
Definition: EnhancedBiasWeighter.cxx:678
EnhancedBiasWeighter::parsePrescaleXML
virtual std::unordered_map< std::string, ChainDetail > parsePrescaleXML(const std::string &prescaleXML) const override
Parse a presscale XML and return a ordered summary of its content To make most use of the XML parsing...
Definition: EnhancedBiasWeighter.cxx:249
EnhancedBiasWeighter.h
ReadLumiBlock::getLumiBlockLength
float getLumiBlockLength(uint32_t lb, MsgStream &msg) const
Definition: ReadLumiBlock.cxx:102
Trk::u
@ u
Enums for curvilinear frames.
Definition: ParamDefs.h:83
dqt_zlumi_pandas.weight
int weight
Definition: dqt_zlumi_pandas.py:200
EnhancedBiasWeighter::m_inelasticCrossSection
Gaudi::Property< double > m_inelasticCrossSection
Definition: EnhancedBiasWeighter.h:196
EnhancedBiasWeighter::m_enforceEBGRL
Gaudi::Property< bool > m_enforceEBGRL
Definition: EnhancedBiasWeighter.h:189
ExtractEBRunDetails.xml
xml
Definition: ExtractEBRunDetails.py:239
EnhancedBiasWeighter::m_weightsDirectory
Gaudi::Property< std::string > m_weightsDirectory
Definition: EnhancedBiasWeighter.h:197
EnhancedBiasWeighter::findLocalFile
std::string findLocalFile(const std::string &fileName) const
Definition: EnhancedBiasWeighter.cxx:745
AthCommonDataStore< AthCommonMsg< AlgTool > >::evtStore
ServiceHandle< StoreGateSvc > & evtStore()
The standard StoreGateSvc (event store) Returns (kind of) a pointer to the StoreGateSvc.
Definition: AthCommonDataStore.h:85
EnhancedBiasWeighter::m_bunches
std::vector< int32_t > m_bunches
Number of BCIDs in each bunch group.
Definition: EnhancedBiasWeighter.h:217
EnhancedBiasWeighter::isGoodLB
virtual bool isGoodLB(const xAOD::EventInfo *eventInfo) const override
Definition: EnhancedBiasWeighter.cxx:590
FortranAlgorithmOptions.fileName
fileName
Definition: FortranAlgorithmOptions.py:13
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
EnhancedBiasWeighter::getAverageMu
virtual double getAverageMu() const override
Definition: EnhancedBiasWeighter.cxx:711
python.BunchSpacingUtils.lb
lb
Definition: BunchSpacingUtils.py:88
SG::Decorator
Helper class to provide type-safe access to aux data.
Definition: Decorator.h:58
lumiFormat.i
int i
Definition: lumiFormat.py:92
EnhancedBiasWeighter::m_readLumiBlock
ReadLumiBlock m_readLumiBlock
Cache lumi block lengths.
Definition: EnhancedBiasWeighter.h:219
ret
T ret(T t)
Definition: rootspy.cxx:260
endmsg
#define endmsg
Definition: AnalysisConfig_Ntuple.cxx:63
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
master.flag
bool flag
Definition: master.py:29
EnhancedBiasWeighter::getAverageLumi
virtual double getAverageLumi() const override
Definition: EnhancedBiasWeighter.cxx:706
xAOD::uint64_t
uint64_t
Definition: EventInfo_v1.cxx:123
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
nEvents
int nEvents
Definition: fbtTestBasics.cxx:77
xAOD::eventNumber
eventNumber
Definition: EventInfo_v1.cxx:124
xAOD::EventInfo_v1::lumiBlock
uint32_t lumiBlock() const
The current event's luminosity block number.
EnhancedBiasWeighter::m_useBunchCrossingData
Gaudi::Property< bool > m_useBunchCrossingData
Definition: EnhancedBiasWeighter.h:190
EnhancedBiasWeighter::isMC
virtual bool isMC() const override
Definition: EnhancedBiasWeighter.cxx:630
EnhancedBiasWeighter::FULL_RING
constexpr static uint32_t FULL_RING
Number of bunches in a full ring.
Definition: EnhancedBiasWeighter.h:56
CxxUtils::atof
double atof(std::string_view str)
Converts a string into a double / float.
Definition: Control/CxxUtils/Root/StringUtils.cxx:91
ReadLumiBlock::updateLumiBlocks
bool updateLumiBlocks(uint32_t run, MsgStream &msg)
Load information for.
Definition: ReadLumiBlock.cxx:42
BunchCrossingCondData::distanceFromFront
int distanceFromFront(const bcid_type bcid, const BunchDistanceType type=NanoSec) const
The distance of the specific bunch crossing from the front of the train.
Definition: BunchCrossingCondData.cxx:35
EnhancedBiasWeighter::m_bunchCrossingKey
SG::ReadCondHandleKey< BunchCrossingCondData > m_bunchCrossingKey
Tool to get distance into bunch train.
Definition: EnhancedBiasWeighter.h:185
EnhancedBiasWeighter::m_eventNumberToIdMap
std::unordered_map< uint64_t, int32_t > m_eventNumberToIdMap
Map event number to a weighting ID.
Definition: EnhancedBiasWeighter.h:203
EnhancedBiasWeighter::getEBWeight
virtual double getEBWeight(const xAOD::EventInfo *eventInfo) const override
Definition: EnhancedBiasWeighter.cxx:391
PathResolver.h
EnhancedBiasWeighter::m_mcFilterEfficiency
Gaudi::Property< double > m_mcFilterEfficiency
Definition: EnhancedBiasWeighter.h:193
id
SG::auxid_t id
Definition: Control/AthContainers/Root/debug.cxx:191
EnhancedBiasWeighter::LHC_FREQUENCY
constexpr static double LHC_FREQUENCY
Definition: EnhancedBiasWeighter.h:55
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:192
EnhancedBiasWeighter::m_errorOnMissingEBWeights
Gaudi::Property< bool > m_errorOnMissingEBWeights
Definition: EnhancedBiasWeighter.h:188
SG::CondHandleKey::initialize
StatusCode initialize(bool used=true)
EnhancedBiasWeighter::getPairedBunches
virtual uint32_t getPairedBunches() const override
Definition: EnhancedBiasWeighter.cxx:689
EnhancedBiasWeighter::addBranches
virtual StatusCode addBranches() const override
Decorate the AOD with EnhancedBias weighting quantities such that no CVMFS or DB access is required o...
Definition: EnhancedBiasWeighter.cxx:717
EnhancedBiasWeighter::EnhancedBiasWeighter
EnhancedBiasWeighter(const std::string &name)
Definition: EnhancedBiasWeighter.cxx:29
EnhancedBiasWeighter::getRunNumber
virtual uint32_t getRunNumber() const override
Definition: EnhancedBiasWeighter.cxx:634
EnhancedBiasWeighter::m_goodLB
std::unordered_map< uint32_t, uint8_t > m_goodLB
Like a Good Run List flag for EnhancedBias runs.
Definition: EnhancedBiasWeighter.h:214
EnhancedBiasWeighter::m_mutex
std::mutex m_mutex
Protection for above map.
Definition: EnhancedBiasWeighter.h:206
xAOD::EventInfo_v1
Class describing the basic event information.
Definition: EventInfo_v1.h:43
EnhancedBiasWeighter::finalize
virtual StatusCode finalize() override
Definition: EnhancedBiasWeighter.cxx:69
PathResolverFindCalibFile
std::string PathResolverFindCalibFile(const std::string &logical_file_name)
Definition: PathResolver.cxx:431
EnhancedBiasWeighter::isUnbiasedEvent
virtual bool isUnbiasedEvent(const xAOD::EventInfo *eventInfo) const override
Definition: EnhancedBiasWeighter.cxx:571
DeMoAtlasDataLoss.runNumber
string runNumber
Definition: DeMoAtlasDataLoss.py:64
PathResolverFindDataFile
std::string PathResolverFindDataFile(const std::string &logical_file_name)
Definition: PathResolver.cxx:379
lumiFormat.lumi
lumi
Definition: lumiFormat.py:113
DiTauMassTools::MaxHistStrategyV2::e
e
Definition: PhysicsAnalysis/TauID/DiTauMassTools/DiTauMassTools/HelperFunctions.h:26
EnhancedBiasWeighter::loadWeights
StatusCode loadWeights()
Read into memory from XML event weights for this EnhancedBias run.
Definition: EnhancedBiasWeighter.cxx:75
EnhancedBiasWeighter::m_idToWeightMap
std::unordered_map< int32_t, double > m_idToWeightMap
Map a weighting ID to a Enhanced Bias event weight.
Definition: EnhancedBiasWeighter.h:210
EnhancedBiasWeighter::m_deadtime
double m_deadtime
Online deadtime to correct for in rate prediction.
Definition: EnhancedBiasWeighter.h:200
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
EnhancedBiasWeighter::m_mcModifiedCrossSection
double m_mcModifiedCrossSection
Product of xsec, filter & kfactor.
Definition: EnhancedBiasWeighter.h:202
python.TriggerAPI.TriggerAPISession.chainName
chainName
Definition: TriggerAPISession.py:353
AthCommonMsg< AlgTool >::msg
MsgStream & msg() const
Definition: AthCommonMsg.h:24
EnhancedBiasWeighter::m_lumiPerLB
std::unordered_map< uint32_t, double > m_lumiPerLB
Map of instantaneous luminosity per LB.
Definition: EnhancedBiasWeighter.h:213
EnhancedBiasWeighter::m_mcKFactor
Gaudi::Property< double > m_mcKFactor
Definition: EnhancedBiasWeighter.h:194
CxxUtils::atoi
int atoi(std::string_view str)
Helper functions to unpack numbers decoded in string into integers and doubles The strings are requir...
Definition: Control/CxxUtils/Root/StringUtils.cxx:85
python.dummyaccess.exists
def exists(filename)
Definition: dummyaccess.py:9
xAOD::EventInfo_v1::bcid
uint32_t bcid() const
The bunch crossing ID of the event.
xAOD::lumiBlock
setTeId lumiBlock
Definition: L2StandAloneMuon_v1.cxx:327
CaloNoise_fillDB.mu
mu
Definition: CaloNoise_fillDB.py:53
EnhancedBiasWeighter::loadLumi
StatusCode loadLumi()
Read into memory this EnhancedBias run's XML.
Definition: EnhancedBiasWeighter.cxx:146
Amg::distance
float distance(const Amg::Vector3D &p1, const Amg::Vector3D &p2)
calculates the distance between two point in 3D space
Definition: GeoPrimitivesHelpers.h:54
TSU::T
unsigned long long T
Definition: L1TopoDataTypes.h:35
node
Definition: memory_hooks-stdcmalloc.h:74
ChainDetail
Structure to encompass the data stored in a prescales XML generated by the RuleBook.
Definition: EnhancedBiasWeighter.h:25
xAOD::EventInfo_v1::actualInteractionsPerCrossing
float actualInteractionsPerCrossing() const
Average interactions per crossing for the current BCID - for in-time pile-up.
Definition: EventInfo_v1.cxx:380