Commit 94982bef authored by Marco Vanadia's avatar Marco Vanadia Committed by Nils Erik Krumnack
Browse files

add soft muons at particle level in AnalysisTop

parent 01142904
......@@ -1531,6 +1531,9 @@ namespace top {
m_particleLevelTreeManager->makeOutputVariable(m_el_phi, "el_phi");
m_particleLevelTreeManager->makeOutputVariable(m_el_e, "el_e");
m_particleLevelTreeManager->makeOutputVariable(m_el_charge, "el_charge");
m_particleLevelTreeManager->makeOutputVariable(m_el_true_type, "el_true_type");
m_particleLevelTreeManager->makeOutputVariable(m_el_true_origin, "el_true_origin");
m_particleLevelTreeManager->makeOutputVariable(m_el_pt_bare, "el_pt_bare");
m_particleLevelTreeManager->makeOutputVariable(m_el_eta_bare, "el_eta_bare");
......@@ -1545,12 +1548,36 @@ namespace top {
m_particleLevelTreeManager->makeOutputVariable(m_mu_phi, "mu_phi");
m_particleLevelTreeManager->makeOutputVariable(m_mu_e, "mu_e");
m_particleLevelTreeManager->makeOutputVariable(m_mu_charge, "mu_charge");
m_particleLevelTreeManager->makeOutputVariable(m_mu_true_type, "mu_true_type");
m_particleLevelTreeManager->makeOutputVariable(m_mu_true_origin, "mu_true_origin");
m_particleLevelTreeManager->makeOutputVariable(m_mu_pt_bare, "mu_pt_bare");
m_particleLevelTreeManager->makeOutputVariable(m_mu_eta_bare, "mu_eta_bare");
m_particleLevelTreeManager->makeOutputVariable(m_mu_phi_bare, "mu_phi_bare");
m_particleLevelTreeManager->makeOutputVariable(m_mu_e_bare, "mu_e_bare");
}
if(m_config->useSoftMuons())
{
m_particleLevelTreeManager->makeOutputVariable(m_softmu_pt, "softmu_pt");
m_particleLevelTreeManager->makeOutputVariable(m_softmu_eta, "softmu_eta");
m_particleLevelTreeManager->makeOutputVariable(m_softmu_phi, "softmu_phi");
m_particleLevelTreeManager->makeOutputVariable(m_softmu_e, "softmu_e");
m_particleLevelTreeManager->makeOutputVariable(m_softmu_charge, "softmu_charge");
m_particleLevelTreeManager->makeOutputVariable(m_softmu_true_type, "softmu_true_type");
m_particleLevelTreeManager->makeOutputVariable(m_softmu_true_origin, "softmu_true_origin");
if(m_config->softmuonAdditionalTruthInfo())
{
if(m_config->softmuonAdditionalTruthInfoCheckPartonOrigin()) m_particleLevelTreeManager->makeOutputVariable(m_softmu_parton_origin_flag, "softmu_parton_origin_flag");
m_particleLevelTreeManager->makeOutputVariable(m_softmu_particle_origin_flag, "softmu_particle_origin_flag");
m_particleLevelTreeManager->makeOutputVariable(m_softmu_parent_pdgid,"softmu_parent_pdgid");
m_particleLevelTreeManager->makeOutputVariable(m_softmu_b_hadron_parent_pdgid,"softmu_b_hadron_parent_pdgid");
m_particleLevelTreeManager->makeOutputVariable(m_softmu_c_hadron_parent_pdgid,"softmu_c_hadron_parent_pdgid");
}
}
}//end of muons branches
//photons
if (m_config->useTruthPhotons()) {
......@@ -4196,6 +4223,9 @@ namespace top {
m_el_eta_bare.resize(plEvent.m_electrons->size());
m_el_phi_bare.resize(plEvent.m_electrons->size());
m_el_e_bare.resize(plEvent.m_electrons->size());
m_el_true_type.resize(plEvent.m_electrons->size());
m_el_true_origin.resize(plEvent.m_electrons->size());
for (const auto& elPtr : *plEvent.m_electrons) {
m_el_pt[i] = elPtr->pt();
......@@ -4208,6 +4238,14 @@ namespace top {
m_el_eta_bare[i] = elPtr->auxdata<float>("eta_bare");
m_el_phi_bare[i] = elPtr->auxdata<float>("phi_bare");
m_el_e_bare[i] = elPtr->auxdata<float>("e_bare");
if(elPtr->isAvailable<unsigned int>("particleType")) m_el_true_type[i] = elPtr->auxdata<unsigned int>("particleType");
else if(elPtr->isAvailable<unsigned int>("classifierParticleType")) m_el_true_type[i] = elPtr->auxdata<unsigned int>("classifierParticleType");
else m_el_true_type[i] = 0;
if(elPtr->isAvailable<unsigned int>("particleOrigin")) m_el_true_origin[i] = elPtr->auxdata<unsigned int>("particleOrigin");
else if(elPtr->isAvailable<unsigned int>("classifierParticleOrigin")) m_el_true_origin[i] = elPtr->auxdata<unsigned int>("classifierParticleOrigin");
else m_el_true_origin[i] = 0;
++i;
}
......@@ -4227,6 +4265,9 @@ namespace top {
m_mu_eta_bare.resize(plEvent.m_muons->size());
m_mu_phi_bare.resize(plEvent.m_muons->size());
m_mu_e_bare.resize(plEvent.m_muons->size());
m_mu_true_type.resize(plEvent.m_muons->size());
m_mu_true_origin.resize(plEvent.m_muons->size());
for (const auto& muPtr : *plEvent.m_muons) {
m_mu_pt[i] = muPtr->pt();
......@@ -4239,10 +4280,92 @@ namespace top {
m_mu_eta_bare[i] = muPtr->auxdata<float>("eta_bare");
m_mu_phi_bare[i] = muPtr->auxdata<float>("phi_bare");
m_mu_e_bare[i] = muPtr->auxdata<float>("e_bare");
if(muPtr->isAvailable<unsigned int>("particleType")) m_mu_true_type[i] = muPtr->auxdata<unsigned int>("particleType");
else if(muPtr->isAvailable<unsigned int>("classifierParticleType")) m_mu_true_type[i] = muPtr->auxdata<unsigned int>("classifierParticleType");
else m_mu_true_type[i] = 0;
if(muPtr->isAvailable<unsigned int>("particleOrigin")) m_mu_true_origin[i] = muPtr->auxdata<unsigned int>("particleOrigin");
else if(muPtr->isAvailable<unsigned int>("classifierParticleOrigin")) m_mu_true_origin[i] = muPtr->auxdata<unsigned int>("classifierParticleOrigin");
else m_mu_true_origin[i] = 0;
++i;
}
}
i=0;
if(m_config->useSoftMuons()) {
m_softmu_pt.resize(plEvent.m_softmuons->size());
m_softmu_eta.resize(plEvent.m_softmuons->size());
m_softmu_phi.resize(plEvent.m_softmuons->size());
m_softmu_e.resize(plEvent.m_softmuons->size());
m_softmu_charge.resize(plEvent.m_softmuons->size());
m_softmu_true_type.resize(plEvent.m_softmuons->size());
m_softmu_true_origin.resize(plEvent.m_softmuons->size());
if(m_config->softmuonAdditionalTruthInfo())
{
m_softmu_parton_origin_flag.resize(plEvent.m_softmuons->size());
m_softmu_particle_origin_flag.resize(plEvent.m_softmuons->size());
m_softmu_parent_pdgid.resize(plEvent.m_softmuons->size());
m_softmu_b_hadron_parent_pdgid.resize(plEvent.m_softmuons->size());
m_softmu_c_hadron_parent_pdgid.resize(plEvent.m_softmuons->size());
}
for (const auto& muPtr : *plEvent.m_softmuons) {
m_softmu_pt[i] = muPtr->pt();
m_softmu_eta[i] = muPtr->eta();
m_softmu_phi[i] = muPtr->phi();
m_softmu_e[i] = muPtr->e();
m_softmu_charge[i] = muPtr->charge();
if(muPtr->isAvailable<unsigned int>("particleType")) m_softmu_true_type[i] = muPtr->auxdata<unsigned int>("particleType");
else if(muPtr->isAvailable<unsigned int>("classifierParticleType")) m_softmu_true_type[i] = muPtr->auxdata<unsigned int>("classifierParticleType");
else m_softmu_true_type[i] = 0;
if(muPtr->isAvailable<unsigned int>("particleOrigin")) m_softmu_true_origin[i] = muPtr->auxdata<unsigned int>("particleOrigin");
else if(muPtr->isAvailable<unsigned int>("classifierParticleOrigin")) m_softmu_true_origin[i] = muPtr->auxdata<unsigned int>("classifierParticleOrigin");
else m_softmu_true_origin[i] = 0;
if(m_config->softmuonAdditionalTruthInfo())
{
m_softmu_parton_origin_flag[i]=0;
if(m_config->softmuonAdditionalTruthInfoCheckPartonOrigin())
{
static const SG::AuxElement::Accessor<top::LepPartonOriginFlag> leppartonoriginflag("LepPartonOriginFlag");
if(leppartonoriginflag.isAvailable(*muPtr)) m_softmu_parton_origin_flag[i]=static_cast<int>(leppartonoriginflag(*muPtr));
}
m_softmu_particle_origin_flag[i]=0;
m_softmu_parent_pdgid[i]=0;
m_softmu_b_hadron_parent_pdgid[i]=0;
m_softmu_c_hadron_parent_pdgid[i]=0;
static const SG::AuxElement::Accessor<top::LepParticleOriginFlag> lepparticleoriginflag("LepParticleOriginFlag");
if(lepparticleoriginflag.isAvailable(*muPtr)) m_softmu_particle_origin_flag[i]=static_cast<int>(lepparticleoriginflag(*muPtr));
static const SG::AuxElement::Accessor<const xAOD::TruthParticle*> Mother("truthMotherLink");
const xAOD::TruthParticle* mother = 0;
if(Mother.isAvailable(*muPtr)) mother=Mother(*muPtr);
if(mother) m_softmu_parent_pdgid[i]=mother->pdgId();
static const SG::AuxElement::Accessor<const xAOD::TruthParticle*> BMother("truthBMotherLink");
const xAOD::TruthParticle* Bmother = 0;
if(BMother.isAvailable(*muPtr)) Bmother=BMother(*muPtr);
if(Bmother) m_softmu_b_hadron_parent_pdgid[i]=Bmother->pdgId();
static const SG::AuxElement::Accessor<const xAOD::TruthParticle*> CMother("truthCMotherLink");
const xAOD::TruthParticle* Cmother = 0;
if(CMother.isAvailable(*muPtr)) Cmother=CMother(*muPtr);
if(Cmother) m_softmu_c_hadron_parent_pdgid[i]=Cmother->pdgId();
if(m_config->softmuonAdditionalTruthInfoDoVerbose()) asg::msgUserCode::ATH_MSG_INFO("writing truth soft muon with pt="<<m_softmu_pt[i] <<" parton_origin_flag="<<m_softmu_parton_origin_flag[i]<<" particle_origin_flag="<<m_softmu_particle_origin_flag[i]<<" parent_pdg_id="<<m_softmu_parent_pdgid[i]<<" b_hadron_parent_pdg_id="<<m_softmu_b_hadron_parent_pdgid[i]<<" c_hadron_parent_pdg_id="<<m_softmu_c_hadron_parent_pdgid[i]);
}
++i;
}
}//end of soft muons part
}//end of muons part
//photons
if (m_config->useTruthPhotons()) {
......
......@@ -439,7 +439,12 @@ namespace top {
"Muon pT cut for [Particle Level / Truth] object selection (in MeV). Default 25 GeV.", "25000");
registerParameter("TruthMuonEta",
"Absolute Muon eta cut for [Particle Level / Truth] object selection. Default 2.5.", "2.5");
registerParameter("TruthSoftMuonPt",
"Soft Muon pT cut for [Particle Level / Truth] object selection (in MeV). Default 4 GeV.", "4000");
registerParameter("TruthSoftMuonEta",
"Absolute Soft Muon eta cut for [Particle Level / Truth] object selection. Default 2.5.", "2.5");
registerParameter("TruthPhotonPt",
"Photon pT cut for [Particle Level / Truth] object selection (in MeV). Default 25 GeV.",
"25000");
......
......@@ -312,6 +312,7 @@ namespace top {
// Particle Level / Truth Configuration
m_truth_electron{25000., 2.5, true, false},
m_truth_muon{25000., 2.5, true, false},
m_truth_softmuon{4000., 2.5},
m_truth_photon{25000., 2.5, "SET_ME", "SET_ME"},
m_truth_jet{25000., 2.5},
// -----------------------------------------------]]]
......@@ -1445,6 +1446,29 @@ namespace top {
this->truth_muon_PtCut(std::stof(settings->value("TruthMuonPt")));
this->truth_muon_EtaCut(std::stof(settings->value("TruthMuonEta")));
float truth_softmu_ptcut=4000.;
try{
truth_softmu_ptcut=std::stof(settings->value("TruthSoftMuonPt"));
}
catch (...) {
throw std::runtime_error {
"TopConfig: can't convert provided TruthSoftMuonPt into float"
};
}
float truth_softmu_etacut=2.5;
try{
truth_softmu_etacut=std::stof(settings->value("TruthSoftMuonEta"));
}
catch (...) {
throw std::runtime_error {
"TopConfig: can't convert provided TruthSoftMuonEta into float"
};
}
this->truth_softmuon_PtCut(truth_softmu_ptcut);
this->truth_softmuon_EtaCut(truth_softmu_etacut);
this->truth_photon_PtCut(std::stof(settings->value("TruthPhotonPt")));
this->truth_photon_EtaCut(std::stof(settings->value("TruthPhotonEta")));
......
......@@ -1566,6 +1566,22 @@ namespace top {
inline virtual float truth_muon_EtaCut() const {return m_truth_muon.EtaCut;}
inline virtual bool truth_muon_NotFromHadron() const {return m_truth_muon.NotFromHadron;}
inline virtual bool truth_muon_TauIsHadron() const {return m_truth_muon.TauIsHadron;}
// soft muons
inline virtual void truth_softmuon_PtCut(const float pt) {
if (!m_configFixed) {
m_truth_softmuon.PtCut = pt;
}
}
inline virtual void truth_softmuon_EtaCut(const float eta) {
if (!m_configFixed) {
m_truth_softmuon.EtaCut = eta;
}
}
inline virtual float truth_softmuon_PtCut() const {return m_truth_softmuon.PtCut;}
inline virtual float truth_softmuon_EtaCut() const {return m_truth_softmuon.EtaCut;}
// photons
inline virtual void truth_photon_PtCut(const float pt) {
......@@ -2362,6 +2378,15 @@ namespace top {
bool TauIsHadron; // [ParticleLevel / Truth] Whether a tauon is a
// hadron during the 'NotFromHadron' check
} m_truth_muon;
// soft muons
struct {
float PtCut; // [ParticleLevel / Truth] Muon Object
// Selection minimum pT Cut (Standard ATLAS
// units, [MeV]).
float EtaCut; // [ParticleLevel / Truth] Muon Object
// Selection maximum absolute eta Cut.
} m_truth_softmuon;
// photons
struct {
......
......@@ -1053,26 +1053,11 @@ void TopObjectSelection::applySelectionPreOverlapRemovalJetGhostTracks() {
{
for (auto iMu : goodSoftMuons) {
// Get muon iMu
const xAOD::Muon* muon = xaod_softmu->at(iMu);
muon->auxdecor<bool>("hasRecoMuonHistoryInfo")=false;
muon->auxdecor<const xAOD::TruthParticle*>("truthMuonLink") = 0;
muon->auxdecor<top::LepParticleOriginFlag>("LepParticleOriginFlag") = top::LepParticleOriginFlag::MissingTruthInfo;
muon->auxdecor<const xAOD::TruthParticle*>("truthMotherLink") = 0;
muon->auxdecor<const xAOD::TruthParticle*>("truthFirstNonLeptonMotherLink") = 0;
muon->auxdecor<const xAOD::TruthParticle*>("truthBMotherLink") = 0;
muon->auxdecor<const xAOD::TruthParticle*>("truthCMotherLink") = 0;
muon->auxdecor<top::LepPartonOriginFlag>("LepPartonOriginFlag") = top::LepPartonOriginFlag::MissingTruthInfo;
muon->auxdecor<const xAOD::TruthParticle*>("truthPartonMotherLink") = 0;
muon->auxdecor<const xAOD::TruthParticle*>("truthTopMotherLink") = 0;
muon->auxdecor<const xAOD::TruthParticle*>("truthWMotherLink") = 0;
muon->auxdecor<const xAOD::TruthParticle*>("truthZMotherLink") = 0;
muon->auxdecor<const xAOD::TruthParticle*>("truthPhotonMotherLink") = 0;
muon->auxdecor<const xAOD::TruthParticle*>("truthHiggsMotherLink") = 0;
muon->auxdecor<const xAOD::TruthParticle*>("truthBSMMotherLink") = 0;
top::truth::getRecoMuonHistory(muon,m_config->softmuonAdditionalTruthInfoCheckPartonOrigin(),m_config->getShoweringAlgorithm(),m_config->softmuonAdditionalTruthInfoDoVerbose());
// Get muon iMu
const xAOD::Muon* muon = xaod_softmu->at(iMu);
top::truth::initRecoMuonHistoryInfo(muon,m_config->softmuonAdditionalTruthInfoCheckPartonOrigin()); //it's safer if we initialize everything to default for each muon before filling the muon history
top::truth::getRecoMuonHistory(muon,m_config->softmuonAdditionalTruthInfoCheckPartonOrigin(),m_config->getShoweringAlgorithm(),m_config->softmuonAdditionalTruthInfoDoVerbose());
}//end of loop on soft muons
}
void TopObjectSelection::applyTightSelectionPostOverlapRemoval(const xAOD::IParticleContainer* xaod,
......
......@@ -5,11 +5,13 @@ atlas_subdir( TopParticleLevel None )
# This package depends on other packages:
atlas_depends_on_subdirs( PUBLIC
xAODBase
xAODTruth
xAODJet
xAODMissingET
xAODCore
xAODRootAccess
FourMomUtils
TopEvent
TopConfiguration
TopDataPreparation
......@@ -36,11 +38,14 @@ atlas_add_library( TopParticleLevel Root/*.cxx Root/*.h Root/*.icc
TopParticleLevel/*.h TopParticleLevel/*.icc TopParticleLevel/*/*.h
TopParticleLevel/*/*.icc
PUBLIC_HEADERS TopParticleLevel
LINK_LIBRARIES xAODTruth
LINK_LIBRARIES
xAODBase
xAODTruth
xAODJet
xAODMissingET
xAODCore
xAODRootAccess
FourMomUtils
TopEvent
TopConfiguration
TopDataPreparation
......
......@@ -26,6 +26,17 @@ std::ostream & operator << (std::ostream& os, const top::ParticleLevelEvent& plE
} else {
os << "ParticleLevelEvent: Cannot find muon truth collection. Did you set the truth collection correctly?\n";
}
if (plEvent.m_softmuons) {
os << "Number of soft muons: " << plEvent.m_softmuons->size() << "\n";
for (const auto& muPtr : *plEvent.m_softmuons) {
if (muPtr) {
os << " " << *muPtr << "\n";
}
}
} else {
os << "ParticleLevelEvent: Cannot find muon truth collection. Did you set the truth collection correctly?\n";
}
if (plEvent.m_jets) {
os << "Number of jets: " << plEvent.m_jets->size() << "\n";
......
......@@ -8,6 +8,7 @@
// Created: Sun Feb 22 13:24:02 2015
#include "TopParticleLevel/ParticleLevelLoader.h"
#include "TopParticleLevel/TruthTools.h"
#include <list>
#include <cassert>
......@@ -24,6 +25,7 @@
#include "TopParticleLevel/ParticleLevelTauObjectSelector.h"
#include "TopConfiguration/TopConfig.h"
#include "FourMomUtils/xAODP4Helpers.h"
#include <boost/algorithm/string.hpp>
......@@ -622,6 +624,103 @@ namespace top {
m_goodTaus->push_back(tau);
}
}
if (m_config->useTruthMuons() && m_config->useSoftMuons() ) {
xAOD::TruthParticleContainer* goodSoftMuons = new xAOD::TruthParticleContainer();
xAOD::TruthParticleAuxContainer* goodSoftMuonsAux = new xAOD::TruthParticleAuxContainer();
goodSoftMuons->setStore(goodSoftMuonsAux); //< Connect the two
m_goodSoftMuons.reset(goodSoftMuons);
m_goodSoftMuonsAux.reset(goodSoftMuonsAux);
//if we want the soft muon truth history, the parent navigation for the TruthMuons collection is unfortunately working only in DAOD_PHYS, in other derivations
//we need a workaround, i.e. we need to use the muon from the TruthParticles container instead of the one from the TruthMuon container
std::vector<const xAOD::TruthParticle*> truth_particles_vec; //this is an helper vector to speed up looking for the right muon...
const xAOD::TruthParticleContainer* truth_particles = nullptr;
if (m_config->useTruthParticles() && m_config->softmuonAdditionalTruthInfo()) {
top::check(evtStore()->retrieve(truth_particles, m_config->sgKeyMCParticle()),
"xAOD::TEvent::retrieve failed for Truth Particles");
if(truth_particles)
{
for(const xAOD::TruthParticle* p : *truth_particles)
{
if(p->isMuon() && p->status()==1) truth_particles_vec.push_back(p);
}
}
}
for (std::size_t i = 0; i < muons->size(); ++i) { //note we don't use dressed muons in this case
if(std::find(idx_muons.begin(), idx_muons.end(), i)!=idx_muons.end()) continue; //we don't want to store muons both as standard muons and as soft muons
const auto& muPtr = muons->at(i);
//here we apply the selection for soft muons
if(muPtr->absPdgId()!=13) continue;
if(muPtr->pt()<m_config->truth_softmuon_PtCut()) continue;
if(fabs(muPtr->eta())>m_config->truth_softmuon_EtaCut()) continue;
//now the association with the jets
if(m_config->useTruthJets())
{
bool isInJet=false;
for(xAOD::Jet* jetPtr : *m_goodJets)
{
float dR = xAOD::P4Helpers::deltaR(*muPtr,*jetPtr,m_config->softmuonDRJetcutUseRapidity());
if(dR<m_config->softmuonDRJetcut())
{
isInJet=true;
break;
}
}
if(!isInJet) continue;
}
//end of selection
if(m_config->softmuonAdditionalTruthInfo() && (!muPtr->isAvailable<bool>("hasTruthMuonHistoryInfo") || !muPtr->auxdecor<bool>("hasTruthMuonHistoryInfo"))) //if "hasTruthMuonPartonHistoryInfo" exists and is true, we already filled these info for this muon (since muon history filling can be done in several parts of the code for good reasons)
{
bool doPartonHistory=m_config->softmuonAdditionalTruthInfoCheckPartonOrigin();
top::truth::initTruthMuonHistoryInfo(muPtr,doPartonHistory);
//in DAOD_PHYS we can just navigate directly from the muon from TruthMuons
if (m_config->getDerivationStream() == "PHYS")
{
top::truth::getTruthMuonHistory(muPtr,doPartonHistory,m_config->getShoweringAlgorithm(),m_config->softmuonAdditionalTruthInfoDoVerbose());
}
else //apparently in older derivation formats we have to navigate using the muon from the TruthParticles container, this is annoying
{
//first we find the associated truth muon from truth_particles
const xAOD::TruthParticle* assMuon = 0;
for(const xAOD::TruthParticle* p : truth_particles_vec)
{
if(!p) continue;
if(p->barcode() == muPtr->barcode())
{
assMuon = p;
break;
}
}
if(assMuon) //then we use it
{
//if we don't have the info correctly filled already, let's initialize it to default values
if(!assMuon->isAvailable<bool>("hasTruthMuonHistoryInfo") || ! assMuon->auxdecor<bool>("hasTruthMuonHistoryInfo")) top::truth::initTruthMuonHistoryInfo(assMuon,doPartonHistory);
//we have to use the associated muon from the TruthParticles container in this case
top::truth::getTruthMuonHistory(assMuon,doPartonHistory,m_config->getShoweringAlgorithm(),m_config->softmuonAdditionalTruthInfoDoVerbose());
//then we copy the info to our muon
top::truth::copyTruthMuonHistoryInfo(assMuon,muPtr);
}
}
}//end of additional soft muon filling
xAOD::TruthParticle* muon = new xAOD::TruthParticle();
muon->makePrivateStore(*muPtr);
m_goodSoftMuons->push_back(muon);
}
// sort muons based on dressed pT -- otherwise they remain sorted according to bare pT
std::sort(m_goodSoftMuons->begin(), m_goodSoftMuons->end(), top::descendingPtSorter);
}
// ======================================================================
......@@ -629,12 +728,13 @@ namespace top {
// Put everything into storage, i.e. into the ParticleLevel.event object
plEvent.m_electrons = m_config->useTruthElectrons() ? m_goodElectrons.get() : nullptr;
plEvent.m_muons = m_config->useTruthMuons() ? m_goodMuons.get() : nullptr;
plEvent.m_softmuons = (m_config->useTruthMuons() && m_config->useSoftMuons()) ? m_goodSoftMuons.get() : nullptr;
plEvent.m_photons = m_config->useTruthPhotons() ? m_goodPhotons.get() : nullptr;
plEvent.m_jets = m_config->useTruthJets() ? m_goodJets.get() : nullptr;
plEvent.m_largeRJets = m_config->useTruthLargeRJets() ? m_goodLargeRJets.get() : nullptr;
plEvent.m_taus = m_config->useTruthTaus() ? m_goodTaus.get() : nullptr;
plEvent.m_met = m_config->useTruthMET() ? (*mets)[ "NonInt" ] : nullptr;
// Reclustered jets
if (m_config->useRCJets()) {
top::check(m_particleLevelRCJetObjectLoader->execute(
......
......@@ -30,6 +30,82 @@ using namespace TopParticleLevel;
namespace top {
namespace truth {
void initCommonMuonHistoryInfo(const xAOD::IParticle* muon, bool doPartonHistory)
{
muon->auxdecor<top::LepParticleOriginFlag>("LepParticleOriginFlag") = top::LepParticleOriginFlag::MissingTruthInfo;
muon->auxdecor<const xAOD::TruthParticle*>("truthMotherLink") = 0;
muon->auxdecor<const xAOD::TruthParticle*>("truthFirstNonLeptonMotherLink") = 0;
muon->auxdecor<const xAOD::TruthParticle*>("truthBMotherLink") = 0;
muon->auxdecor<const xAOD::TruthParticle*>("truthCMotherLink") = 0;
if(doPartonHistory)
{
muon->auxdecor<top::LepPartonOriginFlag>("LepPartonOriginFlag") = top::LepPartonOriginFlag::MissingTruthInfo;
muon->auxdecor<const xAOD::TruthParticle*>("truthPartonMotherLink") = 0;
muon->auxdecor<const xAOD::TruthParticle*>("truthTopMotherLink") = 0;
muon->auxdecor<const xAOD::TruthParticle*>("truthWMotherLink") = 0;
muon->auxdecor<const xAOD::TruthParticle*>("truthZMotherLink") = 0;
muon->auxdecor<const xAOD::TruthParticle*>("truthPhotonMotherLink") = 0;
muon->auxdecor<const xAOD::TruthParticle*>("truthHiggsMotherLink") = 0;
muon->auxdecor<const xAOD::TruthParticle*>("truthBSMMotherLink") = 0;
}
}
void initRecoMuonHistoryInfo(const xAOD::Muon* muon, bool doPartonHistory)
{
muon->auxdecor<bool>("hasRecoMuonHistoryInfo")=false;
muon->auxdecor<const xAOD::TruthParticle*>("truthMuonLink") = 0;
initCommonMuonHistoryInfo(muon,doPartonHistory);
}
void initTruthMuonHistoryInfo(const xAOD::TruthParticle* truthmu, bool doPartonHistory)
{
truthmu->auxdecor<bool>("hasTruthMuonHistoryInfo")=false;
if(doPartonHistory) truthmu->auxdecor<bool>("hasTruthMuonPartonHistoryInfo")=false;
initCommonMuonHistoryInfo(truthmu,doPartonHistory);
}
void copyRecoMuonHistoryInfo(const xAOD::Muon* m_origin, const xAOD::Muon* m_target)
{
copyCommonMuonHistoryInfo(m_origin,m_target);
m_target->auxdecor<bool>("hasRecoMuonHistoryInfo") = m_origin->auxdecor<bool>("hasRecoMuonHistoryInfo");
m_target->auxdecor<const xAOD::TruthParticle*>("truthMuonLink") = m_origin->auxdecor<const xAOD::TruthParticle*>("truthMuonLink");
}
void copyTruthMuonHistoryInfo(const xAOD::TruthParticle* tm_origin, const xAOD::TruthParticle* tm_target)
{
copyCommonMuonHistoryInfo(tm_origin,tm_target);
tm_target->auxdecor<bool>("hasTruthMuonHistoryInfo")= tm_origin->auxdecor<bool>("hasTruthMuonHistoryInfo");
tm_target->auxdecor<bool>("hasTruthMuonPartonHistoryInfo")= tm_origin->auxdecor<bool>("hasTruthMuonPartonHistoryInfo");
}
void copyCommonMuonHistoryInfo(const xAOD::IParticle* m_origin, const xAOD::IParticle* m_target)
{
if(!m_origin->isAvailable<top::LepParticleOriginFlag>("LepParticleOriginFlag"))
{
ATH_MSG_ERROR(" top::truth::copyCommonMuonHistoryInfo called with an origin muon which has no truth info!");
throw;
}
m_target->auxdecor<top::LepParticleOriginFlag>("LepParticleOriginFlag") = m_origin->auxdecor<top::LepParticleOriginFlag>("LepParticleOriginFlag");
m_target->auxdecor<const xAOD::TruthParticle*>("truthMotherLink") = m_origin->auxdecor<const xAOD::TruthParticle*>("truthMotherLink");
m_target->auxdecor<const xAOD::TruthParticle*>("truthFirstNonLeptonMotherLink") = m_origin->auxdecor<const xAOD::TruthParticle*>("truthFirstNonLeptonMotherLink");
m_target->auxdecor<const xAOD::TruthParticle*>("truthBMotherLink") = m_origin->auxdecor<const xAOD::TruthParticle*>("truthBMotherLink");
m_target->auxdecor<const xAOD::TruthParticle*>("truthCMotherLink") = m_origin->auxdecor<const xAOD::TruthParticle*>("truthCMotherLink");
if(m_origin->isAvailable<top::LepPartonOriginFlag>("LepPartonOriginFlag"))
{
m_target->auxdecor<top::LepPartonOriginFlag>("LepPartonOriginFlag") = m_origin->auxdecor<top::LepPartonOriginFlag>("LepPartonOriginFlag");
<