ATLAS Offline Software
Macros | Functions
TrigGlobEffCorrExample3c.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 <sstream>
#include <random>
#include <vector>
#include <array>

Go to the source code of this file.

Macros

#define MSGSOURCE   "Example 3c"
 

Functions

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

Macro Definition Documentation

◆ MSGSOURCE

#define MSGSOURCE   "Example 3c"

Definition at line 95 of file TrigGlobEffCorrExample3c.cxx.

Function Documentation

◆ main()

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

For property 'ElectronEfficiencyTools':

For property 'ElectronScaleFactorTools':

For property 'ListOfLegsPerTool':

For property 'ListOfTagsPerTool':

For property 'ElectronLegsPerTag':

To tag electron(s) as 'Signal'

To emulate PID selection (90% loose-to-medium efficiency)

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

<key in map file>, <PID WP>, <iso WP> Single electron trigger: electrons tagged 'Signal'

Dielectron trigger: all electrons (tagged or not)

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

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

2015 periods D-H, J

Get a random run number, and decorate the event info

electron must be above softest trigger threshold (e12 here)

Add 'Signal' decorations to random electrons also count 'Signal' electrons above e24_xxx threshold

Events must contain enough leptons to trigger

single-electron trigger

dielectron

Finally retrieve the global trigger scale factor

Definition at line 99 of file TrigGlobEffCorrExample3c.cxx.

100 {
101  ANA_CHECK_SET_TYPE(bool)
102  const char* filename = nullptr;
103  bool debug = false, cmdline_error = false, toys = false;
104  for(int i=1;i<argc;++i)
105  {
106  if(string(argv[i]) == "--debug") debug = true;
107  else if(string(argv[i]) == "--toys") toys = true;
108  else if(!filename && *argv[i]!='-') filename = argv[i];
109  else cmdline_error = true;
110  }
111  if(!filename || cmdline_error)
112  {
113  Error(MSGSOURCE, "No file name received!");
114  Error(MSGSOURCE, " Usage: %s [--debug] [--toys] [DxAOD file name]", argv[0]);
115  return 1;
116  }
117  #ifdef XAOD_STANDALONE
118  xAOD::Init(MSGSOURCE).ignore();
119  TFile* file = TFile::Open(filename, "READ");
120  if(!file)
121  {
122  Error(MSGSOURCE, "Unable to open file!");
123  return 2;
124  }
127  StatusCode::enableFailure();
128  #else
129  IAppMgrUI* app = POOL::Init();
131  TString file(filename);
132  #endif
133  event.readFrom(file).ignore();
134  Long64_t entries = event.getEntries();
135  Info(MSGSOURCE, "Number of events in the file: %lli", entries);
136 
137  /* ********************************************************************** */
138 
139  Info(MSGSOURCE, "Configuring the electron CP tools");
141  ToolHandleArray<IAsgElectronEfficiencyCorrectionTool> electronEffTools;
143  ToolHandleArray<IAsgElectronEfficiencyCorrectionTool> electronSFTools;
145  std::map<std::string,std::string> legsPerTool;
147  std::map<std::string,std::string> tagsPerTool;
149  std::map<std::string,std::string> legsPerTag;
151  static const SG::Decorator<char> dec_signal("Signal");
153  std::bernoulli_distribution bernoulliPdf(0.9);
154 
156  vector<asg::AnaToolHandle<IAsgElectronEfficiencyCorrectionTool>> factory;
157  enum{ cLEGS, cTAG, cKEY, cPID, cISO };
158  std::vector<std::array<std::string,5> > toolConfigs = {
161  {"e24_lhmedium_L1EM20VH_OR_e60_lhmedium_OR_e120_lhloose", "Signal", "2015_e24_lhmedium_L1EM20VH_OR_e60_lhmedium_OR_e120_lhloose", "Medium", ""},
163  {"e12_lhloose_L1EM10VH", "*,Signal", "2015_e12_lhloose_L1EM10VH", "LooseBLayer", ""}
164  };
165 
166  const char* mapPath = "ElectronEfficiencyCorrection/2015_2017/"
167  "rel21.2/Moriond_February2018_v2/map6.txt";
168  for(auto& cfg : toolConfigs)
169  for(int j=0;j<2;++j)
170  {
171  string name = "AsgElectronEfficiencyCorrectionTool/"
172  + ((j? "ElTrigEff_" : "ElTrigSF_")
173  + std::to_string(factory.size()/2));
174  auto t = factory.emplace(factory.end(), name);
175  t->setProperty("MapFilePath", mapPath).ignore();
176  t->setProperty("TriggerKey", string(j?"":"Eff_") + cfg[cKEY]).ignore();
177  t->setProperty("IdKey", cfg[cPID]).ignore();
178  t->setProperty("IsoKey", cfg[cISO]).ignore();
179 
180  t->setProperty("CorrelationModel", "TOTAL").ignore();
181  t->setProperty("ForceDataType", (int)PATCore::ParticleDataType::Full).ignore();
182  if(t->initialize() != StatusCode::SUCCESS)
183  {
184  Error(MSGSOURCE, "Unable to initialize the electron CP tool <%s>!",
185  t->name().c_str());
186  return 3;
187  }
188  auto& handles = (j? electronSFTools : electronEffTools);
189  handles.push_back(t->getHandle());
192  name = handles[handles.size()-1].name();
193  legsPerTool[name] = cfg[cLEGS];
194  tagsPerTool[name] = cfg[cTAG];
195  if(!j)
196  {
197  for(auto& tag : ::split_comma_delimited(cfg[cTAG]))
198  {
199  if(legsPerTag[tag]=="") legsPerTag[tag] = cfg[cLEGS];
200  else legsPerTag[tag] += "," + cfg[cLEGS];
201  }
202  }
203 
204  }
205 
206  /* ********************************************************************** */
207 
208  Info(MSGSOURCE, "Configuring the global trigger SF tool");
209  asg::AnaToolHandle<ITrigGlobalEfficiencyCorrectionTool> myTool("TrigGlobalEfficiencyCorrectionTool/TrigGlobal");
210  myTool.setProperty("ElectronEfficiencyTools", electronEffTools).ignore();
211  myTool.setProperty("ElectronScaleFactorTools", electronSFTools).ignore();
212  const char* triggers2015 =
213  "e24_lhmedium_L1EM20VH_OR_e60_lhmedium_OR_e120_lhloose"
214  "|| 2e12_lhloose_L12EM10VH";
215  myTool.setProperty("TriggerCombination2015", triggers2015).ignore();
216  myTool.setProperty("LeptonTagDecorations", "Signal").ignore();
217  myTool.setProperty("ListOfLegsPerTool", legsPerTool).ignore();
218  myTool.setProperty("ListOfTagsPerTool", tagsPerTool).ignore();
219  myTool.setProperty("ListOfLegsPerTag", legsPerTag).ignore();
220 
221  if(debug) myTool.setProperty("OutputLevel", MSG::DEBUG).ignore();
222  if(toys) myTool.setProperty("NumberOfToys", 1000).ignore();
223  if(myTool.initialize() != StatusCode::SUCCESS)
224  {
225  Error(MSGSOURCE, "Unable to initialize the TrigGlob tool!");
226  return 3;
227  }
228 
231  const unsigned periodRuns[] = {
233  276073, 278727, 279932, 280423, 281130, 282625
234  };
235  std::uniform_int_distribution<unsigned> uniformPdf(0,
236  sizeof(periodRuns)/sizeof(*periodRuns) - 1);
237  std::default_random_engine randomEngine;
238 
239  static const SG::ConstAccessor<int> truthType("truthType");
240  static const SG::ConstAccessor<int> truthOrigin("truthOrigin");
241 
242  /* ********************************************************************** */
243 
244  Info(MSGSOURCE, "Starting the event loop");
245  unsigned errors = 0;
246  double nSuitableEvents = 0., sumW = 0.;
247  static const SG::Decorator<unsigned> RandomRunNumberDec("RandomRunNumber");
248  for(Long64_t entry = 0; entry < entries; ++entry)
249  {
250  event.getEntry(entry);
251 
253  const xAOD::EventInfo* eventInfo = nullptr;
254  event.retrieve(eventInfo,"EventInfo").ignore();
255  unsigned runNumber = periodRuns[uniformPdf(randomEngine)];
256  RandomRunNumberDec(*eventInfo) = runNumber;
257  vector<const xAOD::Electron*> myTriggeringElectrons;
258  const xAOD::ElectronContainer* electrons = nullptr;
259  event.retrieve(electrons,"Electrons").ignore();
260  for(auto electron : *electrons)
261  {
262  if(!electron->caloCluster()) continue;
263  float eta = fabs(electron->caloCluster()->etaBE(2));
264  float pt = electron->pt();
265  if(pt<10e3f || eta>=2.47) continue;
266  if(!truthType.isAvailable(*electron)) continue;
267  if(!truthOrigin.isAvailable(*electron)) continue;
268  int t = truthType(*electron), o = truthOrigin(*electron);
269  if(t!=2 || !(o==10 || (o>=12 && o<=22) || o==43)) continue;
271  if(pt < 13e3f) continue;
272 
273  myTriggeringElectrons.push_back(electron);
274  }
275 
276  vector<const xAOD::Muon*> myTriggeringMuons;
277 
280  unsigned nTrig1L = 0;
281  for(auto electron : myTriggeringElectrons)
282  {
283  bool signal = bernoulliPdf(randomEngine);
284  dec_signal(*electron) = signal? 1 : 0;
285  if(signal && electron->pt()>25e3f) ++nTrig1L;
286  }
287 
289  if(nTrig1L < 1
290  && myTriggeringElectrons.size() < 2)
291  {
292  continue;
293  }
294 
295 
297  double sf = 1.;
298  auto cc = myTool->getEfficiencyScaleFactor(myTriggeringElectrons,
299  myTriggeringMuons, sf);
301  {
302  nSuitableEvents += 1;
303  sumW += sf;
304  }
305  else
306  {
307  Warning(MSGSOURCE, "Scale factor evaluation failed");
308  ++errors;
309  }
310  if(errors>10)
311  {
312  Error(MSGSOURCE, "Too many errors reported!");
313  break;
314  }
315  }
316  Info(MSGSOURCE, "Average scale factor: %f (over %ld events)",
317  sumW / nSuitableEvents, long(nSuitableEvents));
318  #ifndef XAOD_STANDALONE
319  ANA_CHECK(app->finalize())
320  #endif
321  return errors? 4 : 0;
322 }
SGTest::store
TestStore store
Definition: TestStore.cxx:23
asg::AnaToolHandle< ITrigGlobalEfficiencyCorrectionTool >
eta
Scalar eta() const
pseudorapidity method
Definition: AmgMatrixBasePlugin.h:83
MSGSOURCE
#define MSGSOURCE
Definition: TrigGlobEffCorrExample3c.cxx:94
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 >
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
xAOD::TEvent::kClassAccess
@ kClassAccess
Access auxiliary data using the aux containers.
Definition: Control/xAODRootAccess/xAODRootAccess/TEvent.h:100
ZDCMsg::Info
@ Info
Definition: ZDCMsg.h:20
IDTPM::truthType
int truthType(const U &p)
Definition: TrackParametersHelper.h:274
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:46
IDTPM::truthOrigin
int truthOrigin(const U &p)
Definition: TrackParametersHelper.h:283
PATCore::ParticleDataType::Full
@ Full
Definition: PATCoreEnums.h:22
DiTauMassTools::ignore
void ignore(T &&)
Definition: PhysicsAnalysis/TauID/DiTauMassTools/DiTauMassTools/HelperFunctions.h:58
Cut::signal
@ signal
Definition: SUSYToolsAlg.cxx:67
event
POOL::TEvent event(POOL::TEvent::kClassAccess)
SG::Decorator< char >
lumiFormat.i
int i
Definition: lumiFormat.py:85
LArCellNtuple.argv
argv
Definition: LArCellNtuple.py:152
file
TFile * file
Definition: tile_monitor.h:29
DQHistogramMergeRegExp.argc
argc
Definition: DQHistogramMergeRegExp.py:20
DataVector
Derived DataVector<T>.
Definition: DataVector.h:794
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:40
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
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
CaloCondBlobAlgs_fillNoiseFromASCII.tag
string tag
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:24
InDetDD::electrons
@ electrons
Definition: InDetDD_Defs.h:17
xAOD::TEvent
Tool for accessing xAOD files outside of Athena.
Definition: Control/xAODRootAccess/xAODRootAccess/TEvent.h:84
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