ATLAS Offline Software
Loading...
Searching...
No Matches
McEventCollectionFilter.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
6// Oleg.Fedin@cern.ch, August 2010
9//
10#include "AtlasHepMC/GenEvent.h"
13#include "AtlasHepMC/Flow.h"
15//
16#include "InDetSimEvent/SiHit.h"
21// CLHEP
23
24#include "TruthUtils/MagicNumbers.h" // for SUPPRESSED_PILEUP_BARCODE
25
26McEventCollectionFilter::McEventCollectionFilter(const std::string &name, ISvcLocator *pSvcLocator)
27 : AthReentrantAlgorithm(name, pSvcLocator)
28{
29}
30
31
33{
34 // Check and initialize keys
36 ATH_MSG_VERBOSE("Initialized ReadHandleKey: " << m_inputTruthCollectionKey);
38 ATH_MSG_VERBOSE("Initialized WriteHandleKey: " << m_outputTruthCollectionKey);
39
42 ATH_MSG_VERBOSE("Initialized ReadHandleKey: " << m_inputTRTHitsKey);
43 } else {
44 ATH_MSG_DEBUG("Not keeping electrons from TRT hits");
45 }
46
47 return StatusCode::SUCCESS;
48}
49
50
51StatusCode McEventCollectionFilter::execute(const EventContext &ctx) const
52{
53 ATH_MSG_DEBUG("Filtering McEventCollection...");
54
56 if (!inputCollection.isValid()) {
57 ATH_MSG_ERROR("Could not get input truth collection " << inputCollection.name() << " from store " << inputCollection.store());
58 return StatusCode::FAILURE;
59 }
60 ATH_MSG_DEBUG("Found input truth collection " << inputCollection.name() << " in store " << inputCollection.store());
61
63 ATH_CHECK(outputCollection.record(std::make_unique<McEventCollection>()));
64 if (!outputCollection.isValid()) {
65 ATH_MSG_ERROR("Could not record output truth collection " << outputCollection.name() << " to store " << outputCollection.store());
66 return StatusCode::FAILURE;
67 }
68 ATH_MSG_DEBUG("Recorded output truth collection " << outputCollection.name() << " in store " << outputCollection.store());
69
70 //.......Create new particle (geantino) to link hits from pileup
72 genPart->set_pdg_id(m_pileUpParticlePDGID); //Geantino
73 genPart->set_status(1);
74#ifndef HEPMC3
76#endif
78 genVertex->add_particle_out(genPart);
79
80 const HepMC::GenEvent* genEvt = *(inputCollection->begin());
81 //......copy GenEvent to the new one and remove all vertex
82 HepMC::GenEvent* evt = HepMC::copyemptyGenEvent(genEvt);
83#ifdef HEPMC3
84 for (const auto &oldbp : genEvt->beams()) {
85 // Would be good to have a helper function here like:
86 // GenParticlePtr copyGenParticleToNewGenEvent(ConstGenParticlePtr particleToBeCopied, GenEvent* newGenEvent);
87 // This would copy GenParticle Attributes as well
88 HepMC::GenParticlePtr bp=std::make_shared<HepMC::GenParticle>(oldbp->data());
89 evt->add_beam_particle(bp);
91 // Possibly also add a call to genVertex->add_particle_in(bp); ?
92 }
93 if (genEvt->cross_section()) {
94 auto cs = std::make_shared<HepMC3::GenCrossSection>(*genEvt->cross_section().get());
95 evt->set_cross_section(std::move(cs));
96 }
97 // to set geantino vertex as a truth primary vertex
98 HepMC::ConstGenVertexPtr hScatVx = genEvt->vertices().at(3-1);
99 if (hScatVx != nullptr) {
100 HepMC::FourVector pmvxpos=hScatVx->position();
101 genVertex->set_position(pmvxpos);
102 // to set geantino kinematic phi=eta=0, E=p=E_hard_scat
103
104 if (hScatVx->particles_in().size()==2) {
105 double sum = hScatVx->particles_in().at(0)->momentum().e()+hScatVx->particles_in().at(1)->momentum().e();
106 genPart->set_momentum(HepMC::FourVector(sum,0,0,sum));
107 }
108 }
109#else
110 evt->set_beam_particles(genEvt->beam_particles());
111 if (genEvt->cross_section()) {
112 evt->set_cross_section(*genEvt->cross_section());
113 }
114 // to set geantino vertex as a truth primary vertex
116 if (hScatVx != nullptr) {
117 HepMC::FourVector pmvxpos=hScatVx->position();
118 genVertex->set_position(pmvxpos);
119 // to set geantino kinematic phi=eta=0, E=p=E_hard_scat
120 HepMC::GenVertex::particles_in_const_iterator itrp =hScatVx->particles_in_const_begin();
121 if (hScatVx->particles_in_size()==2) {
122 HepMC::FourVector mom1=(*itrp)->momentum();
123 HepMC::FourVector mom2=(*(++itrp))->momentum();
124 double sum = mom1.e()+mom2.e();
125 genPart->set_momentum(HepMC::FourVector(sum,0,0,sum));
126 }
127 }
128#endif
129
130
131 // electrons from TRT hits
134 if (!inputCollectionH.isValid()) {
135 ATH_MSG_ERROR("Could not get input hits collection " << inputCollectionH.name() << " from store " << inputCollectionH.store());
136 return StatusCode::FAILURE;
137 }
138 ATH_MSG_DEBUG("Found input hits collection " << inputCollectionH.name() << " in store " << inputCollectionH.store());
139
140 for (const TRTUncompressedHit &hit : *inputCollectionH) {
141 const HepMcParticleLink& link = hit.particleLink();
142 int pdgID = hit.GetParticleEncoding();
143 if (std::abs(pdgID) != 11 || HepMC::barcode(link) == HepMC::UNDEFINED_ID) continue; // FIXME barcode-based
144 HepMC::ConstGenParticlePtr particle = link.cptr();
145 HepMC::ConstGenVertexPtr vx = particle->production_vertex();
146 HepMC::GenParticlePtr newParticle = HepMC::newGenParticlePtr(particle->momentum(), particle->pdg_id(), particle->status());
147#ifndef HEPMC3
148 HepMC::suggest_barcode(newParticle, HepMC::barcode(link)); // HepMC2 still barcode-based
149#endif
150 const HepMC::FourVector &position = vx->position();
151 HepMC::GenVertexPtr newVertex = HepMC::newGenVertexPtr(position);
152 newVertex->add_particle_out(newParticle);
153 evt->add_vertex(std::move(newVertex));
154#ifdef HEPMC3
155 HepMC::suggest_barcode(newParticle, HepMC::barcode(link)); // FIXME
156#endif
157 }
158 }
159
160 //.....add new vertex with geantino
161 evt->add_vertex(std::move(genVertex));
162#ifdef HEPMC3
164#endif
165 int referenceBarcode = HepMC::barcode(genPart);
166 ATH_MSG_DEBUG("Reference barcode: " << referenceBarcode);
167
168 outputCollection->push_back(evt);
169
170 return StatusCode::SUCCESS;
171}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_DEBUG(x)
An algorithm that can be simultaneously executed in multiple threads.
McEventCollectionFilter(const std::string &name, ISvcLocator *pSvcLocator)
Gaudi::Property< bool > m_keepElectronsLinkedToTRTHits
SG::ReadHandleKey< McEventCollection > m_inputTruthCollectionKey
virtual StatusCode initialize() override
SG::WriteHandleKey< McEventCollection > m_outputTruthCollectionKey
Gaudi::Property< int > m_pileUpParticlePDGID
virtual StatusCode execute(const EventContext &ctx) const override
SG::ReadHandleKey< TRTUncompressedHitCollection > m_inputTRTHitsKey
virtual bool isValid() override final
Can the handle be successfully dereferenced?
std::string store() const
Return the name of the store holding the object we are proxying.
const std::string & name() const
Return the StoreGate ID for the referenced object.
int barcode(const T *p)
Definition Barcode.h:16
constexpr int UNDEFINED_ID
constexpr int SUPPRESSED_PILEUP_BARCODE(std::numeric_limits< int32_t >::max())
This barcode is used by objects matched to particles from pile-up interactions in standard MC Product...
GenVertex * barcode_to_vertex(const GenEvent *e, int id)
Definition GenEvent.h:628
HepMC::GenVertex * GenVertexPtr
Definition GenVertex.h:59
bool suggest_barcode(T &p, int i)
Definition GenEvent.h:671
GenVertexPtr newGenVertexPtr(const HepMC::FourVector &pos=HepMC::FourVector(0.0, 0.0, 0.0, 0.0), const int i=0)
Definition GenVertex.h:64
GenParticlePtr newGenParticlePtr(const HepMC::FourVector &mom=HepMC::FourVector(0.0, 0.0, 0.0, 0.0), int pid=0, int status=0)
Definition GenParticle.h:39
GenEvent * copyemptyGenEvent(const GenEvent *inEvt)
Definition GenEvent.h:654
GenParticle * GenParticlePtr
Definition GenParticle.h:37
const GenParticle * ConstGenParticlePtr
Definition GenParticle.h:38
const HepMC::GenVertex * ConstGenVertexPtr
Definition GenVertex.h:60