ATLAS Offline Software
Loading...
Searching...
No Matches
FixHepMC Class Reference

A "fix-up" algorithm to correct weird event records. More...

#include <FixHepMC.h>

Inheritance diagram for FixHepMC:
Collaboration diagram for FixHepMC:

Public Member Functions

 FixHepMC (const std::string &name, ISvcLocator *pSvcLocator)
StatusCode execute (const EventContext &ctx)
 Execute method.
StatusCode finalize ()
virtual StatusCode sysInitialize () override
 Override sysInitialize.
virtual bool isClonable () const override
 Specify if the algorithm is clonable.
virtual StatusCode sysExecute (const EventContext &ctx) override
 Execute an algorithm.
virtual const DataObjIDColl & extraOutputDeps () const override
 Return the list of extra output dependencies.
virtual bool filterPassed (const EventContext &ctx) const
 Get filter decision:
virtual void setFilterPassed (bool state, const EventContext &ctx) const
 Set filter decision:
ServiceHandle< StoreGateSvc > & evtStore ()
 The standard StoreGateSvc (event store) Returns (kind of) a pointer to the StoreGateSvc.
const ServiceHandle< StoreGateSvc > & detStore () const
 The standard StoreGateSvc/DetectorStore Returns (kind of) a pointer to the StoreGateSvc.
virtual StatusCode sysStart () override
 Handle START transition.
virtual std::vector< Gaudi::DataHandle * > inputHandles () const override
 Return this algorithm's input handles.
virtual std::vector< Gaudi::DataHandle * > outputHandles () const override
 Return this algorithm's output handles.
Gaudi::Details::PropertyBase & declareProperty (Gaudi::Property< T, V, H > &t)
void updateVHKA (Gaudi::Details::PropertyBase &)
MsgStream & msg () const
bool msgLvl (const MSG::Level lvl) const
Event loop algorithm methods
virtual StatusCode initialize () override
Event collection accessors (const and non-const)
HepMC::GenEvent *event ATLAS_NOT_CONST_THREAD_SAFE ()
 Access the current signal event (first in the McEventCollection).
McEventCollection *events ATLAS_NOT_CONST_THREAD_SAFE ()
 Access the current event's McEventCollection.
const HepMC::GenEventevent_const (const EventContext &ctx) const
 Access the current signal event (const).
const McEventCollectionevents_const (const EventContext &ctx) const
 Access the current event's McEventCollection (const).

Protected Member Functions

virtual bool isReEntrant () const override final
 Legacy algorithms are not thread-safe.
void renounceArray (SG::VarHandleKeyArray &handlesArray)
 remove all handles from I/O resolution
std::enable_if_t< std::is_void_v< std::result_of_t< decltype(&T::renounce)(T)> > &&!std::is_base_of_v< SG::VarHandleKeyArray, T > &&std::is_base_of_v< Gaudi::DataHandle, T >, void > renounce (T &h)
void extraDeps_update_handler (Gaudi::Details::PropertyBase &ExtraDeps)
 Add StoreName to extra input/output deps as needed.

Private Types

typedef ServiceHandle< StoreGateSvcStoreGateSvc_t

Private Member Functions

Gaudi::Details::PropertyBase & declareGaudiProperty (Gaudi::Property< T, V, H > &hndl, const SG::VarHandleKeyType &)
 specialization for handling Gaudi::Property<SG::VarHandleKey>
Classifiers for identifying particles to be removed
bool isPID0 (const HepMC::ConstGenParticlePtr &p) const
bool isNonTransportableInDecayChain (const HepMC::ConstGenParticlePtr &p) const
bool isSimpleLoop (const HepMC::ConstGenParticlePtr &p) const
bool fromDecay (const HepMC::ConstGenParticlePtr &p, std::shared_ptr< std::set< int > > &storage) const

Private Attributes

DataObjIDColl m_extendedExtraObjects
 Extra output dependency collection, extended by AthAlgorithmDHUpdate to add symlinks.
StoreGateSvc_t m_evtStore
 Pointer to StoreGate (event store by default).
StoreGateSvc_t m_detStore
 Pointer to StoreGate (detector store by default).
std::vector< SG::VarHandleKeyArray * > m_vhka
bool m_varHandleArraysDeclared
Config properties
bool m_killLoops
bool m_killPDG0
bool m_cleanDecays
bool m_purgeUnstableWithoutEndVtx
bool m_ignoreSemiDisconnected
std::string m_forced_momentum {""}
std::string m_forced_length {""}
bool m_unitsFix
bool m_setHasCycles
Cleaned-particle counters

Mark that there are cycles (loops) in these events

long m_loopKilled
long m_pdg0Killed
long m_decayCleaned
long m_unstablePurged
long m_totalSeen
long m_replacedPIDs
std::map< int, int > m_pidmap
 map of pids to change.
std::map< int, int > m_replacedpid_counts
 map of counters of replacements.
MC::Loops< HepMC::GenEvent, HepMC::ConstGenParticlePtr, HepMC::ConstGenVertexPtrm_looper
 member to detect loops

Properties

SG::ReadHandleKey< McEventCollectionm_mcevents_const { this, "McEventKey", "GEN_EVENT", "StoreGate key of the MC event collection" }
 Const handle to the MC event collection.
std::string m_mcEventKey {}
 StoreGate key for the MC event collection (defaults to GEN_EVENT).
BooleanProperty m_mkMcEvent {this, "MakeMcEvent", false, "Create a new MC event collection if it doesn't exist"}
 Flag to determine if a new MC event collection should be made if it doesn't exist.

Detailed Description

A "fix-up" algorithm to correct weird event records.

FixHepMC is run in evgen production, after the chain of input, shower, hadronization, and afterburner generators, but before the TestHepMC check algorithm, any analysis algs, and the POOL event stream output. Its job is to "normalise" strange event features to allow greater consistency of MC event record use in ATLAS.

Examples of its features include removing dummy "padding" particles from event records, stripping parton and EW boson intermediates from hadron/tau decay chains, and ensuring that every event has at least one entry in its event weight vector.

Definition at line 31 of file FixHepMC.h.

Member Typedef Documentation

◆ StoreGateSvc_t

typedef ServiceHandle<StoreGateSvc> AthCommonDataStore< AthCommonMsg< Gaudi::Algorithm > >::StoreGateSvc_t
privateinherited

Definition at line 388 of file AthCommonDataStore.h.

Constructor & Destructor Documentation

◆ FixHepMC()

FixHepMC::FixHepMC ( const std::string & name,
ISvcLocator * pSvcLocator )

Definition at line 15 of file FixHepMC.cxx.

16 : GenBase(name, pSvcLocator)
17 , m_loopKilled(0)
18 , m_pdg0Killed(0)
21 , m_totalSeen(0)
23{
24 declareProperty("KillLoops", m_killLoops = true, "Remove particles in loops?");
25 declareProperty("KillPDG0", m_killPDG0 = true, "Remove particles with PDG ID 0?");
26 declareProperty("CleanDecays", m_cleanDecays = true, "Clean decay chains from non-propagating particles?");
27 declareProperty("PurgeUnstableWithoutEndVtx", m_purgeUnstableWithoutEndVtx = false, "Remove unstable particles without decay vertex?");
28 declareProperty("IgnoreSemiDisconnected", m_ignoreSemiDisconnected = false, "Ignore semi-disconnected particles (normal in Sherpa)");
29 declareProperty("PIDmap", m_pidmap = std::map<int,int>(), "Map of PDG IDs to replace");
30 declareProperty("forced_momentum", m_forced_momentum = "MEV", "Forced momentum unit");
31 declareProperty("forced_length", m_forced_length = "MM", "Forced length unit");
32 declareProperty("ApplyUnitsFix", m_unitsFix = true, "Attempt to identify momentum units problems and fix them");
33 declareProperty("SetHasCycles", m_setHasCycles = false, "Note hat this event has cycles (loops)");
34}
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
bool m_setHasCycles
Definition FixHepMC.h:59
bool m_purgeUnstableWithoutEndVtx
Definition FixHepMC.h:54
long m_replacedPIDs
Definition FixHepMC.h:69
bool m_killPDG0
Definition FixHepMC.h:52
std::string m_forced_momentum
Definition FixHepMC.h:56
bool m_unitsFix
Definition FixHepMC.h:58
long m_totalSeen
Definition FixHepMC.h:68
long m_pdg0Killed
Definition FixHepMC.h:65
long m_decayCleaned
Definition FixHepMC.h:66
bool m_ignoreSemiDisconnected
Definition FixHepMC.h:55
bool m_cleanDecays
Definition FixHepMC.h:53
bool m_killLoops
Definition FixHepMC.h:51
long m_unstablePurged
Definition FixHepMC.h:67
long m_loopKilled
Definition FixHepMC.h:64
std::map< int, int > m_pidmap
map of pids to change.
Definition FixHepMC.h:72
std::string m_forced_length
Definition FixHepMC.h:57
GenBase(const std::string &name, ISvcLocator *pSvcLocator)
Constructor.
Definition GenBase.cxx:11

Member Function Documentation

◆ ATLAS_NOT_CONST_THREAD_SAFE() [1/2]

McEventCollection *events GenBase::ATLAS_NOT_CONST_THREAD_SAFE ( )
inherited

Access the current event's McEventCollection.

Note
This function will make a new McEventCollection if there is not already a valid one and MakeMcEvent=True.

◆ ATLAS_NOT_CONST_THREAD_SAFE() [2/2]

HepMC::GenEvent *event GenBase::ATLAS_NOT_CONST_THREAD_SAFE ( )
inlineinherited

Access the current signal event (first in the McEventCollection).

Note
This function will make a new McEventCollection if there is not already a valid one and MakeMcEvent=True.

Definition at line 74 of file GenBase.h.

74 {
75 if (events()->empty())
76 ATH_MSG_ERROR("McEventCollection is empty during first event access");
77 return *(events()->begin());
78 }
#define ATH_MSG_ERROR(x)
static const Attributes_t empty

◆ declareGaudiProperty()

Gaudi::Details::PropertyBase & AthCommonDataStore< AthCommonMsg< Gaudi::Algorithm > >::declareGaudiProperty ( Gaudi::Property< T, V, H > & hndl,
const SG::VarHandleKeyType &  )
inlineprivateinherited

specialization for handling Gaudi::Property<SG::VarHandleKey>

Definition at line 156 of file AthCommonDataStore.h.

158 {
160 hndl.value(),
161 hndl.documentation());
162
163 }

◆ declareProperty()

Gaudi::Details::PropertyBase & AthCommonDataStore< AthCommonMsg< Gaudi::Algorithm > >::declareProperty ( Gaudi::Property< T, V, H > & t)
inlineinherited

Definition at line 145 of file AthCommonDataStore.h.

145 {
146 typedef typename SG::HandleClassifier<T>::type htype;
148 }
Gaudi::Details::PropertyBase & declareGaudiProperty(Gaudi::Property< T, V, H > &hndl, const SG::VarHandleKeyType &)
specialization for handling Gaudi::Property<SG::VarHandleKey>

◆ detStore()

const ServiceHandle< StoreGateSvc > & AthCommonDataStore< AthCommonMsg< Gaudi::Algorithm > >::detStore ( ) const
inlineinherited

The standard StoreGateSvc/DetectorStore Returns (kind of) a pointer to the StoreGateSvc.

Definition at line 95 of file AthCommonDataStore.h.

◆ event_const()

const HepMC::GenEvent * GenBase::event_const ( const EventContext & ctx) const
inlineinherited

Access the current signal event (const).

Definition at line 81 of file GenBase.h.

81 {
82 const McEventCollection* coll = events_const(ctx);
83 if (coll->empty())
84 ATH_MSG_ERROR("Const McEventCollection is empty during first event access");
85 return *(coll->begin());
86 }
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
bool empty() const noexcept
Returns true if the collection is empty.
const McEventCollection * events_const(const EventContext &ctx) const
Access the current event's McEventCollection (const).
Definition GenBase.h:95

◆ events_const()

const McEventCollection * GenBase::events_const ( const EventContext & ctx) const
inlineinherited

Access the current event's McEventCollection (const).

Definition at line 95 of file GenBase.h.

95 {
96 SG::ReadHandle<McEventCollection> ret = SG::makeHandle(m_mcevents_const, ctx);
97 if (!ret.isValid())
98 ATH_MSG_ERROR("No McEventCollection found in StoreGate with key " << m_mcevents_const.key());
99 return ret.cptr();
100 }
SG::ReadHandleKey< McEventCollection > m_mcevents_const
Const handle to the MC event collection.
Definition GenBase.h:119
virtual bool isValid() override final
Can the handle be successfully dereferenced?
const_pointer_type cptr()
Dereference the pointer.
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())

◆ evtStore()

ServiceHandle< StoreGateSvc > & AthCommonDataStore< AthCommonMsg< Gaudi::Algorithm > >::evtStore ( )
inlineinherited

The standard StoreGateSvc (event store) Returns (kind of) a pointer to the StoreGateSvc.

Definition at line 85 of file AthCommonDataStore.h.

◆ execute()

StatusCode FixHepMC::execute ( const EventContext & ctx)
virtual

Execute method.

Case 1: particles without production vertex, except beam particles (status 4)

Case 2: non-final-state particles without end vertex

AV: In case we have 3 particles, we try to add a vertex that corresponds to 1->2 and 1->1 splitting. AV: In case we have 4 particles, we can try to do that as well.

YH: In the case of Sherpa with HEPMC_TREE_LIKE: 1, where the YH: incoming/outgoing particles of the signal process have no YH: production/end vertices, this treatment can produce a loop. YH: Skip it by setting IgnoreSemiDisconnected = True.

The condition below will cover 1->1, 1->2 and 2->1 cases

Remove loops inside decay chains AV: Please note that this approach would distort some branching ratios. If some particle would have decay products with bad PDG ids, after the operation below the visible branching ratio of these decays would be zero.

Check the bad particles have prod and end vertices

Check that all particles coming into the decay vertex of a decay-loop particle candidate came from the same production vertex

remove loop

Reimplemented from GenBase.

Definition at line 36 of file FixHepMC.cxx.

36 {
37 for (McEventCollection::const_iterator ievt = events()->begin(); ievt != events()->end(); ++ievt) {
38 // FIXME: const_cast
39 HepMC::GenEvent* evt = const_cast<HepMC::GenEvent*>(*ievt);
40 m_looper.findLoops(evt,true);
41 /* AV: To understand why some algorithms fail one would have to request debug explicitly, but that is the reviwers consensus.*/
42 if (!m_looper.loop_particles().empty() || !m_looper.loop_vertices().empty()) {
43 ATH_MSG_DEBUG("Found " << m_looper.loop_vertices().size() << " vertices in loops");
44 ATH_MSG_DEBUG("Found " << m_looper.loop_particles().size() << " particles in loops");
45 ATH_MSG_DEBUG("Please use MC::Loops::findLoops for this event to obtain all particles and vertices in the loops");
46 }
47 auto old_momentum = evt->momentum_unit();
48 auto old_length = evt->length_unit();
49 evt->set_units(
50 m_forced_momentum != "" ? HepMC3::Units::momentum_unit(m_forced_momentum): old_momentum,
51 m_forced_length != "" ? HepMC3::Units::length_unit(m_forced_length): old_length);
52 if ( m_forced_momentum != "" && m_forced_momentum != HepMC3::Units::name(old_momentum) ) ATH_MSG_WARNING("Updated momentum units " << HepMC3::Units::name(old_momentum) << "->" << m_forced_momentum);
53 if ( m_forced_length != "" && m_forced_length != HepMC3::Units::name(old_length) ) ATH_MSG_WARNING("Updated length units " << HepMC3::Units::name(old_length) << "->" << m_forced_length);
54
55 if (!m_pidmap.empty()) {
56 for (auto ip: *evt) {
57 // Skip this particle if (somehow) its pointer is null
58 if (!ip) continue;
59 auto newpid = m_pidmap.find(ip->pdg_id());
60 if (newpid == m_pidmap.end()) continue;
61 ip->set_pdg_id(newpid->second);
62 // Increment the counter for replaced PDG IDs
64 m_replacedpid_counts[ip->pdg_id()]++;
65 }
66 }
67
68 if (m_setHasCycles){
69 // If asked, tag the event as having cycles and alert the user that this problem exists
70 auto cycles = std::make_shared<HepMC3::IntAttribute>(1);
71 evt->add_attribute(HepMCStr::cycles, cycles);
72 }
73
74 // Add a unit entry to the event weight vector if it's currently empty
75 if (evt->weights().empty()) {
76 ATH_MSG_DEBUG("Adding a unit weight to empty event weight vector");
77 evt->weights().push_back(1);
78 }
79 // Set a (0,0,0) vertex to be the signal vertex if not already set
81 const HepMC::FourVector nullpos;
82 for (auto iv: evt->vertices()) {
83 if (iv->position() == nullpos) {
84 ATH_MSG_DEBUG("Setting representative event position vertex");
86 break;
87 }
88 }
89 }
90
91 // Catch cases with more than 2 beam particles (16.11.2021)
92 std::vector<HepMC::GenParticlePtr> beams_t;
93 for (const HepMC::GenParticlePtr& p : evt->beams()) {
94 if (p->status() == 4) beams_t.push_back(p);
95 }
96 if (beams_t.size() > 2) {
97 ATH_MSG_INFO("Invalid number of beam particles " << beams_t.size() << ". Will try to fix.");
98 std::vector<HepMC::GenParticlePtr> bparttoremove;
99 for (const auto& bpart : beams_t) {
100 if (bpart->id() == 0 && bpart->production_vertex()) bparttoremove.push_back(bpart);
101 }
102 for (auto bpart: bparttoremove) {
103 bpart->production_vertex()->remove_particle_out(bpart);
104 }
105 }
106
107 // Some generators / samples have a mis-match between the units they report and the units used for momentum, usually because we have applied
108 // a correction to the momentum without also correcting the units. Here we're going to check for states that look particularly suspicious
109 // and apply a correction if required. We will try to identify those issues based on the beam particles.
110 if (m_unitsFix){ // Only if requested - allow folks to disable this if they know what they're doing
111 double units_problem = -1.;
112 // If we have beam particles, let's use them - it's much faster!
113 if (beams_t.size() > 0 ){
114 for (const HepMC::GenParticlePtr& p : beams_t){
115 if (p->momentum().pz() > 1e9) units_problem = p->momentum().pz();
116 }
117 // if we didn't have beam particles, we'll go through some of the main record
118 } else {
119 for (const HepMC::GenParticlePtr& p : evt->particles()) {
120 if (p && p->momentum().pz() > 1e9) units_problem = p->momentum().pz();
121 }
122 }
123 if (units_problem>0){ // No particles should have momenta above 1 PeV; this must be a units issue
124 ATH_MSG_INFO("Apparent units problem; beam particles have z-momentum " << units_problem << " in MeV. Will divide by 1000.");
125 MC::MeVToGeV(evt); //Only scales momenta and masses
126 }
127 }
128
129 // Some heuristics to catch problematic cases
130 std::vector<HepMC::GenParticlePtr> semi_disconnected, decay_loop_particles;
131 for (auto ip : evt->particles()) {
132 // Skip this particle if (somehow) its pointer is null
133 if (!ip) continue;
134 bool particle_to_fix = false;
135 int abspid = std::abs(ip->pdg_id());
136 auto vProd = ip->production_vertex();
137 auto vEnd = ip->end_vertex();
139 if ( (!vProd || vProd->id() == 0) && vEnd && ip->status() != 4) {
140 particle_to_fix = true;
141 ATH_MSG_DEBUG("Found particle " << ip->pdg_id() << " without production vertex! HepMC status = " << ip->status());
142 }
144 if (vProd && !vEnd && ip->status() != 1) {
145 particle_to_fix = true;
146 ATH_MSG_DEBUG("Found particle " << ip->pdg_id() << " without decay vertex! HepMC status = " << ip->status());
147 }
148 if (particle_to_fix) semi_disconnected.push_back(ip);
149 // Case 3: keep track of loop particles inside decay chains (seen in H7+EvtGen)
150 if (abspid == 43 || abspid == 44 || abspid == 30353 || abspid == 30343) {
151 decay_loop_particles.push_back(std::move(ip));
152 }
153 }
154
158
163 if ( !m_ignoreSemiDisconnected && (semi_disconnected.size() == 4 || semi_disconnected.size() == 3 || semi_disconnected.size() == 2)) {
164 size_t no_endv = 0;
165 size_t no_prov = 0;
166 HepMC::FourVector sum(0,0,0,0);
167 std::set<HepMC::GenVertexPtr> standalone;
168 for (const auto& part : semi_disconnected) {
169 if (!part->production_vertex() || !part->production_vertex()->id()) {
170 no_prov++; sum += part->momentum();
171 }
172 if (!part->end_vertex()) {
173 no_endv++; sum -= part->momentum();
174 }
175 if (part->production_vertex()) standalone.insert(part->production_vertex());
176 if (part->end_vertex()) standalone.insert(part->end_vertex());
177 }
178 ATH_MSG_INFO("Heuristics: found " << semi_disconnected.size() << " semi-disconnected particles. Momentum sum is " << sum << " Standalone vertices " << standalone.size());
179 bool standalonevertex = (standalone.size() == 1 && (*standalone.begin())->particles_in().size() + (*standalone.begin())->particles_out().size() == semi_disconnected.size());
181 if (! standalonevertex && no_endv && no_prov && ( no_endv + no_prov == semi_disconnected.size() )) {
182 if (std::abs(sum.px()) < 1e-2 && std::abs(sum.py()) < 1e-2 && std::abs(sum.pz()) < 1e-2 ) {
183 ATH_MSG_INFO("Try " << no_endv << "->" << no_prov << " splitting/merging.");
184 auto v = HepMC::newGenVertexPtr();
185 for (auto part : semi_disconnected) {
186 if (!part->production_vertex() || part->production_vertex()->id() == 0) v->add_particle_out(std::move(part));
187 }
188 for (auto part : semi_disconnected) {
189 if (!part->end_vertex()) v->add_particle_in(std::move(part));
190 }
191 evt->add_vertex(std::move(v));
192 }
193 }
194 }
195
200 for (auto part: decay_loop_particles) {
202 auto vend = part->end_vertex();
203 auto vprod = part->production_vertex();
204 if (!vprod || !vend) continue;
205 bool loop_in_decay = true;
208 auto sisters = vend->particles_in();
209 for (auto sister: sisters) {
210 if (vprod != sister->production_vertex()) loop_in_decay = false;
211 }
212 if (!loop_in_decay) continue;
213
215 auto daughters = vend->particles_out();
216 for (auto p : daughters) vprod->add_particle_out(std::move(p));
217 for (auto sister : sisters) {
218 vprod->remove_particle_out(sister);
219 vend->remove_particle_in(sister);
220 evt->remove_particle(std::move(sister));
221 }
222 evt->remove_vertex(std::move(vend));
223
224 }
225
226 // Event particle content cleaning -- remove "bad" structures
227 std::vector<HepMC::GenParticlePtr> toremove;
228 for (auto ip: evt->particles()) {
229 // Skip this particle if (somehow) its pointer is null
230 if (!ip) continue;
231 m_totalSeen += 1;
232 // Flag to declare if a particle should be removed
233 bool bad_particle = false;
234 // Check for loops
235 if ( m_killLoops && isSimpleLoop(ip) ) {
236 bad_particle = true;
237 m_loopKilled += 1;
238 ATH_MSG_DEBUG( "Found a looper : " );
239 if ( msgLvl( MSG::DEBUG ) ) HepMC::Print::line(ip);
240 }
241 // Check on PDG ID 0
242 if ( m_killPDG0 && isPID0(ip) ) {
243 bad_particle = true;
244 m_pdg0Killed += 1;
245 ATH_MSG_DEBUG( "Found PDG ID 0 : " );
246 if ( msgLvl( MSG::DEBUG ) )HepMC::Print::line(ip);
247 }
248 // Clean decays
249 int abs_pdg_id = std::abs(ip->pdg_id());
250 bool is_decayed_weak_boson = ( abs_pdg_id == 23 || abs_pdg_id == 24 || abs_pdg_id == 25 ) && ip->end_vertex();
251 if ( m_cleanDecays && isNonTransportableInDecayChain(ip) && !is_decayed_weak_boson ) {
252 bad_particle = true;
253 m_decayCleaned += 1;
254 ATH_MSG_DEBUG( "Found a bad particle in a decay chain : " );
255 if ( msgLvl( MSG::DEBUG ) ) HepMC::Print::line(ip);
256 }
257 // Only add to the toremove vector once, even if multiple tests match
258 if (bad_particle) toremove.push_back(std::move(ip));
259 }
260
261 // Properties before cleaning
262 const int num_particles_orig = evt->particles().size();
263
264 // Do the cleaning
265 if (!toremove.empty()) {
266 ATH_MSG_DEBUG("Cleaning event record of " << toremove.size() << " bad particles");
267 for (auto part: toremove) evt->remove_particle(std::move(part));
268 }
269
271 int purged=0;
272 do {
273 purged=0;
274 const std::vector <HepMC::GenParticlePtr> allParticles=evt->particles();
275 for(auto p : allParticles) {
276 HepMC::ConstGenVertexPtr end_v=p->end_vertex();
277 if(p->status() == 2 && !end_v) {
278 evt->remove_particle(std::move(p));
279 ++purged;
281 }
282 }
283 }
284 while (purged>0);
285 }
286
287 const int num_particles_filt = evt->particles().size();
288
289 if(num_particles_orig!=num_particles_filt) {
290 // Write out the change in the number of particles
291 ATH_MSG_INFO("Particles filtered: " << num_particles_orig << " -> " << num_particles_filt);
292 }
293
294 } // End of the loop over events in the MC event collection
295 return StatusCode::SUCCESS;
296}
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
bool msgLvl(const MSG::Level lvl) const
DataModel_detail::const_iterator< DataVector > const_iterator
Definition DataVector.h:838
bool isPID0(const HepMC::ConstGenParticlePtr &p) const
Definition FixHepMC.cxx:316
bool isNonTransportableInDecayChain(const HepMC::ConstGenParticlePtr &p) const
Definition FixHepMC.cxx:337
std::map< int, int > m_replacedpid_counts
map of counters of replacements.
Definition FixHepMC.h:73
MC::Loops< HepMC::GenEvent, HepMC::ConstGenParticlePtr, HepMC::ConstGenVertexPtr > m_looper
member to detect loops
Definition FixHepMC.h:76
bool isSimpleLoop(const HepMC::ConstGenParticlePtr &p) const
Definition FixHepMC.cxx:343
const std::string cycles
HepMC3::FourVector FourVector
void set_signal_process_vertex(GenEvent *e, T &v)
Definition GenEvent.h:591
ConstGenVertexPtr signal_process_vertex(const GenEvent *e)
Definition GenEvent.h:597
HepMC3::GenParticlePtr GenParticlePtr
Definition GenParticle.h:19
GenVertexPtr newGenVertexPtr(const HepMC3::FourVector &pos=HepMC3::FourVector::ZERO_VECTOR(), const int i=0)
Definition GenVertex.h:25
HepMC3::ConstGenVertexPtr ConstGenVertexPtr
Definition GenVertex.h:24
HepMC3::GenEvent GenEvent
Definition GenEvent.h:39
void MeVToGeV(HepMC::GenEvent *evt)

◆ extraDeps_update_handler()

void AthCommonDataStore< AthCommonMsg< Gaudi::Algorithm > >::extraDeps_update_handler ( Gaudi::Details::PropertyBase & ExtraDeps)
protectedinherited

Add StoreName to extra input/output deps as needed.

use the logic of the VarHandleKey to parse the DataObjID keys supplied via the ExtraInputs and ExtraOuputs Properties to add the StoreName if it's not explicitly given

◆ extraOutputDeps()

const DataObjIDColl & AthCommonAlgorithm< Gaudi::Algorithm >::extraOutputDeps ( ) const
overridevirtualinherited

Return the list of extra output dependencies.

This list is extended to include symlinks implied by inheritance relations.

Definition at line 89 of file AthCommonAlgorithm.cxx.

54{
55 // If we didn't find any symlinks to add, just return the collection
56 // from the base class. Otherwise, return the extended collection.
57 if (!m_extendedExtraObjects.empty()) {
59 }
61}
Common base class for algorithms.

◆ filterPassed()

virtual bool AthCommonAlgorithm< Gaudi::Algorithm >::filterPassed ( const EventContext & ctx) const
inlinevirtualinherited

Get filter decision:

Definition at line 93 of file AthCommonAlgorithm.h.

93 {
94 return execState( ctx ).filterPassed();
95 }
virtual bool filterPassed(const EventContext &ctx) const
Get filter decision:

◆ finalize()

StatusCode FixHepMC::finalize ( )

Definition at line 299 of file FixHepMC.cxx.

299 {
300 if (m_killLoops ) ATH_MSG_INFO( "Removed " << m_loopKilled << " of " << m_totalSeen << " particles because of loops." );
301 if (m_killPDG0 ) ATH_MSG_INFO( "Removed " << m_pdg0Killed << " of " << m_totalSeen << " particles because of PDG ID 0." );
302 if (m_cleanDecays) ATH_MSG_INFO( "Removed " << m_decayCleaned << " of " << m_totalSeen << " particles while cleaning decay chains." );
303 if(m_purgeUnstableWithoutEndVtx) ATH_MSG_INFO( "Removed " << m_unstablePurged << " of " << m_totalSeen << " unstable particles because they had no decay vertex." );
304 if (!m_pidmap.empty()) {
305 ATH_MSG_INFO( "Replaced " << m_replacedPIDs << " PIDs of particles." );
306 for (const auto& p: m_replacedpid_counts) ATH_MSG_INFO( "Replaced " << p.first << " PIDs " << p.second << "times." );
307 }
308 return StatusCode::SUCCESS;
309}

◆ fromDecay()

bool FixHepMC::fromDecay ( const HepMC::ConstGenParticlePtr & p,
std::shared_ptr< std::set< int > > & storage ) const
private

Definition at line 321 of file FixHepMC.cxx.

321 {
322 if (!p) return false;
323 auto v=p->production_vertex();
324 if (!v) return false;
325 for ( const auto& anc: v->particles_in()) {
326 if (MC::isDecayed(anc) && (MC::isTau(anc->pdg_id()) || MC::isHadron(anc->pdg_id()))) return true;
327 }
328 if (storage->find(p->id()) != storage->end()) return false;
329 storage->insert(p->id());
330 for ( const auto& anc: v->particles_in()) {
331 if (fromDecay(anc, storage)) return true;
332 }
333 return false;
334}
bool fromDecay(const HepMC::ConstGenParticlePtr &p, std::shared_ptr< std::set< int > > &storage) const
Definition FixHepMC.cxx:321
bool isDecayed(const T &p)
Identify if the particle decayed.
bool isHadron(const T &p)
bool isTau(const T &p)

◆ initialize()

StatusCode GenBase::initialize ( )
overridevirtualinherited

Reimplemented in CopyEventWeight, CountHepMC, DumpMC, EvtInclusiveDecay, FillFilterValues, GenFilter, GenModule, HepMCReadFromFile, PrintHijingPars, PrintMC, TestHepMC, and WriteHepMC.

Definition at line 17 of file GenBase.cxx.

17 {
18 ATH_CHECK( m_mcevents_const.initialize() );
20
21 return StatusCode::SUCCESS;
22}
#define ATH_CHECK
Evaluate an expression and check for errors.
std::string m_mcEventKey
StoreGate key for the MC event collection (defaults to GEN_EVENT).
Definition GenBase.h:110

◆ inputHandles()

virtual std::vector< Gaudi::DataHandle * > AthCommonDataStore< AthCommonMsg< Gaudi::Algorithm > >::inputHandles ( ) const
overridevirtualinherited

Return this algorithm's input handles.

We override this to include handle instances from key arrays if they have not yet been declared. See comments on updateVHKA.

◆ isClonable()

virtual bool AthCommonAlgorithm< Gaudi::Algorithm >::isClonable ( ) const
inlineoverridevirtualinherited

Specify if the algorithm is clonable.

Only relevant for non-reentrant algorithms. Actual number of clones needs to be set via the "Cardinality" property.

Reimplemented in AFP_DigiTop, AlgB, AlgT, BCM_Digitization, CscDigitBuilder, CscDigitToCscRDO, G4AtlasAlg, G4RunAlg, HGTD_Digitization, HiveAlgBase, InDet::GNNSeedingTrackMaker, InDet::SCT_Clusterization, InDet::SiSPGNNTrackMaker, InDet::SiSPSeededTrackFinder, InDet::SiTrackerSpacePointFinder, ISF::SimKernelMT, ITk::StripDigitization, ITkPixelCablingAlg, ITkStripCablingAlg, LArHitEMapMaker, LArTTL1Maker, LUCID_DigiTop, LVL1::L1TopoSimulation, MergeCalibHits, MergeGenericMuonSimHitColl, MergeHijingPars, MergeMcEventCollection, MergeTrackRecordCollection, MergeTruthJets, MergeTruthParticles, MuonDigitizer, PileUpMTAlg, PixelDigitization, RoIBResultToxAOD, SCT_ByteStreamErrorsTestAlg, SCT_CablingCondAlgFromCoraCool, SCT_CablingCondAlgFromText, SCT_ConditionsParameterTestAlg, SCT_ConditionsSummaryTestAlg, SCT_ConfigurationConditionsTestAlg, SCT_Digitization, SCT_FlaggedConditionTestAlg, SCT_LinkMaskingTestAlg, SCT_MajorityConditionsTestAlg, SCT_ModuleVetoTestAlg, SCT_MonitorConditionsTestAlg, SCT_PrepDataToxAOD, SCT_RawDataToxAOD, SCT_ReadCalibChipDataTestAlg, SCT_ReadCalibDataTestAlg, SCT_RODVetoTestAlg, SCT_SensorsTestAlg, SCT_SiliconConditionsTestAlg, SCT_StripVetoTestAlg, SCT_TdaqEnabledTestAlg, SCT_TestCablingAlg, SCTEventFlagWriter, SCTRawDataProvider, SCTSiLorentzAngleTestAlg, SCTSiPropertiesTestAlg, SGInputLoader, Simulation::BeamEffectsAlg, TileHitVecToCnt, TileMuonFitter, TilePulseForTileMuonReceiver, TileRawChannelMaker, TRTDigitization, and ZDC_DigiTop.

Definition at line 68 of file AthCommonAlgorithm.h.

68 {
69 return true;
70 }

◆ isNonTransportableInDecayChain()

bool FixHepMC::isNonTransportableInDecayChain ( const HepMC::ConstGenParticlePtr & p) const
private

Definition at line 337 of file FixHepMC.cxx.

337 {
338 auto storage = std::make_shared<std::set<int>>();
339 return !MC::isTransportable(p->pdg_id()) && fromDecay(p, storage);
340}
bool isTransportable(const T &p)

◆ isPID0()

bool FixHepMC::isPID0 ( const HepMC::ConstGenParticlePtr & p) const
private

Definition at line 316 of file FixHepMC.cxx.

316 {
317 return p->pdg_id() == 0;
318}

◆ isReEntrant()

virtual bool AthAlgorithm::isReEntrant ( ) const
inlinefinaloverrideprotectedvirtualinherited

Legacy algorithms are not thread-safe.

Definition at line 47 of file AthAlgorithm.h.

47{ return false; }

◆ isSimpleLoop()

bool FixHepMC::isSimpleLoop ( const HepMC::ConstGenParticlePtr & p) const
private

Definition at line 343 of file FixHepMC.cxx.

343 {
344 return (p->production_vertex() == p->end_vertex() && p->end_vertex() != nullptr);
345}

◆ msg()

MsgStream & AthCommonMsg< Gaudi::Algorithm >::msg ( ) const
inlineinherited

Definition at line 24 of file AthCommonMsg.h.

24 {
25 return this->msgStream();
26 }

◆ msgLvl()

bool AthCommonMsg< Gaudi::Algorithm >::msgLvl ( const MSG::Level lvl) const
inlineinherited

Definition at line 30 of file AthCommonMsg.h.

30 {
31 return this->msgLevel(lvl);
32 }

◆ outputHandles()

virtual std::vector< Gaudi::DataHandle * > AthCommonDataStore< AthCommonMsg< Gaudi::Algorithm > >::outputHandles ( ) const
overridevirtualinherited

Return this algorithm's output handles.

We override this to include handle instances from key arrays if they have not yet been declared. See comments on updateVHKA.

◆ renounce()

std::enable_if_t< std::is_void_v< std::result_of_t< decltype(&T::renounce)(T)> > &&!std::is_base_of_v< SG::VarHandleKeyArray, T > &&std::is_base_of_v< Gaudi::DataHandle, T >, void > AthCommonDataStore< AthCommonMsg< Gaudi::Algorithm > >::renounce ( T & h)
inlineprotectedinherited

Definition at line 380 of file AthCommonDataStore.h.

381 {
382 h.renounce();
384 }
std::enable_if_t< std::is_void_v< std::result_of_t< decltype(&T::renounce)(T)> > &&!std::is_base_of_v< SG::VarHandleKeyArray, T > &&std::is_base_of_v< Gaudi::DataHandle, T >, void > renounce(T &h)

◆ renounceArray()

void AthCommonDataStore< AthCommonMsg< Gaudi::Algorithm > >::renounceArray ( SG::VarHandleKeyArray & handlesArray)
inlineprotectedinherited

remove all handles from I/O resolution

Definition at line 364 of file AthCommonDataStore.h.

364 {
366 }

◆ setFilterPassed()

virtual void AthCommonAlgorithm< Gaudi::Algorithm >::setFilterPassed ( bool state,
const EventContext & ctx ) const
inlinevirtualinherited

Set filter decision:

Reimplemented in AthFilterAlgorithm.

Definition at line 99 of file AthCommonAlgorithm.h.

99 {
101 }
virtual void setFilterPassed(bool state, const EventContext &ctx) const
Set filter decision:

◆ sysExecute()

StatusCode AthCommonAlgorithm< Gaudi::Algorithm >::sysExecute ( const EventContext & ctx)
overridevirtualinherited

Execute an algorithm.

We override this in order to work around an issue with the Algorithm base class storing the event context in a member variable that can cause crashes in MT jobs.

Reimplemented in AthAnalysisAlgorithm.

Definition at line 80 of file AthCommonAlgorithm.cxx.

41{
42 return BaseAlg::sysExecute (ctx);
43}

◆ sysInitialize()

StatusCode AthCommonAlgorithm< Gaudi::Algorithm >::sysInitialize ( )
overridevirtualinherited

Override sysInitialize.

Override sysInitialize from the base class.

Loop through all output handles, and if they're WriteCondHandles, automatically register them and this Algorithm with the CondSvc

Scan through all outputHandles, and if they're WriteCondHandles, register them with the CondSvc

Reimplemented from AthCommonDataStore< AthCommonMsg< Gaudi::Algorithm > >.

Reimplemented in AthAnalysisAlgorithm, AthFilterAlgorithm, AthHistogramAlgorithm, HypoBase, InputMakerBase, and PyAthena::Alg.

Definition at line 60 of file AthCommonAlgorithm.cxx.

71 {
73
74 if (sc.isFailure()) {
75 return sc;
76 }
77
78 ServiceHandle<ICondSvc> cs("CondSvc",name());
79 for (auto h : outputHandles()) {
80 if (h->isCondition() && h->mode() == Gaudi::DataHandle::Writer) {
81 // do this inside the loop so we don't create the CondSvc until needed
82 if ( cs.retrieve().isFailure() ) {
83 ATH_MSG_WARNING("no CondSvc found: won't autoreg WriteCondHandles");
85 }
86 if (cs->regHandle(this,*h).isFailure()) {
88 ATH_MSG_ERROR("unable to register WriteCondHandle " << h->fullKey()
89 << " with CondSvc");
90 }
91 }
92 }
93 return sc;
94}
virtual StatusCode sysInitialize() override
virtual std::vector< Gaudi::DataHandle * > outputHandles() const override

◆ sysStart()

virtual StatusCode AthCommonDataStore< AthCommonMsg< Gaudi::Algorithm > >::sysStart ( )
overridevirtualinherited

Handle START transition.

We override this in order to make sure that conditions handle keys can cache a pointer to the conditions container.

◆ updateVHKA()

void AthCommonDataStore< AthCommonMsg< Gaudi::Algorithm > >::updateVHKA ( Gaudi::Details::PropertyBase & )
inlineinherited

Definition at line 308 of file AthCommonDataStore.h.

308 {
309 // debug() << "updateVHKA for property " << p.name() << " " << p.toString()
310 // << " size: " << m_vhka.size() << endmsg;
311 for (auto &a : m_vhka) {
313 for (auto k : keys) {
314 k->setOwner(this);
315 }
316 }
317 }

Member Data Documentation

◆ m_cleanDecays

bool FixHepMC::m_cleanDecays
private

Definition at line 53 of file FixHepMC.h.

◆ m_decayCleaned

long FixHepMC::m_decayCleaned
private

Definition at line 66 of file FixHepMC.h.

◆ m_detStore

StoreGateSvc_t AthCommonDataStore< AthCommonMsg< Gaudi::Algorithm > >::m_detStore
privateinherited

Pointer to StoreGate (detector store by default).

Definition at line 393 of file AthCommonDataStore.h.

◆ m_evtStore

StoreGateSvc_t AthCommonDataStore< AthCommonMsg< Gaudi::Algorithm > >::m_evtStore
privateinherited

Pointer to StoreGate (event store by default).

Definition at line 390 of file AthCommonDataStore.h.

◆ m_extendedExtraObjects

DataObjIDColl AthCommonAlgorithm< Gaudi::Algorithm >::m_extendedExtraObjects
privateinherited

Extra output dependency collection, extended by AthAlgorithmDHUpdate to add symlinks.

Empty if no symlinks were found.

Definition at line 108 of file AthCommonAlgorithm.h.

◆ m_forced_length

std::string FixHepMC::m_forced_length {""}
private

Definition at line 57 of file FixHepMC.h.

57{""}; // Force length unit for the event

◆ m_forced_momentum

std::string FixHepMC::m_forced_momentum {""}
private

Definition at line 56 of file FixHepMC.h.

56{""}; // Force momentum unit for the event

◆ m_ignoreSemiDisconnected

bool FixHepMC::m_ignoreSemiDisconnected
private

Definition at line 55 of file FixHepMC.h.

◆ m_killLoops

bool FixHepMC::m_killLoops
private

Definition at line 51 of file FixHepMC.h.

◆ m_killPDG0

bool FixHepMC::m_killPDG0
private

Definition at line 52 of file FixHepMC.h.

◆ m_looper

member to detect loops

Definition at line 76 of file FixHepMC.h.

◆ m_loopKilled

long FixHepMC::m_loopKilled
private

Definition at line 64 of file FixHepMC.h.

◆ m_mcEventKey

std::string GenBase::m_mcEventKey {}
protectedinherited

StoreGate key for the MC event collection (defaults to GEN_EVENT).

Definition at line 110 of file GenBase.h.

110{};

◆ m_mcevents_const

SG::ReadHandleKey<McEventCollection> GenBase::m_mcevents_const { this, "McEventKey", "GEN_EVENT", "StoreGate key of the MC event collection" }
privateinherited

Const handle to the MC event collection.

Definition at line 119 of file GenBase.h.

119{ this, "McEventKey", "GEN_EVENT", "StoreGate key of the MC event collection" };

◆ m_mkMcEvent

BooleanProperty GenBase::m_mkMcEvent {this, "MakeMcEvent", false, "Create a new MC event collection if it doesn't exist"}
protectedinherited

Flag to determine if a new MC event collection should be made if it doesn't exist.

Definition at line 112 of file GenBase.h.

112{this, "MakeMcEvent", false, "Create a new MC event collection if it doesn't exist"};

◆ m_pdg0Killed

long FixHepMC::m_pdg0Killed
private

Definition at line 65 of file FixHepMC.h.

◆ m_pidmap

std::map<int,int> FixHepMC::m_pidmap
private

map of pids to change.

Definition at line 72 of file FixHepMC.h.

◆ m_purgeUnstableWithoutEndVtx

bool FixHepMC::m_purgeUnstableWithoutEndVtx
private

Definition at line 54 of file FixHepMC.h.

◆ m_replacedpid_counts

std::map<int,int> FixHepMC::m_replacedpid_counts
private

map of counters of replacements.

Definition at line 73 of file FixHepMC.h.

◆ m_replacedPIDs

long FixHepMC::m_replacedPIDs
private

Definition at line 69 of file FixHepMC.h.

◆ m_setHasCycles

bool FixHepMC::m_setHasCycles
private

Definition at line 59 of file FixHepMC.h.

◆ m_totalSeen

long FixHepMC::m_totalSeen
private

Definition at line 68 of file FixHepMC.h.

◆ m_unitsFix

bool FixHepMC::m_unitsFix
private

Definition at line 58 of file FixHepMC.h.

◆ m_unstablePurged

long FixHepMC::m_unstablePurged
private

Definition at line 67 of file FixHepMC.h.

◆ m_varHandleArraysDeclared

bool AthCommonDataStore< AthCommonMsg< Gaudi::Algorithm > >::m_varHandleArraysDeclared
privateinherited

Definition at line 399 of file AthCommonDataStore.h.

◆ m_vhka

std::vector<SG::VarHandleKeyArray*> AthCommonDataStore< AthCommonMsg< Gaudi::Algorithm > >::m_vhka
privateinherited

Definition at line 398 of file AthCommonDataStore.h.


The documentation for this class was generated from the following files: