ATLAS Offline Software
Loading...
Searching...
No Matches
TrkPriVxPurityTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3*/
4
6
7// forward includes
10
11// normal includes
16#include "AtlasHepMC/GenEvent.h"
18
20
24
25#include <map>
26#include <vector>
27
28namespace Trk {
29
31 return StatusCode::SUCCESS;
32 }//end of initialize method
33
35 msg(MSG::INFO) << "Finalize successful" << endmsg;
36 return StatusCode::SUCCESS;
37 }
38
39 TrkPriVxPurityTool::TrkPriVxPurityTool ( const std::string& t, const std::string& n, const IInterface* p ) : AthAlgTool ( t,n,p ) {
40//tolerances around the signal pp interaction to create a primary vertex candidate:
41//defaul values are: sigma z = 1um (0.001 mm), sigma r = 1um (0.001 mm)
42 declareProperty ( "VertexRTolerance", m_r_tol = 0.001 );
43
44 declareProperty ( "VertexZTolerance", m_z_tol = 0.001 );
45
46//name of the rec <-> sim truth map to be read from the storegate
47//default one is the output of the InDetTrackTruthMaker (see InDetTruthAlgs in InnerDetector packasge)
48 declareProperty ( "SimTrackMapName", m_trackParticleTruthCollName = "TrackParticleTruthCollection" );
49
50//name of the Mc event collection. Required to get the signal event.
51 declareProperty ( "MonteCarloCollection", m_mc_collection_name = "TruthEvent" );
52
53// declaring the interface fo the tool itself
54 declareInterface<TrkPriVxPurityTool> ( this );
55
56 }//end of constructor
57
59 = default;
60
61//analysis method
63//protection and related
64 if ( vertex != nullptr ) {
65 const std::vector<Trk::VxTrackAtVertex *> * tracks = vertex->vxTrackAtVertex();
66 if ( tracks !=nullptr ) {
67
68// first getting the Mc Event collection
69 const McEventCollection * mcCollection ( nullptr );
70 StatusCode sc = evtStore()->retrieve ( mcCollection, m_mc_collection_name );
71 if ( sc.isFailure() ) {
72 if (msgLvl(MSG::DEBUG)) {
73 msg() << "Unable to retrieve MC collection: " << m_mc_collection_name << endmsg;
74 msg() << "Zero pointer returned." << endmsg;
75 }
76 return nullptr;
77 }
78
79//getting the signal event itself
80 McEventCollection::const_iterator it = mcCollection->begin();
81 const HepMC::GenEvent* genEvent= ( *it );
82
83 if( genEvent->vertices_empty() ) {
84 ATH_MSG_DEBUG( "No vertices found in first GenEvent" );
85 return nullptr;
86 }
87#ifdef HEPMC3
88 auto pv = genEvent->vertices()[0];
89#else
90 auto pv = *(genEvent->vertices_begin());
91#endif
92
93//analysing the MC event to create PV candidate
94//first finding the vertex of primary pp interaction
95
96//and storing its position
97 const auto& pv_pos = pv ->position();
98 double pv_r = pv_pos.perp();
99 double pv_z = pv_pos.z();
100
101// storing all the ids of vertices reasonably close to the primary one.
102// here the region of interest is selected.
103 std::map<int,HepMC::ConstGenVertexPtr> vertex_ids;
104#ifdef HEPMC3
105 for (const auto& vtx: genEvent->vertices()){
106 const auto& lv_pos = vtx->position();
107 if ( std::abs ( lv_pos.perp() - pv_r ) <m_r_tol && std::abs ( lv_pos.z() - pv_z ) <m_z_tol ) {vertex_ids[vtx->id()] = vtx;}
108 }//end of loop over all the vertices
109#else
110 for ( HepMC::GenEvent::vertex_const_iterator i = genEvent->vertices_begin(); i != genEvent->vertices_end() ;++i ) {
111 auto vtx=*i;
112 const auto& lv_pos = vtx->position();
113 if ( std::abs ( lv_pos.perp() - pv_r ) <m_r_tol && std::abs ( lv_pos.z() - pv_z ) <m_z_tol ) {vertex_ids[ HepMC::barcode(vtx) ]= vtx;}
114 }//end of loop over all the vertices
115#endif
116
117
118//getting the track truth collection
119 const TrackParticleTruthCollection * trackParticleTruthCollection ( nullptr );
120 sc = evtStore()->retrieve ( trackParticleTruthCollection, m_trackParticleTruthCollName );
121
122 if ( sc.isFailure() ) {
123 if (msgLvl(MSG::DEBUG)) {
124 msg() << "Cannot retrieve " << m_trackParticleTruthCollName << endmsg;
125 msg() << "Zero pointer returned" << endmsg;
126 }
127 return nullptr;
128 }
129
130//looping over the tracks to find those matched to the GenParticle originating from signal PV
131 std::vector<Trk::VxTrackAtVertex *>::const_iterator vt = tracks->begin();
132 std::vector<Trk::VxTrackAtVertex *>::const_iterator ve = tracks->end();
133 unsigned int n_failed = 0;
134 std::vector<double> in_weights ( 0 );
135 std::vector<double> out_weights ( 0 );
136 std::vector<double> pu_weights ( 0 );
137 std::vector<double> no_correspondance ( 0 );
138
139
140 for ( ;vt!=ve;++vt ) {
141//original element link
142//ugly so far, we'll correct the EDM later
143 if ( ( *vt ) !=nullptr ) {
144
145 ITrackLink * origLink = ( **vt ).trackOrParticleLink();
146
147 if ( origLink !=nullptr ) {
148 // get to the original track particle
149 LinkToTrackParticleBase * tr_part = dynamic_cast< LinkToTrackParticleBase * > ( origLink );
150 if ( tr_part !=nullptr && tr_part->isValid()) {
151
152
153 std::map< Rec::TrackParticleTruthKey, TrackParticleTruth>::const_iterator ttItr = trackParticleTruthCollection->end();
154
155 const Rec::TrackParticle* tp = dynamic_cast<const Rec::TrackParticle*>(**tr_part);
156 if(tp) {
157 const Rec::TrackParticleContainer* tpCont = dynamic_cast<const Rec::TrackParticleContainer*>(tr_part->getStorableObjectPointer());
158 if (tpCont) {
160 linkTruth.setElement(tp);
161 linkTruth.setStorableObject(*tpCont);
162 ttItr = trackParticleTruthCollection->find(Rec::TrackParticleTruthKey(linkTruth));
163 }
164 }
165
166
167 if (ttItr != trackParticleTruthCollection->end() ) {
168 const HepMcParticleLink& particleLink = ttItr->second.particleLink();
169#ifdef HEPMC3
170 HepMC::ConstGenParticlePtr genParticle = particleLink.scptr();
171#else
172 HepMC::ConstGenParticlePtr genParticle = particleLink.cptr();
173#endif
174
175 if(genParticle) {
176 const auto *tpEvent = genParticle->parent_event();
177 if(tpEvent==genEvent) {
178 HepMC::ConstGenVertexPtr pVertex{nullptr};
179 if (genParticle) pVertex = genParticle->production_vertex();
180 if ( pVertex) {
181 int link_pid = genParticle->pdg_id();
182 bool primary_track = false;
183 bool secondary_track = false;
184
185//loop over the particles until decision is really taken
186 do {
187#ifdef HEPMC3
188 auto idf_res = vertex_ids.find ( pVertex->id() );
189#else
190 auto idf_res = vertex_ids.find ( HepMC::barcode(pVertex) );
191#endif
192
193//for the HepMcParticle Link, the signal event has an index 0.
194// tagging on it
195 if ( idf_res != vertex_ids.end() ) {
196//this is a primary track, storing its weight
197 primary_track = true;
198 in_weights.push_back ( ( *vt )->weight() );
199 }else {
200//this vertex is not from the central region.
201//checking whether it is a bremsstrahlung
202//if so, propagating track to its origin, otherwise rejecting it completely.
203 if ( pVertex->particles_in_size() == 1 ) {
204// one mother particle: is it a brem of some kind?
205#ifdef HEPMC3
206 auto inp = pVertex->particles_in()[0] ;
207#else
208 auto inp =*(pVertex->particles_in_const_begin()) ;
209#endif
210 auto tmpVertex_loc = inp ->production_vertex();
211 if ( inp ->pdg_id() == link_pid && tmpVertex_loc) {
212// seems like a brem (this can be generator/simulation dependent unfortunately)
213// continue iterating
214 pVertex = tmpVertex_loc;
215 }else {
216 secondary_track = true;
217 out_weights.push_back ( ( *vt )->weight() );
218 }//end of "no id change" check
219 }else {
220
221//has more than one mother particle; comes from reaction, not from central region
222// it is an outlier
223 secondary_track = true;
224 out_weights.push_back ( ( *vt )->weight() );
225 }//end of reaction check
226 }//end of central region check
227 }while ( !primary_track && !secondary_track );//end of loop over gen particles
228 }else {
229
230// this track has no production vertex. Whatever it is, it does not
231// come from the primary interaction, consider as pileup
232 if (msgLvl(MSG::INFO)) {
233 msg() <<"A truth particle with no production vertex found."<<endmsg;
234 msg() <<"Since it does not come from PV, consider as PileUp"<<endmsg;
235 }
236 pu_weights.push_back ( ( *vt )->weight() );
237 } //end of particle link without production vertex check.
238 }else {
239
240// std::cout<<"Not equal events "<< std::endl;
241 pu_weights.push_back ( ( *vt )->weight() );
242 }//end of event pointers comparison
243 }else{
244
245//the corresponding link to the track particles is zero.
246//This seems to be a fake (broken link in any case).
247 no_correspondance.push_back ( ( *vt )->weight() );
248 }//end of genParticle check
249 }//end of search for correspondance in the trurth collection
250 }else{
251 if (msgLvl(MSG::DEBUG)) msg() <<"This track at vertex has no valid link to its original trackparticle "<<endmsg;
252 ++ n_failed;
253 }//end of search for the truth link
254 }else{
255 if (msgLvl(MSG::DEBUG)) msg() <<"There is an empty pointer in the vector<VxTrackAtVertex *> for this vertex"<<endmsg;
256 ++n_failed;
257 }
258 }//end of valid link check
259 } //end of check of the empty pointer in the vector
260
261//debug
262// std::cout<<"Total number of tracks fitted to the vertex: "<<tracks->size() <<std::endl;
263// std::cout<<"Number of tracks w/o truth correspondance: "<<no_correspondance.size() <<std::endl;
264// std::cout<<"Number of correct tracks: "<<total_size<<std::endl;
265// std::cout<<"Number of tracks with broken origin links "<<n_failed<<std::endl;
266// std::cout<<"Number of fitted outliers "<<out_weights.size() <<std::endl;
267// std::cout<<"Number of fitted intliers "<<in_weights.size() <<std::endl;
268
269 return new Trk::TrkPriVxPurity ( tracks->size(), pu_weights, no_correspondance,
270 n_failed, in_weights, out_weights );
271 } // end of if tracks != 0
272 }else{
273 if (msgLvl(MSG::ERROR)) {
274 msg()<<"Empty vertex pointer received"<<endmsg;
275 msg()<<"Empty pointer returned."<<endmsg;
276 }
277 return nullptr;
278 }//end of empty vertex check
279 return nullptr;
280 }//end of purity method
281
282
283}//end of namespace definitions
#define endmsg
#define ATH_MSG_DEBUG(x)
static Double_t sc
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()
bool msgLvl(const MSG::Level lvl) const
MsgStream & msg() const
DataModel_detail::const_iterator< DataVector > const_iterator
Definition DataVector.h:838
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
This defines the McEventCollection, which is really just an ObjectVector of McEvent objectsFile: Gene...
TrkPriVxPurityTool(const std::string &t, const std::string &n, const IInterface *p)
AlgTool constructor.
std::string m_mc_collection_name
Name of the MC event collection to read.
std::string m_trackParticleTruthCollName
Name of the track true <-> rec map to be read from the storegate.
double m_z_tol
Primary vertex definition for MC: tolerances taken in z (mm) around the simulated point of proton-pro...
StatusCode initialize()
AlgTool method.
const TrkPriVxPurity * purity(const Trk::VxCandidate *vertex) const
Actual analysis method, returning a Trk::TrkPriVxPurity object for a given TrkVxCandidate.
double m_r_tol
Primary vertex definition for MC: tolerances taken in r (mm) around the simulated point of proton-pro...
StatusCode finalize()
AlgTool method.
virtual ~TrkPriVxPurityTool()
AlgTool destructor.
A prototype data class for primary vertex purity.
int barcode(const T *p)
Definition Barcode.h:16
const GenParticle * ConstGenParticlePtr
Definition GenParticle.h:38
const HepMC::GenVertex * ConstGenVertexPtr
Definition GenVertex.h:60
Ensure that the ATLAS eigen extensions are properly loaded.