ATLAS Offline Software
Loading...
Searching...
No Matches
TruthParticleCnvTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4
6// TruthParticleCnvTool.cxx
7// Implementation file for class TruthParticleCnvTool
8// Author: S.Binet<binet@cern.ch>
9// P.A Delsart <delsart in2p3 dot fr> (pile-up compatibility)
11
12// STL includes
13#include <sstream>
14
15// FrameWork includes
16#include "GaudiKernel/IPartPropSvc.h"
17#include "GaudiKernel/ThreadLocalContext.h"
18
19// CLHEP/HepMC includes
20#include "AtlasHepMC/GenEvent.h"
25#include "HepPDT/ParticleData.hh"
26
27// McParticleKernel includes
29
30// McParticleEvent includes
32
33// McParticleTools includes
35
36// GeneratorObjects includes
38
40
41
45
49 const std::string& name,
50 const IInterface* parent ) :
51 base_class( type, name, parent ),
54 m_pdt ( nullptr ),
56{
57 //
58 // Property declaration
59 //
60
61 declareProperty( "DataType",
63 "Type of data we are dealing with (Full/Fast/Truth...)" );
64
65 declareProperty( "TruthIsolationTool",
66 m_isolationTool = IsolTool_t( "TruthIsolationTool" ),
67 "Pointer to the TruthIsolationTool to be able to compute "
68 "transverse energy isolations for various isolation cones cuts. "
69 "See McParticleEvent/TruthParticleParameters.h for cone cuts." );
70
71
72 declareProperty( "DoEtIsolations",
73 m_doEtIsolation = false,
74 "Switch to compute or not the Et-isolations for TruthParticle "
75 "(and their underlying @c HepMC::GenParticle).\n"
76 "Default is to not compute these Et-isolations (and save CPU)." );
77
79
80 declareProperty( "SelectSignalType",
82 "Switch to select different type of signal\n"
83 " hard scatter 0\n"
84 " hard scatter plus minbias 1\n"
85 " only minbias -1\n"
86 "Default is hard scatter only." );
87
88 declareInterface<ITruthParticleCnvTool>(this);
89}
90
97
101{
102 ATH_MSG_INFO("Initializing " << name() << "...");
103
104 // Get the Particle Properties Service
105 ServiceHandle<IPartPropSvc> partPropSvc("PartPropSvc", name());
106 if ( !partPropSvc.retrieve().isSuccess() ) {
107 ATH_MSG_ERROR(" Could not initialize Particle Properties Service");
108 return StatusCode::FAILURE;
109 }
110
111 m_pdt = partPropSvc->PDT();
112 if ( nullptr == m_pdt ) {
113 ATH_MSG_ERROR("Could not retrieve HepPDT::ParticleDataTable from "\
114 "ParticleProperties Service !!");
115 return StatusCode::FAILURE;
116 }
117
118 // retrieve the TruthIsolation tool only if asked for.
119 if ( m_doEtIsolation.value() ) {
120 ATH_CHECK(m_isolationTool.retrieve());
121 }
122 else {
123 m_isolationTool.disable();
124 }
125
126 //initialize DataHandleKeys
129
130 // for compatibility with earlier version we accept <0 values :
133
134
136 (" DoEtIsolations: [" << std::boolalpha
137 << m_doEtIsolation.value() << "]" << endmsg
138 << " McEvents: [" << m_mcEventsReadHandleKey.key() << "]" << endmsg
139 << " TruthParticlesOutput: [" << m_mcPartsOutputWriteHandleKey.key() << "]"
140 << endmsg
141 << " SelectSignalType: [" << m_selectSignalType << "]");
142
143 return StatusCode::SUCCESS;
144}
145
147{
148 return execute (Gaudi::Hive::currentContext());
149}
150
151
152StatusCode TruthParticleCnvTool::execute (const EventContext& ctx) const
153{
154 ATH_MSG_DEBUG("Executing " << name() << "...");
155
156 //Setup WriteHandle, and record new TruthParticleContainer
158 ATH_CHECK(mcPartsOutputWriteHandle.record(std::make_unique<TruthParticleContainer>()));
159
160 if (!mcPartsOutputWriteHandle.isValid()){
161 ATH_MSG_ERROR("Invalid WriteHandle for TruthParticleContainer with key: " << m_mcPartsOutputWriteHandleKey.key());
162 return StatusCode::FAILURE;
163 }
164
165 //Setup ReadHandle for input McEventCollection
167
168 if (!mcEventsReadHandle.isValid()){
169 ATH_MSG_WARNING("Invalid ReadHandle for McEventCollection with key ["
170 << m_mcEventsReadHandleKey.key() << "] !!"
171 << endmsg
172 << "TruthParticleContainer [" << m_mcPartsOutputWriteHandleKey.key()
173 << "] will be EMPTY !!");
174 return StatusCode::RECOVERABLE;
175 }
176
177 ATH_MSG_DEBUG(" Found McEventCollection of size = "<< mcEventsReadHandle->size() );
178 // do the actual convertion (it is merely an interface adaptation now...)
179 // selection for particles from minbias copied from the JetsFromTruthTool
180
181 std::size_t genEventIndex = 0;
182 const ITruthParticleVisitor* dummyVisitor = nullptr;
183 bool all_good = true;
184
185 McEventCollection::const_iterator fEvt = mcEventsReadHandle->begin();
186 McEventCollection::const_iterator lEvt = mcEventsReadHandle->end();
188
189 ATH_MSG_DEBUG(" Found McEventCollection iterators : "<< (fEvt-mcEventsReadHandle->begin()) << " to "<< (lEvt-mcEventsReadHandle->begin()) );
190
191 for(McEventCollection::const_iterator it=fEvt ; it != lEvt; ++it){
192 const HepMC::GenEvent* evt = *it;
193 // there are holes in a McEventCollection when pile-up is enabled
194 // so deal with it
195 if (nullptr == evt) {
196 continue;
197 }
198 genEventIndex = (it - mcEventsReadHandle->begin());
199 ATH_MSG_DEBUG(" adding event id="<< HepMC::signal_process_id(evt)<<" genEventIndex="<< genEventIndex );
200
201 if( HepMC::signal_process_id(evt) == 0 ) continue;
202 if (!this->convert( mcEventsReadHandle.ptr(), genEventIndex, mcPartsOutputWriteHandle.ptr(), dummyVisitor ).isSuccess()) {
203 ATH_MSG_DEBUG("Failed to convert an event...");
204 all_good = false;
205 }
206 }
207
208 // VERY IMPORTANT ! Reset the index to the first GenEvent included
209 // in this TruthParticleContainer. This will be used when read back from disk.
210 mcPartsOutputWriteHandle->setGenEvent( mcEventsReadHandle.ptr(), (fEvt - mcEventsReadHandle->begin() ) );
211
212
213 return all_good
214 ? StatusCode::SUCCESS
215 : StatusCode::RECOVERABLE;
216}
217
218
222
223StatusCode
225 const unsigned int genEventIndex,
227 const ITruthParticleVisitor* visitor ) const
228{
229 ATH_MSG_DEBUG("Converting McEventCollection to TruthParticleContainer");
230
231 if ( nullptr == m_pdt ) {
232 ATH_MSG_ERROR("Could not convert McEventCollection into "\
233 "TruthParticleContainer if NO ParticleDataTable is "\
234 "available !!");
235 return StatusCode::FAILURE;
236 }
237
238 if ( nullptr == mcCollection ) {
239 ATH_MSG_WARNING("Null pointer to McEventCollection !");
240 return StatusCode::RECOVERABLE;
241 }
242
243 if ( mcCollection->size() <= genEventIndex ) {
244 ATH_MSG_WARNING("McEventCollection size: " << mcCollection->size()
245 << endmsg
246 << "Requested element nbr : " << genEventIndex << " !!");
247 return StatusCode::RECOVERABLE;
248 }
249
251
253 ATH_MSG_DEBUG("Retrieve the GenEvent from given McEventCollection");
254 const HepMC::GenEvent * evt = (*mcCollection)[genEventIndex];
255 container->setGenEvent( mcCollection, genEventIndex, sg );
256
257 // reserve enough space for the container so we don't have to relocate it
258 container->reserve( container->size() + evt->particles_size() );
259
261 TruthParticleContainer::Map_t bcToMcPart = container->m_particles;
262
263
264#ifdef HEPMC3
265 // Process particles in barcode order.
266 auto bcmapatt = evt->attribute<HepMC::GenEventBarcodes>("barcodes");
267 if (!bcmapatt) ATH_MSG_ERROR("TruthParticleCnvTool.cxx: Event does not contain barcodes attribute");
268 std::map<int, HepMC3::ConstGenParticlePtr> bcmap = bcmapatt->barcode_to_particle_map();
269 for (const auto &[bc,hepMcPart]: bcmap) {
270#else
271 for (auto hepMcPart: *evt) {
272 int bc = HepMC::barcode(hepMcPart);
273#endif
274
275 TruthParticle * mcPart = new TruthParticle( hepMcPart, container );
276 container->push_back( mcPart );
277
278 if ( visitor ) {
279 visitor->visit( mcPart );
280 }
281
282 mcPart->setCharge( MC::charge( int(mcPart->pdgId())) );
283 mcPart->setGenEventIndex( genEventIndex);
284
285 if ( hepMcPart != mcPart->genParticle() ) {
286 ATH_MSG_ERROR("TruthParticle is not wrapping the GenParticle : "
287 << hepMcPart << " !!");
288 }
289 HepMcParticleLink mcLink( bc, genEventIndex, HepMcParticleLink::IS_POSITION, HepMcParticleLink::IS_BARCODE, sg ); // FIXME barcode-based
290 bcToMcPart[ mcLink.compress() ] = mcPart;
291
292 }//> end loop over particles
293
294 // at this point the whole GenEvent has been proxied.
295 // so we can setup its VectorMap
296 container->setParticles( bcToMcPart );
297
298 // connect the TruthParticleContainer to the container of TruthEtIsolations
299 // if it exists and if we are asked for
300 if ( m_doEtIsolation.value() ) {
301 const std::string& etIsolName
302 = m_isolationTool->etIsolationsName( container->genEventName() );
303 if ( etIsolName.empty() ) {
304 ATH_MSG_WARNING("Could not retrieve the name of the "
305 "TruthEtIsolations container (requested: ["
306 << container->genEventName() << "])");
307 return StatusCode::RECOVERABLE;
308 }
309
310 const TruthEtIsolationsContainer* etIsols = nullptr;
311 if ( !evtStore()->retrieve( etIsols, etIsolName ).isSuccess() ) {
312 ATH_MSG_WARNING("Could not retrieve the TruthEtIsolations container at ["
313 << etIsolName << "] !!");
314 return StatusCode::RECOVERABLE;
315 }
316
317 // index of HepMC::GenEvent within the McEventCollection is the same
318 // than the one of the TruthEtIsolations within the TruthEtIsolationsCont.
319 container->setEtIsolations( etIsols, genEventIndex );
320 }
321
322 return StatusCode::SUCCESS;
323}
#define True
#define endmsg
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
ATLAS-specific HepMC functions.
Hold a pointer to the current event store.
DataModel_detail::const_iterator< DataVector > const_iterator
Definition DataVector.h:838
size_type size() const noexcept
Returns the number of elements in the collection.
virtual void visit(TruthParticle *truthParticle) const =0
The method to visit a TruthParticle to apply further modifications to the instance at hand.
This defines the McEventCollection, which is really just an ObjectVector of McEvent objectsFile: Gene...
virtual int pdgId() const
Return enum indicating particle id the enum file is available in Event/EventKernel/PdtPdg....
PileuType_t
define some Pile-up classification Important : this classification is copied in McParticleAlgs/python...
static void findEventIterators(PileuType_t putype, McEventCollection::const_iterator &fEvt, McEventCollection::const_iterator &lEvt)
Find interval [fEvt,lEvt] containing all GenEvents of type putype from the McEventCollection.
static IProxyDict * store()
Fetch the current store.
const_pointer_type ptr()
Dereference the pointer.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
pointer_type ptr()
Dereference the pointer.
int m_selectSignalTypeProp
Type of truth particle we want to create (property to be set by jobO)
virtual ~TruthParticleCnvTool()
Destructor:
TruthParticleCnvTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
SG::WriteHandleKey< TruthParticleContainer > m_mcPartsOutputWriteHandleKey
Output TruthParticle WriteHandleKey (built from the McEventCollection)
ToolHandle< ITruthIsolationTool > IsolTool_t
virtual StatusCode execute() const override
ParticleDataType::DataType m_dataType
Type of data we are dealing with (Full/Fast/Truth/...)
IsolTool_t m_isolationTool
Pointer to the ITruthIsolationTool to be able to retrieve the previously computed transverse energy i...
void setDataType(const int type)
Inline methods:
virtual StatusCode initialize() override
Athena Algorithm's Hooks.
const HepPDT::ParticleDataTable * m_pdt
Particle Property service.
PileUpClassification::PileuType_t m_selectSignalType
Type of truth particle we want to create.
StatusCode convert(const McEventCollection *mcEvts, const unsigned int genEvtIndex, TruthParticleContainer *mcParts, const ITruthParticleVisitor *visitor) const override
Converts a McEventCollection into an TruthParticleContainer (ie: converts it into an AOD compliant co...
BooleanProperty m_doEtIsolation
Switch to compute or not the Et-isolations for TruthParticle (and their underlying HepMC::GenParticle...
SG::ReadHandleKey< McEventCollection > m_mcEventsReadHandleKey
ReadHandleKey for the McEventCollection the TruthParticles will be made from.
std::unordered_map< long, const TruthParticle * > Map_t
barcode to TruthParticle dictionary
HepMC::ConstGenParticlePtr genParticle() const
Retrieve the GenParticle this TruthParticle has been made from (if any)
void setCharge(const ChargeType charge)
Set the charge of this TruthParticle.
int signal_process_id(const GenEvent &e)
Definition GenEvent.h:636
int barcode(const T *p)
Definition Barcode.h:16
double charge(const T &p)
Information about type of data used to fill particle.