ATLAS Offline Software
Macros | Functions
TrigGlobEffCorrExample1.cxx File Reference
#include <TFile.h>
#include <TError.h>
#include "AthAnalysisBaseComps/AthAnalysisHelper.h"
#include "POOLRootAccess/TEvent.h"
#include "AsgMessaging/MessageCheck.h"
#include "AsgTools/AnaToolHandle.h"
#include "EgammaAnalysisInterfaces/IAsgElectronEfficiencyCorrectionTool.h"
#include "MuonAnalysisInterfaces/IMuonTriggerScaleFactors.h"
#include "TriggerAnalysisInterfaces/ITrigGlobalEfficiencyCorrectionTool.h"
#include "xAODEventInfo/EventInfo.h"
#include "xAODEgamma/ElectronContainer.h"
#include "xAODMuon/MuonContainer.h"
#include "PATCore/PATCoreEnums.h"
#include "AthContainers/AuxElement.h"
#include "AthContainers/ConstAccessor.h"
#include "AthContainers/Decorator.h"
#include <random>
#include <vector>
#include <array>

Go to the source code of this file.

Macros

#define MSGSOURCE   "Example 1"
 

Functions

int main (int argc, char *argv[])
 

Macro Definition Documentation

◆ MSGSOURCE

#define MSGSOURCE   "Example 1"

Definition at line 51 of file TrigGlobEffCorrExample1.cxx.

Function Documentation

◆ main()

int main ( int  argc,
char *  argv[] 
)

For property 'ElectronEfficiencyTools':

For property 'ElectronScaleFactorTools':

For property 'ListOfLegsPerTool':

RAII on-the-fly creation of electron CP tools:

{

<key in map file>} Single-electron trigger (same tool instance for 2015-2018):

Dielectron trigger (same tool instance for 2015-2018):

Complementary 2e17_lhvloose_nod0_L12EM15VHI trigger

one instance per trigger leg x working point

two instances: 0 -> MC efficiencies, 1 -> SFs

Safer to retrieve the name from the final ToolHandle, it might be prefixed (by the parent tool name) when the handle is copied

For property 'MuonTools':

2017 before accidental prescale of L12EM15VHI

2017 during accidental prescale

2017 after accidental prescale + 2018

Uniform random run number generation spanning the target dataset. In real life, use the PileupReweightingTool instead!

2015 periods D-H, J

2016 periods A-L

2017 periods B-K

2018 periods B-Q

Get a random run number, and decorate the event info

lepton must be above softest trigger threshold:

2017 during accidental prescale: 2e24

2016-2018: 2e17

2015: 2e12

also count leptons above single-lepton trigger threshold

lepton must be above softest trigger threshold (mu8noL1 here):

also count leptons above single-lepton trigger threshold

and count muons suitable for the hard leg of the dimuon trigger

Events must contain enough leptons to trigger

single-lepton trigger

dielectron

dimuon

Finally retrieve the global trigger scale factor

Definition at line 55 of file TrigGlobEffCorrExample1.cxx.

56 {
57  ANA_CHECK_SET_TYPE(bool)
58  const char* filename = nullptr;
59  bool debug = false, cmdline_error = false, toys = false;
60  for(int i=1;i<argc;++i)
61  {
62  if(string(argv[i]) == "--debug") debug = true;
63  else if(string(argv[i]) == "--toys") toys = true;
64  else if(!filename && *argv[i]!='-') filename = argv[i];
65  else cmdline_error = true;
66  }
67  if(!filename || cmdline_error)
68  {
69  Error(MSGSOURCE, "No file name received!");
70  Error(MSGSOURCE, " Usage: %s [--debug] [--toys] [DxAOD file name]", argv[0]);
71  return 1;
72  }
73  #ifdef XAOD_STANDALONE
74  xAOD::Init(MSGSOURCE).ignore();
75  TFile* file = TFile::Open(filename, "READ");
76  if(!file)
77  {
78  Error(MSGSOURCE, "Unable to open file!");
79  return 2;
80  }
83  StatusCode::enableFailure();
84  #else
85  IAppMgrUI* app = POOL::Init();
87  TString file(filename);
88  #endif
89  event.readFrom(file).ignore();
90  Long64_t entries = event.getEntries();
91  Info(MSGSOURCE, "Number of events in the file: %lli", entries);
92 
93  /* ********************************************************************** */
94 
95  Info(MSGSOURCE, "Configuring the electron CP tools");
97  ToolHandleArray<IAsgElectronEfficiencyCorrectionTool> electronEffTools;
99  ToolHandleArray<IAsgElectronEfficiencyCorrectionTool> electronSFTools;
101  std::map<string,string> legsPerTool;
102 
104  vector<asg::AnaToolHandle<IAsgElectronEfficiencyCorrectionTool>> factory;
105  enum{ cLEGS, cKEY };
106  vector<std::array<string,2>> toolConfigs = {
109  {"e24_lhmedium_L1EM20VH_OR_e60_lhmedium_OR_e120_lhloose, e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0",
110  "SINGLE_E_2015_e24_lhmedium_L1EM20VH_OR_e60_lhmedium_OR_e120_lhloose_2016_2018_e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0"},
112  {"e12_lhloose_L1EM10VH, e17_lhvloose_nod0, e24_lhvloose_nod0_L1EM20VH",
113  "DI_E_2015_e12_lhloose_L1EM10VH_2016_e17_lhvloose_nod0_2017_2018_e24_lhvloose_nod0_L1EM20VH"},
115  {"e17_lhvloose_nod0_L1EM15VHI",
116  "DI_E_2015_e12_lhloose_L1EM10VH_2016_e17_lhvloose_nod0_2017_2018_e17_lhvloose_nod0_L1EM15VHI"}
117  };
118 
119  const char* mapPath = "ElectronEfficiencyCorrection/2015_2017/"
120  "rel21.2/Consolidation_September2018_v1/map2.txt";
121  for(auto& cfg : toolConfigs)
122  for(int j=0;j<2;++j)
123  {
124  string name = "AsgElectronEfficiencyCorrectionTool/"
125  + ((j? "ElTrigEff_" : "ElTrigSF_")
126  + std::to_string(factory.size()/2));
127  auto t = factory.emplace(factory.end(), name);
128  t->setProperty("MapFilePath", mapPath).ignore();
129  t->setProperty("TriggerKey", string(j?"":"Eff_") + cfg[cKEY]).ignore();
130  t->setProperty("IdKey", "Tight").ignore();
131  t->setProperty("IsoKey", "FCTight").ignore();
132  t->setProperty("CorrelationModel", "TOTAL").ignore();
133  t->setProperty("ForceDataType", (int)PATCore::ParticleDataType::Full).ignore();
134  if(t->initialize() != StatusCode::SUCCESS)
135  {
136  Error(MSGSOURCE, "Unable to initialize the electron CP tool <%s>!",
137  t->name().c_str());
138  return 3;
139  }
140  auto& handles = (j? electronSFTools : electronEffTools);
141  handles.push_back(t->getHandle());
144  name = handles[handles.size()-1].name();
145  legsPerTool[name] = cfg[cLEGS];
146 
147  }
148 
149  /* ********************************************************************** */
150 
151  Info(MSGSOURCE, "Configuring the muon CP tools");
153  ToolHandleArray<CP::IMuonTriggerScaleFactors> muonTools;
154  asg::AnaToolHandle<CP::IMuonTriggerScaleFactors> muonTool("CP::MuonTriggerScaleFactors/MuonTrigEff");
155  muonTool.setProperty("MuonQuality", "Tight").ignore();
156  muonTool.setProperty("useRel207", false).ignore();
157  if(muonTool.initialize() != StatusCode::SUCCESS)
158  {
159  Error(MSGSOURCE, "Unable to initialize the muon CP tool!");
160  return 3;
161  }
162  muonTools.push_back(muonTool.getHandle());
163 
164  /* ********************************************************************** */
165 
166  Info(MSGSOURCE, "Configuring the global trigger SF tool");
167  asg::AnaToolHandle<ITrigGlobalEfficiencyCorrectionTool> myTool("TrigGlobalEfficiencyCorrectionTool/TrigGlobal");
168  myTool.setProperty("ElectronEfficiencyTools", electronEffTools).ignore();
169  myTool.setProperty("ElectronScaleFactorTools", electronSFTools).ignore();
170  myTool.setProperty("MuonTools", muonTools).ignore();
171  std::map<std::string, std::string> triggers;
172  triggers["2015"] =
173  "mu20_iloose_L1MU15_OR_mu50"
174  "|| mu18_mu8noL1"
175  "|| e24_lhmedium_L1EM20VH_OR_e60_lhmedium_OR_e120_lhloose"
176  "|| 2e12_lhloose_L12EM10VH";
177  triggers["2016"] =
178  "mu26_ivarmedium_OR_mu50"
179  "|| mu22_mu8noL1"
180  "|| e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0"
181  "|| 2e17_lhvloose_nod0";
182  std::string only2e24 =
183  "mu26_ivarmedium_OR_mu50"
184  "|| mu22_mu8noL1"
185  "|| e26_lhtight_nod0_ivarloose_OR_e60_lhmedium_nod0_OR_e140_lhloose_nod0"
186  "|| 2e24_lhvloose_nod0";
187  std::string nominal = only2e24 + "|| 2e17_lhvloose_nod0_L12EM15VHI";
188  triggers["324320-326695"] = nominal;
189  triggers["326834-328393"] = only2e24;
190  triggers["329385-364292"] = nominal;
191  myTool.setProperty("TriggerCombination", triggers).ignore();
192  myTool.setProperty("ListOfLegsPerTool", legsPerTool).ignore();
193 
194  if(debug) myTool.setProperty("OutputLevel", MSG::DEBUG).ignore();
195  if(toys) myTool.setProperty("NumberOfToys", 1000).ignore();
196  if(myTool.initialize() != StatusCode::SUCCESS)
197  {
198  Error(MSGSOURCE, "Unable to initialize the TrigGlob tool!");
199  return 3;
200  }
201 
204  const unsigned periodRuns[] = {
206  276073, 278727, 279932, 280423, 281130, 282625,
208  296939, 300345, 301912, 302737, 303638, 303943, 305291, 307124,
209  305359, 309311, 310015,
211  325713, 329385, 330857, 332720, 334842, 336497, 336832, 338183,
213  348885, 349534, 350310, 352274, 354107, 354826, 355261, 355331,
214  355529, 357050, 359191, 361635, 361738, 363664
215  };
216  std::uniform_int_distribution<unsigned> uniformPdf(0,
217  sizeof(periodRuns)/sizeof(*periodRuns) - 1);
218  std::default_random_engine randomEngine;
219 
220  static const SG::ConstAccessor<int> truthType("truthType");
221  static const SG::ConstAccessor<int> truthOrigin("truthOrigin");
222 
223  /* ********************************************************************** */
224 
225  Info(MSGSOURCE, "Starting the event loop");
226  unsigned errors = 0;
227  double nSuitableEvents = 0., sumW = 0.;
228  static const SG::Decorator<unsigned> RandomRunNumberDec("RandomRunNumber");
229  for(Long64_t entry = 0; entry < entries; ++entry)
230  {
231  event.getEntry(entry);
232 
234  const xAOD::EventInfo* eventInfo = nullptr;
235  event.retrieve(eventInfo,"EventInfo").ignore();
236  unsigned runNumber = periodRuns[uniformPdf(randomEngine)];
237  RandomRunNumberDec(*eventInfo) = runNumber;
238 
239  unsigned nTrig1L = 0, nTrig2mu = 0;
240 
241  vector<const xAOD::Electron*> myTriggeringElectrons;
242  const xAOD::ElectronContainer* electrons = nullptr;
243  event.retrieve(electrons,"Electrons").ignore();
244  for(auto electron : *electrons)
245  {
246  if(!electron->caloCluster()) continue;
247  float eta = fabs(electron->caloCluster()->etaBE(2));
248  float pt = electron->pt();
249  if(pt<10e3f || eta>=2.47) continue;
250  if(!truthType.isAvailable(*electron)) continue;
251  if(!truthOrigin.isAvailable(*electron)) continue;
252  int t = truthType(*electron), o = truthOrigin(*electron);
253  if(t!=2 || !(o==10 || (o>=12 && o<=22) || o==43)) continue;
255  if((runNumber>=326834 && runNumber<=328393 && pt<25e3f)
256  || (runNumber>290000 && pt<18e3f)
257  || (pt<13e3f)) continue;
258  if(pt >= (runNumber>290000? 27e3f : 25e3f)) ++nTrig1L;
260 
261  myTriggeringElectrons.push_back(electron);
262  }
263 
264  vector<const xAOD::Muon*> myTriggeringMuons;
265  const xAOD::MuonContainer* muons = nullptr;
266  event.retrieve(muons,"Muons").ignore();
267  for(auto muon : *muons)
268  {
269  float pt = muon->pt();
270  if(pt<10e3f || fabs(muon->eta())>=2.5) continue;
271  auto mt = muon->muonType();
272  if(mt!=xAOD::Muon::Combined && mt!=xAOD::Muon::MuonStandAlone) continue;
273  auto& mtp = *(muon->primaryTrackParticle());
274  if(!truthType.isAvailable(mtp)) continue;
275  if(!truthOrigin.isAvailable(mtp)) continue;
276  int t = truthType(mtp), o = truthOrigin(mtp);
277  if(t!=6 || !(o==10 || (o>=12 && o<=22) || o==43)) continue;
279  if(pt < 10e3f) continue;
281  if(pt >= (runNumber>290000? 27.3e3f : 21e3f)) ++nTrig1L;
283  if(pt >= (runNumber>290000? 23e3f : 19e3f)) ++nTrig2mu;
284 
285  myTriggeringMuons.push_back(muon);
286  }
287 
289  if(nTrig1L==0
290  && myTriggeringElectrons.size()<2
291  && (nTrig2mu==0 || myTriggeringMuons.size()<2))
292  {
293  continue;
294  }
295 
296 
298  double sf = 1.;
299  auto cc = myTool->getEfficiencyScaleFactor(myTriggeringElectrons,
300  myTriggeringMuons, sf);
302  {
303  nSuitableEvents += 1;
304  sumW += sf;
305  }
306  else
307  {
308  Warning(MSGSOURCE, "Scale factor evaluation failed");
309  ++errors;
310  }
311  if(errors>10)
312  {
313  Error(MSGSOURCE, "Too many errors reported!");
314  break;
315  }
316  }
317  Info(MSGSOURCE, "Average scale factor: %f (over %ld events)",
318  sumW / nSuitableEvents, long(nSuitableEvents));
319  #ifndef XAOD_STANDALONE
320  ANA_CHECK(app->finalize())
321  #endif
322  return errors? 4 : 0;
323 }
store
StoreGateSvc * store
Definition: fbtTestBasics.cxx:69
xAOD::muon
@ muon
Definition: TrackingPrimitives.h:195
asg::AnaToolHandle< CP::IMuonTriggerScaleFactors >
MSGSOURCE
#define MSGSOURCE
Definition: TrigGlobEffCorrExample1.cxx:50
eta
Scalar eta() const
pseudorapidity method
Definition: AmgMatrixBasePlugin.h:79
test_pyathena.pt
pt
Definition: test_pyathena.py:11
ANA_CHECK
#define ANA_CHECK(EXP)
check whether the given expression was successful
Definition: Control/AthToolSupport/AsgMessaging/AsgMessaging/MessageCheck.h:324
SG::ConstAccessor< int >
LArCellConditions.argv
argv
Definition: LArCellConditions.py:112
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
python.TrigTLAMonitorAlgorithm.triggers
triggers
Definition: TrigTLAMonitorAlgorithm.py:196
xAOD::TEvent::kClassAccess
@ kClassAccess
Access auxiliary data using the aux containers.
Definition: Control/xAODRootAccess/xAODRootAccess/TEvent.h:97
ZDCMsg::Info
@ Info
Definition: ZDCMsg.h:20
POOL::Init
IAppMgrUI * Init(const char *options="POOLRootAccess/basic.opts")
Bootstraps (creates and configures) the Gaudi Application with the provided options file.
Definition: PhysicsAnalysis/POOLRootAccess/src/TEvent.cxx:29
POOL::TEvent::kClassAccess
@ kClassAccess
Definition: PhysicsAnalysis/POOLRootAccess/POOLRootAccess/TEvent.h:45
PATCore::ParticleDataType::Full
@ Full
Definition: PATCoreEnums.h:22
DiTauMassTools::ignore
void ignore(T &&)
Definition: PhysicsAnalysis/TauID/DiTauMassTools/DiTauMassTools/HelperFunctions.h:54
event
POOL::TEvent event(POOL::TEvent::kClassAccess)
SG::Decorator
Helper class to provide type-safe access to aux data.
Definition: Decorator.h:58
lumiFormat.i
int i
Definition: lumiFormat.py:92
top::nominal
@ nominal
Definition: ScaleFactorRetriever.h:29
file
TFile * file
Definition: tile_monitor.h:29
DQHistogramMergeRegExp.argc
argc
Definition: DQHistogramMergeRegExp.py:20
DataVector
Derived DataVector<T>.
Definition: DataVector.h:581
Trk::Combined
@ Combined
Definition: TrackSummaryTool.h:32
mergePhysValFiles.errors
list errors
Definition: DataQuality/DataQualityUtils/scripts/mergePhysValFiles.py:43
GetAllXsec.entry
list entry
Definition: GetAllXsec.py:132
POOL::TEvent
Definition: PhysicsAnalysis/POOLRootAccess/POOLRootAccess/TEvent.h:39
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:195
debug
const bool debug
Definition: MakeUncertaintyPlots.cxx:53
ActsTrk::to_string
std::string to_string(const DetectorType &type)
Definition: GeometryDefs.h:34
WriteCaloSwCorrections.cfg
cfg
Definition: WriteCaloSwCorrections.py:23
xAOD::EventInfo_v1
Class describing the basic event information.
Definition: EventInfo_v1.h:43
DeMoAtlasDataLoss.runNumber
string runNumber
Definition: DeMoAtlasDataLoss.py:64
CP::CorrectionCode::Ok
@ Ok
The correction was done successfully.
Definition: CorrectionCode.h:38
xAOD::TStore
A relatively simple transient store for objects created in analysis.
Definition: TStore.h:44
mapkey::sf
@ sf
Definition: TElectronEfficiencyCorrectionTool.cxx:38
ANA_CHECK_SET_TYPE
#define ANA_CHECK_SET_TYPE(TYPE)
set the type for ANA_CHECK to report failures
Definition: Control/AthToolSupport/AsgMessaging/AsgMessaging/MessageCheck.h:314
DEBUG
#define DEBUG
Definition: page_access.h:11
xAOD::EgammaParameters::electron
@ electron
Definition: EgammaEnums.h:18
CaloCellTimeCorrFiller.filename
filename
Definition: CaloCellTimeCorrFiller.py:24
entries
double entries
Definition: listroot.cxx:49
L1Topo::Error
Error
The different types of error that can be flagged in the L1TopoRDO.
Definition: Error.h:16
InDetDD::electrons
@ electrons
Definition: InDetDD_Defs.h:17
xAOD::TEvent
Tool for accessing xAOD files outside of Athena.
Definition: Control/xAODRootAccess/xAODRootAccess/TEvent.h:81
python.handimod.cc
int cc
Definition: handimod.py:523
xAOD::Init
StatusCode Init(const char *appname)
Function initialising ROOT/PyROOT for using the ATLAS EDM.
Definition: Init.cxx:31