ATLAS Offline Software
Functions
top-xaod.cxx File Reference
#include <iostream>
#include <memory>
#include "TFile.h"
#include "TTree.h"
#include "TTreeFormula.h"
#include "TSystem.h"
#include "xAODRootAccess/TEvent.h"
#include "xAODRootAccess/TStore.h"
#include "xAODRootAccess/TActiveStore.h"
#include "xAODCore/tools/ReadStats.h"
#include "xAODCore/tools/PerfStats.h"
#include "xAODCore/tools/IOStats.h"
#include "xAODCutFlow/CutBookkeeper.h"
#include "xAODCutFlow/CutBookkeeperContainer.h"
#include "FakeBkgTools/AsymptMatrixTool.h"
#include "TopCorrections/ScaleFactorCalculator.h"
#include "TopCorrections/PDFScaleFactorCalculator.h"
#include "TopSystematicObjectMaker/ObjectCollectionMaker.h"
#include "TopConfiguration/ConfigurationSettings.h"
#include "TopConfiguration/TopConfig.h"
#include "TopConfiguration/SelectionConfigurationData.h"
#include "TopConfiguration/Tokenize.h"
#include "TopAnalysis/AnalysisTrackingHelper.h"
#include "TopAnalysis/EventSelectionManager.h"
#include "TopAnalysis/Tools.h"
#include "TopCPTools/TopToolStore.h"
#include "TopAnalysis/ObjectLoaderBase.h"
#include "TopAnalysis/EventSaverBase.h"
#include "TopEvent/EventTools.h"
#include "TopEvent/TopEventMaker.h"
#include "TopEvent/SystematicEvent.h"
#include "TopObjectSelectionTools/TopObjectSelection.h"
#include "TopObjectSelectionTools/EventCleaningSelection.h"
#include "TopPartons/CalcTtbarPartonHistory.h"
#include "TopPartons/CalcTthPartonHistory.h"
#include "TopPartons/CalcTtbarLightPartonHistory.h"
#include "TopPartons/CalcTbbarPartonHistory.h"
#include "TopPartons/CalcWtbPartonHistory.h"
#include "TopPartons/CalcTTZPartonHistory.h"
#include "TopPartons/CalcTopPartonHistory.h"
#include "TopPartons/CalcTtbarGammaPartonHistory.h"
#include "TopPartons/CalcThqPartonHistory.h"
#include "TopPartons/CalcTzqPartonHistory.h"
#include "TopParticleLevel/ParticleLevelLoader.h"
#include "TopDataPreparation/SampleXsection.h"
#include "xAODRootAccess/tools/TFileAccessTracer.h"
#include "PathResolver/PathResolver.h"
#include "TopAnalysis/MsgCategory.h"

Go to the source code of this file.

Functions

int main (int argc, char **argv)
 

Function Documentation

◆ main()

int main ( int  argc,
char **  argv 
)

Truth events –///

– End of Truth events – start of reconstruction level events –///

– We veto events that do not pass the GRL, trigger or have bad calorimeters –/// – No point calibrating and cutting on events that fail these cuts –/// – We only apply a veto if ALL selectors request a cut –/// – And if the user selects "OutputEvents SelectedEvents" –///

– Count initial events –///

– Does event pass the GRL? (always true for MC) –/// – Only veto events when ALL user selectors request GRL –///

– Are the Tile and LAr calorimeters in a good state? (always true for MC) –/// – Only veto events when ALL user selectors request GOODCALO –///

– Do we have a Primary Vertex? –/// – Only veto events when ALL user selectors request PRIVTX – ///

– Wondering which triggers are available ??? –/// – Uncomment this line and get ready for a LOT of output –///

– Does event pass any trigger ? –/// – Only veto events when ALL user selectors request TRIGDEC –/// – And all trigger fail –///

– Nominal objects – /// – Calibrate objects and make all required systematic copies –///

– Object selection (e.g. good electrons, muons, jets etc.). Event selection cuts comes later –///

– Recalculate MissingET based on object selection –///

– Systematic objects – /// – Calibrate objects and make all required systematic copies –///

– Object selection (e.g. good electrons, muons, jets etc.). Event selection cuts comes later –///

– Recalculate MissingET based on object selection –///

– Scale Factor calculation –///

– Loop over all systematics and make a "top::Event" for each –///

– Make a top::Event –///

– Apply event selection –///

– Save event - we defer to eventSaver the decision to write or not –///

– For printout at the end of job, only count nominal events –///

– End loop over all calibration systematics –///

– End of tight events –///

– Loop over all Loose systematics and make a "top::Event" for each –///

– Make a top::Event –///

– Apply event selection –///

– weights for matrix-method fakes estimate from IFF tools, only for nominal –///

– Save event - we defer to eventSaver the decision to write or not –///

– For printout at the end of job, only count nominal events –///

– End loop over all loose calibration systematics –///

– End of loose events –///

– Needed for xAOD output, all systematics go into the same TTree –///

Definition at line 85 of file top-xaod.cxx.

85  {
86  if (argc != 3) {
87  ATH_MSG_INFO("Code to perform object and event selection and write-out\n"
88  << "a few histograms and / or a tree in xAOD format.\n"
89  << "Use like:\n"
90  << " " << argv[0] << " cuts.txt input.txt\n"
91  << " cuts.txt - file containing cuts\n"
92  << " input.txt - file containing list of input files\n"
93  << "\n"
94  << "For example\n"
95  << " " << argv[0]
96  << " $ROOTCOREBIN/data/TopAnalysis/nocuts.txt $ROOTCOREBIN/data/TopAnalysis/input-13TeV-fondueworld.txt\n");
97  return 1;
98  }
99 
100  gErrorAbortLevel = kError;
101 
102  // to disable the sending of file access statistics
104 
105  //magic xAOD stuff
106  //true = fail at even the slightest xaod issue
107  top::xAODInit(true);
108  StatusCode::enableFailure();
109 
111 
112  ATH_MSG_INFO("INPUT: Configuration file (argv[1]) = "
113  << argv[1] << "\n");
114  std::string settingsFilename = PathResolver::find_file(argv[1],"DATAPATH",PathResolver::LocalSearch);
115 
116  ATH_MSG_INFO("LOCATED (using PathResolverFindFile ): Configuration file = "
117  << settingsFilename << "\n");
118 
119  ATH_MSG_INFO("Configuration Files:\n"
120  << settingsFilename << "\n"
121  << argv[2] << "\n");
122 
123  //load the settings from the input file
124  auto* const settings = top::ConfigurationSettings::get();
125  settings->loadFromFile(settingsFilename);
126  ATH_MSG_INFO("Configuration:\n" << *settings << "\n");
127 
128  // only after printing full configuration check if there are issues and inform user and crash if necessary
129  settings->checkSettings();
130 
131  const std::string libraryNames = settings->value("LibraryNames");
132  top::loadLibraries(libraryNames);
133 
134  // Analysis tracking
135  std::unique_ptr<top::AnalysisTrackingHelper> tracker;
136  {
137  bool useTracking = true;
138  settings->retrieve("WriteTrackingData", useTracking);
139  if (useTracking) {
140  tracker.reset(new top::AnalysisTrackingHelper());
141  }
142  }
143 
144  // I/O Performance stats?
145  // Summary gives a summary
146  // Full gives detailed info on each collection in the file
147  unsigned int doPerfStats(0);
148  if (settings->value("PerfStats") == "Summary") doPerfStats = 1;
149 
150  if (settings->value("PerfStats") == "Full") doPerfStats = 2;
151 
152  //load the event selection from the input file
153  std::string cutsFilename = std::string(settingsFilename);
154 
155  //open the files (to check they exist) and count how many events we have
156  std::vector<std::string> filenames = top::fileList(std::string(argv[2]));
157  size_t totalYield = top::checkFiles(filenames);
158 
159  //open output file
160  std::unique_ptr<TFile> outputFile(TFile::Open((settings->value("OutputFilename") + ".tmp").c_str(), "RECREATE"));
161 
162  // A configuration that John can easily understand
163  // This is not the same as a good configuration
164  std::shared_ptr<top::TopConfig> topConfig(new top::TopConfig());
165 
166  //picking the first file was a bad idea because in the derivations it often
167  //has no events (no CollectionTree). Be sure to pick a file with events in
168  //it -- this is needed to determine the year to setup triggers
169  //FIXME -- can we have this in MetaData without having to open CollectionTree ?
170  {
171  std::string usethisfile = filenames[0];
172  for (const auto& filename : filenames) {
173  std::unique_ptr<TFile> checkingYieldFile(TFile::Open(filename.c_str()));
174 
175  //collection tree means > 0 events
176  const TTree* const collectionTree = dynamic_cast<TTree* > (checkingYieldFile->Get("CollectionTree"));
177  if (collectionTree) {
178  usethisfile = filename;
179  break;
180  }
181  }
182 
183  // read FileMetaData using AsgMetadataTool
184  std::unique_ptr<TFile> testFile(TFile::Open(usethisfile.c_str()));
185  if (!top::readMetaData(testFile.get(), topConfig)) {
186  ATH_MSG_ERROR("Unable to access FileMetaData in this file : " << usethisfile
187  << "\nPlease report this message.");
188  return 1;
189  }
190 
191  ATH_MSG_INFO("Derivation stream is -> " << topConfig->getDerivationStream());
192 
193  // Pass the settings file to the TopConfig
194  topConfig->setConfigSettings(settings);
195 
196  if (topConfig->isMC() && !topConfig->isTruthDxAOD()) {
197  // now need to get and set the parton shower generator from TopDataPrep
198  SampleXsection tdp;
199  // Package/filename - XS file we want to use (can now be configured via cutfile)
200  const std::string tdp_filename = settings->value("TDPPath");
201  // Use the path resolver to find the first file in the list of possible paths ($CALIBPATH)
202  const std::string fullpath = PathResolverFindCalibFile(tdp_filename);
203  if (!tdp.readFromFile(fullpath.c_str())) {
204  ATH_MSG_ERROR("TopDataPreparation - could not read file\n" << tdp_filename);
205  return 1;
206  }
207  ATH_MSG_INFO("SampleXsection::Found " << fullpath);
208 
209  tdp.setTranslator(topConfig->GetMCMCTranslator());
210 
211  int ShowerIndex = tdp.getShoweringIndex(topConfig->getDSID());
212  ATH_MSG_INFO("DSID: " << topConfig->getDSID() << "\t" << "ShowerIndex: " << ShowerIndex << " PS generator: "<< tdp.getShoweringString(topConfig->getDSID()));
213  topConfig->setMapIndex(ShowerIndex);
214  topConfig->setShoweringAlgorithm(tdp.getShowering(topConfig->getDSID()));
215  }
216  // check year
217  {
219  top::check(xaodEvent.readFrom(testFile.get()), "Failed to read file in");
220  const unsigned int entries = xaodEvent.getEntries();
221  if (entries > 0) {
222  xaodEvent.getEntry(0);
223  const xAOD::EventInfo* eventInfo(nullptr);
224  top::check(xaodEvent.retrieve(eventInfo, topConfig->sgKeyEventInfo()), "Failed to retrieve EventInfo");
225  const unsigned int runnumber = eventInfo->runNumber();
226  const std::string thisYear = topConfig->getYear(runnumber, topConfig->isMC());
227  topConfig->SetYear(thisYear);
228  } else {
229  topConfig->SetYear("UNKNOWN");
230  }
231  topConfig->SetTriggersToYear(topConfig->isMC());
232  }
233 
234  } //close and delete the ptr to testFile
235 
236 
238 
239  // This first input file needs to be open, because some CP tools expect to be able to
240  // read stuff during initialization
241  // At minimum, the PMGTruthWeightTool needs access to metadata
242  std::unique_ptr<TFile> metadataInitFile(TFile::Open(filenames[0].c_str()));
243  top::check(xaodEvent.readFrom(metadataInitFile.get()), "xAOD::TEvent readFrom failed");
244 
245  // Setup all asg::AsgTools
246  top::TopToolStore topTools("top::TopToolStore");
247  top::check(topTools.setProperty("config", topConfig),
248  "Failed to setProperty of topTools");
249  top::check(topTools.initialize(), "Failed to initialize topTools");
250 
251  // retrieve PMGTruthWeightTool
252  ToolHandle<PMGTools::IPMGTruthWeightTool> m_pmg_weightTool("PMGTruthWeightTool");
253  if (topConfig->isMC() && !m_pmg_weightTool.retrieve()) {
254  ATH_MSG_ERROR("Cannot retrieve PMGTruthWeightTool.");
255  return 1;
256  }
257 
258  // EventCleaningSelection
259  // Decorates EventInfo with GRL decision (always true for MC)
260  // Evaluates all triggers requested from all selections
261  // Trigger matching
262  // Check for good Tile and LAr calorimeters
263  // Let's check this passes before running expensive calibrations
264  // If ANY selection does not request a trigger, we won't veto any events
265 
266  std::unique_ptr<top::EventCleaningSelection> eventCleaning(new top::EventCleaningSelection(
267  "top::EventCleaningSelection"));
268  top::check(eventCleaning->setProperty("config", topConfig),
269  "Failed to setProperty of triggerGRLSelection");
270  top::check(eventCleaning->initialize(),
271  "Failed to initialize triggerGRLSelection");
272  eventCleaning->setEventSelections(settings->selections());
273 
274 
275  // Systematic object collection making
276  std::unique_ptr<top::TopObjectSelection> objectSelection;
277  std::unique_ptr<top::ObjectCollectionMaker> systObjMaker(new top::ObjectCollectionMaker("top::ObjectCollectionMaker"));
278  top::check(systObjMaker->setProperty("config", topConfig), "Failed to setProperty of systObjMaker");
279  if (!topConfig->isTruthDxAOD()) {
280  top::check(systObjMaker->initialize(), "Failed to initialize systObjMaker");
281  objectSelection.reset(top::loadObjectSelection(topConfig));
282  objectSelection->print(msg(MSG::Level::INFO)); // forward to msg stream using INFO level
283  }
284 
285  //setup event-level cuts
286  top::EventSelectionManager eventSelectionManager(settings->selections(), outputFile.get(), libraryNames, topConfig);
287 
288  //The loader tool for top::ParticleLevelEvent objects
289  top::ParticleLevelLoader particleLevelLoader(topConfig);
290 
291  // Fix the configuration - it now knows about:
292  // * all objects collections to work with
293  // * all systematic variations
294  topConfig->fixConfiguration();
295 
296 
297  // OK let's printout the TopConfig
298  ATH_MSG_INFO(*topConfig << "\n");
299  if (tracker) tracker->setTopConfig(topConfig);
300 
301  //Top parton history for MC events
302  // This is quite ugly and simple, it will be harmonized with in the future
303  // along with all other factory methods (it's not a factory method right now)
304  std::unique_ptr<top::CalcTopPartonHistory> topPartonHistory(nullptr);
305  if (settings->value("TopPartonHistory") == "ttbar") {
306  topPartonHistory =
307  std::unique_ptr<top::CalcTopPartonHistory> (new top::CalcTtbarPartonHistory("top::CalcTtbarPartonHistory"));
308  top::check(topPartonHistory->setProperty("config",
309  topConfig), "Failed to setProperty of top::CalcTtbarPartonHistory");
310  } else if (settings->value("TopPartonHistory") == "ttbarlight") {
311  topPartonHistory =
312  std::unique_ptr<top::CalcTopPartonHistory> (new top::CalcTtbarLightPartonHistory(
313  "top::CalcTtbarLightPartonHistory"));
314  top::check(topPartonHistory->setProperty("config",
315  topConfig), "Failed to setProperty of top::CalcTtbarLightPartonHistory");
316  } else if (settings->value("TopPartonHistory") == "tb") {
317  topPartonHistory =
318  std::unique_ptr<top::CalcTopPartonHistory> (new top::CalcTbbarPartonHistory("top::CalcTbbarPartonHistory"));
319  top::check(topPartonHistory->setProperty("config",
320  topConfig), "Failed to setProperty of top::CalcTbbarPartonHistory");
321  } else if (settings->value("TopPartonHistory") == "Wtb") {
322  topPartonHistory =
323  std::unique_ptr<top::CalcTopPartonHistory> (new top::CalcWtbPartonHistory("top::CalcWtbPartonHistory"));
324  top::check(topPartonHistory->setProperty("config", topConfig),
325  "Failed to setProperty of top::CalcWtbPartonHistory");
326  } else if (settings->value("TopPartonHistory") == "ttz") {
327  topPartonHistory =
328  std::unique_ptr<top::CalcTopPartonHistory> (new top::CalcTTZPartonHistory("top::CalcTTZPartonHistory"));
329  top::check(topPartonHistory->setProperty("config", topConfig),
330  "Failed to setProperty of top::CalcTTZPartonHistory");
331  } else if (settings->value("TopPartonHistory") == "ttgamma") {
332  topPartonHistory =
333  std::unique_ptr<top::CalcTopPartonHistory> (new top::CalcTtbarGammaPartonHistory(
334  "top::CalcTtbarGammaPartonHistory"));
335  top::check(topPartonHistory->setProperty("config",
336  topConfig), "Failed to setProperty of top::CalcTtbarGammaPartonHistory");
337  } else if (settings->value("TopPartonHistory") == "tHq") {
338  topPartonHistory =
339  std::unique_ptr<top::CalcTopPartonHistory>(new top::CalcThqPartonHistory("top::CalcThqPartonHistory"));
340  top::check(topPartonHistory->setProperty("config", topConfig),
341  "Failed to setProperty of top::CalcThqPartonHistory");
342  } else if (settings->value("TopPartonHistory") == "tZq") {
343  topPartonHistory =
344  std::unique_ptr<top::CalcTopPartonHistory>(new top::CalcTzqPartonHistory("top::CalcTzqPartonHistory"));
345  top::check(topPartonHistory->setProperty("config", topConfig),
346  "Failed to setProperty of top::CalcTzqPartonHistory");
347  } else if (settings->value("TopPartonHistory") == "ttH") {
348  topPartonHistory = std::unique_ptr<top::CalcTopPartonHistory> (new top::CalcTthPartonHistory("top::CalcTthPartonHistory"));
349  top::check(topPartonHistory->setProperty("config", topConfig), "Failed to setProperty of top::CalcTthPartonHistory");
350  }
351 
352  //LHAPDF SF calculation
353  std::unique_ptr<top::PDFScaleFactorCalculator> PDF_SF(nullptr);
354  PDF_SF =
355  std::unique_ptr<top::PDFScaleFactorCalculator> (new top::PDFScaleFactorCalculator("top::PDFScaleFactorCalculator"));
356  if (topConfig->doLHAPDF()) {
357  top::check(PDF_SF->setProperty("config", topConfig), "Failed to set config for PDF SF Calculator");
358  top::check(PDF_SF->initialize(), "Failed to initialize PDF SF calculator");
359  }
360 
361 
362  // make top::Event objects
363  std::unique_ptr<top::TopEventMaker> topEventMaker(new top::TopEventMaker("top::TopEventMaker"));
364  top::check(topEventMaker->setProperty("config", topConfig), "Failed to setProperty of top::TopEventMaker");
365  top::check(topEventMaker->initialize(), "Failed to initialize top::TopEventMaker");
366  // Debug messages?
367  // topEventMaker.msg().setLevel(MSG::DEBUG);
368 
369  std::unique_ptr<top::ScaleFactorCalculator> topScaleFactors(new top::ScaleFactorCalculator(
370  "top::ScaleFactorCalculator"));
371  top::check(topScaleFactors->setProperty("config", topConfig), "Failed to setProperty of top::ScaleFactorCalculator");
372  top::check(topScaleFactors->initialize(), "Failed to initialize top::ScaleFactorCalculator");
373 
374  std::vector<std::unique_ptr<CP::AsymptMatrixTool> > topfakesMMWeightsIFF;
375  std::vector<std::vector<std::string> > FakesMMConfigIFF;
376  if (!topConfig->isMC() && topConfig->doLooseEvents() && topConfig->doFakesMMWeightsIFF()) {
377  if (topConfig->FakesMMConfigIFF() != "") {
378  std::vector<std::string> tokens;
379  top::tokenize(topConfig->FakesMMConfigIFF(), tokens, ";");
380  std::reverse(tokens.begin(), tokens.end());
381  while (tokens.size()) {
382  const auto& token = tokens.back();
383  std::vector<std::string> tokens2;
384  top::tokenize(token, tokens2, ":");
385  top::check(tokens2.size() == 3,
386  "Failed to read FakesMMConfigIFF: " + topConfig->FakesMMConfigIFF() + " has size " +
387  std::to_string(tokens2.size()) + " (should be 3)");
388  FakesMMConfigIFF.push_back(tokens2);
389  FakesMMConfigIFF.back()[0] = PathResolverFindCalibFile(tokens2[0]);
390  tokens.pop_back();
391  }
392  }
393  for (unsigned int mmi = 0; mmi < FakesMMConfigIFF.size(); ++mmi) {
394  topfakesMMWeightsIFF.emplace_back(std::make_unique<CP::AsymptMatrixTool>("AsymptMatrixTool_" + std::to_string (mmi)));
395  top::check(topfakesMMWeightsIFF.back()->setProperty("InputFiles",
396  std::vector<std::string>{FakesMMConfigIFF[mmi][0]}),
397  "Failed To setProperty InputFiles of AsymptMatrixTool");
398  top::check(topfakesMMWeightsIFF.back()->setProperty("Selection",
399  FakesMMConfigIFF[mmi][1]),
400  "Failed to set the selection FakesMMIFFConfigs for selection " + FakesMMConfigIFF[mmi][1]);
401  top::check(topfakesMMWeightsIFF.back()->setProperty("Process",
402  FakesMMConfigIFF[mmi][2]),
403  "Failed to set the selection FakesMMIFFConfigs for process " + FakesMMConfigIFF[mmi][2]);
404  top::check(topfakesMMWeightsIFF.back()->setProperty("EnergyUnit",
405  "GeV"),
406  "Failed to setProperty EnergyUnit of AsymptMatrixTool");
407  top::check(topfakesMMWeightsIFF.back()->setProperty("ConvertWhenMissing",
408  true),
409  "Failed to setProperty ConvertWhenMissing of AsymptMatrixTool");
410  top::check(topfakesMMWeightsIFF.back()->setProperty("TightDecoration",
411  "passPreORSelection,as_char"),
412  "Failed to setProperty TightDecoration of AsymptMatrixTool");
413  MSG::Level IFFoutputLevel = topConfig->FakesMMIFFDebug() ? MSG::DEBUG : MSG::INFO;
414  top::check(topfakesMMWeightsIFF.back()->setProperty("OutputLevel", IFFoutputLevel),
415  "Failed to setProperty of AsymptMatrixTool");
416  top::check(topfakesMMWeightsIFF.back()->initialize(), "Failed to initialize AsymptMatrixTool");
417  }
418  }
419 
420  //A list of extra branches that we create in this code and want to save
421  std::vector<std::string> extraBranches;
422  eventSelectionManager.addExtraBranches(extraBranches);
423 
424  //output file format (and any user-modified code)
425  std::unique_ptr<top::EventSaverBase> eventSaver(top::loadEventSaver(topConfig));
426  eventSaver->initialize(topConfig, outputFile.get(), extraBranches);
427 
428  // save sum of weights before derivations
429  outputFile->cd();
430  TTree* sumWeights = new TTree("sumWeights", "");
431  float totalEventsWeighted = 0;
432  double totalEventsWeighted_temp = 0;
433  std::vector<float> totalEventsWeighted_LHE3;
434  std::vector<double> totalEventsWeighted_LHE3_temp;// having doubles is necessary in case of re-calculation of the sum
435  // of weights on the fly
436  std::vector<std::string> names_LHE3;
437  bool recalc_LHE3 = false;
438  bool recalculateNominalWeightSum = false;
439  int dsid = topConfig->getDSID();
440  int isAFII = topConfig->isAFII();
441  ULong64_t totalEvents = 0;
442  ULong64_t totalEventsInFiles = 0;
443  std::unordered_map<std::string, std::vector<std::string>> boostedTaggersSFSysNames = topConfig->boostedTaggersSFSysNames();
444 
445  sumWeights->Branch("dsid", &dsid);
446  sumWeights->Branch("isAFII", &isAFII);
447  sumWeights->Branch("totalEventsWeighted", &totalEventsWeighted);
448  if (topConfig->doMCGeneratorWeights()) {// the main problem is that we don't have the list of names a priori
449  sumWeights->Branch("totalEventsWeighted_mc_generator_weights", &totalEventsWeighted_LHE3);
450  sumWeights->Branch("names_mc_generator_weights", &names_LHE3);
451  }
452  sumWeights->Branch("totalEvents", &totalEvents, "totalEvents/l");
453 
454  for(auto& it : boostedTaggersSFSysNames) {
455  sumWeights->Branch(("sysNames_"+it.first).c_str(),&it.second);
456  }
457 
458  TTree* sumPdfWeights = 0;
459  std::unordered_map<std::string, std::vector<float>*> totalEventsPdfWeighted;
460  int dsidPdf = topConfig->getDSID();
461  bool pdfMetadataExists = false;
462  if (topConfig->doLHAPDF()) {
463  sumPdfWeights = new TTree("PDFsumWeights", "");
464  sumPdfWeights->Branch("dsid", &dsidPdf);
465  for (const auto& pdf_set : topConfig->LHAPDFSets()) {
466  totalEventsPdfWeighted[pdf_set] = new std::vector<float>();
467  sumPdfWeights->Branch(pdf_set.c_str(), totalEventsPdfWeighted[pdf_set]);
468  }
469  }
470 
471  //the analysis loop
472  ATH_MSG_INFO("Starting event loop\n");
473 
474  // Performance stats
475  if (doPerfStats > 0) xAOD::PerfStats::instance().start(); // start Perfstats timer
476 
477  unsigned int totalYieldSoFar = 0;
478  unsigned int skippedEventsSoFar = 0;
479  unsigned int eventSavedReco(0), eventSavedRecoLoose(0), eventSavedTruth(0), eventSavedParticle(0);
480 
481  // Close the file that we opened only for metadata
482  metadataInitFile->Close();
483 
484  for (const auto& filename : filenames) {
485  if (topConfig->numberOfEventsToRun() != 0 && totalYieldSoFar >= topConfig->numberOfEventsToRun()) break;
486  ATH_MSG_INFO("Opening " << filename);
487  std::unique_ptr<TFile> inputFile(TFile::Open(filename.c_str()));
488 
489  // the derivation framework is making files with an empty collection tree
490  // which TEvent can now handle
491  // However, at least for data, this is causing problems with the trigger menu
492  // skip the file, after the meta data access above
493  const TTree* const collectionTree = dynamic_cast<TTree* > (inputFile->Get("CollectionTree"));
494  if (!collectionTree && !topConfig->isMC()) {
495  if (top::ConfigurationSettings::get()->feature("SkipInputFilesWithoutCollectionTree")) {
496  ATH_MSG_INFO("No CollectionTree found, skipping file");
497  continue;
498  }
499  }
500 
501  top::check(xaodEvent.readFrom(inputFile.get()), "xAOD::TEvent readFrom failed");
502 
503  // Sum of weights and raw number of entries before skimming in current file
504  double sumW_file = 0;
505  ULong64_t initialEvents = 0;
506 
507  // vector of MC generator weights and their names in current file
508  std::vector<float> LHE3_sumW_file;
509  std::vector<std::string> LHE3_names_file;
510 
511  const xAOD::CutBookkeeperContainer* cutBookKeepers = nullptr;
512  if(topConfig->isTruthDxAOD())
513  {
514  ATH_MSG_INFO("Bookkeepers are not read for TRUTH derivations");
515  } else {
516  top::check(xaodEvent.retrieveMetaInput(cutBookKeepers, "CutBookkeepers"), "Cannot retrieve CutBookkeepers");
517  if (topConfig->isMC()) {
518 
519  // here we attempt to name the CutBookkeepers based on the MC weight names
520  const std::vector<std::string> &weight_names = m_pmg_weightTool->getWeightNames();
521  // try to retrieve CutBookKeepers for LHE3Weights first
522  top::parseCutBookkeepers(xaodEvent, weight_names.size(), LHE3_names_file, LHE3_sumW_file);
523  // if we have MC generator weights, we rename the bookkeepers in sumWeights TTree to match the weight names from MetaData
524  top::renameCutBookkeepers(LHE3_names_file, weight_names);
525 
526  // raw number of events taken from "AllExecutedEvents" bookkeeper, which corresponds to 0th MC weight
527  // but these are raw entries, so doesn't matter if 0th MC weight is nominal or not
528  initialEvents = top::getRawEventsBookkeeper(cutBookKeepers);
529 
530  // determine the nominal sum of weight -- we already found the nominal weight in ScaleFactorCalculator
531  const size_t nominalWeightIndex = topConfig->nominalWeightIndex();
532  sumW_file = LHE3_sumW_file.at(nominalWeightIndex);
533  } else {
534  initialEvents = top::getRawEventsBookkeeper(cutBookKeepers);
535  sumW_file = initialEvents; // this is data, it's the same number...
536  }
537  }
538 
539  totalEventsWeighted += sumW_file;
540  totalEvents += initialEvents;
541 
542  // now we must fill two vectors in sync for MCGeneratorWeights sum of weights
543  if (topConfig->doMCGeneratorWeights() && topConfig->isMC()) {
544  if (totalEventsWeighted_LHE3.size() != 0) {
545  if (totalEventsWeighted_LHE3.size() != LHE3_sumW_file.size()
546  || names_LHE3.size() != LHE3_names_file.size()
547  || names_LHE3.size() != totalEventsWeighted_LHE3.size()) {
548  ATH_MSG_ERROR("Strange inconsistency of vector sizes in sum of LHE3 weights calculation.");
549  return 1;
550  }
551  for (unsigned int i_genweights = 0; i_genweights < LHE3_names_file.size();
552  i_genweights++) {
553  if (names_LHE3.at(i_genweights) != LHE3_names_file.at(i_genweights)) {
554  ATH_MSG_ERROR("Strange inconsistency in the vector of weight names in sum of LHE3 weights calculation.");
555  return 1;
556  } else {
557  totalEventsWeighted_LHE3.at(i_genweights)
558  = totalEventsWeighted_LHE3.at(i_genweights)
559  + LHE3_sumW_file.at(i_genweights);
560  }
561  }
562  } else {
563  for (unsigned int i_genweights = 0; i_genweights < LHE3_names_file.size();
564  i_genweights++) {
565  names_LHE3.push_back(LHE3_names_file.at(i_genweights));
566  totalEventsWeighted_LHE3.push_back(LHE3_sumW_file.at(i_genweights));
567  }
568  }
569  if (!names_LHE3.empty()) {
570  ATH_MSG_INFO("The sum of weights for the following LHE3 weights were retrieved from the input file:");
571  MsgStream &msgInfo = msg(MSG::Level::INFO);
572  for (const std::string& s : names_LHE3)
573  msgInfo << s << " ";
574  msgInfo << std::endl;
575  msgInfo.doOutput();
576  } else {
577  ATH_MSG_INFO("No sum of LHE3 weights could be found in meta-data. Will try to recompute these sums.\n"
578  "This only works on un-skimmed derivations, and the names of these weights may be unknown (but we'll try to read them from the PMG tool");
579  recalc_LHE3 = true;
580  }
581  }
582 
583  if (topConfig->isTruthDxAOD()) recalculateNominalWeightSum=true;
584 
585  if (topConfig->printCDIpathWarning()) {
587  "\n*************************************************************************\n"
588  << "YOU ARE USING A CUSTOM PATH TO THE CDI FILE WHICH IS NOT THE DEFAULT PATH\n"
589  << " YOU MANY NOT BE USING THE LATEST BTAGGING RECOMMENDATIONS \n"
590  << "*************************************************************************\n\n");
591  }
592  if (topConfig->printEgammaCalibModelWarning()) {
594  "\n*************************************************************************\n"
595  << " YOU HAVE CHANGED DEFAULT EGAMMA CALIBRATION MODEL \n"
596  << " TO USE DEFAULT MODEL, REMOVE 'EGammaCalibrationModel' FROM CONFIG FILE \n"
597  << "*************************************************************************\n\n");
598  }
599  if (topConfig->printEIDFileWarning()) {
601  "\n*************************************************************************\n"
602  << " YOU ARE USING THIS CUSTOM PATH TO THE ELECTRON ID SF FILE: \n\n"
603  << topConfig->electronIDSFFilePath() << "(Tight) \n\n"
604  << topConfig->electronIDSFFileLoosePath() << "(Loose) \n\n"
605  << " INSTEAD OF THE MOST RECENT RECOMMENDED MAP \n"
606  << " YOU MANY NOT BE USING THE LATEST ELECTRON ID RECOMMENDATIONS \n"
607  << "*************************************************************************\n\n");
608  }
609 
610 
611  const unsigned int entries = xaodEvent.getEntries();
612  totalEventsInFiles += entries;
613  unsigned int firstEvent = 0;
614  if (topConfig->numberOfEventsToSkip() > skippedEventsSoFar) {
615  firstEvent = topConfig->numberOfEventsToSkip() - skippedEventsSoFar;
616  skippedEventsSoFar += entries < firstEvent ? entries : firstEvent;
617  }
618  unsigned int entry;
619  bool isFirst(true);
620  for (entry = firstEvent; entry < entries; ++entry, ++totalYieldSoFar) {
621  if (topConfig->numberOfEventsToRun() != 0 && totalYieldSoFar >= topConfig->numberOfEventsToRun()) break;
622 
623  if (entry % 100 == 0)
624  ATH_MSG_INFO("Processing event " << totalYieldSoFar << " / " << totalYield
625  << " (current file: " << entry << " / " << entries << ")");
626 
627  // clear the TStore - get rid of the last events objects
629  // increment the event
630  xaodEvent.getEntry(entry);
631 
632  // Pile up and MC event weight - used to normalize the cut flows
633  float mcEventWeight(1.), pileupWeight(1.);
634  if (topConfig->isMC()) mcEventWeight = topScaleFactors->mcEventWeight();
635 
636  if (topConfig->doPileupReweighting() && !topConfig->isTruthDxAOD()) {
637  top::check(topScaleFactors->executePileup(), "Failed to execute pileup reweighting");
638  pileupWeight = topScaleFactors->pileupWeight();
639  }
640 
641  if (topConfig->isMC()) {
642  // if requested, pre-calculate TopPartons and PDF info
643  // Run topPartonHistory
644  if (topConfig->doTopPartonHistory()) top::check(topPartonHistory->execute(), "Failed to execute topPartonHistory");
645 
646  // calculate PDF weights
647  if (topConfig->doLHAPDF()) top::check(PDF_SF->execute(),
648  "Failed to execute PDF SF");
649  }
650 
651  // perform any operation common to both reco and truth level
652  // currently we load the MC generator weights and PDFs if requested
653  eventSaver->execute();
654 
656  if (topConfig->isMC()) {
657 
658  // Save, if requested, MC truth block, PDFInfo, TopPartons
659  eventSaver->saveTruthEvent();
660  if(topConfig->doTopPartonLevel()) ++eventSavedTruth;
661 
662  // Particle level analysis, saved only for truth events passing fiducial selection
663 
664  // --------------------------------------------------
665  // If the truth loader is active, perform truth loading.
666  if (particleLevelLoader.active()) {
667  // --------------------------------------------------
668  // Get the top::TruthEvent for the current event
669  top::ParticleLevelEvent particleLevelEvent = particleLevelLoader.load();
670 
671  //event selection
672  const bool saveEventInOutputFile = eventSelectionManager.applyParticleLevel(particleLevelEvent);
673 
674  if (saveEventInOutputFile) {
675  eventSaver->saveParticleLevelEvent(particleLevelEvent);
676  ++eventSavedParticle;
677  }
678  }
679  }
680  if (totalYieldSoFar == 0 && topConfig->isMC() && topConfig->doLHAPDF()) {
681  const xAOD::TruthEventContainer* truthEvent(nullptr);
682  top::check(xaodEvent.retrieve(truthEvent, topConfig->sgKeyTruthEvent()), "Failed to retrieve TruthEvent container for LHAPDF");
683  top::check(truthEvent->size() == 1, "TruthEvent container size != 1, not sure what to do with PDF reweighting");
684  for (const auto *tePtr : *truthEvent) {
685  for (auto& pdf : totalEventsPdfWeighted) {
686  if (tePtr->isAvailable< std::vector<float> >("AnalysisTop_" + pdf.first + "_Weights")) {
687  pdf.second->resize(tePtr->auxdata< std::vector<float> >("AnalysisTop_" + pdf.first + "_Weights").size());
688  }
689  }
690  }
691  }
692  // on the first event, set the size of the vector of sum of LHE3 weights in case it needs to be calculated on the
693  // fly
694 
695  if (topConfig->isMC()) {
696  const xAOD::EventInfo* ei(nullptr);
697  top::check(xaodEvent.retrieve(ei, topConfig->sgKeyEventInfo()),
698  "Failed to retrieve LHE3 weights from EventInfo");
699  if (topConfig->isMC() && topConfig->forceRandomRunNumber() > 0) {
700  ei->auxdecor<unsigned int>("RandomRunNumber") = topConfig->forceRandomRunNumber();
701  }
702 
703  if(recalculateNominalWeightSum)
704  {
705  if (totalYieldSoFar == 0) ATH_MSG_INFO("Trying to recalculate nominal weights sum for TRUTH derivation");
706  const size_t nominalWeightIndex = topConfig->nominalWeightIndex();
707  totalEventsWeighted_temp += ei->mcEventWeights().at(nominalWeightIndex);
708  totalEvents++;
709  }
710 
711  if(topConfig->doMCGeneratorWeights())
712  {
713  unsigned int weightsSize = ei->mcEventWeights().size();
714  if (recalc_LHE3) {
715  if (totalYieldSoFar == 0) {
716  totalEventsWeighted_LHE3_temp.resize(weightsSize);
717  for (unsigned int i_LHE3 = 0; i_LHE3 < weightsSize; i_LHE3++) {
718  totalEventsWeighted_LHE3_temp.at(i_LHE3) = ei->mcEventWeights().at(i_LHE3);
719  }
720  names_LHE3.resize(weightsSize);
721 
722  const std::vector<std::string> &weight_names = m_pmg_weightTool->getWeightNames();
723  if(weight_names.size() != weightsSize)
724  {
725  ATH_MSG_INFO("In top-xaod, while calculating mc weights sums on the fly, names from PMG tools have different size wrt weight vector, we'll not retrieve weight names");
726  std::fill(names_LHE3.begin(), names_LHE3.end(), "?");
727  }
728  else{
729  for(unsigned int i_wgt=0; i_wgt<weight_names.size(); i_wgt++) names_LHE3[i_wgt]=weight_names[i_wgt];
730  }
731  } else {
732  for (unsigned int i_LHE3 = 0; i_LHE3 < weightsSize; i_LHE3++) {
733  totalEventsWeighted_LHE3_temp.at(i_LHE3) = totalEventsWeighted_LHE3_temp.at(i_LHE3) +
734  ei->mcEventWeights().at(i_LHE3);
735  }
736  }
737  } else if (weightsSize != names_LHE3.size()) {// don't recalc sum of weights, but cross-check the size of the
738  // vectors
739  ATH_MSG_ERROR("Strange size inconsistency in the AllExecutedEvents* "
740  "sum of weights bookkeepers from the meta-data and the vector of "
741  "LHE3 weights in the EventInfo container.");
742  return 1;
743  }
744  }
745  }
747  if (topConfig->isTruthDxAOD()) continue;
748 
749 
754 
756  eventSelectionManager.countInitial(mcEventWeight, pileupWeight);
757 
760  bool passGRLVeto = eventCleaning->applyGRL();
761  if (!passGRLVeto) continue;
762  eventSelectionManager.countGRL(mcEventWeight, pileupWeight);
763 
766  bool passGoodCalo = eventCleaning->applyGoodCalo();
767  if (!passGoodCalo) continue;
768  eventSelectionManager.countGoodCalo(mcEventWeight, pileupWeight);
769 
772  bool passPriVtx = eventCleaning->applyPrimaryVertex();
773  if (!passPriVtx) continue;
774  eventSelectionManager.countPrimaryVertex(mcEventWeight, pileupWeight);
775 
778  // eventCleaning->printTriggers();
779 
783  bool passAnyTriggerVeto = eventCleaning->applyTrigger();
784  if (!passAnyTriggerVeto) continue;
785 
788  top::check(systObjMaker->execute(true), "Failed to execute systObjMaker");
789 
791  top::check(objectSelection->execute(true), "Failed to execute objectSelection");
792 
794  top::check(systObjMaker->recalculateMET(true), "Failed to recalculateMET with systObjMaker");
795 
798  top::check(systObjMaker->execute(false), "Failed to execute systObjMaker");
799 
801  top::check(objectSelection->execute(false), "Failed to execute objectSelection");
802 
804  top::check(systObjMaker->recalculateMET(false), "Failed to recalculateMET with systObjMaker");
805 
806 
808  if (topConfig->isMC()) top::check(topScaleFactors->execute(), "Failed to calculate scale factors");
809 
810  if (topConfig->doTightEvents()) {
812  const xAOD::SystematicEventContainer* allSystematics = topEventMaker->systematicEvents(
813  topConfig->sgKeyTopSystematicEvents());
814  for (const auto *currentSystematic : *allSystematics) {
815  if (!(currentSystematic->hashValue() == topConfig->nominalHashValue() || topConfig->doTightSysts())) continue;
816 
818  top::Event topEvent = topEventMaker->makeTopEvent(currentSystematic);
820  const bool passAnyEventSelection = eventSelectionManager.apply(topEvent, *currentSystematic);
821  // check if we are using actual mu for mc16d or mc16e
822  if (isFirst && topConfig->isMC()) {
823  const int runNumber = topEvent.m_info->runNumber();
824  if (runNumber >= 300000) {
825  if ((!topConfig->isAFII() && topConfig->PileupActualMu_FS().size() == 0) ||
826  (topConfig->isAFII() && topConfig->PileupActualMu_AF().size() == 0)) {
827  ATH_MSG_WARNING("\n***************************************************************************************"
828  "\nYou are running over MC campaigns which support actual mu rewighting, but you are not using it!"
829  "\nYou are strongly adviced to use it.\nCheck https://twiki.cern.ch/twiki/bin/view/AtlasProtected/TopxAODStartGuideR21#PRW_and_Lumicalc_files"
830  "\n***************************************************************************************\n");
831  }
832  }
833  }
834  currentSystematic->auxdecor<char>(topConfig->passEventSelectionDecoration()) = passAnyEventSelection ? 1 : 0;
835  topEvent.m_saveEvent = passAnyEventSelection;
837  eventSaver->saveEvent(topEvent);
838 
840  if (passAnyEventSelection &&
841  currentSystematic->hashValue() == topConfig->nominalHashValue()) ++eventSavedReco;
842  }
844  }
846 
847  if (topConfig->doLooseEvents()) {
849  const xAOD::SystematicEventContainer* allSystematicsLoose = topEventMaker->systematicEvents(
850  topConfig->sgKeyTopSystematicEventsLoose());
851  for (const auto *currentSystematic : *allSystematicsLoose) {
852  if (!(currentSystematic->hashValue() == topConfig->nominalHashValue() || topConfig->doLooseSysts())) continue;
853 
855  top::Event topEvent = topEventMaker->makeTopEvent(currentSystematic);
857  const bool passAnyEventSelection = eventSelectionManager.apply(topEvent, *currentSystematic);
858 
859  // check if we are using actual mu for mc16d or mc16e
860  if (isFirst && topConfig->isMC()) {
861  const int runNumber = topEvent.m_info->runNumber();
862  if (runNumber >= 300000) {
863  if ((!topConfig->isAFII() && topConfig->PileupActualMu_FS().size() == 0) ||
864  (topConfig->isAFII() && topConfig->PileupActualMu_AF().size() == 0)) {
865  ATH_MSG_WARNING("\n***************************************************************************************"
866  "\nYou are running over mc16d or mc16e sample but you are not using actual mu reweighting!"
867  "\nYou are strongly adviced to use it.\nCheck https://twiki.cern.ch/twiki/bin/view/AtlasProtected/TopxAODStartGuideR21#PRW_and_Lumicalc_files"
868  "\n***************************************************************************************\n");
869  }
870  }
871  }
872  currentSystematic->auxdecor<char>(topConfig->passEventSelectionDecoration()) = passAnyEventSelection ? 1 : 0;
873  topEvent.m_saveEvent = passAnyEventSelection;
875  if (!topConfig->isMC() && topConfig->doFakesMMWeightsIFF() &&
876  currentSystematic->hashValue() == topConfig->nominalHashValue()) {
878  for (xAOD::Electron *t : topEvent.m_electrons)
879  lepton.push_back(static_cast<xAOD::Electron*>(t));
880  for (xAOD::Muon *t : topEvent.m_muons)
881  lepton.push_back(static_cast<xAOD::Muon*>(t));
882 
883  std::vector<float> mmweight;
884  for (unsigned int mmi = 0; mmi < topfakesMMWeightsIFF.size(); ++mmi) {
885  top::check(topfakesMMWeightsIFF[mmi]->addEvent(lepton),
886  "Failed to execute fakes mmweight IFF addEvent()");
887  float asmWgt = 0.;
888  top::check(topfakesMMWeightsIFF[mmi]->applySystematicVariation(
889  {}), "Failed to execute fakes mmweight IFF applySystematicVariation()");
890  top::check(topfakesMMWeightsIFF[mmi]->getEventWeight(asmWgt, FakesMMConfigIFF[mmi][1],
891  FakesMMConfigIFF[mmi][2]), "Failed to execute fakes mmweight IFF getEventWeight()");
892 
893  mmweight.push_back(asmWgt);
894  }
895  topEvent.m_info->auxdecor<std::vector<float> >("ASM_weight") = mmweight;
896  }
898  eventSaver->saveEvent(topEvent);
899 
901  if (passAnyEventSelection &&
902  currentSystematic->hashValue() == topConfig->nominalHashValue()) ++eventSavedRecoLoose;
903  }
905  }
907 
909  eventSaver->saveEventToxAOD();
910  isFirst = false;
911  } //loop over events in current file
912  if (tracker) tracker->addInputFile(inputFile->GetName(), entry - firstEvent);
913 
914  // do it at the end, so we can get the DS id from the first event
915  // notice this is different from the normal sum of weights: all entries matter, not only the highest per file
916  if (topConfig->doLHAPDF()) {
917  bool pdfInCBK = false;
918  if (xaodEvent.retrieveMetaInput(cutBookKeepers, "CutBookkeepers")) {
919  // try to get the first entry
920  std::string pdf_set = totalEventsPdfWeighted.begin()->first;
921  std::string p = pdf_set + "_0";
922  for (const auto *cbk : *cutBookKeepers) {
923  std::string pdfName = cbk->name();
924  if (p != pdfName) continue;
925  pdfMetadataExists = true;
926  pdfInCBK = true;
927  // reload to set iterator back to original state
928  if (!xaodEvent.retrieveMetaInput(cutBookKeepers, "CutBookkeepers")) {
929  }
930  break;
931  }
932  }
933  // if the pdf info was in the CBK the PDFSumOfWeights retrieve never happens,
934  // and cutBookKeepers, will keep its reference to the main CBK
935  if (!pdfInCBK) { // only try this if the info is not in the CBK -- this is legacy stuff
936  if (!xaodEvent.retrieveMetaInput(cutBookKeepers, "PDFSumOfWeights")) {
937  pdfMetadataExists = false;
938  }
939  }
940  if (pdfMetadataExists && topConfig->saveLHAPDFEvent() && topConfig->baseLHAPDF().empty()) {
941  // just make a copy of it, but not all derivations have it, so just ignore it if it is not there
942  for (auto& pdfentry : totalEventsPdfWeighted) {
943  std::string pdf_set = pdfentry.first;
944  for (size_t n = 0; n < totalEventsPdfWeighted[pdf_set]->size(); ++n) {
945  std::string p = pdf_set + "_" + std::to_string(n);
946  bool foundPdf = false;
947  for (const auto *cbk : *cutBookKeepers) {
948  std::string pdfName = cbk->name();
949  if (p != pdfName) continue;
950  totalEventsPdfWeighted[pdf_set]->at(n) = cbk->sumOfEventWeights();
951  foundPdf = true;
952  break;
953  }
954  if (!foundPdf) { // asked for PDF weighting, the PDF metadata exists, but this particular PDF is missing
955  // crash hard
957  "The force is not strong with us, young Padawan ...\n"
958  "You want to save weights to do PDF reweighting using '" << pdf_set <<
959  "', which I figure has " << totalEventsPdfWeighted[pdf_set]->size() << " sets on it.\n"
960  "There is metadata information for the sum of MC*PDF weights in PDFSumOfWeights, "
961  "but none seem to refer to '" << p << "' therefore I do not know how to estimate "
962  "the sum of weights before acceptance for this configuration.\n"
963  "May the force be with you in your next attempt.");
964  return 1;
965  }
966  }
967  }
968  sumPdfWeights->Fill();
969  }
970  } //doLHAPDF
971  } //loop over files
972 
973  if (doPerfStats > 0) xAOD::PerfStats::instance().stop(); // Stop the PerfStats timer
974 
975  if (topConfig->doLHAPDF()) top::check(PDF_SF->finalize(), "Failed to finalize PDF SF");
976 
977  // this fills the sum of weights
978  // if the list of input files has more than
979  // one type of dataset (ie: the first file is ttbar and the second one
980  // is W+jets), then the Fill statement below needs to come in the end of
981  // each file's processing instead ... but why would you do that?!
982  if (recalc_LHE3) {// in case the sum of LHE3 weight has been re-calculated with double (but we need floats in the end)
983  for (double d:totalEventsWeighted_LHE3_temp) totalEventsWeighted_LHE3.push_back(d);
984  }
985  if(recalculateNominalWeightSum)
986  {
987  totalEventsWeighted=totalEventsWeighted_temp;
988  }
989  sumWeights->Fill();
990  outputFile->cd();
991 
992  if (topConfig->doLHAPDF()) {
993  // Save sum of weights of PDF variations
994  // Only do this if the metadata is not available
995  if (totalEventsInFiles != totalEvents && !pdfMetadataExists) {
996  ATH_MSG_ERROR("These are not the droids you are looking for.\n"
997  "You are running over skimmed derivations. We cannot determine "
998  "the sum of MC*PDF weights before skimming "
999  "because no PDF metadata is available in the file!");
1000  return 1;
1001  }
1002  // save recomputed sum weights
1003  if ((!topConfig->baseLHAPDF().empty() || !pdfMetadataExists)) {
1004  for (auto& pdf_result : topConfig->getLHAPDFResults())
1005  *(totalEventsPdfWeighted[pdf_result.first]) = pdf_result.second;
1006  sumPdfWeights->Fill();
1007  }
1008  } //doLHAPDF
1009 
1010  outputFile->cd();
1011  eventSelectionManager.finalise();
1012  eventSaver->finalize();
1013  outputFile->cd();
1014  if (tracker) tracker->writeTree("AnalysisTracking");
1015  outputFile->Close();
1016  bool outputFileGood = !outputFile->TestBit(TFile::kWriteError);
1017  if (outputFileGood) {
1018  if (gSystem->Rename(outputFile->GetName(), settings->value("OutputFilename").c_str()) != 0) outputFileGood = false;
1019  }
1020 
1021  if (!topConfig->isTruthDxAOD()) {
1022  if (topConfig->doTightEvents())
1023  ATH_MSG_INFO("Events saved to output file nominal reconstruction tree: " << eventSavedReco);
1024  if (topConfig->doLooseEvents())
1025  ATH_MSG_INFO("Events saved to output file nominal loose reconstruction tree: " << eventSavedRecoLoose);
1026  }
1027  if (topConfig->isMC()) {
1028  ATH_MSG_INFO("Events saved to output file truth tree : " << eventSavedTruth);
1029  if (particleLevelLoader.active()) {
1030  ATH_MSG_INFO("Events saved to output file particle level tree : " << eventSavedParticle);
1031  }
1032  }
1033  ATH_MSG_INFO("Total sum-of-weights (for normalization) : " << totalEventsWeighted);
1034 
1035  //print some xAOD performance info
1036  if (doPerfStats == 1) xAOD::IOStats::instance().stats().Print("Summary");
1037  if (doPerfStats == 2) xAOD::IOStats::instance().stats().Print();
1038 
1039  if (!outputFileGood) {
1040  ATH_MSG_ERROR("ERROR: an I/O error occured while attempting to save the output file.");
1041  return 1;
1042  }
1043 
1044  return 0;
1045 }
top::ConfigurationSettings::feature
bool feature(std::string const &name) const
test whether an (experimental) feature should be enabled
Definition: ConfigurationSettings.cxx:1033
store
StoreGateSvc * store
Definition: fbtTestBasics.cxx:69
top::Event::m_info
const xAOD::EventInfo * m_info
Pointer to the event info - nullptr if not loaded, but that's probably a bad idea.
Definition: Event.h:90
top::CalcTtbarLightPartonHistory
Definition: CalcTtbarLightPartonHistory.h:32
python.SystemOfUnits.s
int s
Definition: SystemOfUnits.py:131
top::loadLibraries
void loadLibraries(const std::string &libraryNames)
So that we can load external libraries with (1) extra event selection tools in, (2) user defined obje...
Definition: Tools.cxx:275
top::CalcThqPartonHistory
Definition: CalcThqPartonHistory.h:20
python.PerfMonSerializer.p
def p
Definition: PerfMonSerializer.py:743
ATH_MSG_INFO
#define ATH_MSG_INFO(x)
Definition: AthMsgStreamMacros.h:31
PathResolver::find_file
static std::string find_file(const std::string &logical_file_name, const std::string &search_path, SearchType search_type=LocalSearch)
Definition: PathResolver.cxx:251
xAOD::IOStats::stats
ReadStats & stats()
Access the object belonging to the current thread.
Definition: IOStats.cxx:17
xAOD::PerfStats::start
void start(bool clear=true)
Start the statistics collection.
top::EventSelectionManager
Maybe you want to run multiple selections (e+jets, mu+jets) on the same input files at the same time.
Definition: EventSelectionManager.h:40
SG::VIEW_ELEMENTS
@ VIEW_ELEMENTS
this data object is a view, it does not own its elmts
Definition: OwnershipPolicy.h:18
top::CalcTzqPartonHistory
Definition: CalcTzqPartonHistory.h:20
hist_file_dump.d
d
Definition: hist_file_dump.py:137
top::TopObjectSelection::execute
StatusCode execute(bool)
Code that runs for every event (note that it runs the selection on all the systematic variations too)...
Definition: TopObjectSelection.cxx:165
xAOD::ReadStats::Print
void Print(::Option_t *option="") const
Print information about the collected statistics.
xAOD::TFileAccessTracer::enableDataSubmission
static void enableDataSubmission(::Bool_t value)
Function for turning data submission on/off.
Definition: TFileAccessTracer.cxx:281
top::tokenize
void tokenize(const std::string &input, Container &output, const std::string &delimiters=" ", bool trim_empty=false)
Tokenize an input string using a set of delimiters.
Definition: Tokenize.h:24
skel.it
it
Definition: skel.GENtoEVGEN.py:423
top::checkFiles
size_t checkFiles(const std::vector< std::string > &filenames)
Open each file in the vector and get the number of events in it.
Definition: Tools.cxx:206
readDataHeader.totalEvents
int totalEvents
Definition: readDataHeader.py:73
top::CalcTTZPartonHistory
Definition: CalcTTZPartonHistory.h:28
xAOD::TActiveStore::store
static TStore * store()
Access the currently active TStore object.
Definition: TActiveStore.cxx:16
top::loadObjectSelection
top::TopObjectSelection * loadObjectSelection(const std::shared_ptr< top::TopConfig > &config)
Users may want to define (and load!) their own object selection.
Definition: Tools.cxx:291
top::readMetaData
bool readMetaData(TFile *inputFile, const std::shared_ptr< top::TopConfig > &config)
This function will be used to load the metadata object and pull information from it.
Definition: Tools.cxx:331
LArCellConditions.argv
argv
Definition: LArCellConditions.py:112
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
beamspotman.tokens
tokens
Definition: beamspotman.py:1284
xAOD::TEvent::kClassAccess
@ kClassAccess
Access auxiliary data using the aux containers.
Definition: Control/xAODRootAccess/xAODRootAccess/TEvent.h:97
dumpFileToPlots.pdfName
string pdfName
Definition: dumpFileToPlots.py:21
xAOD::TStore::clear
void clear()
Clear the store of all of its contents.
Definition: TStore.cxx:105
top::TopConfig
Definition: TopConfig.h:41
xAOD::Muon_v1
Class describing a Muon.
Definition: Muon_v1.h:38
top::fileList
std::vector< std::string > fileList(const std::string &filename)
Given a filename for a text file, parse it and extract a list of root files.
Definition: Tools.cxx:239
SG::AuxElement::auxdecor
Decorator< T, ALLOC >::reference_type auxdecor(const std::string &name) const
Fetch an aux decoration, as a non-const reference.
xAOD::EventInfo_v1::runNumber
uint32_t runNumber() const
The current event's run number.
top::ParticleLevelLoader
Loading tool which creates a particle level event object.
Definition: ParticleLevelLoader.h:53
top::CalcTthPartonHistory
Definition: CalcTthPartonHistory.h:19
DeMoUpdate.reverse
reverse
Definition: DeMoUpdate.py:563
PathResolver::LocalSearch
@ LocalSearch
Definition: PathResolver.h:27
top::TopEventMaker
TopEventMaker produce top::Event objects from xAOD::SystematicEvent objects.
Definition: TopEventMaker.h:32
compareGeometries.outputFile
string outputFile
Definition: compareGeometries.py:25
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
SampleXsection
Definition: SampleXsection.h:19
top::CalcWtbPartonHistory
Definition: CalcWtbPartonHistory.h:31
top::Event::m_muons
xAOD::MuonContainer m_muons
Container of muons (can be sorted)
Definition: Event.h:105
TrigConf::MSGTC::Level
Level
Definition: Trigger/TrigConfiguration/TrigConfBase/TrigConfBase/MsgStream.h:21
SampleXsection::setTranslator
void setTranslator(const std::unordered_map< std::string, std::string > &map)
Definition: SampleXsection.h:57
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
CaloCondBlobAlgs_fillNoiseFromASCII.inputFile
string inputFile
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:17
top::Event::m_electrons
xAOD::ElectronContainer m_electrons
Container of electrons (can be sorted)
Definition: Event.h:99
SampleXsection::readFromFile
bool readFromFile(const char *fName)
Definition: SampleXsection.cxx:23
beamspotman.n
n
Definition: beamspotman.py:731
SampleXsection::getShoweringString
std::string getShoweringString(const int dsid) const
Definition: SampleXsection.cxx:145
Generate_dsid_ranseed.dsid
dsid
Definition: Generate_dsid_ranseed.py:6
Analysis::kError
@ kError
Definition: CalibrationDataVariables.h:60
top::ConfigurationSettings::get
static ConfigurationSettings * get(bool reset=false)
Design patterns 101.
Definition: ConfigurationSettings.cxx:714
top::AnalysisTrackingHelper
Helper for collecting data for analysis tracking.
Definition: AnalysisTrackingHelper.h:20
top::xAODInit
void xAODInit(bool failOnUnchecked)
A little wrapper for the xAOD tools.
Definition: Tools.cxx:46
top::check
void check(bool thingToCheck, const std::string &usefulFailureMessage)
Print an error message and terminate if thingToCheck is false.
Definition: EventTools.cxx:15
top::parseCutBookkeepers
void parseCutBookkeepers(xAOD::TEvent &xaodEvent, const std::size_t size, std::vector< std::string > &names, std::vector< float > &sumW)
Search bookkeepers for ones matching AllExecutedEvents, and which originate from AOD before skimming.
Definition: Tools.cxx:89
top::ParticleLevelEvent
Definition: ParticleLevelEvent.h:24
xAOD::CutBookkeeperContainer_v1
Container that holds the Container of all CutBookkeepers.
Definition: CutBookkeeperContainer_v1.h:27
SampleXsection::getShowering
showering getShowering(const int dsid) const
Definition: SampleXsection.cxx:131
DQHistogramMergeRegExp.argc
argc
Definition: DQHistogramMergeRegExp.py:20
xAOD::IOStats::instance
static IOStats & instance()
Singleton object accessor.
Definition: IOStats.cxx:11
top::CalcTtbarPartonHistory
Definition: CalcTtbarPartonHistory.h:33
DataVector
Derived DataVector<T>.
Definition: DataVector.h:581
DeMoScan.runnumber
runnumber
Definition: DeMoScan.py:266
top::TopToolStore
Definition: TopToolStore.h:49
top::getRawEventsBookkeeper
ULong64_t getRawEventsBookkeeper(const xAOD::CutBookkeeperContainer *cutBookKeepers)
Get raw number of events before skimming from "AllExecutedEvents" bookkeeper.
Definition: Tools.cxx:125
GetAllXsec.entry
list entry
Definition: GetAllXsec.py:132
ActsTrk::to_string
std::string to_string(const DetectorType &type)
Definition: GeometryDefs.h:34
top::TopObjectSelection::print
virtual void print(MsgStream &os) const
Print details of this object selection to wherever the user asks for.
Definition: TopObjectSelection.cxx:1162
xAOD::PerfStats::instance
static PerfStats & instance()
Function accessing the singleton instance.
xAOD::Electron_v1
Definition: Electron_v1.h:34
xAOD::EventInfo_v1
Class describing the basic event information.
Definition: EventInfo_v1.h:43
grepfile.filenames
list filenames
Definition: grepfile.py:34
PathResolverFindCalibFile
std::string PathResolverFindCalibFile(const std::string &logical_file_name)
Definition: PathResolver.cxx:431
DeMoAtlasDataLoss.runNumber
string runNumber
Definition: DeMoAtlasDataLoss.py:64
xAOD::TStore
A relatively simple transient store for objects created in analysis.
Definition: TStore.h:44
top::AnalysisTrackingHelper::addInputFile
void addInputFile(std::string const &path, unsigned long long entriesProcessed)
Notify helper that an input file was processed.
Definition: AnalysisTrackingHelper.cxx:67
lumiFormat.fill
fill
Definition: lumiFormat.py:111
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
python.Constants.INFO
int INFO
Definition: Control/AthenaCommon/python/Constants.py:16
top::CalcTtbarGammaPartonHistory
Definition: CalcTtbarGammaPartonHistory.h:33
DEBUG
#define DEBUG
Definition: page_access.h:11
PowhegPythia8EvtGen_jetjet.pdf
pdf
Definition: PowhegPythia8EvtGen_jetjet.py:4
CaloCellTimeCorrFiller.filename
filename
Definition: CaloCellTimeCorrFiller.py:24
top::ObjectCollectionMaker
Definition: ObjectCollectionMaker.h:45
entries
double entries
Definition: listroot.cxx:49
top::renameCutBookkeepers
void renameCutBookkeepers(std::vector< std::string > &bookkeeper_names, const std::vector< std::string > &pmg_weight_names)
Rename CutBookkeeper names according to MC generator weight names reported by PMGTruthWeightTool.
Definition: Tools.cxx:143
xAOD::PerfStats::stop
void stop()
Stop the statistics collection.
top::Event
Very simple class to hold event data after reading from a file.
Definition: Event.h:49
CscCalibQuery.testFile
testFile
Definition: CscCalibQuery.py:274
SampleXsection::getShoweringIndex
int getShoweringIndex(const int dsid) const
Definition: SampleXsection.cxx:150
top::AnalysisTrackingHelper::setTopConfig
void setTopConfig(std::shared_ptr< TopConfig > const &topConfig)
Notify helper about configuration options.
Definition: AnalysisTrackingHelper.cxx:76
top::AnalysisTrackingHelper::writeTree
void writeTree(std::string const &treename)
Store tracking data in current TFile.
Definition: AnalysisTrackingHelper.cxx:81
top::ScaleFactorCalculator
Definition: ScaleFactorCalculator.h:44
top::loadEventSaver
top::EventSaverBase * loadEventSaver(const std::shared_ptr< top::TopConfig > &config)
Users may also want to write out custom ntuples / xAODs.
Definition: Tools.cxx:314
python.AutoConfigFlags.msg
msg
Definition: AutoConfigFlags.py:7
top::PDFScaleFactorCalculator
For testing PDF reweighting with LHAPDF6.
Definition: PDFScaleFactorCalculator.h:37
top::CalcTbbarPartonHistory
Definition: CalcTbbarPartonHistory.h:33
xAOD::TEvent
Tool for accessing xAOD files outside of Athena.
Definition: Control/xAODRootAccess/xAODRootAccess/TEvent.h:81
top::EventCleaningSelection
Definition: EventCleaningSelection.h:32
beamspotman.fullpath
string fullpath
Definition: beamspotman.py:1039
top::Event::m_saveEvent
bool m_saveEvent
save the event?
Definition: Event.h:87