10 #include "TTreeFormula.h"
75 using namespace TopAnalysis;
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"
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"
96 <<
" $ROOTCOREBIN/data/TopAnalysis/nocuts.txt $ROOTCOREBIN/data/TopAnalysis/input-13TeV-fondueworld.txt\n");
100 gErrorAbortLevel =
kError;
108 StatusCode::enableFailure();
116 ATH_MSG_INFO(
"LOCATED (using PathResolverFindFile ): Configuration file = "
117 << settingsFilename <<
"\n");
120 << settingsFilename <<
"\n"
125 settings->loadFromFile(settingsFilename);
129 settings->checkSettings();
131 const std::string libraryNames = settings->value(
"LibraryNames");
135 std::unique_ptr<top::AnalysisTrackingHelper> tracker;
137 bool useTracking =
true;
138 settings->retrieve(
"WriteTrackingData", useTracking);
147 unsigned int doPerfStats(0);
148 if (settings->value(
"PerfStats") ==
"Summary") doPerfStats = 1;
150 if (settings->value(
"PerfStats") ==
"Full") doPerfStats = 2;
153 std::string cutsFilename = std::string(settingsFilename);
160 std::unique_ptr<TFile>
outputFile(TFile::Open((settings->value(
"OutputFilename") +
".tmp").c_str(),
"RECREATE"));
173 std::unique_ptr<TFile> checkingYieldFile(TFile::Open(
filename.c_str()));
176 const TTree*
const collectionTree =
dynamic_cast<TTree*
> (checkingYieldFile->Get(
"CollectionTree"));
177 if (collectionTree) {
184 std::unique_ptr<TFile>
testFile(TFile::Open(usethisfile.c_str()));
186 ATH_MSG_ERROR(
"Unable to access FileMetaData in this file : " << usethisfile
187 <<
"\nPlease report this message.");
200 const std::string tdp_filename = settings->value(
"TDPPath");
204 ATH_MSG_ERROR(
"TopDataPreparation - could not read file\n" << tdp_filename);
242 std::unique_ptr<TFile> metadataInitFile(TFile::Open(
filenames[0].c_str()));
243 top::check(xaodEvent.
readFrom(metadataInitFile.get()),
"xAOD::TEvent readFrom failed");
247 top::check(topTools.setProperty(
"config", topConfig),
248 "Failed to setProperty of topTools");
252 ToolHandle<PMGTools::IPMGTruthWeightTool> m_pmg_weightTool(
"PMGTruthWeightTool");
253 if (topConfig->
isMC() && !m_pmg_weightTool.retrieve()) {
267 "top::EventCleaningSelection"));
268 top::check(eventCleaning->setProperty(
"config", topConfig),
269 "Failed to setProperty of triggerGRLSelection");
271 "Failed to initialize triggerGRLSelection");
276 std::unique_ptr<top::TopObjectSelection> objectSelection;
278 top::check(systObjMaker->setProperty(
"config", topConfig),
"Failed to setProperty of systObjMaker");
304 std::unique_ptr<top::CalcTopPartonHistory> topPartonHistory(
nullptr);
305 if (settings->value(
"TopPartonHistory") ==
"ttbar") {
308 top::check(topPartonHistory->setProperty(
"config",
309 topConfig),
"Failed to setProperty of top::CalcTtbarPartonHistory");
310 }
else if (settings->value(
"TopPartonHistory") ==
"ttbarlight") {
313 "top::CalcTtbarLightPartonHistory"));
314 top::check(topPartonHistory->setProperty(
"config",
315 topConfig),
"Failed to setProperty of top::CalcTtbarLightPartonHistory");
316 }
else if (settings->value(
"TopPartonHistory") ==
"tb") {
319 top::check(topPartonHistory->setProperty(
"config",
320 topConfig),
"Failed to setProperty of top::CalcTbbarPartonHistory");
321 }
else if (settings->value(
"TopPartonHistory") ==
"Wtb") {
324 top::check(topPartonHistory->setProperty(
"config", topConfig),
325 "Failed to setProperty of top::CalcWtbPartonHistory");
326 }
else if (settings->value(
"TopPartonHistory") ==
"ttz") {
329 top::check(topPartonHistory->setProperty(
"config", topConfig),
330 "Failed to setProperty of top::CalcTTZPartonHistory");
331 }
else if (settings->value(
"TopPartonHistory") ==
"ttgamma") {
334 "top::CalcTtbarGammaPartonHistory"));
335 top::check(topPartonHistory->setProperty(
"config",
336 topConfig),
"Failed to setProperty of top::CalcTtbarGammaPartonHistory");
337 }
else if (settings->value(
"TopPartonHistory") ==
"tHq") {
340 top::check(topPartonHistory->setProperty(
"config", topConfig),
341 "Failed to setProperty of top::CalcThqPartonHistory");
342 }
else if (settings->value(
"TopPartonHistory") ==
"tZq") {
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");
353 std::unique_ptr<top::PDFScaleFactorCalculator> PDF_SF(
nullptr);
357 top::check(PDF_SF->setProperty(
"config", topConfig),
"Failed to set config for PDF SF Calculator");
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");
370 "top::ScaleFactorCalculator"));
371 top::check(topScaleFactors->setProperty(
"config", topConfig),
"Failed to setProperty of top::ScaleFactorCalculator");
374 std::vector<std::unique_ptr<CP::AsymptMatrixTool> > topfakesMMWeightsIFF;
375 std::vector<std::vector<std::string> > FakesMMConfigIFF;
378 std::vector<std::string>
tokens;
382 const auto& token =
tokens.back();
383 std::vector<std::string> tokens2;
386 "Failed to read FakesMMConfigIFF: " + topConfig->
FakesMMConfigIFF() +
" has size " +
388 FakesMMConfigIFF.push_back(tokens2);
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",
406 "Failed to setProperty EnergyUnit of AsymptMatrixTool");
407 top::check(topfakesMMWeightsIFF.back()->setProperty(
"ConvertWhenMissing",
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");
414 top::check(topfakesMMWeightsIFF.back()->setProperty(
"OutputLevel", IFFoutputLevel),
415 "Failed to setProperty of AsymptMatrixTool");
416 top::check(topfakesMMWeightsIFF.back()->initialize(),
"Failed to initialize AsymptMatrixTool");
421 std::vector<std::string> extraBranches;
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;
436 std::vector<std::string> names_LHE3;
437 bool recalc_LHE3 =
false;
438 bool recalculateNominalWeightSum =
false;
440 int isAFII = topConfig->
isAFII();
442 ULong64_t totalEventsInFiles = 0;
443 std::unordered_map<std::string, std::vector<std::string>> boostedTaggersSFSysNames = topConfig->
boostedTaggersSFSysNames();
445 sumWeights->Branch(
"dsid", &
dsid);
446 sumWeights->Branch(
"isAFII", &isAFII);
447 sumWeights->Branch(
"totalEventsWeighted", &totalEventsWeighted);
449 sumWeights->Branch(
"totalEventsWeighted_mc_generator_weights", &totalEventsWeighted_LHE3);
450 sumWeights->Branch(
"names_mc_generator_weights", &names_LHE3);
452 sumWeights->Branch(
"totalEvents", &
totalEvents,
"totalEvents/l");
454 for(
auto&
it : boostedTaggersSFSysNames) {
455 sumWeights->Branch((
"sysNames_"+
it.first).c_str(),&
it.second);
458 TTree* sumPdfWeights = 0;
459 std::unordered_map<std::string, std::vector<float>*> totalEventsPdfWeighted;
460 int dsidPdf = topConfig->
getDSID();
461 bool pdfMetadataExists =
false;
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]);
477 unsigned int totalYieldSoFar = 0;
478 unsigned int skippedEventsSoFar = 0;
479 unsigned int eventSavedReco(0), eventSavedRecoLoose(0), eventSavedTruth(0), eventSavedParticle(0);
482 metadataInitFile->Close();
493 const TTree*
const collectionTree =
dynamic_cast<TTree*
> (
inputFile->Get(
"CollectionTree"));
494 if (!collectionTree && !topConfig->
isMC()) {
504 double sumW_file = 0;
505 ULong64_t initialEvents = 0;
508 std::vector<float> LHE3_sumW_file;
509 std::vector<std::string> LHE3_names_file;
514 ATH_MSG_INFO(
"Bookkeepers are not read for TRUTH derivations");
517 if (topConfig->
isMC()) {
520 const std::vector<std::string> &weight_names = m_pmg_weightTool->getWeightNames();
532 sumW_file = LHE3_sumW_file.at(nominalWeightIndex);
535 sumW_file = initialEvents;
539 totalEventsWeighted += sumW_file;
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.");
551 for (
unsigned int i_genweights = 0; i_genweights < LHE3_names_file.size();
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.");
557 totalEventsWeighted_LHE3.at(i_genweights)
558 = totalEventsWeighted_LHE3.at(i_genweights)
559 + LHE3_sumW_file.at(i_genweights);
563 for (
unsigned int i_genweights = 0; i_genweights < LHE3_names_file.size();
565 names_LHE3.push_back(LHE3_names_file.at(i_genweights));
566 totalEventsWeighted_LHE3.push_back(LHE3_sumW_file.at(i_genweights));
569 if (!names_LHE3.empty()) {
570 ATH_MSG_INFO(
"The sum of weights for the following LHE3 weights were retrieved from the input file:");
572 for (
const std::string&
s : names_LHE3)
574 msgInfo << std::endl;
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");
583 if (topConfig->
isTruthDxAOD()) recalculateNominalWeightSum=
true;
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");
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");
601 "\n*************************************************************************\n"
602 <<
" YOU ARE USING THIS CUSTOM PATH TO THE ELECTRON ID SF FILE: \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");
613 unsigned int firstEvent = 0;
616 skippedEventsSoFar +=
entries < firstEvent ?
entries : firstEvent;
623 if (
entry % 100 == 0)
624 ATH_MSG_INFO(
"Processing event " << totalYieldSoFar <<
" / " << totalYield
625 <<
" (current file: " <<
entry <<
" / " <<
entries <<
")");
633 float mcEventWeight(1.), pileupWeight(1.);
641 if (topConfig->
isMC()) {
648 "Failed to execute PDF SF");
656 if (topConfig->
isMC()) {
666 if (particleLevelLoader.
active()) {
672 const bool saveEventInOutputFile = eventSelectionManager.
applyParticleLevel(particleLevelEvent);
674 if (saveEventInOutputFile) {
676 ++eventSavedParticle;
680 if (totalYieldSoFar == 0 && topConfig->
isMC() && topConfig->
doLHAPDF()) {
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());
695 if (topConfig->
isMC()) {
698 "Failed to retrieve LHE3 weights from EventInfo");
703 if(recalculateNominalWeightSum)
705 if (totalYieldSoFar == 0)
ATH_MSG_INFO(
"Trying to recalculate nominal weights sum for TRUTH derivation");
707 totalEventsWeighted_temp += ei->
mcEventWeights().at(nominalWeightIndex);
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);
720 names_LHE3.resize(weightsSize);
722 const std::vector<std::string> &weight_names = m_pmg_weightTool->getWeightNames();
723 if(weight_names.size() != weightsSize)
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(),
"?");
729 for(
unsigned int i_wgt=0; i_wgt<weight_names.size(); i_wgt++) names_LHE3[i_wgt]=weight_names[i_wgt];
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) +
737 }
else if (weightsSize != names_LHE3.size()) {
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.");
756 eventSelectionManager.
countInitial(mcEventWeight, pileupWeight);
760 bool passGRLVeto = eventCleaning->
applyGRL();
761 if (!passGRLVeto)
continue;
762 eventSelectionManager.
countGRL(mcEventWeight, pileupWeight);
767 if (!passGoodCalo)
continue;
768 eventSelectionManager.
countGoodCalo(mcEventWeight, pileupWeight);
773 if (!passPriVtx)
continue;
783 bool passAnyTriggerVeto = eventCleaning->
applyTrigger();
784 if (!passAnyTriggerVeto)
continue;
801 top::check(objectSelection->
execute(
false),
"Failed to execute objectSelection");
814 for (
const auto *currentSystematic : *allSystematics) {
820 const bool passAnyEventSelection = eventSelectionManager.
apply(topEvent, *currentSystematic);
822 if (isFirst && topConfig->
isMC()) {
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");
840 if (passAnyEventSelection &&
841 currentSystematic->hashValue() == topConfig->
nominalHashValue()) ++eventSavedReco;
851 for (
const auto *currentSystematic : *allSystematicsLoose) {
857 const bool passAnyEventSelection = eventSelectionManager.
apply(topEvent, *currentSystematic);
860 if (isFirst && topConfig->
isMC()) {
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");
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()");
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()");
893 mmweight.push_back(asmWgt);
895 topEvent.
m_info->
auxdecor<std::vector<float> >(
"ASM_weight") = mmweight;
901 if (passAnyEventSelection &&
902 currentSystematic->hashValue() == topConfig->
nominalHashValue()) ++eventSavedRecoLoose;
917 bool pdfInCBK =
false;
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();
925 pdfMetadataExists =
true;
937 pdfMetadataExists =
false;
942 for (
auto& pdfentry : totalEventsPdfWeighted) {
943 std::string pdf_set = pdfentry.first;
944 for (
size_t n = 0;
n < totalEventsPdfWeighted[pdf_set]->size(); ++
n) {
946 bool foundPdf =
false;
947 for (
const auto *cbk : *cutBookKeepers) {
948 std::string
pdfName = cbk->name();
950 totalEventsPdfWeighted[pdf_set]->at(
n) = cbk->sumOfEventWeights();
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.");
968 sumPdfWeights->Fill();
983 for (
double d:totalEventsWeighted_LHE3_temp) totalEventsWeighted_LHE3.push_back(
d);
985 if(recalculateNominalWeightSum)
987 totalEventsWeighted=totalEventsWeighted_temp;
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!");
1003 if ((!topConfig->
baseLHAPDF().empty() || !pdfMetadataExists)) {
1005 *(totalEventsPdfWeighted[pdf_result.first]) = pdf_result.second;
1006 sumPdfWeights->Fill();
1014 if (tracker) tracker->
writeTree(
"AnalysisTracking");
1016 bool outputFileGood = !
outputFile->TestBit(TFile::kWriteError);
1017 if (outputFileGood) {
1018 if (gSystem->Rename(
outputFile->GetName(), settings->value(
"OutputFilename").c_str()) != 0) outputFileGood =
false;
1023 ATH_MSG_INFO(
"Events saved to output file nominal reconstruction tree: " << eventSavedReco);
1025 ATH_MSG_INFO(
"Events saved to output file nominal loose reconstruction tree: " << eventSavedRecoLoose);
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);
1033 ATH_MSG_INFO(
"Total sum-of-weights (for normalization) : " << totalEventsWeighted);
1039 if (!outputFileGood) {
1040 ATH_MSG_ERROR(
"ERROR: an I/O error occured while attempting to save the output file.");