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 auto pv = genEvent->vertices()[0];
88
89//analysing the MC event to create PV candidate
90//first finding the vertex of primary pp interaction
91
92//and storing its position
93 const auto& pv_pos = pv ->position();
94 double pv_r = pv_pos.perp();
95 double pv_z = pv_pos.z();
96
97// storing all the ids of vertices reasonably close to the primary one.
98// here the region of interest is selected.
99 std::map<int,HepMC::ConstGenVertexPtr> vertex_ids;
100 for (const auto& vtx: genEvent->vertices()){
101 const auto& lv_pos = vtx->position();
102 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;}
103 }//end of loop over all the vertices
104
105//getting the track truth collection
106 const TrackParticleTruthCollection * trackParticleTruthCollection ( nullptr );
107 sc = evtStore()->retrieve ( trackParticleTruthCollection, m_trackParticleTruthCollName );
108
109 if ( sc.isFailure() ) {
110 if (msgLvl(MSG::DEBUG)) {
111 msg() << "Cannot retrieve " << m_trackParticleTruthCollName << endmsg;
112 msg() << "Zero pointer returned" << endmsg;
113 }
114 return nullptr;
115 }
116
117//looping over the tracks to find those matched to the GenParticle originating from signal PV
118 std::vector<Trk::VxTrackAtVertex *>::const_iterator vt = tracks->begin();
119 std::vector<Trk::VxTrackAtVertex *>::const_iterator ve = tracks->end();
120 unsigned int n_failed = 0;
121 std::vector<double> in_weights ( 0 );
122 std::vector<double> out_weights ( 0 );
123 std::vector<double> pu_weights ( 0 );
124 std::vector<double> no_correspondance ( 0 );
125
126
127 for ( ;vt!=ve;++vt ) {
128//original element link
129//ugly so far, we'll correct the EDM later
130 if ( ( *vt ) !=nullptr ) {
131
132 ITrackLink * origLink = ( **vt ).trackOrParticleLink();
133
134 if ( origLink !=nullptr ) {
135 // get to the original track particle
136 LinkToTrackParticleBase * tr_part = dynamic_cast< LinkToTrackParticleBase * > ( origLink );
137 if ( tr_part !=nullptr && tr_part->isValid()) {
138
139
140 std::map< Rec::TrackParticleTruthKey, TrackParticleTruth>::const_iterator ttItr = trackParticleTruthCollection->end();
141
142 const Rec::TrackParticle* tp = dynamic_cast<const Rec::TrackParticle*>(**tr_part);
143 if(tp) {
144 const Rec::TrackParticleContainer* tpCont = dynamic_cast<const Rec::TrackParticleContainer*>(tr_part->getStorableObjectPointer());
145 if (tpCont) {
147 linkTruth.setElement(tp);
148 linkTruth.setStorableObject(*tpCont);
149 ttItr = trackParticleTruthCollection->find(Rec::TrackParticleTruthKey(linkTruth));
150 }
151 }
152
153
154 if (ttItr != trackParticleTruthCollection->end() ) {
155 const HepMcParticleLink& particleLink = ttItr->second.particleLink();
156 HepMC::ConstGenParticlePtr genParticle = particleLink.scptr();
157 if(genParticle) {
158 const auto *tpEvent = genParticle->parent_event();
159 if(tpEvent==genEvent) {
160 HepMC::ConstGenVertexPtr pVertex{nullptr};
161 if (genParticle) pVertex = genParticle->production_vertex();
162 if ( pVertex) {
163 int link_pid = genParticle->pdg_id();
164 bool primary_track = false;
165 bool secondary_track = false;
166
167//loop over the particles until decision is really taken
168 do {
169 auto idf_res = vertex_ids.find ( pVertex->id() );
170
171//for the HepMcParticle Link, the signal event has an index 0.
172// tagging on it
173 if ( idf_res != vertex_ids.end() ) {
174//this is a primary track, storing its weight
175 primary_track = true;
176 in_weights.push_back ( ( *vt )->weight() );
177 }else {
178//this vertex is not from the central region.
179//checking whether it is a bremsstrahlung
180//if so, propagating track to its origin, otherwise rejecting it completely.
181 if ( pVertex->particles_in_size() == 1 ) {
182// one mother particle: is it a brem of some kind?
183 auto inp = pVertex->particles_in()[0] ;
184 auto tmpVertex_loc = inp ->production_vertex();
185 if ( inp ->pdg_id() == link_pid && tmpVertex_loc) {
186// seems like a brem (this can be generator/simulation dependent unfortunately)
187// continue iterating
188 pVertex = tmpVertex_loc;
189 }else {
190 secondary_track = true;
191 out_weights.push_back ( ( *vt )->weight() );
192 }//end of "no id change" check
193 }else {
194
195//has more than one mother particle; comes from reaction, not from central region
196// it is an outlier
197 secondary_track = true;
198 out_weights.push_back ( ( *vt )->weight() );
199 }//end of reaction check
200 }//end of central region check
201 }while ( !primary_track && !secondary_track );//end of loop over gen particles
202 }else {
203
204// this track has no production vertex. Whatever it is, it does not
205// come from the primary interaction, consider as pileup
206 if (msgLvl(MSG::INFO)) {
207 msg() <<"A truth particle with no production vertex found."<<endmsg;
208 msg() <<"Since it does not come from PV, consider as PileUp"<<endmsg;
209 }
210 pu_weights.push_back ( ( *vt )->weight() );
211 } //end of particle link without production vertex check.
212 }else {
213
214// std::cout<<"Not equal events "<< std::endl;
215 pu_weights.push_back ( ( *vt )->weight() );
216 }//end of event pointers comparison
217 }else{
218
219//the corresponding link to the track particles is zero.
220//This seems to be a fake (broken link in any case).
221 no_correspondance.push_back ( ( *vt )->weight() );
222 }//end of genParticle check
223 }//end of search for correspondance in the trurth collection
224 }else{
225 if (msgLvl(MSG::DEBUG)) msg() <<"This track at vertex has no valid link to its original trackparticle "<<endmsg;
226 ++ n_failed;
227 }//end of search for the truth link
228 }else{
229 if (msgLvl(MSG::DEBUG)) msg() <<"There is an empty pointer in the vector<VxTrackAtVertex *> for this vertex"<<endmsg;
230 ++n_failed;
231 }
232 }//end of valid link check
233 } //end of check of the empty pointer in the vector
234
235//debug
236// std::cout<<"Total number of tracks fitted to the vertex: "<<tracks->size() <<std::endl;
237// std::cout<<"Number of tracks w/o truth correspondance: "<<no_correspondance.size() <<std::endl;
238// std::cout<<"Number of correct tracks: "<<total_size<<std::endl;
239// std::cout<<"Number of tracks with broken origin links "<<n_failed<<std::endl;
240// std::cout<<"Number of fitted outliers "<<out_weights.size() <<std::endl;
241// std::cout<<"Number of fitted intliers "<<in_weights.size() <<std::endl;
242
243 return new Trk::TrkPriVxPurity ( tracks->size(), pu_weights, no_correspondance,
244 n_failed, in_weights, out_weights );
245 } // end of if tracks != 0
246 }else{
247 if (msgLvl(MSG::ERROR)) {
248 msg()<<"Empty vertex pointer received"<<endmsg;
249 msg()<<"Empty pointer returned."<<endmsg;
250 }
251 return nullptr;
252 }//end of empty vertex check
253 return nullptr;
254 }//end of purity method
255
256
257}//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.
HepMC3::ConstGenParticlePtr ConstGenParticlePtr
Definition GenParticle.h:20
HepMC3::ConstGenVertexPtr ConstGenVertexPtr
Definition GenVertex.h:24
HepMC3::GenEvent GenEvent
Definition GenEvent.h:39
Ensure that the ATLAS eigen extensions are properly loaded.