diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/Root/Tools.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/Root/Tools.cxx index 3574e189429fc769e2cf43efee6407d913880229..5fb00c304378facc651e5a2382ec410c6fc04c96 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/Root/Tools.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/Root/Tools.cxx @@ -162,33 +162,34 @@ namespace top { throw std::runtime_error("Cannot determine the derivation stream. Please report."); } - void parseCutBookkeepers(const xAOD::CutBookkeeperContainer *cutBookKeepers, + void parseCutBookkeepers(xAOD::TEvent& xaodEvent, const std::size_t size, std::vector<std::string> &names, std::vector<float>& sumW, const bool isHLLHC) { - std::vector<int> maxCycle; - for (const xAOD::CutBookkeeper *cbk : *cutBookKeepers) { - // skip RDO and ESD numbers, which are nonsense; and - // skip the derivation number, which is the one after skimming - // we want the primary xAOD numbers - if ((cbk->inputStream() != "StreamAOD") && !(isHLLHC && cbk->inputStream() == "StreamDAOD_TRUTH1")) - continue; - // only accept "AllExecutedEvents" bookkeeper (0th MC weight) - // or "AllExecutedEvents_NonNominalMCWeight_XYZ" where XYZ is the MC weight index - if (!((cbk->name() == "AllExecutedEvents") - || (cbk->name().find("AllExecutedEvents_NonNominalMCWeight_") != std::string::npos))) - continue; - const std::string name = cbk->name(); - auto pos_name = std::find(names.begin(), names.end(), name); - // is it a previously unencountered bookkeeper? If yes append its name to the vector of names - // if not no need, but we must check the corresponding entry for the sum of weights exist - if (pos_name == names.end()) { - names.push_back(name); - maxCycle.push_back(cbk->cycle()); - sumW.push_back(cbk->sumOfEventWeights()); - } else if (cbk->cycle() > maxCycle.at(pos_name - names.begin())) { - maxCycle.at(pos_name - names.begin()) = cbk->cycle(); - sumW.at(pos_name - names.begin()) = cbk->sumOfEventWeights(); - } else { - continue; + + for (std::size_t icbk = 0; icbk < size; ++icbk) { + const std::string cbkName = (icbk == 0) ? "CutBookkeepers" : "CutBookkeepers_weight_" + std::to_string(icbk); + const xAOD::CutBookkeeperContainer* cutBookKeepers = nullptr; + top::check(xaodEvent.retrieveMetaInput(cutBookKeepers, cbkName), "Cannot retrieve CutBookkeepers: " + cbkName); + + std::vector<int> maxCycle; + for (const xAOD::CutBookkeeper *cbk : *cutBookKeepers) { + // skip RDO and ESD numbers, which are nonsense; and + // skip the derivation number, which is the one after skimming + // we want the primary xAOD numbers + if ((cbk->inputStream() != "StreamAOD") && !(isHLLHC && cbk->inputStream() == "StreamDAOD_TRUTH1")) + continue; + if (cbk->name() != "AllExecutedEvents") continue; + const std::string name = cbk->name() + "_weight_" + std::to_string(icbk); + auto pos_name = std::find(names.begin(), names.end(), name); + // is it a previously unencountered bookkeeper? If yes append its name to the vector of names + // if not no need, but we must check the corresponding entry for the sum of weights exist + if (pos_name == names.end()) { + names.push_back(name); + maxCycle.push_back(cbk->cycle()); + sumW.push_back(cbk->sumOfEventWeights()); + } else if (cbk->cycle() > maxCycle.at(pos_name - names.begin())) { + maxCycle.at(pos_name - names.begin()) = cbk->cycle(); + sumW.at(pos_name - names.begin()) = cbk->sumOfEventWeights(); + } } } } @@ -215,7 +216,7 @@ namespace top { const std::vector<std::string>& pmg_weight_names) { // prefix in the bookkeeper names to remove - static const std::string name_prefix = "AllExecutedEvents_NonNominalMCWeight_"; + static const std::string name_prefix = "AllExecutedEvents_weight_"; // check if we have more than one MC generator weight, in that case we have to do the renaming if (pmg_weight_names.size() > 1) { @@ -228,13 +229,9 @@ namespace top { // rename the bookkeepers based on the weight names from PMGTool // this names are then also written into the sumWeights TTree in output files for (std::string &name : bookkeeper_names) { - if (name == "AllExecutedEvents") { - name = pmg_weight_names.at(0); - } else { - // erase "AllExecutedEvents_NonNominalMCWeight_" prefix - int index = std::stoi(name.erase(0, name_prefix.size())); - name = pmg_weight_names.at(index); - } + // erase "AllExecutedEvents_weight_" prefix + int index = std::stoi(name.erase(0, name_prefix.size())); + name = pmg_weight_names.at(index); } } else { // expect only one MC weight in this sample, hence only one AllExecutedEvents* bookeeeper diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/TopAnalysis/Tools.h b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/TopAnalysis/Tools.h index 613d72b399c6d216c1c36a0ed3cac953e7f1c7e9..6c8977bffe13687878e26c374cb10a29d1a085ad 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/TopAnalysis/Tools.h +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/TopAnalysis/Tools.h @@ -101,12 +101,13 @@ namespace top { * @brief Search bookkeepers for ones matching AllExecutedEvents, and which * originate from AOD before skimming. * - * @param cutBookKeepers Container with bookkeepers + * @param TEvent to retrieve the cutbookkeepers + * @param number of the generator weights * @param names Vector of names of the selected bookkeepers * @param sumW Vector of sum of weights of the selected bookkeepers * @param isHLLHC Whether this is a HLLHC ugprade sample, it uses different stream for bookkeepers */ - void parseCutBookkeepers(const xAOD::CutBookkeeperContainer *cutBookKeepers, + void parseCutBookkeepers(xAOD::TEvent& event, const std::size_t size, std::vector<std::string> &names, std::vector<float>& sumW, const bool isHLLHC=false); /** diff --git a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/util/top-xaod.cxx b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/util/top-xaod.cxx index 51b41c0a076cbfe9bebbe1125303a64e1168adf4..9781df7352ec8a83aec2e8bbb3213575a613fc3b 100644 --- a/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/util/top-xaod.cxx +++ b/PhysicsAnalysis/TopPhys/xAOD/TopAnalysis/util/top-xaod.cxx @@ -561,39 +561,30 @@ int main(int argc, char** argv) { std::vector<float> LHE3_sumW_file; std::vector<std::string> LHE3_names_file; - // See https://twiki.cern.ch/twiki/bin/view/AtlasProtected/AnalysisMetadata#Event_Bookkeepers - const xAOD::CutBookkeeperContainer* cutBookKeepers = 0; - // Try to get the cut bookkeepers. - // <tom.neep@cern.ch> (4/4/16): Not there in DAOD_TRUTH1? - // If we can't get them and we are running on TRUTH then carry on, - // but anything else is bad! + const xAOD::CutBookkeeperContainer* cutBookKeepers = nullptr; if(topConfig->isTruthDxAOD()) { ATH_MSG_INFO("Bookkeepers are not read for TRUTH derivations"); - } - else if (!xaodEvent.retrieveMetaInput(cutBookKeepers, "CutBookkeepers")) { - ATH_MSG_ERROR("Failed to retrieve cut book keepers"); - return 1; } else { + top::check(xaodEvent.retrieveMetaInput(cutBookKeepers, "CutBookkeepers"), "Cannot retrieve CutBookkeepers"); if (topConfig->isMC()) { - // try to retrieve CutBookKeepers for LHE3Weights first - top::parseCutBookkeepers(cutBookKeepers, LHE3_names_file, LHE3_sumW_file, topConfig->HLLHC()); // here we attempt to name the CutBookkeepers based on the MC weight names // but we might end up in a situation where we don't have PMGTruthWeightTool // e.g. if TruthMetaData container is broken in derivation // we continue without names of the MC weights, only indices will be available ToolHandle<PMGTools::IPMGTruthWeightTool> m_pmg_weightTool("PMGTruthWeightTool"); - if (m_pmg_weightTool.retrieve()) { - const std::vector<std::string> &weight_names = m_pmg_weightTool->getWeightNames(); - // if we have MC generator weights, we rename the bookkeepers in sumWeights TTree to match the weight names from MetaData - top::renameCutBookkeepers(LHE3_names_file, weight_names); - } else { - for (std::string &name : LHE3_names_file) { - name = "?"; - } + if (!m_pmg_weightTool.retrieve()) { + ATH_MSG_ERROR("Cannot retrieve PMGTruthWeightTool"); + return 1; } + const std::vector<std::string> &weight_names = m_pmg_weightTool->getWeightNames(); + // try to retrieve CutBookKeepers for LHE3Weights first + top::parseCutBookkeepers(xaodEvent, weight_names.size(), LHE3_names_file, LHE3_sumW_file, topConfig->HLLHC()); + // if we have MC generator weights, we rename the bookkeepers in sumWeights TTree to match the weight names from MetaData + top::renameCutBookkeepers(LHE3_names_file, weight_names); + // raw number of events taken from "AllExecutedEvents" bookkeeper, which corresponds to 0th MC weight // but these are raw entries, so doesn't matter if 0th MC weight is nominal or not initialEvents = top::getRawEventsBookkeeper(cutBookKeepers, topConfig->HLLHC());