30 #include <boost/algorithm/string.hpp>
37 :
asg::AsgTool(
"ParticleLevelLoader"),
40 m_objectSelector_Electron(nullptr),
41 m_objectSelector_Muon(nullptr),
42 m_objectSelector_Photon(nullptr),
43 m_objectSelector_Jet(nullptr),
44 m_objectSelector_LargeRJet(nullptr),
45 m_objectSelector_Tau(nullptr),
47 m_active(m_config->doTopParticleLevel() &&
49 (m_config->useTruthElectrons() ||
50 m_config->useTruthMuons() ||
51 m_config->useTruthPhotons() ||
52 m_config->useTruthJets() ||
53 m_config->useTruthLargeRJets() ||
54 m_config->useTruthTaus() ||
55 m_config->useTruthMET())) {
60 m_config->truth_electron_NotFromHadron(),
61 m_config->truth_electron_TauIsHadron()
70 m_config->truth_muon_NotFromHadron(),
114 msgInfo <<
"Particle level reconstruction is enabled; telling you how I am configured:" <<
'\n';
115 msgInfo <<
" " << std::setw(20) <<
"UseElectrons? " << std::setw(5) << std::boolalpha <<
117 if (
m_config->useTruthElectrons()) {
118 msgInfo <<
" [" <<
m_config->sgKeyTruthElectrons() <<
"]" <<
'\n'
119 <<
" --- Pt > " <<
m_config->truth_electron_PtCut() <<
'\n'
120 <<
" --- |eta| < " <<
m_config->truth_electron_EtaCut() <<
'\n'
121 <<
" --- notFromHadron? " << std::boolalpha <<
m_config->truth_electron_NotFromHadron() <<
'\n'
122 <<
" --- tauIsHadron? " << std::boolalpha <<
m_config->truth_electron_TauIsHadron() <<
'\n';
126 msgInfo <<
" " << std::setw(20) <<
"UseMuons? " << std::setw(5) << std::boolalpha <<
129 msgInfo <<
" [" <<
m_config->sgKeyTruthMuons() <<
"]" <<
'\n'
130 <<
" --- Pt > " <<
m_config->truth_muon_PtCut() <<
'\n'
131 <<
" --- |eta| < " <<
m_config->truth_muon_EtaCut() <<
'\n'
132 <<
" --- notFromHadron? " << std::boolalpha <<
m_config->truth_muon_NotFromHadron() <<
'\n'
133 <<
" --- tauIsHadron? " << std::boolalpha <<
m_config->truth_muon_TauIsHadron() <<
'\n';
137 msgInfo <<
" " << std::setw(20) <<
"UsePhotons? " << std::setw(5) << std::boolalpha <<
140 msgInfo <<
" [" <<
m_config->sgKeyTruthPhotons() <<
"]" <<
'\n'
141 <<
" --- Pt > " <<
m_config->truth_photon_PtCut() <<
'\n'
142 <<
" --- |eta| < " <<
m_config->truth_photon_EtaCut() <<
'\n'
143 <<
" --- Origin = " <<
m_config->truth_photon_Origin() <<
'\n'
144 <<
" --- Isolation = " <<
m_config->truth_photon_Isolation() <<
'\n';
148 msgInfo <<
" " << std::setw(20) <<
"UseJets? " << std::setw(5) << std::boolalpha <<
m_config->useTruthJets();
150 msgInfo <<
" [" <<
m_config->sgKeyTruthJets() <<
"]" <<
'\n'
151 <<
" --- Pt > " <<
m_config->truth_jet_PtCut() <<
'\n'
152 <<
" --- |eta| < " <<
m_config->truth_jet_EtaCut() <<
'\n';
156 msgInfo <<
" " << std::setw(20) <<
"UseLargeRJets? " << std::setw(5) << std::boolalpha <<
159 msgInfo <<
" [" <<
m_config->sgKeyTruthLargeRJets() <<
"]" <<
'\n'
160 <<
" --- Pt > " <<
m_config->truth_jet_largeR_PtCut() <<
'\n'
161 <<
" --- |eta| < " <<
m_config->truth_jet_largeR_EtaCut() <<
'\n';
165 msgInfo <<
" " << std::setw(20) <<
"UseTaus? " << std::setw(5) << std::boolalpha <<
m_config->useTruthTaus();
167 msgInfo <<
" [" <<
m_config->sgKeyTruthTaus() <<
"]" <<
'\n'
168 <<
" --- Pt > " <<
m_config->truth_tau_PtCut() <<
'\n'
169 <<
" --- |eta| < " <<
m_config->truth_tau_EtaCut() <<
'\n';
173 msgInfo <<
" " << std::setw(20) <<
"UseMET? " << std::setw(5) << std::boolalpha <<
m_config->useTruthMET();
175 msgInfo <<
" [" <<
m_config->sgKeyTruthMET() <<
"]" <<
'\n';
179 msgInfo <<
" " << std::setw(20) <<
"DoOverlapRemoval Mu-Jet? " << std::setw(5) << std::boolalpha <<
180 m_config->doParticleLevelOverlapRemovalMuJet() <<
'\n';
181 msgInfo <<
" " << std::setw(20) <<
"DoOverlapRemoval El-Jet? " << std::setw(5) << std::boolalpha <<
182 m_config->doParticleLevelOverlapRemovalElJet() <<
'\n';
183 msgInfo <<
" " << std::setw(20) <<
"DoOverlapRemoval Jet-Photon? " << std::setw(5) << std::boolalpha <<
184 m_config->doParticleLevelOverlapRemovalJetPhoton() <<
'\n';
191 "Failed to initialize ParticleLevelRCJetObjectLoader");
194 if (
m_config->useVarRCJets() ==
true) {
201 std::string
name =
rho + mass_scale;
206 "Failed to set VarRCjets property of VarRCJet");
209 "Failed to set VarRCjets rho property of VarRCJet");
212 "Failed to set VarRCjets mass scale property of VarRCJet");
218 msgInfo <<
"Particle level reconstruction is disabled." <<
'\n';
236 "xAOD::TEvent::retrieve failed for EventInfo");
262 if (
m_config->useTruthElectrons()) {
264 "xAOD::TEvent::retrieve failed for Truth Electrons");
269 "xAOD::TEvent::retrieve failed for Truth Muons");
274 "xAOD::TEvent::retrieve failed for Truth Photons");
279 "xAOD::TEvent::retrieve failed for Truth Jets");
282 if (
m_config->useTruthLargeRJets()) {
284 "xAOD::TEvent::retrieve failed for Truth Jets Large R");
289 "xAOD::TEvent::retrieve failed for Truth Taus");
294 "xAOD::TEvent::retrieve failed for Truth Missing ET");
307 if (
m_config->useTruthElectrons()) {
311 "Failure to load dressed electrons.");
319 "Failure to load dressed muons.");
326 std::list<std::size_t> idx_electrons;
327 std::list<std::size_t> idx_muons;
328 std::list<std::size_t> idx_photons;
329 std::list<std::size_t> idx_jets;
330 std::list<std::size_t> idx_largeRJets;
331 std::list<std::size_t> idx_taus;
334 if (
m_config->useTruthElectrons()) {
349 idx_electrons.push_back(
i);
356 for (std::size_t
i = 0;
i < muons->size(); ++
i) {
357 const auto*
muon = muons->at(
i);
360 if (
muon->absPdgId() != 13) {
370 idx_muons.push_back(
i);
377 for (std::size_t
i = 0;
i < photons->size(); ++
i) {
378 const auto*
photon = photons->at(
i);
381 if (
photon->absPdgId() != 22) {
395 if (
m_config->useTruthElectrons()) {
407 idx_photons.push_back(
i);
413 for (std::size_t
i = 0;
i <
jets->size(); ++
i) {
415 idx_jets.push_back(
i);
421 if (
m_config->useTruthLargeRJets()) {
422 for (std::size_t
i = 0;
i < largeRJets->size(); ++
i) {
424 idx_largeRJets.push_back(
i);
431 for (std::size_t
i = 0;
i < taus->size(); ++
i) {
433 idx_taus.push_back(
i);
449 bool useRapidityInDeltaRCalculation =
m_config->useParticleLevelOverlapRemovalWithRapidity();
453 #ifdef TOP_PARTICLE_LEVEL_DEBUG_OVERLAP_REMOVAL
454 const std::size_t nMuonsPreOR {
459 idx_muons.remove_if([&idx_jets, &
jets, &useRapidityInDeltaRCalculation,
this](std::size_t
m) {
460 for (
auto j : idx_jets) {
468 #ifdef TOP_PARTICLE_LEVEL_DEBUG_OVERLAP_REMOVAL
469 ATH_MSG_INFO(
"[top::ParticleLevelLoader] Muon-In-Jet OR: "
470 << nMuonsPreOR <<
" -> " << idx_muons.size());
476 #ifdef TOP_PARTICLE_LEVEL_DEBUG_OVERLAP_REMOVAL
477 const std::size_t nElectronsPreOR {
482 idx_electrons.remove_if([&idx_jets, &
jets, &useRapidityInDeltaRCalculation,
this](std::size_t
e) {
483 for (
auto j : idx_jets) {
491 #ifdef TOP_PARTICLE_LEVEL_DEBUG_OVERLAP_REMOVAL
492 ATH_MSG_INFO(
"[top::ParticleLevelLoader] Electron-In-Jet OR: "
493 << nElectronsPreOR <<
" -> " << idx_electrons.size());
498 if (
m_config->useTruthPhotons() &&
m_config->useTruthJets() &&
m_config->doParticleLevelOverlapRemovalJetPhoton()) {
499 #ifdef TOP_PARTICLE_LEVEL_DEBUG_OVERLAP_REMOVAL
500 const std::size_t nJetPreOR {
505 idx_jets.remove_if([&idx_photons, &photons, &useRapidityInDeltaRCalculation, &
jets](std::size_t j) {
506 for (
auto ph : idx_photons) {
514 #ifdef TOP_PARTICLE_LEVEL_DEBUG_OVERLAP_REMOVAL
515 ATH_MSG_INFO(
"[top::ParticleLevelLoader] Jet-In-Photon OR: "
516 << nJetsPreOR <<
" -> " << idx_jets.size());
531 if (
m_config->useTruthElectrons()) {
534 goodElectrons->setStore(goodElectronsAux);
539 for (
auto e : idx_electrons) {
553 goodMuons->setStore(goodMuonsAux);
558 for (
auto m : idx_muons) {
561 muon->makePrivateStore(*muPtr);
572 goodPhotons->setStore(goodPhotonsAux);
577 for (
auto ph : idx_photons) {
578 const auto& phPtr = photons->at(ph);
580 photon->makePrivateStore(*phPtr);
588 goodJets->setStore(goodJetsAux);
593 for (
auto j : idx_jets) {
594 const auto& jetPtr =
jets->at(j);
596 jet->makePrivateStore(*jetPtr);
601 if (
m_config->useTruthLargeRJets()) {
604 goodLargeRJets->setStore(goodLargeRJetsAux);
609 for (
auto j : idx_largeRJets) {
610 const auto& jetPtr = largeRJets->at(j);
612 jet->makePrivateStore(*jetPtr);
620 goodTaus->setStore(goodTausAux);
625 for (
auto t : idx_taus) {
626 const auto& tauPtr = taus->at(
t);
636 goodSoftMuons->setStore(goodSoftMuonsAux);
643 std::vector<const xAOD::TruthParticle*> truth_particles_vec;
645 if (
m_config->useTruthParticles() &&
m_config->softmuonAdditionalTruthInfo()) {
647 "xAOD::TEvent::retrieve failed for Truth Particles");
657 for (std::size_t
i = 0;
i < muons->size(); ++
i) {
658 if(
std::find(idx_muons.begin(), idx_muons.end(),
i)!=idx_muons.end())
continue;
659 const auto& muPtr = muons->at(
i);
662 if(muPtr->absPdgId()!=13)
continue;
663 if(muPtr->pt()<
m_config->truth_softmuon_PtCut())
continue;
664 if(fabs(muPtr->eta())>
m_config->truth_softmuon_EtaCut())
continue;
673 if(dR<m_config->softmuonDRJetcut())
679 if(!isInJet)
continue;
683 if(
m_config->softmuonAdditionalTruthInfo() && (!muPtr->isAvailable<
bool>(
"hasTruthMuonHistoryInfo") || !muPtr->auxdecor<
bool>(
"hasTruthMuonHistoryInfo")))
685 bool doPartonHistory=
m_config->softmuonAdditionalTruthInfoCheckPartonOrigin();
689 if (
m_config->getDerivationStream() ==
"PHYS")
720 muon->makePrivateStore(*muPtr);
741 plEvent.
m_met =
m_config->useTruthMET() ? (*mets)[
"NonInt" ] :
nullptr;
746 plEvent),
"Failed to execute ParticleLevelRCJetObjectLoader container");
754 for (
auto rcjet : *rc_jets) {
757 " Can't find reclustered jet decoration \"PassedSelection\" - we need it to decide if we should keep the reclustered jet in the top::Event instance or not!");
766 std::string
name =
rho + mass_scale;
768 plEvent),
"Failed to execute RCJet container");
778 for (
auto vrcjet : *vrc_jets) {
781 " Can't find jet decoration \"PassedSelection\" - we need it to decide if we should keep the variable-R reclustered jet in the top::Event instance or not!");
795 std::unique_ptr<xAOD::TruthParticleContainer>&
store,
796 std::unique_ptr<xAOD::ShallowAuxContainer>& storeAux)
const {
799 store.reset(dressed.first);
800 storeAux.reset(dressed.second);
802 for (
auto pl : *
store.get()) {
803 TLorentzVector fvDressed;
804 fvDressed.SetPtEtaPhiE(pl->auxdata<
float>(
"pt_dressed"),
805 pl->auxdata<
float>(
"eta_dressed"),
806 pl->auxdata<
float>(
"phi_dressed"),
807 pl->auxdata<
float>(
"e_dressed"));
812 pl->auxdata<
float>(
"pt_bare") = pl->pt();
813 pl->auxdata<
float>(
"eta_bare") = pl->eta();
814 pl->auxdata<
float>(
"phi_bare") = pl->phi();
815 pl->auxdata<
float>(
"e_bare") = pl->e();
817 pl->setPx(fvDressed.Px());
818 pl->setPy(fvDressed.Py());
819 pl->setPz(fvDressed.Pz());
820 pl->setE(fvDressed.E());
828 const float dressingCone )
const {
832 static const std::string decoName {
833 "originalTruthParticle"
837 bool useRapidityInDeltaRCalculation =
m_config->useParticleLevelOverlapRemovalWithRapidity();
839 for (
const auto *
particle : dressedParticles) {
840 bool tp_isValid =
false;
844 tp_isValid = truthProxy.
isValid();
850 if (not tp_isValid) {