diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkMCTruth/CMakeLists.txt b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkMCTruth/CMakeLists.txt index 0d50f59a1331e80b609709aec7fbe756ab508327..4d703be048a6917beb4a40bca3b01b13c439279d 100644 --- a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkMCTruth/CMakeLists.txt +++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkMCTruth/CMakeLists.txt @@ -13,7 +13,7 @@ find_package( Boost ) atlas_add_component( DerivationFrameworkMCTruth src/*.cxx src/components/*.cxx INCLUDE_DIRS ${Boost_INCLUDE_DIRS} ${FASTJET_INCLUDE_DIRS} ${HEPPDT_INCLUDE_DIRS} ${ROOT_INCLUDE_DIRS} - LINK_LIBRARIES ${Boost_LIBRARIES} ${FASTJET_LIBRARIES} ${HEPPDT_LIBRARIES} ${ROOT_LIBRARIES} AthenaBaseComps AthenaKernel AtlasHepMCLib DerivationFrameworkInterfaces ExpressionEvaluationLib GaudiKernel GeneratorObjects MCTruthClassifierLib StoreGateLib TauAnalysisToolsLib TruthUtils xAODBase xAODEgamma xAODEventInfo xAODJet xAODMuon xAODTruth ) + LINK_LIBRARIES ${Boost_LIBRARIES} ${FASTJET_LIBRARIES} ${HEPPDT_LIBRARIES} ${ROOT_LIBRARIES} AthenaBaseComps AthenaKernel AtlasHepMCLib DerivationFrameworkInterfaces ExpressionEvaluationLib GaudiKernel GenInterfacesLib GeneratorObjects MCTruthClassifierLib StoreGateLib TauAnalysisToolsLib TruthUtils xAODBase xAODEgamma xAODEventInfo xAODEventShape xAODJet xAODMuon xAODTruth ) # Install files from the package: atlas_install_python_modules( python/*.py ) diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkMCTruth/python/GenFilterToolSetup.py b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkMCTruth/python/GenFilterToolSetup.py index 530c5165733bbe97ce44a62df685ddc83512f021..6e46b304e038338e7bb18b6b92cc6bdb1d34fdca 100644 --- a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkMCTruth/python/GenFilterToolSetup.py +++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkMCTruth/python/GenFilterToolSetup.py @@ -11,8 +11,8 @@ if not hasattr(ToolSvc,'DFCommonTruthClassifier'): ToolSvc += DFCommonTruthClassifier #Save the post-shower HT and MET filter values that will make combining filtered samples easier (adds to the EventInfo) -#from AthenaCommon import CfgMgr -#DFCommonTruthGenFilter = CfgMgr.DerivationFramework__GenFilterTool( -# "DFCommonTruthGenFilt", -# ) -#ToolSvc += DFCommonTruthGenFilter +from AthenaCommon import CfgMgr +DFCommonTruthGenFilter = CfgMgr.DerivationFramework__GenFilterTool( + "DFCommonTruthGenFilt", + ) +ToolSvc += DFCommonTruthGenFilter diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkMCTruth/src/GenFilterTool.cxx b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkMCTruth/src/GenFilterTool.cxx new file mode 100644 index 0000000000000000000000000000000000000000..5c2b9c64d6b4f80bfb1fbfb91f5e3ab4bee1c007 --- /dev/null +++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkMCTruth/src/GenFilterTool.cxx @@ -0,0 +1,230 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +*/ + +// Class header file +#include "GenFilterTool.h" + +// EDM includes +#include "xAODEventInfo/EventInfo.h" +#include "xAODJet/JetContainer.h" + +// Tool handle interface +#include "MCTruthClassifier/IMCTruthClassifier.h" + +namespace DerivationFramework { + + using namespace MCTruthPartClassifier; + + static bool isNonInteracting(int pid) { + const int apid = abs(pid); + if (apid == 12 || apid == 14 || apid == 16) return true; //< neutrinos + if (apid == 1000022 || apid == 1000024 || apid == 5100022) return true; // SUSY & KK photon and Z partners + if (apid == 39 || apid == 1000039 || apid == 5000039) return true; //< gravitons: standard, SUSY and KK + if (apid == 9000001 || apid == 9000002 || apid == 9000003 || apid == 9000004 || apid == 9000005 || apid == 9000006) return true; //< exotic particles from monotop model + return false; + } + + static SG::AuxElement::Decorator<float> dec_genFiltHT("GenFiltHT"); + static SG::AuxElement::Decorator<float> dec_genFiltMET("GenFiltMET"); + static SG::AuxElement::Decorator<float> dec_genFiltPTZ("GenFiltPTZ"); + static SG::AuxElement::Decorator<float> dec_genFiltFatJ("GenFiltFatJ"); + + GenFilterTool::GenFilterTool(const std::string& t, const std::string& n, const IInterface* p) + : AthAlgTool(t,n,p) + , m_classif("MCTruthClassifier/DFCommonTruthClassifier") + { + + declareInterface<DerivationFramework::IAugmentationTool>(this); + + declareProperty("EventInfoName",m_eventInfoName="EventInfo"); + declareProperty("MCCollectionName",m_mcName="TruthParticles"); + declareProperty("TruthJetCollectionName",m_truthJetsName="AntiKt4TruthWZJets"); + declareProperty("MinJetPt",m_MinJetPt = 35e3); + declareProperty("MaxJetEta",m_MaxJetEta = 2.5); + declareProperty("MinLeptonPt",m_MinLepPt = 25e3); + declareProperty("MaxLeptonEta",m_MaxLepEta = 2.5); + declareProperty("SimBarcodeOffset", m_SimBarcodeOffset = 200000); + } + + + GenFilterTool::~GenFilterTool(){} + + + bool GenFilterTool::isPrompt( const xAOD::TruthParticle* tp ) const + { + ParticleOrigin orig = getPartOrigin(tp); + ATH_MSG_VERBOSE("Particle has origin " << orig); + + switch(orig) { + case Unknown: + case PhotonConv: + case DalitzDec: + case ElMagProc: + case Mu: + case LightMeson: + case StrangeMeson: + case CharmedMeson: + case BottomMeson: + case CCbarMeson: + case JPsi: + case BBbarMeson: + case LightBaryon: + case StrangeBaryon: + case CharmedBaryon: + case BottomBaryon: + case PionDecay: + case KaonDecay: + return false; + default: + break; + } + return true; + } + + MCTruthPartClassifier::ParticleOrigin GenFilterTool::getPartOrigin( const xAOD::TruthParticle* tp ) const + { + if(m_originMap.find(tp)==m_originMap.end()) { + std::pair<ParticleType, ParticleOrigin> classification = m_classif->particleTruthClassifier( tp ); + m_originMap[tp] = classification.second; + } + return m_originMap[tp]; + } + + + StatusCode GenFilterTool::addBranches() const{ + ATH_MSG_VERBOSE("GenFilterTool::addBranches()"); + + const xAOD::EventInfo* eventInfo; + if (evtStore()->retrieve(eventInfo,m_eventInfoName).isFailure()) { + ATH_MSG_ERROR("could not retrieve event info " <<m_eventInfoName); + return StatusCode::FAILURE; + } + + const xAOD::TruthParticleContainer* truthPC = 0; + if (evtStore()->retrieve(truthPC,m_mcName).isFailure()) { + ATH_MSG_ERROR("WARNING could not retrieve TruthParticleContainer " <<m_mcName); + return StatusCode::FAILURE; + } + + m_originMap.clear(); + + float genFiltHT(0.), genFiltMET(0.), genFiltPTZ(0.), genFiltFatJ(0.); + ATH_CHECK( getGenFiltVars(truthPC, genFiltHT, genFiltMET, genFiltPTZ, genFiltFatJ) ); + + ATH_MSG_DEBUG("Computed generator filter quantities: HT " << genFiltHT/1e3 << ", MET " << genFiltMET/1e3 << ", PTZ " << genFiltPTZ/1e3 << ", FatJ " << genFiltFatJ/1e3 ); + + dec_genFiltHT(*eventInfo) = genFiltHT; + dec_genFiltMET(*eventInfo) = genFiltMET; + dec_genFiltPTZ(*eventInfo) = genFiltPTZ; + dec_genFiltFatJ(*eventInfo) = genFiltFatJ; + + return StatusCode::SUCCESS; + } + + StatusCode GenFilterTool::getGenFiltVars(const xAOD::TruthParticleContainer* tpc, float& genFiltHT, float& genFiltMET, float& genFiltPTZ, float& genFiltFatJ) const { + // Get jet container out + const xAOD::JetContainer* truthjets = 0; + if ( evtStore()->retrieve( truthjets, m_truthJetsName).isFailure() || !truthjets ){ + ATH_MSG_ERROR( "No xAOD::JetContainer found in StoreGate with key " << m_truthJetsName ); + return StatusCode::FAILURE; + } + + // Get HT + genFiltHT = 0.; + for (const auto& tj : *truthjets) { + if ( tj->pt()>m_MinJetPt && fabs(tj->eta())<m_MaxJetEta ) { + ATH_MSG_VERBOSE("Adding truth jet with pt " << tj->pt() + << ", eta " << tj->eta() + << ", phi " << tj->phi() + << ", nconst = " << tj->numConstituents()); + genFiltHT += tj->pt(); + } + } + + // Get MET and add leptons to HT + float MEx(0.), MEy(0.); + for (const auto& tp : *tpc){ + int pdgid = tp->pdgId(); + if (tp->barcode() >= m_SimBarcodeOffset) continue; // Particle is from G4 + if (pdgid==21 && tp->e()==0) continue; // Work around for an old generator bug + if ( tp->status() %1000 !=1 ) continue; // Stable! + + if ((abs(pdgid)==11 || abs(pdgid)==13) && tp->pt()>m_MinLepPt && fabs(tp->eta())<m_MaxLepEta) { + if( isPrompt(tp) ) { + ATH_MSG_VERBOSE("Adding prompt lepton with pt " << tp->pt() + << ", eta " << tp->eta() + << ", phi " << tp->phi() + << ", status " << tp->status() + << ", pdgId " << pdgid); + genFiltHT += tp->pt(); + } + } + + if (isNonInteracting(pdgid) && isPrompt(tp) ) { + ATH_MSG_VERBOSE("Found prompt nonInteracting particle with pt " << tp->pt() + << ", eta " << tp->eta() + << ", phi " << tp->phi() + << ", status " << tp->status() + << ", pdgId " << pdgid); + MEx += tp->px(); + MEy += tp->py(); + } + } + genFiltMET = sqrt(MEx*MEx+MEy*MEy); + + // Get PTZ + float PtZ(.0); + float MinPt_PTZ(5000.), MaxEta_PTZ(5.0), MinMass_PTZ(20000.), MaxMass_PTZ(14000000.); + bool AllowElecMu_PTZ = false; + bool AllowSameCharge_PTZ = false; + for (const xAOD::TruthParticle* pitr1 : *tpc){ + int pdgId1 = pitr1->pdgId(); + if (pitr1->barcode() >= m_SimBarcodeOffset) continue; + if (pitr1->status()!=1) continue; + // Pick electrons or muons with Pt > MinPt_PTZ and |eta| < m_maxEta + if (abs(pdgId1) == 11 || abs(pdgId1) == 13) { + if (pitr1->pt() >= MinPt_PTZ && fabs(pitr1->eta()) <= MaxEta_PTZ){ + for (const xAOD::TruthParticle* pitr2 : *tpc){ + if (pitr2==pitr1) continue; + if (pitr2->barcode() >= m_SimBarcodeOffset) continue; + if (pitr2->status()!=1) continue; + int pdgId2 = pitr2->pdgId(); + // Pick electrons or muons with Pt > MinPt_PTZ and |eta| < MaxEta_PTZ + // If AllowSameCharge_PTZ is not true only pick those with opposite charge to the first particle + // If AllowElecMu_PTZ is true allow also Z -> emu compinations (with charge requirements as above) + if ((AllowSameCharge_PTZ && (abs(pdgId2) == abs(pdgId1) || (AllowElecMu_PTZ && (abs(pdgId2) == 11 || abs(pdgId2) == 13) ) ) ) || + (!AllowSameCharge_PTZ && (pdgId2 == -1*pdgId1 || (AllowElecMu_PTZ && (pdgId2 == (pdgId1 < 0 ? 1 : -1) * 11 || (pdgId1 < 0 ? 1 : -1) * pdgId2 == 13) ) ) ) ) { + if (pitr2->pt() >= MinPt_PTZ && fabs(pitr2->eta()) <= MaxEta_PTZ){ + double invMass = (pitr1->p4()+pitr2->p4()).M(); + double dilepPt = (pitr1->p4()+pitr2->p4()).Pt(); + // Only consider pair that fall in the mass window + if (MinMass_PTZ < invMass && invMass < MaxMass_PTZ) { + if (dilepPt > PtZ) PtZ = dilepPt; + } + } + } + } + } + } + } + genFiltPTZ = PtZ; + + //Get FatJ + // Get correct jet container + const xAOD::JetContainer* truthjets10 = 0; + if ( evtStore()->retrieve( truthjets10, "AntiKt10TruthJets").isFailure() || !truthjets10 ){ + ATH_MSG_ERROR( "No xAOD::JetContainer found in StoreGate with key AntiKt10TruthJets" ); + return StatusCode::FAILURE; + } + genFiltFatJ=0.; + for (const auto& j : *truthjets10) { + if (j->pt()>genFiltFatJ) genFiltFatJ=j->pt(); + } + + + return StatusCode::SUCCESS; + } + + +} /// namespace \ No newline at end of file diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkMCTruth/src/GenFilterTool.h b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkMCTruth/src/GenFilterTool.h new file mode 100644 index 0000000000000000000000000000000000000000..68cf1c780247bd192d5868f69e701185bdbd4e8b --- /dev/null +++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkMCTruth/src/GenFilterTool.h @@ -0,0 +1,65 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +*/ + +/* + * @file GenFilterTool.h + * @author TJ Khoo + * @date July 2015 + * @brief tool to decorate EventInfo with quantities needed to disentangle generator filtered samples +*/ + +#ifndef DerivationFrameworkMCTruth_GenFilterTool_H +#define DerivationFrameworkMCTruth_GenFilterTool_H + +// Base classes +#include "AthenaBaseComps/AthAlgTool.h" +#include "DerivationFrameworkInterfaces/IAugmentationTool.h" + +// Tool handle for the MC truth classifier +#include "GaudiKernel/ToolHandle.h" + +// EDM include -- typedef, so has to be included +#include "xAODTruth/TruthParticleContainer.h" + +// Defs for the particle origin +#include "MCTruthClassifier/MCTruthClassifierDefs.h" + +// STL includes +#include <string> + +class IMCTruthClassifier; + +namespace DerivationFramework { + + class GenFilterTool : public AthAlgTool, public IAugmentationTool { + + public: + GenFilterTool(const std::string& t, const std::string& n, const IInterface* p); + ~GenFilterTool(); + virtual StatusCode addBranches() const; + + StatusCode getGenFiltVars(const xAOD::TruthParticleContainer* tpc, float& genFiltHT, float& genFiltMET, float& genFiltPTZ, float& genFiltFatJ) const; + + bool isPrompt( const xAOD::TruthParticle* tp ) const; + MCTruthPartClassifier::ParticleOrigin getPartOrigin(const xAOD::TruthParticle* tp) const; + + private: + + std::string m_eventInfoName; + std::string m_mcName; + std::string m_truthJetsName; + + float m_MinJetPt; //!< Min pT for the truth jets + float m_MaxJetEta; //!< Max eta for the truth jets + float m_MinLepPt; //!< Min pT for the truth leptons + float m_MaxLepEta; //!< Max eta for the truth leptons + int m_SimBarcodeOffset; //!< G4 particle barcode offset value (Particles having a barcode greater than this value are defined to be G4 particles) + + mutable std::map<const xAOD::TruthParticle*,MCTruthPartClassifier::ParticleOrigin> m_originMap; + ToolHandle<IMCTruthClassifier> m_classif; + }; /// class + +} /// namespace + +#endif \ No newline at end of file diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkMCTruth/src/TruthEDDecorator.cxx b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkMCTruth/src/TruthEDDecorator.cxx new file mode 100644 index 0000000000000000000000000000000000000000..f6859a93176cea04a586ba52b8a7fce301231d41 --- /dev/null +++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkMCTruth/src/TruthEDDecorator.cxx @@ -0,0 +1,59 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +*/ + +// Class header file +#include "TruthEDDecorator.h" + +// EDM includes +#include "xAODEventInfo/EventInfo.h" +#include "xAODEventShape/EventShape.h" + +namespace DerivationFramework { + + static const SG::AuxElement::Accessor<float> acc_Density("Density"); + + TruthEDDecorator::TruthEDDecorator(const std::string& t, const std::string& n, const IInterface* p) + : AthAlgTool(t,n,p) + { + declareInterface<DerivationFramework::IAugmentationTool>(this); + + declareProperty("EventInfoName",m_eventInfoName="EventInfo"); + declareProperty("EnergyDensityKeys",m_edKeys={"TruthIsoCentralEventShape","TruthIsoForwardEventShape"}); + declareProperty("DecorationSuffix",m_ed_suffix="_rho"); + } + + + TruthEDDecorator::~TruthEDDecorator(){} + + + StatusCode TruthEDDecorator::initialize(){ + for (size_t i=0;i<m_edKeys.size();++i){ + m_dec_eventShape.push_back( SG::AuxElement::Decorator<float>(m_edKeys[i]+m_ed_suffix) ); + } + return StatusCode::SUCCESS; + } + + + StatusCode TruthEDDecorator::addBranches() const{ + ATH_MSG_VERBOSE("addBranches()"); + + // Get the event info that we will decorate onto + const xAOD::EventInfo* eventInfo(nullptr); + if (evtStore()->retrieve(eventInfo,m_eventInfoName).isFailure()) { + ATH_MSG_ERROR("could not retrieve event info " <<m_eventInfoName); + return StatusCode::FAILURE; + } + + const xAOD::EventShape* eventShape(nullptr); + for (size_t i=0;i<m_edKeys.size();++i){ + // Get the event shapes from which we'll get the densities + ATH_CHECK( evtStore()->retrieve(eventShape,m_edKeys[i]) ); + // Decorate the densities onto the event info + m_dec_eventShape[i](*eventInfo) = acc_Density(*eventShape); + } + + return StatusCode::SUCCESS; + } + +} /// namespace \ No newline at end of file diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkMCTruth/src/TruthEDDecorator.h b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkMCTruth/src/TruthEDDecorator.h new file mode 100644 index 0000000000000000000000000000000000000000..f1c991fa32f1c50f0952257ec668405291827090 --- /dev/null +++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkMCTruth/src/TruthEDDecorator.h @@ -0,0 +1,45 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +*/ + +/* + * @file TruthEDDecorator.h + * @author Zach Marshall + * @date Nov 2019 + * @brief tool to decorate EventInfo with truth-level energy density +*/ + +#ifndef DerivationFrameworkMCTruth_TruthEDDecorator_H +#define DerivationFrameworkMCTruth_TruthEDDecorator_H + +// Base classes +#include "AthenaBaseComps/AthAlgTool.h" +#include "DerivationFrameworkInterfaces/IAugmentationTool.h" + +// Members +#include "AthContainers/AuxElement.h" + +// STL includes +#include <string> +#include <vector> + +namespace DerivationFramework { + + class TruthEDDecorator : public AthAlgTool, public IAugmentationTool { + + public: + TruthEDDecorator(const std::string& t, const std::string& n, const IInterface* p); + ~TruthEDDecorator(); + virtual StatusCode addBranches() const override final; + StatusCode initialize() override final; + + private: + std::string m_eventInfoName; + std::vector<std::string> m_edKeys; + std::string m_ed_suffix; + std::vector<SG::AuxElement::Decorator<float> > m_dec_eventShape; + }; /// class + +} /// namespace + +#endif \ No newline at end of file diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkMCTruth/src/TruthMetaDataWriter.cxx b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkMCTruth/src/TruthMetaDataWriter.cxx new file mode 100644 index 0000000000000000000000000000000000000000..1ace75c810dcf70698d6cd0d7247c5e32ebcf69e --- /dev/null +++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkMCTruth/src/TruthMetaDataWriter.cxx @@ -0,0 +1,136 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +*/ + +///////////////////////////////////////////////////////////////// +// TruthMetaDataWriter.cxx +// Author: James Catmore (James.Catmore@cern.ch) + +// Header for this class +#include "TruthMetaDataWriter.h" + +// EDM Objects that we need +#include "xAODTruth/TruthMetaData.h" +#include "xAODTruth/TruthMetaDataAuxContainer.h" +#include "xAODEventInfo/EventInfo.h" + +// For accessing the tagInfo +#include "AthenaPoolUtilities/CondAttrListCollection.h" + +// Service for the weights +#include "GenInterfaces/IHepMCWeightSvc.h" + +// Constructor +DerivationFramework::TruthMetaDataWriter::TruthMetaDataWriter(const std::string& t, + const std::string& n, + const IInterface* p) + : AthAlgTool(t,n,p) + , m_metaStore( "MetaDataStore", n ) + , m_weightSvc( "HepMCWeightSvc/HepMCWeightSvc" , n ) +{ + declareInterface<DerivationFramework::IAugmentationTool>(this); + declareProperty( "MetaObjectName", m_metaName = "TruthMetaData" ); + declareProperty( "MetaDataStore", m_metaStore ); +} + +// Destructor +DerivationFramework::TruthMetaDataWriter::~TruthMetaDataWriter() { +} + +// Athena initialize and finalize +StatusCode DerivationFramework::TruthMetaDataWriter::initialize() +{ + ATH_MSG_VERBOSE("initialize() ..."); + // Initialize the service handles + CHECK( m_metaStore.retrieve() ); + CHECK( m_weightSvc.retrieve() ); + + // Create an empty truth meta data container: + xAOD::TruthMetaDataAuxContainer* aux = new xAOD::TruthMetaDataAuxContainer(); + m_tmd = new xAOD::TruthMetaDataContainer(); + m_tmd->setStore( aux ); + // Record it in the metadata store + CHECK( m_metaStore->record( aux, m_metaName + "Aux." ) ); + CHECK( m_metaStore->record( m_tmd, m_metaName ) ); + + return StatusCode::SUCCESS; +} + +StatusCode DerivationFramework::TruthMetaDataWriter::finalize() +{ + ATH_MSG_VERBOSE("finalize() ..."); + return StatusCode::SUCCESS; +} + +// Selection and collection creation +StatusCode DerivationFramework::TruthMetaDataWriter::addBranches() const +{ + + //The mcChannelNumber is used as a unique identifier for which truth meta data belongs to + uint32_t mcChannelNumber = 0; + // If this fails, we are running on a datatype with no EventInfo. Such data types should + // definitely not be mixing MC samples, so this should be safe (will fall back to 0 above) + if (evtStore()->contains<xAOD::EventInfo>("EventInfo")){ + const DataHandle<xAOD::EventInfo> eventInfo = nullptr; + CHECK( evtStore()->retrieve(eventInfo, "EventInfo") ); + mcChannelNumber = eventInfo->mcChannelNumber(); + } + + //Inserting in a (unordered_)set returns an <iterator, boolean> pair, where the boolean + //is used to check if the key already exists (returns false in the case it exists) + if( m_existingMetaDataChan.insert(mcChannelNumber).second ) { + xAOD::TruthMetaData* md = new xAOD::TruthMetaData(); + m_tmd->push_back( md ); + + // Get the list of weights from the metadata + std::map<std::string,std::size_t> weight_name_map = m_weightSvc->weightNames(); + + std::vector<std::string> orderedWeightNameVec; + orderedWeightNameVec.reserve( weight_name_map.size() ); + for (auto& entry: weight_name_map) { + orderedWeightNameVec.push_back(entry.first); + } + + //The map from the HepMC record pairs the weight names with a corresponding index, + //it is not guaranteed that the indices are ascending when iterating over the map + std::sort(orderedWeightNameVec.begin(), orderedWeightNameVec.end(), + [&](std::string i, std::string j){return weight_name_map.at(i) < weight_name_map.at(j);}); + + md->setMcChannelNumber(mcChannelNumber); + md->setWeightNames( std::move(orderedWeightNameVec) ); + + // Shamelessly stolen from the file meta data tool + const CondAttrListCollection* tagInfo(nullptr); + ATH_CHECK( detStore()->retrieve( tagInfo, "/TagInfo" ) ); + + // Access the first, and only channel of the object: + const CondAttrListCollection::AttributeList& al = tagInfo->attributeList( 0 ); + + if (al.exists("lhefGenerator")){ + md->setLhefGenerator( al["lhefGenerator"].data< std::string >() ); + } + + if (al.exists("generators")){ + md->setGenerators( al["generators"].data< std::string >() ); + } + + if (al.exists("evgenProcess")){ + md->setEvgenProcess( al["evgenProcess"].data< std::string >() ); + } + + if (al.exists("evgenTune")){ + md->setEvgenTune( al["evgenTune"].data< std::string >() ); + } + + if (al.exists("hardPDF")){ + md->setHardPDF( al["hardPDF"].data< std::string >() ); + } + + if (al.exists("softPDF")){ + md->setSoftPDF( al["softPDF"].data< std::string >() ); + } + // Done getting things from the TagInfo + + } // Done making the new truth metadata object + return StatusCode::SUCCESS; +} diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkMCTruth/src/TruthMetaDataWriter.h b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkMCTruth/src/TruthMetaDataWriter.h new file mode 100644 index 0000000000000000000000000000000000000000..56f254c80212e3d574d76e0ccc411b995c60bcae --- /dev/null +++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkMCTruth/src/TruthMetaDataWriter.h @@ -0,0 +1,50 @@ +/* + Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef DERIVATIONFRAMEWORK_TRUTHMETADATAWRITER_H +#define DERIVATIONFRAMEWORK_TRUTHMETADATAWRITER_H + +// Base classes +#include "AthenaBaseComps/AthAlgTool.h" +#include "DerivationFrameworkInterfaces/IAugmentationTool.h" + +// Handles to services +#include "GaudiKernel/ServiceHandle.h" + +// EDM classes - typedefs, so have to #include them +#include "xAODTruth/TruthMetaDataContainer.h" + +// Standard library includes +#include <string> +#include <unordered_set> + +// Forward declarations +class IHepMCWeightSvc; + +namespace DerivationFramework { + + class TruthMetaDataWriter : public AthAlgTool, public IAugmentationTool { + public: + TruthMetaDataWriter(const std::string& t, const std::string& n, const IInterface* p); + ~TruthMetaDataWriter(); + StatusCode initialize(); + StatusCode finalize(); + virtual StatusCode addBranches() const; + + private: + /// Connection to the metadata store + ServiceHandle< StoreGateSvc > m_metaStore; + /// Service for retrieving the weight names + ServiceHandle< IHepMCWeightSvc > m_weightSvc; + /// The meta data container to be written out + xAOD::TruthMetaDataContainer* m_tmd; + /// SG key and name for meta data + std::string m_metaName; + /// Set for tracking the mc channels for which we already added meta data + mutable std::unordered_set<uint32_t> m_existingMetaDataChan; + + }; +} + +#endif \ No newline at end of file diff --git a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkMCTruth/src/components/DerivationFrameworkMCTruth_entries.cxx b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkMCTruth/src/components/DerivationFrameworkMCTruth_entries.cxx index 685652d2c4b96f8dfd27c961a9b86c5fcc13bc3f..71be27ae597c5e16ad83a021f1c82f7a75852f60 100644 --- a/PhysicsAnalysis/DerivationFramework/DerivationFrameworkMCTruth/src/components/DerivationFrameworkMCTruth_entries.cxx +++ b/PhysicsAnalysis/DerivationFramework/DerivationFrameworkMCTruth/src/components/DerivationFrameworkMCTruth_entries.cxx @@ -17,6 +17,9 @@ #include "src/HardScatterCollectionMaker.h" #include "src/TruthLinkRepointTool.h" #include "DerivationFrameworkMCTruth/TruthPVCollectionMaker.h" +#include "src/GenFilterTool.h" +#include "src/TruthEDDecorator.h" +#include "src/TruthMetaDataWriter.h" using namespace DerivationFramework; @@ -39,3 +42,6 @@ DECLARE_COMPONENT( TruthBornLeptonCollectionMaker ) DECLARE_COMPONENT( HardScatterCollectionMaker ) DECLARE_COMPONENT( TruthLinkRepointTool ) DECLARE_COMPONENT( TruthPVCollectionMaker ) +DECLARE_COMPONENT( GenFilterTool ) +DECLARE_COMPONENT( TruthEDDecorator ) +DECLARE_COMPONENT( TruthMetaDataWriter )