ATLAS Offline Software
OverlapRemovalTester.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
4 
14 
15 
16 // System includes
17 #include <memory>
18 
19 // Boost includes
20 #include "boost/program_options.hpp"
21 
22 // ROOT includes
23 #include "TFile.h"
24 #include "TError.h"
25 #include "TString.h"
26 
27 // Infrastructure includes
28 #ifdef ROOTCORE
29 # include "xAODRootAccess/Init.h"
30 # include "xAODRootAccess/TEvent.h"
31 #endif // ROOTCORE
32 
33 // EDM includes
36 #include "xAODMuon/MuonContainer.h"
37 #include "xAODJet/JetContainer.h"
40 #include "xAODBTagging/BTagging.h"
42 
43 // Local includes
46 
47 using namespace ORUtils;
48 namespace po = boost::program_options;
49 
50 //-----------------------------------------------------------------------------
51 // Error checking macro
52 //-----------------------------------------------------------------------------
53 #define CHECK( ARG ) \
54  do { \
55  const bool result = ARG; \
56  if(!result) { \
57  ::Error(APP_NAME, "Failed to execute: \"%s\"", \
58  #ARG ); \
59  return 1; \
60  } \
61  } while( false )
62 
63 
64 //-----------------------------------------------------------------------------
65 // Global accessors and decorators
66 //-----------------------------------------------------------------------------
67 const bool outputPassValue = false; // overlap objects are 'true'
68 const std::string inputLabel = "selected";
69 const std::string outputLabel = outputPassValue? "passOR" : "overlaps";
70 const std::string bJetLabel = "isBJet";
75 const ort::objLinkAccessor_t objLinkAcc("overlapObject");
76 
77 //-----------------------------------------------------------------------------
78 // Functions for applying a dumb object selection
79 //-----------------------------------------------------------------------------
80 template<class ContainerType>
81 void selectObjects(const ContainerType* container)
82 {
83  for(auto obj : *container){
84  if(obj->pt() > 10000. && fabs(obj->eta()) < 2.5)
85  selectDec(*obj) = true;
86  else selectDec(*obj) = false;
87  }
88 }
89 //-----------------------------------------------------------------------------
90 template<> void selectObjects<xAOD::JetContainer>
91 (const xAOD::JetContainer* jets)
92 {
93  for(auto jet : *jets){
94  bool pass = (jet->pt() > 20000. && fabs(jet->eta()) < 2.5);
95  selectDec(*jet) = pass;
96  // Label bjets
97  // double mv2c10 = 0.;
98  // const xAOD::BTagging* btag = xAOD::BTaggingUtilities::getBTagging( *jet );
99  // if(!btag->MVx_discriminant("MV2c10", mv2c10))
100  // throw std::runtime_error("MV2c10 unavailable");
101  // // This is the 85% efficiency working point
102  // bJetDec(*jet) = (mv2c10 > -0.1416);
103  }
104 }
105 //-----------------------------------------------------------------------------
106 template<> void selectObjects<xAOD::TauJetContainer>
107 (const xAOD::TauJetContainer* taus)
108 {
109  for(auto tau : *taus){
110  bool pass = (tau->isTau(xAOD::TauJetParameters::JetRNNSigLoose) &&
112  tau->pt() > 20000. && fabs(tau->eta()) < 2.5);
113  selectDec(*tau) = pass;
114  }
115 }
116 
117 //-----------------------------------------------------------------------------
118 // Function for printing object results
119 //-----------------------------------------------------------------------------
120 void printObj(const char* APP_NAME, const char* type,
121  const xAOD::IParticle* obj)
122 {
123 
124  // Safety check
125  if(!overlapAcc.isAvailable(*obj)){
126  Error(APP_NAME, "Overlap decoration missing for object");
127  abort();
128  }
129 
130  // Print selected objects
131  if(selectAcc(*obj)){
132  Info(APP_NAME, " %s pt %6.2f eta %5.2f phi %5.2f selected %i %s %i",
133  type, obj->pt()*0.001, obj->eta(), obj->phi(),
134  selectAcc(*obj), outputLabel.c_str(), overlapAcc(*obj));
135  // Check for overlap object link
136  if(objLinkAcc.isAvailable(*obj) && objLinkAcc(*obj).isValid()){
137  const xAOD::IParticle* overlapObj = *objLinkAcc(*obj);
138  std::stringstream ss; ss << overlapObj->type();
139  Info(APP_NAME, " Overlap: type %s pt %6.2f",
140  ss.str().c_str(), overlapObj->pt()*0.001);
141  }
142  }
143 }
144 
145 //-----------------------------------------------------------------------------
146 // Main function
147 //-----------------------------------------------------------------------------
148 int main(int argc, char* argv[])
149 {
150 
151  // The application's name
152  const char* APP_NAME = argv[0];
153 
154  po::options_description optDesc("Allowed options");
155  optDesc.add_options()
156  ("help,h", "produce help message")
157  ("input-file,i", po::value<std::string>()->required(),
158  "input xAOD file name")
159  ("num-events,n", po::value<Long64_t>()->default_value(-1ll),
160  "number of events to process")
161  ("working-point,w", po::value<std::string>()->default_value("standard"),
162  "OR working point");
163 
164  po::variables_map vm;
165  po::store(po::parse_command_line(argc, argv, optDesc), vm);
166  if(vm.count("help")) {
167  std::cout << optDesc << std::endl;
168  return 1;
169  }
170  try {
171  po::notify(vm);
172  }
173  catch(const std::exception& e) {
174  std::cout << e.what() << std::endl;
175  return 1;
176  }
177 
178  // Initialise the application
180  StatusCode::enableFailure();
181 
182  // Open the input file
183  const auto fileName = vm["input-file"].as<std::string>();
184  Info(APP_NAME, "Opening file: %s", fileName.c_str());
185  TFile inputFile( fileName.c_str() );
186 
187  // Create a TEvent object
191 
192  // Decide how many events to run over
193  Long64_t entries = event.getEntries();
194  Long64_t optEntries = vm["num-events"].as<Long64_t>();
195  Info(APP_NAME, "Number of events in the file: %lli", entries);
196  if(optEntries >= 0) entries = std::min(entries, optEntries);
197  Info(APP_NAME, "Processing %lli entries", entries);
198 
199  // Overlap removal tool configuration flags
200  ORUtils::ORFlags orFlags("OverlapRemovalTool", inputLabel, outputLabel);
201 
202  // Parse the requested working point
203  const auto wp = vm["working-point"].as<std::string>();
204  if(wp == "standard") {
205  // use all defaults
206  } else if(wp == "HF") {
207  orFlags.bJetLabel = bJetLabel;
208  } else if(wp == "boosted") {
209  orFlags.boostedLeptons = true;
210  } else if(wp == "boostedHF") {
211  orFlags.bJetLabel = bJetLabel;
212  orFlags.boostedLeptons = true;
213  } else if(wp == "photonFavored") {
214  orFlags.doTaus = false;
215  } else {
216  Error(APP_NAME, "Unsupported working-point: %s", wp.c_str());
217  return 1;
218  }
220 
221  // Get the recommended tool configuration
222  ORUtils::ToolBox toolBox;
223  CHECK( ORUtils::recommendedTools(orFlags, toolBox) );
224 
225  // Special settings for photon-favored OR
226  if(wp == "photonFavored") {
227  CHECK( toolBox.muJetORT.setProperty("UseGhostAssociation", false) );
228  CHECK( toolBox.muJetORT.setProperty("InnerDR", 0.) );
229  CHECK( toolBox.phoEleORT.setProperty("SwapContainerPrecedence", true) );
230  CHECK( toolBox.phoMuORT.setProperty("SwapContainerPrecedence", true) );
231  }
232 
233  // Set message level for all tools
234  //CHECK( toolBox.setGlobalProperty("OutputLevel", MSG::DEBUG) );
235 
236  // Connect and initialize all tools
237  CHECK( toolBox.initialize() );
238  auto& orTool = toolBox.masterTool;
239 
240  // Some object and event counters to help roughly
241  // evaluate the effects of changes in the OR tool.
242  unsigned int nTotalElectrons = 0;
243  unsigned int nTotalMuons = 0;
244  unsigned int nTotalJets = 0;
245  unsigned int nTotalTaus = 0;
246  unsigned int nTotalPhotons = 0;
247  unsigned int nSelectedElectrons = 0;
248  unsigned int nSelectedMuons = 0;
249  unsigned int nSelectedJets = 0;
250  unsigned int nSelectedTaus = 0;
251  unsigned int nSelectedPhotons = 0;
252  unsigned int nOverlapElectrons = 0;
253  unsigned int nOverlapMuons = 0;
254  unsigned int nOverlapJets = 0;
255  unsigned int nOverlapTaus = 0;
256  unsigned int nOverlapPhotons = 0;
257 
258  // Loop over the events
259  std::cout << "Starting loop" << std::endl;
260  for(Long64_t entry = 0; entry < entries; ++entry){
261 
262  event.getEntry(entry);
263 
264  // Print some event information for fun
265  const xAOD::EventInfo* evtInfo = nullptr;
266  CHECK( event.retrieve(evtInfo, "EventInfo") );
267  Info(APP_NAME, "===>>> Processing entry %lli, run %u, event %lu <<<===",
268  entry, evtInfo->runNumber(), evtInfo->eventNumber());
269 
270  // Get electrons
271  const xAOD::ElectronContainer* electrons = nullptr;
272  CHECK( event.retrieve(electrons, "Electrons") );
273  // Get muons
274  const xAOD::MuonContainer* muons = nullptr;
275  CHECK( event.retrieve(muons, "Muons") );
276  // Get jets
277  const xAOD::JetContainer* jets = nullptr;
278  CHECK( event.retrieve(jets, "AntiKt4EMTopoJets") );
279  // Get taus
280  const xAOD::TauJetContainer* taus = nullptr;
281  CHECK( event.retrieve(taus, "TauJets") );
282  // Get photons
283  const xAOD::PhotonContainer* photons = nullptr;
284  CHECK( event.retrieve(photons, "Photons") );
285 
286  // Set input decorations
288  selectObjects(muons);
290  selectObjects(taus);
291  selectObjects(photons);
292 
293  Info(APP_NAME, "nEle %lu, nMuo %lu, nJet %lu, nTau %lu, nPho %lu",
294  electrons->size(), muons->size(),
295  jets->size(), taus->size(),
296  photons->size());
297 
298  // Apply the overlap removal to all objects
299  CHECK( orTool->removeOverlaps(electrons, muons, jets, taus, photons) );
300 
301  //
302  // Now, dump all of the results
303  // TODO: Add counts of selected objects
304  //
305 
306  // electrons
307  Info(APP_NAME, "Now dumping the electrons");
308  for(auto electron : *electrons){
309  if(selectAcc(*electron)) {
310  printObj(APP_NAME, "ele", electron);
311  if(overlapAcc(*electron) != outputPassValue) nOverlapElectrons++;
312  nSelectedElectrons++;
313  }
314  nTotalElectrons++;
315  }
316 
317  // muons
318  Info(APP_NAME, "Now dumping the muons");
319  for(auto muon : *muons){
320  if(selectAcc(*muon)) {
321  printObj(APP_NAME, "muo", muon);
322  if(overlapAcc(*muon) != outputPassValue) nOverlapMuons++;
323  nSelectedMuons++;
324  }
325  nTotalMuons++;
326  }
327 
328  // jets
329  Info(APP_NAME, "Now dumping the jets");
330  for(auto jet : *jets){
331  if(selectAcc(*jet)) {
332  printObj(APP_NAME, "jet", jet);
333  if(overlapAcc(*jet) != outputPassValue) nOverlapJets++;
334  nSelectedJets++;
335  }
336  nTotalJets++;
337  }
338 
339  // taus
340  Info(APP_NAME, "Now dumping the taus");
341  for(auto tau : *taus){
342  if(selectAcc(*tau)) {
343  printObj(APP_NAME, "tau", tau);
344  if(overlapAcc(*tau) != outputPassValue) nOverlapTaus++;
345  nSelectedTaus++;
346  }
347  nTotalTaus++;
348  }
349 
350  // photons
351  Info(APP_NAME, "Now dumping the photons");
352  for(auto photon : *photons){
353  if(selectAcc(*photon)) {
354  printObj(APP_NAME, "pho", photon);
355  if(overlapAcc(*photon) != outputPassValue) nOverlapPhotons++;
356  nSelectedPhotons++;
357  }
358  nTotalPhotons++;
359  }
360 
361  }
362  Info(APP_NAME, "=====================================");
363  Info(APP_NAME, "End of event processing");
364  Info(APP_NAME, "Object count summaries: nOverlap / nSelected / nTotal");
365  Info(APP_NAME, "Number overlap elecs: %5i / %5i / %5i",
366  nOverlapElectrons, nSelectedElectrons, nTotalElectrons);
367  Info(APP_NAME, "Number overlap muons: %5i / %5i / %5i",
368  nOverlapMuons, nSelectedMuons, nTotalMuons);
369  Info(APP_NAME, "Number overlap jets: %5i / %5i / %5i",
370  nOverlapJets, nSelectedJets, nTotalJets);
371  Info(APP_NAME, "Number overlap taus: %5i / %5i / %5i",
372  nOverlapTaus, nSelectedTaus, nTotalTaus);
373  Info(APP_NAME, "Number overlap photons: %5i / %5i / %5i",
374  nOverlapPhotons, nSelectedPhotons, nTotalPhotons);
375 
376  Info(APP_NAME, "Application finished successfully");
377 
378  return 0;
379 }
bJetLabel
const std::string bJetLabel
Definition: OverlapRemovalTester.cxx:70
ORUtils::ORFlags::outputPassValue
bool outputPassValue
Output value to assign passing objects.
Definition: OverlapRemovalInit.h:51
AllowedVariables::e
e
Definition: AsgElectronSelectorTool.cxx:37
SGTest::store
TestStore store
Definition: TestStore.cxx:23
BTaggingUtilities.h
main
int main(int argc, char *argv[])
Definition: OverlapRemovalTester.cxx:148
ORUtils::ORFlags::boostedLeptons
bool boostedLeptons
Activate boosted-lepton recommendations (sliding dR cones)
Definition: OverlapRemovalInit.h:48
xAOD::muon
@ muon
Definition: TrackingPrimitives.h:195
PowhegControl_ttHplus_NLO.ss
ss
Definition: PowhegControl_ttHplus_NLO.py:83
detail::ll
long long ll
Definition: PrimitiveHelpers.h:47
BTagging.h
xAOD::EventInfo_v1::eventNumber
uint64_t eventNumber() const
The current event's event number.
selectDec
const ort::inputDecorator_t selectDec(inputLabel)
inputLabel
const std::string inputLabel
Definition: OverlapRemovalTester.cxx:68
min
constexpr double min()
Definition: ap_fixedTest.cxx:26
xAOD::TEvent::kAthenaAccess
@ kAthenaAccess
Access containers/objects like Athena does.
Definition: Control/xAODRootAccess/xAODRootAccess/TEvent.h:101
outputLabel
const std::string outputLabel
Definition: OverlapRemovalTester.cxx:69
ORUtils::recommendedTools
StatusCode recommendedTools(const ORFlags &flags, ToolBox &toolBox)
Pre-configured standard recommended OR tools.
Definition: OverlapRemovalInit.cxx:50
xAOD::IParticle::type
virtual Type::ObjectType type() const =0
The type of the object as a simple enumeration.
CHECK
#define CHECK(ARG)
Definition: OverlapRemovalTester.cxx:53
SG::ConstAccessor
Helper class to provide constant type-safe access to aux data.
Definition: ConstAccessor.h:55
objLinkAcc
const ort::objLinkAccessor_t objLinkAcc("overlapObject")
xAOD::IParticle
Class providing the definition of the 4-vector interface.
Definition: Event/xAOD/xAODBase/xAODBase/IParticle.h:41
asg::AnaToolHandle::setProperty
StatusCode setProperty(const std::string &property, const T2 &value)
set the given property of the tool.
ORUtils
Definition: AltMuJetOverlapTool.h:20
xAOD::EventInfo_v1::runNumber
uint32_t runNumber() const
The current event's run number.
selectAcc
const ort::inputAccessor_t selectAcc(inputLabel)
ORUtils::ToolBox::muJetORT
OverlapHandle_t muJetORT
Definition: ToolBox.h:72
POOL::TEvent::readFrom
StatusCode readFrom(TFile *file)
Definition: PhysicsAnalysis/POOLRootAccess/src/TEvent.cxx:133
FortranAlgorithmOptions.fileName
fileName
Definition: FortranAlgorithmOptions.py:13
jet
Definition: JetCalibTools_PlotJESFactors.cxx:23
event
POOL::TEvent event(POOL::TEvent::kClassAccess)
SG::Decorator
Helper class to provide type-safe access to aux data.
Definition: Decorator.h:59
ElectronContainer.h
CaloCondBlobAlgs_fillNoiseFromASCII.inputFile
string inputFile
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:17
LArCellNtuple.argv
argv
Definition: LArCellNtuple.py:152
bJetDec
const ort::inputDecorator_t bJetDec(bJetLabel)
ORUtils::ORFlags::bJetLabel
std::string bJetLabel
B-jet decoration.
Definition: OverlapRemovalInit.h:43
APP_NAME
#define APP_NAME
Definition: BoostedXbbTag.cxx:23
calibdata.exception
exception
Definition: calibdata.py:496
TEvent.h
ORUtils::ToolBox::initialize
StatusCode initialize()
Attach and initialize all tools.
Definition: ToolBox.cxx:35
Init.h
DQHistogramMergeRegExp.argc
argc
Definition: DQHistogramMergeRegExp.py:20
TauJetContainer.h
PlotSFuncertainty.wp
wp
Definition: PlotSFuncertainty.py:112
ORUtils::ORFlags::doTaus
bool doTaus
Definition: OverlapRemovalInit.h:62
DataVector
Derived DataVector<T>.
Definition: DataVector.h:794
xAOD::IParticle::pt
virtual double pt() const =0
The transverse momentum ( ) of the particle.
ORUtils::ToolBox::phoMuORT
OverlapHandle_t phoMuORT
Definition: ToolBox.h:77
selectObjects
void selectObjects(const ContainerType *container)
Definition: OverlapRemovalTester.cxx:81
GetAllXsec.entry
list entry
Definition: GetAllXsec.py:132
ORUtils::ToolBox::phoEleORT
OverlapHandle_t phoEleORT
Definition: ToolBox.h:76
OverlapRemovalInit.h
Defines helper functions for initializing the OR tools in C++.
EventInfo.h
xAOD::EventInfo_v1
Class describing the basic event information.
Definition: EventInfo_v1.h:43
MuonContainer.h
ORUtils::ToolBox::masterTool
MasterHandle_t masterTool
Master overlap removal tool handle.
Definition: ToolBox.h:64
xAOD::TauJetParameters::EleRNNLoose
@ EleRNNLoose
Definition: TauDefs.h:132
xAOD::TStore
A relatively simple transient store for objects created in analysis.
Definition: TStore.h:44
xAOD::photon
@ photon
Definition: TrackingPrimitives.h:199
JetContainer.h
ORUtils::ORFlags
A struct of global config options used to simplify the config helper interface.
Definition: OverlapRemovalInit.h:29
POOL::TEvent::retrieve
StatusCode retrieve(const T *&obj)
Definition: PhysicsAnalysis/POOLRootAccess/POOLRootAccess/TEvent.h:74
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
xAOD::EgammaParameters::electron
@ electron
Definition: EgammaEnums.h:18
OverlapRemovalDefs.h
entries
double entries
Definition: listroot.cxx:49
ORUtils::ToolBox
A container and helper class for overlap removal tools.
Definition: ToolBox.h:39
SG::ConstAccessor::isAvailable
bool isAvailable(const ELT &e) const
Test to see if this variable exists in the store.
outputPassValue
const bool outputPassValue
Definition: OverlapRemovalTester.cxx:67
defineDB.jets
list jets
Definition: JetTagCalibration/share/defineDB.py:24
L1Topo::Error
Error
The different types of error that can be flagged in the L1TopoRDO.
Definition: Error.h:16
python.PyAthena.obj
obj
Definition: PyAthena.py:132
printObj
void printObj(const char *APP_NAME, const char *type, const xAOD::IParticle *obj)
Definition: OverlapRemovalTester.cxx:120
DataVector::size
size_type size() const noexcept
Returns the number of elements in the collection.
PhotonContainer.h
xAOD::TauJetParameters::JetRNNSigLoose
@ JetRNNSigLoose
Definition: TauDefs.h:146
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
overlapAcc
const ort::outputAccessor_t overlapAcc(outputLabel)
xAOD::Init
StatusCode Init(const char *appname)
Function initialising ROOT/PyROOT for using the ATLAS EDM.
Definition: Init.cxx:31