ATLAS Offline Software
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
9 #include "VxVertex/VxCandidate.h"
10 
11 // normal includes
14 #include "AtlasHepMC/GenParticle.h"
15 #include "AtlasHepMC/GenVertex.h"
16 #include "AtlasHepMC/GenEvent.h"
18 
20 
24 
25 #include <map>
26 #include <vector>
27 
28 namespace 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
Rec::TrackParticleTruthKey
Definition: TrackParticleTruthKey.h:20
DataModel_detail::const_iterator
Const iterator class for DataVector/DataList.
Definition: DVLIterator.h:82
GenEvent.h
python.PerfMonSerializer.p
def p
Definition: PerfMonSerializer.py:743
Trk::TrkPriVxPurityTool::~TrkPriVxPurityTool
virtual ~TrkPriVxPurityTool()
AlgTool destructor.
AthCommonDataStore< AthCommonMsg< AlgTool > >::declareProperty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T > &t)
Definition: AthCommonDataStore.h:145
GenVertex.h
Trk::TrkPriVxPurityTool::purity
const TrkPriVxPurity * purity(const Trk::VxCandidate *vertex) const
Actual analysis method, returning a Trk::TrkPriVxPurity object for a given TrkVxCandidate.
Definition: TrkPriVxPurityTool.cxx:62
skel.it
it
Definition: skel.GENtoEVGEN.py:423
TrackParticleTruth.h
ParticleTest.tp
tp
Definition: ParticleTest.py:25
AthCommonMsg< AlgTool >::msgLvl
bool msgLvl(const MSG::Level lvl) const
Definition: AthCommonMsg.h:30
TrackParticleTruthCollection.h
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
Trk::TrkPriVxPurityTool::finalize
StatusCode finalize()
AlgTool method.
Definition: TrkPriVxPurityTool.cxx:34
GenParticle.h
AthenaPoolTestRead.sc
sc
Definition: AthenaPoolTestRead.py:27
TrkPriVxPurity.h
AthCommonDataStore< AthCommonMsg< AlgTool > >::evtStore
ServiceHandle< StoreGateSvc > & evtStore()
The standard StoreGateSvc (event store) Returns (kind of) a pointer to the StoreGateSvc.
Definition: AthCommonDataStore.h:85
Trk::TrkPriVxPurityTool::m_trackParticleTruthCollName
std::string m_trackParticleTruthCollName
Name of the track true <-> rec map to be read from the storegate.
Definition: TrkPriVxPurityTool.h:86
TrackParticleTruthKey.h
McEventCollection.h
lumiFormat.i
int i
Definition: lumiFormat.py:92
beamspotman.n
n
Definition: beamspotman.py:731
endmsg
#define endmsg
Definition: AnalysisConfig_Ntuple.cxx:63
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
HepMC::barcode
int barcode(const T *p)
Definition: Barcode.h:16
Trk::TrkPriVxPurity
Definition: TrkPriVxPurity.h:41
VxTrackAtVertex.h
McEventCollection
This defines the McEventCollection, which is really just an ObjectVector of McEvent objects.
Definition: McEventCollection.h:33
LinkToTrackParticleBase.h
Trk::LinkToTrackParticleBase
Definition: LinkToTrackParticleBase.h:17
VxCandidate.h
HepMC::ConstGenParticlePtr
const GenParticle * ConstGenParticlePtr
Definition: GenParticle.h:38
Trk
Ensure that the ATLAS eigen extensions are properly loaded.
Definition: FakeTrackBuilder.h:9
Trk::TrkPriVxPurityTool::initialize
StatusCode initialize()
AlgTool method.
Definition: TrkPriVxPurityTool.cxx:30
Trk::TrkPriVxPurityTool::m_mc_collection_name
std::string m_mc_collection_name
Name of the MC event collection to read.
Definition: TrkPriVxPurityTool.h:91
Trk::TrkPriVxPurityTool::m_r_tol
double m_r_tol
Primary vertex definition for MC: tolerances taken in r (mm) around the simulated point of proton-pro...
Definition: TrkPriVxPurityTool.h:73
Rec::TrackParticleContainer
Definition: Reconstruction/Particle/Particle/TrackParticleContainer.h:33
validateBDTTau.vt
vt
Definition: validateBDTTau.py:43
Trk::TrkPriVxPurityTool::TrkPriVxPurityTool
TrkPriVxPurityTool(const std::string &t, const std::string &n, const IInterface *p)
AlgTool constructor.
Definition: TrkPriVxPurityTool.cxx:39
Rec::TrackParticle
Definition: Reconstruction/Particle/Particle/TrackParticle.h:47
Trk::vertex
@ vertex
Definition: MeasurementType.h:21
TrkPriVxPurityTool.h
Trk::VxCandidate
Definition: VxCandidate.h:27
TrackParticleTruthCollection
Definition: TrackParticleTruthCollection.h:18
DEBUG
#define DEBUG
Definition: page_access.h:11
AthCommonMsg< AlgTool >::msg
MsgStream & msg() const
Definition: AthCommonMsg.h:24
python.changerun.pv
pv
Definition: changerun.py:81
HepMC::ConstGenVertexPtr
const HepMC::GenVertex * ConstGenVertexPtr
Definition: GenVertex.h:60
AthAlgTool
Definition: AthAlgTool.h:26
Trk::TrkPriVxPurityTool::m_z_tol
double m_z_tol
Primary vertex definition for MC: tolerances taken in z (mm) around the simulated point of proton-pro...
Definition: TrkPriVxPurityTool.h:81
DataVector::begin
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.