ATLAS Offline Software
Loading...
Searching...
No Matches
TruthParticleID/McParticleTools/src/TruthIsolationTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3*/
4
5
6// STL includes
7#include <cmath>
8#include <stdexcept>
9#include <sstream>
10#include <fstream>
11
12// FrameWork includes
13#include "GaudiKernel/IPartPropSvc.h"
14
15// CLHEP/HepMC includes
16#include "AtlasHepMC/GenEvent.h"
21#include "CLHEP/Units/SystemOfUnits.h"
22#include "CLHEP/Vector/LorentzVector.h"
23
24// McParticle includes
26
27// McParticleTools includes
28#include "TruthIsolationTool.h"
29
30using CLHEP::GeV;
31
32using CLHEP::HepLorentzVector;
33namespace {
34 inline
35 HepLorentzVector svToLv( const HepMC::FourVector& v )
36 { return { v.x(), v.y(), v.z(), v.t() }; }
37}
38
39using GenParticles_t = std::list<HepMC::ConstGenParticlePtr>;
40
42 const std::string& name,
43 const IInterface* parent ) :
44 AthAlgTool ( type, name, parent ),
45 m_pdt ( nullptr )
46{
47 //
48 // Property declaration
49 //
50
51 declareProperty( "ptGammaMin",
52 m_ptGamMin = 0.5*GeV,
53 "Minimum transverse energy of gammas to be taken into "
54 "account into the isolation computation." );
55
56 declareProperty( "TruthEtIsolationsPrefix",
57 m_prefix = "TruthEtIsol",
58 "Prefix for the TruthEtIsolations container. This is the "
59 "string which will be prepended to the key of the "
60 "McEventCollection to build the (StoreGate) output "
61 "location for the TruthEtIsolations.\nie: \"GEN_EVENT\" "
62 "--> \"<prefix>_GEN_EVENT\"" );
63 m_prefix.declareUpdateHandler
65 this );
66
67 declareProperty( "McEventsOutput",
68 m_mcEventsOutputName = "GEN_AOD",
69 "Name of the McEventCollection we should attach "
70 "isolations to" );
71 m_mcEventsOutputName.declareUpdateHandler
73 this );
74
75 declareInterface<ITruthIsolationTool>(this);
76}
77
79= default;
80
82{
83 // retrieve StoreGate
84 if ( !evtStore().retrieve().isSuccess() ) {
85 ATH_MSG_ERROR("Could not get a handle on StoreGateSvc !!");
86 return StatusCode::FAILURE;
87 }
88
89 ATH_MSG_INFO(" McEventsOutput: [" << m_mcEventsOutputName.value() << "]");
90
91 // Get the Particle Properties Service
92 ServiceHandle<IPartPropSvc> partPropSvc("PartPropSvc", name());
93 if ( !partPropSvc.retrieve().isSuccess() ) {
94 ATH_MSG_ERROR(" Could not initialize Particle Properties Service");
95 return StatusCode::FAILURE;
96 }
97
98 m_pdt = partPropSvc->PDT();
99 if ( nullptr == m_pdt ) {
100 ATH_MSG_ERROR("Could not retrieve HepPDT::ParticleDataTable from "\
101 "ParticleProperties Service !!");
102 return StatusCode::FAILURE;
103 }
104
105 return StatusCode::SUCCESS;
106}
107
108const std::string&
109TruthIsolationTool::etIsolationsName( const std::string& mcEvtName ) const
110{
111 static const std::string s_emptyString = "";
112 const EtIsolMap_t::const_iterator i = m_etIsolMap.find(mcEvtName);
113 if ( i != m_etIsolMap.end() ) {
114 return i->second;
115 }
116
117 return s_emptyString;
118}
119
120StatusCode
121TruthIsolationTool::buildEtIsolations( const std::string& mcEvtName,
123{
124 // retrieve collection
125 const McEventCollection* mcEvts = nullptr;
126 if ( !evtStore()->retrieve( mcEvts, mcEvtName ).isSuccess() ) {
127 ATH_MSG_WARNING("Could not retrieve a McEventCollection at ["
128 << mcEvtName << "] !!" << endmsg
129 << "No Et-isolations will be computed !");
130 return StatusCode::RECOVERABLE;
131 }
132
133 // the name of the output (filtered) McEventCollection we want to attach
134 // the Et-isolations to
135 const std::string& outMcEvtName = m_mcEventsOutputName.value();
136
137 // create the container of TruthEtIsolations
138 std::ostringstream truthEtIsolName;
139 truthEtIsolName << m_prefix.value()
141 ? "Charged"
142 : "")
143 << "_" << outMcEvtName;
144
146 if ( !evtStore()->record( etIsolations,
147 truthEtIsolName.str() ).isSuccess() ) {
148 delete etIsolations;
149 etIsolations = nullptr;
150 ATH_MSG_WARNING("Could not record a TruthEtIsolations container at ["
151 << truthEtIsolName.str() << "] !!");
152 return StatusCode::RECOVERABLE;
153 }
154 if ( !evtStore()->setConst( etIsolations ).isSuccess() ) {
155 ATH_MSG_WARNING("Could not setConst the TruthEtIsolations container at ["
156 << truthEtIsolName.str() << "] !!");
157 }
158
159 // update our registry of EtIsol StoreGate locations
160 m_etIsolMap[outMcEvtName] = truthEtIsolName.str();
161
162 bool allGood = true;
163 for ( std::size_t iMc = 0, iMax = mcEvts->size(); iMc != iMax; ++iMc ) {
164 TruthEtIsolations * etIsols = new TruthEtIsolations( outMcEvtName, iMc );
165 etIsolations->push_back( etIsols );
166 if ( !buildEtIsolations( mcEvtName, (*mcEvts)[iMc], iMc,
167 *etIsols, partSel ).isSuccess() ) {
168 msg(MSG::WARNING)
169 << "Problem encountered while computing Et-isolations for idx=["
170 << iMc << "] of McEventCollection [" << mcEvtName << "] !!"
171 << endmsg;
172 allGood = false;
173 }
174 }
175 return allGood ? StatusCode::SUCCESS : StatusCode::RECOVERABLE;
176}
177
178StatusCode
179TruthIsolationTool::buildEtIsolations( const std::string& mcEvtName,
180 const HepMC::GenEvent* genEvt,
181 const std::size_t genIdx,
182 TruthEtIsolations& etIsols,
184{
185 if ( nullptr == genEvt ) {
186 msg(MSG::WARNING)
187 << "Null pointer to GenEvent (idx = [" << genIdx << "] from "
188 << "McEventCollection [" << mcEvtName << "]) !!"
189 << endmsg;
190 return StatusCode::RECOVERABLE;
191 }
192
193 // create a reduced list of particles
194 GenParticles_t particles;
195 for ( const auto& i: *genEvt) {
196 if ( MC::isGenStable(i) && MC::isSimInteracting(i) ) {
197 particles.push_back( i );
198 }
199 }
200
201 for ( const auto& i: *genEvt) {
202 const HepMC::FourVector hlv = i->momentum();
203 const int ida = std::abs(i->pdg_id());
204 const double pt = hlv.perp();
205
206 // Compute isolation only for photon, electron, muon or tau.
207 // Not for documentation particle
208 const bool doComputeIso = ( ( ida == 22 && pt > m_ptGamMin ) ||
209 ida == 11 || ida == 13 || ida == 15 ) &&
211 if ( doComputeIso ) {
212 computeIso( particles, i, etIsols, partSel );
213 }
214 }
215
216 return StatusCode::SUCCESS;
217}
218
219void
221 const HepMC::ConstGenParticlePtr& part,
222 TruthEtIsolations& etIsolations,
224{
225 const HepLorentzVector hlv = ::svToLv(part->momentum());
226 const int ida = std::abs(part->pdg_id());
227
228 McAod::EtIsolations etIsol = { {0.*GeV, 0.*GeV, 0.*GeV, 0.*GeV,
229 0.*GeV, 0.*GeV, 0.*GeV, 0.*GeV} };
230 McAod::EtIsolations pxi = etIsol;
231 McAod::EtIsolations pyi = etIsol;
232
233 int barcodepart = HepMC::barcode(part);
234 for (const auto & particle : particles) {
235 if ( HepMC::barcode(particle) == barcodepart ) {
236 continue;
237 }
238 if( partSel == ITruthIsolationTool::UseChargedOnly ) {
239 double particleCharge = MC::charge(particle->pdg_id());
240 if( std::abs(particleCharge)<1.e-2 )
241 continue;
242 }
243 const HepLorentzVector itrHlv = ::svToLv(particle->momentum());
244 const double r = hlv.deltaR(itrHlv);
245 for ( std::size_t iCone = 0;
247 ++iCone ) {
249 pxi[iCone] += itrHlv.px();
250 pyi[iCone] += itrHlv.py();
251 }
252 }
253 }
254
255 //
256 // Correction for tau (as was done in the old tool for the time being)
257 double pxv = 0.*GeV;
258 double pyv = 0.*GeV;
259 auto decVtx = part->end_vertex();
260 if (ida == 15 && decVtx) {
261 for (const auto& child: *decVtx) {
262 if ( MC::isSimInteracting(child) ) {
263 if( partSel == ITruthIsolationTool::UseChargedOnly ) {
264 double particleCharge = MC::charge(child->pdg_id());
265 if( std::abs(particleCharge)<1.e-2 )
266 continue;
267 }
268 const HepMC::FourVector childHlv = child->momentum();
269 pxv += childHlv.px();
270 pyv += childHlv.py();
271 }
272 }
273 }
274
275 for ( std::size_t i = 0;
276 i != static_cast<std::size_t>(TruthParticleParameters::NbrOfCones);
277 ++i ) {
278 pxi[i] -= pxv;
279 pyi[i] -= pyv;
280 etIsol[i] = std::sqrt(pxi[i]*pxi[i]+pyi[i]*pyi[i]);
281 }
282
283 etIsolations.setEtIsol( part, etIsol );
284}
285
286void
287TruthIsolationTool::setupTruthEtIsolationsPrefix( Gaudi::Details::PropertyBase& /*truthEtIsolationsPrefix*/ )
288{
289 // no-op for now
290}
291
292void
293TruthIsolationTool::setupMcEventsOutput( Gaudi::Details::PropertyBase& /*mcEventsOutputName*/ )
294{
295 // no-op for now
296}
297
298StatusCode
299TruthIsolationTool::registerAlias( const std::string& originalMcEvtColl,
300 const std::string& aliasMcEvtColl )
301{
302 m_etIsolMap[aliasMcEvtColl] = m_etIsolMap[originalMcEvtColl];
303 return StatusCode::SUCCESS;
304}
#define endmsg
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
ATLAS-specific HepMC functions.
std::list< HepMC::ConstGenParticlePtr > GenParticles_t
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
ServiceHandle< StoreGateSvc > & evtStore()
MsgStream & msg() const
value_type push_back(value_type pElem)
Add an element to the end of the collection.
size_type size() const noexcept
Returns the number of elements in the collection.
ParticleSelect
enumerator to decide which strategy to apply in the selection of particles during the Et-isolation co...
This defines the McEventCollection, which is really just an ObjectVector of McEvent objectsFile: Gene...
container which holds isolation informations for a given HepMC::GenParticle (labelled by barcode) for...
void setEtIsol(const HepMC::ConstGenParticlePtr &genParticle, const TruthParticleParameters::ConeSize coneIdx, const double etIsol)
Set the transverse energy isolation of a HepMC::GenParticle for a given Cone size.
const HepPDT::ParticleDataTable * m_pdt
Particle Property service.
void setupMcEventsOutput(Gaudi::Details::PropertyBase &mcEventsOutputName)
Callback method to ensure consistency of output McEventCollection key.
StringProperty m_mcEventsOutputName
Name of the McEventCollection we should attach isolations to.
EtIsolMap_t m_etIsolMap
A map of McEventCollection StoreGate locations to the according StoreGate location of TruthEtIsolatio...
StatusCode registerAlias(const std::string &originalMcEvtColl, const std::string &aliasMcEvtColl)
Make an alias in the map of isolation energies.
StatusCode buildEtIsolations(const std::string &mcEvtName, ITruthIsolationTool::ParticleSelect sel)
Computes the isolation energies for each of the HepMC::GenEvent contained into the McEventCollection.
void computeIso(const std::list< HepMC::ConstGenParticlePtr > &parts, const HepMC::ConstGenParticlePtr &p, TruthEtIsolations &etIsolations, ITruthIsolationTool::ParticleSelect sel)
Computes and stores the list of transverse isolation energies for various cone sizes into the TruthEt...
void setupTruthEtIsolationsPrefix(Gaudi::Details::PropertyBase &truthEtIsolationsPrefix)
Callback method to ensure consistency of the TruthEtIsolations prefix key.
TruthIsolationTool(const std::string &type, const std::string &name, const IInterface *parent)
const std::string & etIsolationsName(const std::string &mcEvtName) const
Return the name of the TruthEtIsolations container (ie: its StoreGate location) given the StoreGate l...
StringProperty m_prefix
Prefix for the TruthEtIsolations container.
DoubleProperty m_ptGamMin
Minimum transverse energy of gammas to be taken into account into the isolation computation.
virtual ~TruthIsolationTool()
int r
Definition globals.cxx:22
int barcode(const T *p)
Definition Barcode.h:16
const GenParticle * ConstGenParticlePtr
Definition GenParticle.h:38
bool isSimInteracting(const T &p)
Identify if the particle could interact with the detector during the simulation, e....
double charge(const T &p)
bool isGenStable(const T &p)
Determine if the particle is stable at the generator (not det-sim) level,.
bool isPhysical(const T &p)
Identify if the particle is physical, i.e. is stable or decayed.
std::array< double, TruthParticleParameters::NbrOfCones > EtIsolations
An array of doubles of fixed size to modelize the Et isolations for different values of isolation rad...
double coneCut(const TruthParticleParameters::ConeSize idx)
The actual definition of delta R cuts for each cone.
ConeSize
Enum for Cone size indexes (for isolation)