ATLAS Offline Software
Macros | Functions
TrigGlobEffCorrExample3b.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 3b"
 

Functions

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

Macro Definition Documentation

◆ MSGSOURCE

#define MSGSOURCE   "Example 3b"

Definition at line 93 of file TrigGlobEffCorrExample3b.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, only for the leading electron ("Signal")

Dielectron trigger, for the leading electron ("Signal")

Dielectron trigger, for subleading electron(s) (not tagged => "*")

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)

Let's pretend that the leading electron passes TightLH+isolation, thus the event passes the selection; now we tag the electrons:

Leading electron tagged as 'Signal' -> decorated value set to 1 Subleading electron(s) not tagged -> decorated value set to 0

Events must contain enough leptons to trigger

single-electron trigger

dielectron

Finally retrieve the global trigger scale factor

Definition at line 97 of file TrigGlobEffCorrExample3b.cxx.

98 {
99  ANA_CHECK_SET_TYPE(bool)
100  const char* filename = nullptr;
101  bool debug = false, cmdline_error = false, toys = false;
102  for(int i=1;i<argc;++i)
103  {
104  if(string(argv[i]) == "--debug") debug = true;
105  else if(string(argv[i]) == "--toys") toys = true;
106  else if(!filename && *argv[i]!='-') filename = argv[i];
107  else cmdline_error = true;
108  }
109  if(!filename || cmdline_error)
110  {
111  Error(MSGSOURCE, "No file name received!");
112  Error(MSGSOURCE, " Usage: %s [--debug] [--toys] [DxAOD file name]", argv[0]);
113  return 1;
114  }
115  #ifdef XAOD_STANDALONE
116  xAOD::Init(MSGSOURCE).ignore();
117  TFile* file = TFile::Open(filename, "READ");
118  if(!file)
119  {
120  Error(MSGSOURCE, "Unable to open file!");
121  return 2;
122  }
125  StatusCode::enableFailure();
126  #else
127  IAppMgrUI* app = POOL::Init();
129  TString file(filename);
130  #endif
131  event.readFrom(file).ignore();
132  Long64_t entries = event.getEntries();
133  Info(MSGSOURCE, "Number of events in the file: %lli", entries);
134 
135  /* ********************************************************************** */
136 
137  Info(MSGSOURCE, "Configuring the electron CP tools");
139  ToolHandleArray<IAsgElectronEfficiencyCorrectionTool> electronEffTools;
141  ToolHandleArray<IAsgElectronEfficiencyCorrectionTool> electronSFTools;
143  std::map<std::string,std::string> legsPerTool;
145  std::map<std::string,std::string> tagsPerTool;
147  std::map<std::string,std::string> legsPerTag;
149  static const SG::Decorator<char> dec_signal("Signal");
151  std::bernoulli_distribution bernoulliPdf(0.9);
152 
154  vector<asg::AnaToolHandle<IAsgElectronEfficiencyCorrectionTool>> factory;
155  enum{ cLEGS, cTAG, cKEY, cPID, cISO };
156  std::vector<std::array<std::string,5> > toolConfigs = {
159  {"e24_lhmedium_L1EM20VH_OR_e60_lhmedium_OR_e120_lhloose", "Signal", "2015_e24_lhmedium_L1EM20VH_OR_e60_lhmedium_OR_e120_lhloose", "Tight", "FixedCutTightTrackOnly"},
161  {"e12_lhloose_L1EM10VH", "Signal", "2015_e12_lhloose_L1EM10VH", "Tight", "FixedCutTightTrackOnly"},
163  {"e12_lhloose_L1EM10VH", "*", "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 
278  if(myTriggeringElectrons.size() < 1) continue;
279 
282  auto compareByPt = [](const xAOD::Electron*e1, const xAOD::Electron*e2)
283  { return e1->pt() < e2->pt(); };
284  auto leadingElectron = *std::max_element(myTriggeringElectrons.begin(),
285  myTriggeringElectrons.end(), compareByPt);
286  for(auto electron : myTriggeringElectrons)
287  {
290  dec_signal(*electron) = (electron==leadingElectron)? 1 : 0;
291  }
292 
294  if(leadingElectron->pt() < 25e3f
295  && myTriggeringElectrons.size() < 2)
296  {
297  continue;
298  }
299 
300 
302  double sf = 1.;
303  auto cc = myTool->getEfficiencyScaleFactor(myTriggeringElectrons,
304  myTriggeringMuons, sf);
306  {
307  nSuitableEvents += 1;
308  sumW += sf;
309  }
310  else
311  {
312  Warning(MSGSOURCE, "Scale factor evaluation failed");
313  ++errors;
314  }
315  if(errors>10)
316  {
317  Error(MSGSOURCE, "Too many errors reported!");
318  break;
319  }
320  }
321  Info(MSGSOURCE, "Average scale factor: %f (over %ld events)",
322  sumW / nSuitableEvents, long(nSuitableEvents));
323  #ifndef XAOD_STANDALONE
324  ANA_CHECK(app->finalize())
325  #endif
326  return errors? 4 : 0;
327 }
SGTest::store
TestStore store
Definition: TestStore.cxx:23
asg::AnaToolHandle< ITrigGlobalEfficiencyCorrectionTool >
egammaEnergyPositionAllSamples::e1
double e1(const xAOD::CaloCluster &cluster)
return the uncorrected cluster energy in 1st sampling
eta
Scalar eta() const
pseudorapidity method
Definition: AmgMatrixBasePlugin.h:83
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
MSGSOURCE
#define MSGSOURCE
Definition: TrigGlobEffCorrExample3b.cxx:92
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
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::Electron_v1
Definition: Electron_v1.h:34
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
egammaEnergyPositionAllSamples::e2
double e2(const xAOD::CaloCluster &cluster)
return the uncorrected cluster energy in 2nd sampling
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