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 double 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 = std::move(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 && m_doMultiSliceDiJet) {
400  return static_cast<double>(eventInfo->mcEventWeight(0)) * m_mcModifiedCrossSection * m_targetLumi;
401 
402  } else if (m_isMC) {
403 
405  return 1.;
406  }
407 
408  const std::vector<float> weights = eventInfo->mcEventWeights();
409  if (weights.size() > 0) {
410  return weights[0];
411  }
412  return 1.;
413 
414  } else { // isData
415 
416  int32_t ebID = getEventEBID(eventInfo);
417  const auto mapIterator = m_idToWeightMap.find(ebID);
418  if (mapIterator == m_idToWeightMap.end() ) {
419  ATH_MSG_ERROR( "Couldn't find enhanced bias weight for event with ID " << ebID);
420  return 0;
421  }
422  return mapIterator->second;
423 
424  } // isData
425 }
426 
427 
428 double EnhancedBiasWeighter::getEBWeight(const EventContext& context) const
429 {
430 
431  if (m_enforceEBGRL && !isGoodLB(context)) {
432  return 0;
433  }
434 
435  ATH_CHECK( trackAverages(context), 0 );
436 
437  if (m_isMC) {
438 
439  ATH_MSG_ERROR( "Cannot use EventContext based getEBWeight with MC. Needs full EventInfo.");
440  return 0.;
441 
442  } else { // isData
443 
444  int32_t ebID = getEventEBID(context);
445  const auto mapIterator = m_idToWeightMap.find(ebID);
446  if (mapIterator == m_idToWeightMap.end() ) {
447  ATH_MSG_ERROR( "Couldn't find enhanced bias weight for event with ID " << ebID);
448  return 0;
449  }
450  return mapIterator->second;
451 
452  } // isData
453 }
454 
455 
456 StatusCode EnhancedBiasWeighter::trackAverages(const EventContext& context) const
457 {
458  m_lumiAverage += getLBLumi(context);
459  return StatusCode::SUCCESS;
460 }
461 
462 
464 {
465  m_muAverage += std::ceil( eventInfo->actualInteractionsPerCrossing() );
466  m_lumiAverage += getLBLumi(eventInfo);
467  return StatusCode::SUCCESS;
468 }
469 
472 }
474 {
475  if (m_isMC) {
476 
477  // Probability that a single pp interaction yields this MC process (ratio of xsec)
478  const double probOfProcess = m_mcModifiedCrossSection / m_inelasticCrossSection;
479  // Probability that a single bunch-crossing yeild this MC process. Binomial statistics (1 - Prob(exactly 0 interactions, given mu interactions)).
480  const double probOfBunchCrossing = 1. - std::pow( 1. - probOfProcess, std::ceil(eventInfo->actualInteractionsPerCrossing()) );
481  const double bunchCrossingRate = m_pairedBunches * LHC_FREQUENCY;
482  // 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.
483  ATH_MSG_DEBUG("MC livetime debug: probOfProcess:" << probOfProcess << " probOfBunchCrossing:" << probOfBunchCrossing << " bunchCrossingRate:" << bunchCrossingRate << " time:" << (1. / (probOfBunchCrossing * bunchCrossingRate)));
484  return 1. / (probOfBunchCrossing * bunchCrossingRate);
485 
486  } else {
487 
488  uint32_t lumiBlock = eventInfo->lumiBlock();
489  std::lock_guard<std::mutex> scopeLock(m_mutex);
490 
491  // Check the cache
492  const auto inCacheIterator = m_eventLivetime.find( lumiBlock );
493  if (inCacheIterator != m_eventLivetime.end()) return inCacheIterator->second;
494 
495  // Else calculate
496  const auto mapIterator = m_eventsPerLB.find(lumiBlock);
497  if (mapIterator == m_eventsPerLB.end() ) {
499  ATH_MSG_ERROR( "Couldn't find LB info for LB: " << lumiBlock );
500  }
501  return 0;
502  }
503  const int32_t eventsInThisLB = mapIterator->second;
504  const double lbLength = m_readLumiBlock.getLumiBlockLength(lumiBlock, msg());
505  // This event is one in eventsInThisLB, so has an effective temporal contribution of:
506  double eventLivetime = 0;
507  if (eventsInThisLB > 0 && fabs(lbLength) > 1e-10) eventLivetime = (1. / static_cast<double>(eventsInThisLB)) * lbLength;
508  // Cache this (mutable)
509  m_eventLivetime[lumiBlock] = eventLivetime;
510  return eventLivetime;
511 
512  } // isData
513 }
514 
515 double EnhancedBiasWeighter::getEBLiveTime(const EventContext& context) const
516 {
517  if (m_isMC) {
518 
519  ATH_MSG_ERROR( "Cannot use EventContext based getEBLiveTime with MC. Needs full EventInfo.");
520  return 0.;
521 
522  } else {
523 
524  uint32_t lumiBlock = context.eventID().lumi_block();
525  std::lock_guard<std::mutex> scopeLock(m_mutex);
526 
527  // Check the cache
528  const auto inCacheIterator = m_eventLivetime.find( lumiBlock );
529  if (inCacheIterator != m_eventLivetime.end()) return inCacheIterator->second;
530 
531  // Else calculate
532  const auto mapIterator = m_eventsPerLB.find(lumiBlock);
533  if (mapIterator == m_eventsPerLB.end() ) {
535  ATH_MSG_ERROR( "Couldn't find LB info for LB: " << lumiBlock );
536  }
537  return 0.;
538  }
539  const int32_t eventsInThisLB = mapIterator->second;
540  const double lbLength = m_readLumiBlock.getLumiBlockLength(lumiBlock, msg());
541  // This event is one in eventsInThisLB, so has an effective temporal contribution of:
542  double eventLivetime = 0;
543  if (eventsInThisLB > 0 && fabs(lbLength) > 1e-10) eventLivetime = (1. / static_cast<double>(eventsInThisLB)) * lbLength;
544  // Cache this (mutable)
545  m_eventLivetime[lumiBlock] = eventLivetime;
546  return eventLivetime;
547 
548  } // isData
549 
550 }
551 
552 double EnhancedBiasWeighter::getLBLength(const xAOD::EventInfo* eventInfo) const {
553  if (m_isMC) {
554  ATH_MSG_ERROR( "getLBLength Does not work for MC.");
555  return 0.;
556  } else {
557  uint32_t lumiBlock = eventInfo->lumiBlock();
558  const double lbLength = m_readLumiBlock.getLumiBlockLength(lumiBlock, msg());
559  return lbLength;
560  } // isData
561 }
562 
563 
564 
565 double EnhancedBiasWeighter::getLBLength(const EventContext& context) const {
566  if (m_isMC) {
567  ATH_MSG_ERROR( "getLBLength Does not work for MC.");
568  return 0.;
569  } else {
570  uint32_t lumiBlock = context.eventID().lumi_block();
571  const double lbLength = m_readLumiBlock.getLumiBlockLength(lumiBlock, msg());
572  return lbLength;
573  } // isData
574 }
575 
576 
578 {
579  if (m_isMC) {
580 
581  return true;
582 
583  } else { //isData
584 
585  int32_t ebID = getEventEBID(eventInfo);
586  const auto mapIterator = m_idToUnbiasedMap.find(ebID);
587  if (mapIterator == m_idToUnbiasedMap.end() ) {
588  ATH_MSG_ERROR("Couldn't find isUnbiased information for event with ID " << ebID);
589  return false;
590  }
591  return mapIterator->second;
592 
593  } // isData
594 }
595 
597 {
598  if (m_isMC) {
599 
600  return true;
601 
602  } else { // isData
603 
604  uint32_t lumiBlock = eventInfo->lumiBlock();
605 
606  const auto mapIterator = m_goodLB.find(lumiBlock);
607  if (mapIterator == m_goodLB.end() ) {
608  ATH_MSG_ERROR( "Couldn't find LB good/bad info for LB: " << lumiBlock );
609  return false;
610  }
611  return static_cast<bool>(mapIterator->second);
612 
613  } // isData
614 }
615 
616 bool EnhancedBiasWeighter::isGoodLB(const EventContext& context) const
617 {
618  if (m_isMC) {
619 
620  return true;
621 
622  } else { // isData
623 
624  uint32_t lumiBlock = context.eventID().lumi_block();
625 
626  const auto mapIterator = m_goodLB.find(lumiBlock);
627  if (mapIterator == m_goodLB.end() ) {
628  ATH_MSG_ERROR( "Couldn't find LB good/bad info for LB: " << lumiBlock );
629  return false;
630  }
631  return static_cast<bool>(mapIterator->second);
632 
633  } // isData
634 }
635 
637  return m_isMC;
638 }
639 
641  return m_runNumber;
642 }
643 
644 double EnhancedBiasWeighter::getLBLumi(const xAOD::EventInfo* eventInfo) const
645 {
646  if (m_isMC) {
647 
648  const double mu = std::ceil( eventInfo->actualInteractionsPerCrossing() );
650 
651  } else { // isData
652 
653  uint32_t lumiBlock = eventInfo->lumiBlock();
654  const auto mapIterator = m_lumiPerLB.find(lumiBlock);
655  if (mapIterator == m_lumiPerLB.end() ) {
656  ATH_MSG_ERROR( "Couldn't find lumi info for LB: " << lumiBlock );
657  return 0.;
658  }
659  return mapIterator->second;
660 
661  } // isData
662 }
663 
664 double EnhancedBiasWeighter::getLBLumi(const EventContext& context) const
665 {
666  if (m_isMC) {
667 
668  ATH_MSG_ERROR( "Cannot use EventContext based getLBLumi with MC. Needs full EventInfo.");
669  return 0.;
670 
671  } else { // isData
672 
673  uint32_t lumiBlock = context.eventID().lumi_block();
674  const auto mapIterator = m_lumiPerLB.find(lumiBlock);
675  if (mapIterator == m_lumiPerLB.end() ) {
676  ATH_MSG_ERROR( "Couldn't find lumi info for LB: " << lumiBlock );
677  return 0.;
678  }
679  return mapIterator->second;
680 
681  } // isData
682 }
683 
685 {
686  if (m_isMC) {
687  return 1.;
688  }
689  else if (m_deadtimePerLB.count(lumiblock)) {
690  return m_deadtimePerLB.at(lumiblock);
691  }
692  return m_deadtime;
693 }
694 
696 {
697  return m_pairedBunches;
698 }
699 
701 {
702  if (!m_useBunchCrossingData) return StatusCode::SUCCESS;
703 
704  const EventContext& context = Gaudi::Hive::currentContext();
706  ATH_CHECK( bunchCrossingTool.isValid() );
707  distance = bunchCrossingTool->distanceFromFront( eventInfo->bcid(), BunchCrossingCondData::BunchDistanceType::BunchCrossings );
708 
709  return StatusCode::SUCCESS;
710 }
711 
713 {
714  return m_lumiAverage.mean();
715 }
716 
718 {
719  return m_muAverage.mean();
720 }
721 
722 
724 {
725  // Set up the decorator
726  SG::AuxElement::Decorator< double > decoratorEBWeight("EnhancedBiasWeight");
727  SG::AuxElement::Decorator< double > decoratorEBLivetime("EnhancedBiasLivetime");
728  SG::AuxElement::Decorator< double > decoratorLBLumi("LBLumi");
729  SG::AuxElement::Decorator< double > decoratorDeadtime("Deadtime");
730  SG::AuxElement::Decorator< uint32_t > decoratorBCIDDistanceFromFront("BCIDDistanceFromFront");
731  SG::AuxElement::Decorator< char > decoratorUnbiasedFlag("IsUnbiasedEventFlag");
732  SG::AuxElement::Decorator< char > decoratorGoodLBFlag("IsGoodLBFlag");
733 
734  const xAOD::EventInfo* eventInfo(nullptr);
735  uint32_t distance = 0;
736  ATH_CHECK( evtStore()->retrieve(eventInfo, "EventInfo") );
737  ATH_CHECK( getDistanceIntoTrain(eventInfo, distance) );
738 
739  decoratorEBWeight(*eventInfo) = getEBWeight(eventInfo);
740  decoratorEBLivetime(*eventInfo) = getEBLiveTime(eventInfo);
741  decoratorLBLumi(*eventInfo) = getLBLumi(eventInfo);
742  decoratorUnbiasedFlag(*eventInfo) = isUnbiasedEvent(eventInfo);
743  decoratorGoodLBFlag(*eventInfo) = isGoodLB(eventInfo);
744  decoratorDeadtime(*eventInfo) = getDeadtime(eventInfo->lumiBlock());
745  decoratorBCIDDistanceFromFront(*eventInfo) = distance;
746 
747  return StatusCode::SUCCESS;
748 }
749 
750 
751 std::string EnhancedBiasWeighter::findLocalFile (const std::string& fileName) const {
752 
753  if (m_weightsDirectory.empty()) {
754  ATH_MSG_ERROR("Local directory for EB xml not set!");
755  return "";
756  }
757 
758  std::string fullName = m_weightsDirectory+ "/" + fileName;
759 
761  ATH_MSG_ERROR("File " << fullName << " not found!");
762  return "";
763  }
764 
765  return fullName;
766 }
python.PyKernel.retrieve
def retrieve(aClass, aKey=None)
Definition: PyKernel.py:110
nEvents
const int nEvents
Definition: fbtTestBasics.cxx:78
EnhancedBiasWeighter::getEBLiveTime
virtual double getEBLiveTime(const xAOD::EventInfo *eventInfo) const override
Definition: EnhancedBiasWeighter.cxx:473
AllowedVariables::e
e
Definition: AsgElectronSelectorTool.cxx:37
EnhancedBiasWeighter::getBunchCrossingRate
virtual double getBunchCrossingRate() const override
Definition: EnhancedBiasWeighter.cxx:470
EnhancedBiasWeighter::m_doMultiSliceDiJet
Gaudi::Property< bool > m_doMultiSliceDiJet
Definition: EnhancedBiasWeighter.h:203
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
EnhancedBiasWeighter::m_mcCrossSection
Gaudi::Property< double > m_mcCrossSection
Definition: EnhancedBiasWeighter.h:197
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:192
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:187
EnhancedBiasWeighter::getDistanceIntoTrain
virtual StatusCode getDistanceIntoTrain(const xAOD::EventInfo *eventInfo, uint32_t &distance) const override
Definition: EnhancedBiasWeighter.cxx:700
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:207
EnhancedBiasWeighter::m_isMC
Gaudi::Property< bool > m_isMC
Definition: EnhancedBiasWeighter.h:196
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:463
EnhancedBiasWeighter::getLBLumi
virtual double getLBLumi(const xAOD::EventInfo *eventInfo) const override
Definition: EnhancedBiasWeighter.cxx:644
EnhancedBiasWeighter::m_mcIgnoreGeneratorWeights
Gaudi::Property< bool > m_mcIgnoreGeneratorWeights
Definition: EnhancedBiasWeighter.h:200
WriteCellNoiseToCool.fullName
fullName
Definition: WriteCellNoiseToCool.py:461
EnhancedBiasWeighter::getLBLength
virtual double getLBLength(const xAOD::EventInfo *eventInfo) const override
Definition: EnhancedBiasWeighter.cxx:552
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:217
EnhancedBiasWeighter::m_deadtimePerLB
std::unordered_map< uint32_t, double > m_deadtimePerLB
Map of average deadtime per LB.
Definition: EnhancedBiasWeighter.h:221
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:218
asg
Definition: DataHandleTestTool.h:28
SG::ReadCondHandle::isValid
bool isValid()
Definition: ReadCondHandle.h:210
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:684
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:77
dqt_zlumi_pandas.weight
int weight
Definition: dqt_zlumi_pandas.py:190
EnhancedBiasWeighter::m_inelasticCrossSection
Gaudi::Property< double > m_inelasticCrossSection
Definition: EnhancedBiasWeighter.h:201
EnhancedBiasWeighter::m_enforceEBGRL
Gaudi::Property< bool > m_enforceEBGRL
Definition: EnhancedBiasWeighter.h:194
ExtractEBRunDetails.xml
xml
Definition: ExtractEBRunDetails.py:239
EnhancedBiasWeighter::m_weightsDirectory
Gaudi::Property< std::string > m_weightsDirectory
Definition: EnhancedBiasWeighter.h:202
EnhancedBiasWeighter::findLocalFile
std::string findLocalFile(const std::string &fileName) const
Definition: EnhancedBiasWeighter.cxx:751
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:223
EnhancedBiasWeighter::isGoodLB
virtual bool isGoodLB(const xAOD::EventInfo *eventInfo) const override
Definition: EnhancedBiasWeighter.cxx:596
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
EnhancedBiasWeighter::getAverageMu
virtual double getAverageMu() const override
Definition: EnhancedBiasWeighter.cxx:717
python.BunchSpacingUtils.lb
lb
Definition: BunchSpacingUtils.py:86
SG::Decorator
Helper class to provide type-safe access to aux data.
Definition: Decorator.h:59
lumiFormat.i
int i
Definition: lumiFormat.py:85
EnhancedBiasWeighter::m_readLumiBlock
ReadLumiBlock m_readLumiBlock
Cache lumi block lengths.
Definition: EnhancedBiasWeighter.h:225
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:712
xAOD::uint64_t
uint64_t
Definition: EventInfo_v1.cxx:123
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
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:195
EnhancedBiasWeighter::isMC
virtual bool isMC() const override
Definition: EnhancedBiasWeighter.cxx:636
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:38
EnhancedBiasWeighter::m_bunchCrossingKey
SG::ReadCondHandleKey< BunchCrossingCondData > m_bunchCrossingKey
Tool to get distance into bunch train.
Definition: EnhancedBiasWeighter.h:190
EnhancedBiasWeighter::m_eventNumberToIdMap
std::unordered_map< uint64_t, int32_t > m_eventNumberToIdMap
Map event number to a weighting ID.
Definition: EnhancedBiasWeighter.h:209
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:198
id
SG::auxid_t id
Definition: Control/AthContainers/Root/debug.cxx:239
EnhancedBiasWeighter::LHC_FREQUENCY
constexpr static double LHC_FREQUENCY
Definition: EnhancedBiasWeighter.h:55
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
EnhancedBiasWeighter::m_errorOnMissingEBWeights
Gaudi::Property< bool > m_errorOnMissingEBWeights
Definition: EnhancedBiasWeighter.h:193
SG::CondHandleKey::initialize
StatusCode initialize(bool used=true)
weights
Definition: herwig7_interface.h:38
EnhancedBiasWeighter::getPairedBunches
virtual uint32_t getPairedBunches() const override
Definition: EnhancedBiasWeighter.cxx:695
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:723
EnhancedBiasWeighter::EnhancedBiasWeighter
EnhancedBiasWeighter(const std::string &name)
Definition: EnhancedBiasWeighter.cxx:29
EnhancedBiasWeighter::getRunNumber
virtual uint32_t getRunNumber() const override
Definition: EnhancedBiasWeighter.cxx:640
EnhancedBiasWeighter::m_goodLB
std::unordered_map< uint32_t, uint8_t > m_goodLB
Like a Good Run List flag for EnhancedBias runs.
Definition: EnhancedBiasWeighter.h:220
EnhancedBiasWeighter::m_mutex
std::mutex m_mutex
Protection for above map.
Definition: EnhancedBiasWeighter.h:212
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:283
EnhancedBiasWeighter::isUnbiasedEvent
virtual bool isUnbiasedEvent(const xAOD::EventInfo *eventInfo) const override
Definition: EnhancedBiasWeighter.cxx:577
EnhancedBiasWeighter::m_targetLumi
Gaudi::Property< double > m_targetLumi
Definition: EnhancedBiasWeighter.h:204
DeMoAtlasDataLoss.runNumber
string runNumber
Definition: DeMoAtlasDataLoss.py:64
PathResolverFindDataFile
std::string PathResolverFindDataFile(const std::string &logical_file_name)
Definition: PathResolver.cxx:278
lumiFormat.lumi
lumi
Definition: lumiFormat.py:106
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:216
EnhancedBiasWeighter::m_deadtime
double m_deadtime
Online deadtime to correct for in rate prediction.
Definition: EnhancedBiasWeighter.h:206
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:208
python.TriggerAPI.TriggerAPISession.chainName
chainName
Definition: TriggerAPISession.py:426
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:219
EnhancedBiasWeighter::m_mcKFactor
Gaudi::Property< double > m_mcKFactor
Definition: EnhancedBiasWeighter.h:199
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
xAOD::EventInfo_v1::mcEventWeight
float mcEventWeight(size_t i=0) const
The weight of one specific MC event used in the simulation.
Definition: EventInfo_v1.cxx:203
jobOptions.fileName
fileName
Definition: jobOptions.SuperChic_ALP2.py:39
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:328
CaloNoise_fillDB.mu
mu
Definition: CaloNoise_fillDB.py:51
pow
constexpr int pow(int base, int exp) noexcept
Definition: ap_fixedTest.cxx:15
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: node.h:21
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