ATLAS Offline Software
Loading...
Searching...
No Matches
InDetConversionFinderTools.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
5/***************************************************************************
6 InDetConversionFinderTools.cxx - Description
7 -------------------
8 begin : 28-08-2006
9 authors : Tatjana Lenz
10 email : tatjana.lenz@cern.ch
11 changes :
12***************************************************************************/
14
15#include "AthLinks/ElementLink.h"
18
19#include <vector>
20#include <utility>
21
22namespace InDet
23{
24
26 const std::string& n,
27 const IInterface* p)
28 : AthAlgTool(t, n, p)
29{
30 declareInterface<IVertexFinder>(this);
31}
32
34
36 {
37 StatusCode sc = AthAlgTool::initialize();
38 if (sc.isFailure()) {
39 ATH_MSG_FATAL("Unable to initialize InDetConversionFinderTools");
40 return StatusCode::FAILURE;
41 }
42 /* Get the right vertex fitting tool from ToolSvc */
43 if (m_iVertexFitter.retrieve().isFailure()) {
44 ATH_MSG_FATAL("Failed to retrieve tool " << m_iVertexFitter);
45 return StatusCode::FAILURE;
46 }
47 ATH_MSG_DEBUG("Retrieved tool " << m_iVertexFitter);
48
49 /* Get the track pairs selector tool from ToolSvc */
50 if (m_trackPairsSelector.retrieve().isFailure()) {
51 ATH_MSG_FATAL("Failed to retrieve tool " << m_trackPairsSelector);
52 return StatusCode::FAILURE;
53 }
54 ATH_MSG_DEBUG("Retrieved tool " << m_trackPairsSelector);
55
56 /* Get the vertex point estimator tool from ToolSvc */
57 if (m_vertexEstimator.retrieve().isFailure()) {
58 ATH_MSG_FATAL("Failed to retrieve tool " << m_vertexEstimator);
59 return StatusCode::FAILURE;
60 }
61 ATH_MSG_DEBUG("Retrieved tool " << m_vertexEstimator);
62
63 /* Get the postselector tool from ToolSvc */
64 if (m_postSelector.retrieve().isFailure()) {
65 ATH_MSG_FATAL("Failed to retrieve tool " << m_postSelector);
66 return StatusCode::FAILURE;
67 }
68 ATH_MSG_DEBUG("Retrieved tool " << m_postSelector);
69
70 /* Get the single track conversion tool from ToolSvc */
71 if (m_singleTrkConvTool.retrieve().isFailure()) {
72 ATH_MSG_FATAL("Failed to retrieve tool " << m_singleTrkConvTool);
73 return StatusCode::FAILURE;
74 }
75 ATH_MSG_DEBUG("Retrieved tool " << m_singleTrkConvTool);
76
77 /* Get the track selector tool from ToolSvc */
78 if (m_trkSelector.retrieve().isFailure()) {
79 ATH_MSG_FATAL("Failed to retrieve tool " << m_trkSelector);
80 return StatusCode::FAILURE;
81 }
82 ATH_MSG_DEBUG("Retrieved tool " << m_trkSelector);
83
84 ATH_MSG_DEBUG("Initialization successful");
85 return StatusCode::SUCCESS;
86 }
87
89 {
90 return StatusCode::SUCCESS;
91 }
92
93 //TrackCollection
94 std::pair<xAOD::VertexContainer*, xAOD::VertexAuxContainer*>
95 InDetConversionFinderTools::findVertex(const EventContext& /*ctx*/,
96 const TrackCollection* /*trk_coll*/) const
97 {
98
99 ATH_MSG_ERROR("Using Track Container not currently supported returning an empty conatiner");
100
101 // Make collection for conversions.
102 xAOD::VertexContainer* InDetConversionContainer = new xAOD::VertexContainer();
103 xAOD::VertexAuxContainer* InDetConversionContainerAux = new xAOD::VertexAuxContainer();
104 InDetConversionContainer->setStore( InDetConversionContainerAux );
105
106 return std::make_pair(InDetConversionContainer,InDetConversionContainerAux);
107 }
108
109 // TrackParticle Collection
110 std::pair<xAOD::VertexContainer*, xAOD::VertexAuxContainer*>
112 const xAOD::TrackParticleContainer* trk_coll) const
113 {
114 // Make collection for conversions.
115 xAOD::VertexContainer* InDetConversionContainer =
117 xAOD::VertexAuxContainer* InDetConversionContainerAux =
119 InDetConversionContainer->setStore(InDetConversionContainerAux);
120 // Count for number of successful conversions
121 int numConversions = 0;
122
123 // have to be used for the vertex fit
124 Amg::Vector3D pos(0., 0., 0.);
125 Amg::Vector3D initPos(0., 0., 0.);
126
127 // Make seperate lists of positive and negative tracks (after presection
128 // cuts)
129 std::vector<const xAOD::TrackParticle*> negSelectedTracks;
130 negSelectedTracks.clear();
131 std::vector<const xAOD::TrackParticle*> posSelectedTracks;
132 posSelectedTracks.clear();
133 std::vector<int> negIndx;
134 std::vector<int> posIndx;
135
137 // track preselection -->pt-cut
139 for (iter = (*trk_coll).begin(); iter != (*trk_coll).end(); ++iter) {
140 if (m_trkSelector->decision(
141 **iter,
142 nullptr)) { // Only save if track passes the pt, d0, z0 and TRT PID cuts
143 ATH_MSG_DEBUG("Track passed preselection");
144 if ((*iter)->charge() < 0) {
145 negSelectedTracks.push_back(*iter);
146 negIndx.push_back(0);
147 } else {
148 posSelectedTracks.push_back(*iter);
149 posIndx.push_back(0);
150 }
151 } else
152 ATH_MSG_DEBUG("Track failed preselection");
153 } // end pt,d0.z0-cuts
154
155 // Make track pairs. To be used for double leg conversions
156 std::vector<const xAOD::TrackParticle*>::const_iterator iter_pos;
157 std::vector<const xAOD::TrackParticle*>::const_iterator iter_neg;
158 std::vector<Amg::Vector3D> positionList;
159 positionList.clear();
160 std::vector<const xAOD::TrackParticle*> trackParticleList;
161 trackParticleList.clear();
162 std::vector<const xAOD::TrackParticle*> singleTrackConvList;
163 singleTrackConvList.clear();
164 int ipos = -1;
165 int ineg = -1;
166 // Outer loop: Loop over positive tracks
167 for (iter_pos = posSelectedTracks.begin();
168 iter_pos != posSelectedTracks.end();
169 ++iter_pos) {
170 ineg = -1;
171 ipos++;
172 // Inner loop: Loop over negative tracks
173 for (iter_neg = negSelectedTracks.begin();
174 iter_neg != negSelectedTracks.end();
175 ++iter_neg) {
176 ineg++;
177 int flag = 0;
178
179 std::map<std::string, float> intersectionDecors;
180 if (!passPreSelection(cache,
181 *iter_pos,
182 *iter_neg,
183 positionList,
184 initPos,
185 flag,
186 intersectionDecors)) {
187 positionList.clear();
188 continue;
189 }
190
191 // Do the fit
192 if (positionList.size() < 2) {
193 ATH_MSG_DEBUG("No tracks to fit ");
194 positionList.clear();
195 continue;
196 }
197
198 trackParticleList.push_back(*iter_pos);
199 trackParticleList.push_back(*iter_neg);
200
201 std::unique_ptr<xAOD::Vertex> myVertex =
202 m_iVertexFitter->fit(ctx, trackParticleList, initPos);
203 trackParticleList.clear();
204
205 // We have a new vertex
206 if (myVertex) {
207 ATH_MSG_DEBUG("VertexFit successful!");
208 int type = -1;
209 if ((m_isConversion && m_postSelector->selectConversionCandidate(
210 myVertex.get(), flag, positionList)) ||
211 (!m_isConversion &&
212 m_postSelector->selectSecVtxCandidate(
213 myVertex.get(), flag, positionList, type))) {
214
215 ATH_MSG_DEBUG(" Conversion passed postselection cuts");
216 // Remove old element links
217 myVertex->clearTracks();
218
219 // If we do not have a valid type just reset
220 if (!m_isConversion && !(type == 101) && !(type == 110) &&
221 !(type == 11)) {
222 myVertex.reset();
223 }
224
225 // If we have the right type (not reset above) lets fill information
226 // and then push to the containers
227 if (myVertex) {
228 if (m_decorateVertices) {
230 "Decorating vertex with values used in track pair selector");
231 for (const auto& kv :
233 SG::Accessor<float> acc (kv.first);
234 acc (*myVertex) = kv.second;
235 }
236 ATH_MSG_DEBUG("Decorating vertex with values used in vertex "
237 "point estimator");
238 for (const auto& kv : intersectionDecors) {
239 SG::Accessor<float> acc (kv.first);
240 acc (*myVertex) = kv.second;
241 }
242 }
243
245 *trk_coll,
246 ctx);
248 *trk_coll,
249 ctx);
250 myVertex->addTrackAtVertex(newLinkPos);
251 myVertex->addTrackAtVertex(newLinkNeg);
252
253 // Now fill in the containers depending on the 2 possible
254 // cases
255 if (m_isConversion) {
256 myVertex->setVertexType(xAOD::VxType::ConvVtx);
257 InDetConversionContainer->push_back(std::move(myVertex));
258 }
259 else if (type == 101 || type == 110 || type == 11) { // V0
260 myVertex->setVertexType(xAOD::VxType::V0Vtx);
261 InDetConversionContainer->push_back(std::move(myVertex));
262 }
263
264 } // End if on right type
265
266 negIndx[ineg] = 1;
267 posIndx[ipos] = 1;
268 ++numConversions;
269 } else {
270 ATH_MSG_DEBUG("VxCandidate failed the post selection cuts!");
271 myVertex.reset();
272 }
273 } else {
274 ATH_MSG_DEBUG("VertexFit was NOT successful!");
275 }
276 positionList.clear();
277 } // neg loop
278 } // pos loop
279 ATH_MSG_DEBUG("Number of conversions found passing post selection cuts: "
280 << numConversions);
281
282 // single track conversions
283 if (m_isConversion) {
284 for (int ip = 0; ip < int(posIndx.size()); ++ip) {
285 if (posIndx[ip] == 0)
286 singleTrackConvList.push_back(posSelectedTracks[ip]);
287 }
288 for (int in = 0; in < int(negIndx.size()); ++in) {
289 if (negIndx[in] == 0)
290 singleTrackConvList.push_back(negSelectedTracks[in]);
291 }
292
293 std::vector<const xAOD::TrackParticle*>::iterator itk;
294 std::vector<const xAOD::TrackParticle*>::iterator itke = singleTrackConvList.end();
295 int numSingle = 0;
296 for (itk = singleTrackConvList.begin(); itk != itke; ++itk) {
297 if (!m_singleTrkConvTool->selectSingleTrackParticleConversion((*itk)))
298 ATH_MSG_DEBUG("Track failed single track conversion selection");
299 else {
300 xAOD::Vertex* sConver(nullptr);
301 sConver = m_singleTrkConvTool->buildSingleTrackParticleConversion(
302 (*itk), InDetConversionContainer);
303 if (sConver) {
304 sConver->clearTracks();
305
307 newLink.toContainedElement(*trk_coll, *itk, ctx);
308 sConver->addTrackAtVertex(newLink);
310 numSingle++;
311
312 if (m_decorateVertices) {
313 ATH_MSG_DEBUG("Decorating single track vertex with dummy values "
314 "used in track pair selector");
315 for (const auto& kv : InDet::TrackPairsSelector::getLastValues(cache)) {
316 SG::Accessor<float> acc (kv.first);
317 acc (*sConver) = 0.;
318 }
319
320 ATH_MSG_DEBUG("Decorating single track vertex with dummy values "
321 "used in vertex point estimator");
322 for (const std::string& k : InDet::VertexPointEstimator::decorKeys()) {
323 SG::Accessor<float> acc (k);
324 acc (*sConver) = 0.;
325 }
326
327 ATH_MSG_DEBUG("Decorating single track vertex with dummy values "
328 "used in post selector");
329 InDet::ConversionPostSelector::decorateVertex(*sConver, 0., 0., 0., 0., 0.);
330 }
331 }
332 }
333 }
334 ATH_MSG_DEBUG("Number successful reconstructed single track conversion: "
335 << numSingle);
336 }
337
338 return std::make_pair(InDetConversionContainer,
339 InDetConversionContainerAux);
340 }
341
342 bool
345 const xAOD::TrackParticle* track_pos,
346 const xAOD::TrackParticle* track_neg,
347 std::vector<Amg::Vector3D>& trackList,
348 Amg::Vector3D& initPos,
349 int& flag,
350 std::map<std::string, float>& intersectionDecors) const
351 {
352 //Track summary information
353
354 uint8_t nclusPos(0);
355 uint8_t dummy(0);
356 if(track_pos->summaryValue(dummy,xAOD::numberOfSCTHits)){
357 nclusPos += dummy;
358 }
359 if(track_pos->summaryValue(dummy,xAOD::numberOfPixelHits)){
360 nclusPos += dummy;
361 }
362
363 uint8_t nclusNeg(0);
364 if(track_neg->summaryValue(dummy,xAOD::numberOfSCTHits)){
365 nclusNeg += dummy;
366 }
367 if(track_neg->summaryValue(dummy,xAOD::numberOfPixelHits)){
368 nclusNeg += dummy;
369 }
370
371
372 if(nclusNeg>0 && nclusPos>0) flag= 0;
373 if((nclusNeg>0 && nclusPos==0) || (nclusNeg==0 && nclusPos>0)) flag = 1;
374 if(nclusNeg==0 && nclusPos==0) flag = 2;
375 if(m_removeTrt && (flag==1 || flag==2)) return false;
376
377 if (m_trackPairsSelector->selectTrackParticlePair( track_pos,track_neg,cache)){
378
379 const Trk::Perigee& perPos = track_pos->perigeeParameters();
380 const Trk::Perigee& perNeg = track_neg->perigeeParameters();
381 int errorcode = 0;
382 Amg::Vector3D startingPoint(
383 m_vertexEstimator->getCirclesIntersectionPoint(
384 &perPos, &perNeg, flag, errorcode, intersectionDecors));
385 if(m_isConversion && errorcode != 0) return false;
386 if(!m_isConversion){
387 Amg::Vector3D v_direction = perPos.momentum() + perNeg.momentum();
388 double d_alpha = (startingPoint.adjoint()*v_direction)[0]/(startingPoint.mag()*v_direction.mag());
389 if(d_alpha<m_MinFlightAngle) return false;
390 }
391 initPos = startingPoint;
392 double startingPointR = startingPoint.perp();
393 if(startingPointR<800.) {
394 //Get measured track parameters at first track measurement.
395
396 //Position of first hit in track particle
397 Trk::CurvilinearParameters trkPar_pos;
398 Trk::CurvilinearParameters trkPar_neg;
399
400 int index(-1);
401 for(unsigned int i(0); i< track_pos->numberOfParameters() ; ++i ){
402 if( xAOD::FirstMeasurement == track_pos->parameterPosition(i) ){
403 index = i;
404 break;
405 }
406 }
407 if(index!=-1){
408 trkPar_pos = track_pos->curvilinearParameters(index);
409 } else {
410 ATH_MSG_WARNING("Track Particle does not contain first Measurement track parameters");
411 return false;
412 }
413
414 index = -1;
415 for(unsigned int i(0); i< track_neg->numberOfParameters() ; ++i ){
416 if( xAOD::FirstMeasurement == track_neg->parameterPosition(i) ){
417 index = i;
418 break;
419 }
420 }
421 if(index!=-1){
422 trkPar_neg = track_neg->curvilinearParameters(index);
423 } else {
424 ATH_MSG_WARNING("Track Particle does not contain first Measurement track parameters");
425 return false;
426 }
427
428
429 if(!m_isConversion){
430 double posR = trkPar_pos.position().perp();
431 double negR = trkPar_neg.position().perp();
432 double diffR = 1000.;
433 if((startingPointR-posR)<(startingPointR-negR)) diffR = startingPointR-posR;
434 else diffR = startingPointR-negR;
435 if(startingPointR<m_MinInitVtxR) return false;
436 if(diffR<m_mindR || diffR>m_maxdR) return false;
437 }
438
439 //Alternative way to estimate the guess vertex
440 initPos = trkPar_pos.position() + trkPar_neg.position();
441 initPos *= 0.5;
442 // Not correct but will do for now
443 trackList.push_back(trkPar_pos.position());
444 trackList.push_back(trkPar_neg.position());
445
446 }
447 }
448 return true;
449 }
450}// end namespace InDet
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_ERROR(x,...)
#define ATH_MSG_WARNING(x,...)
#define ATH_MSG_FATAL(x,...)
Helper class to provide type-safe access to aux data.
static Double_t sc
DataVector< Trk::Track > TrackCollection
This typedef represents a collection of Trk::Track objects.
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
DataModel_detail::const_iterator< DataVector > const_iterator
Definition DataVector.h:861
value_type push_back(value_type pElem)
Add an element to the end of the collection.
static void decorateVertex(xAOD::Vertex &vertex, float inv_mass, float pt1, float pt2, float fR, float deltaPhiVtxTrk)
Decorate vertices with values used in post selector.
ToolHandle< Trk::ITrackSelectorTool > m_trkSelector
Track Selector Tool.
virtual std::pair< xAOD::VertexContainer *, xAOD::VertexAuxContainer * > findVertex(const EventContext &ctx, const TrackCollection *trk_coll) const override
Find vertex from Trk::TrackCollection.
BooleanProperty m_decorateVertices
Conversion candidate reconstruction for Trk::Tracks.
bool passPreSelection(TrackPairsSelector::Cache &cache, const xAOD::TrackParticle *track_pos, const xAOD::TrackParticle *track_neg, std::vector< Amg::Vector3D > &trackList, Amg::Vector3D &initPos, int &flag, std::map< std::string, float > &intersectionDecors) const
ToolHandle< InDet::VertexPointEstimator > m_vertexEstimator
Initial conversion vertex estimator tool.
ToolHandle< InDet::TrackPairsSelector > m_trackPairsSelector
Initial conversion vertex estimator tool.
ToolHandle< Trk::IVertexFitter > m_iVertexFitter
Vertex fitter interface.
InDetConversionFinderTools(const std::string &t, const std::string &n, const IInterface *p)
ToolHandle< InDet::ConversionPostSelector > m_postSelector
Conversion post-fit selector tool.
ToolHandle< InDet::SingleTrackConversionTool > m_singleTrkConvTool
Single track conversion tool.
static std::map< std::string, float > getLastValues(const Cache &cache)
Return a map with the values calculated for the last pair to decorate the vertex once it is created.
static std::vector< std::string > decorKeys()
Return list of keys used for decorations.
Helper class to provide type-safe access to aux data.
const Amg::Vector3D & momentum() const
Access method for the momentum.
const Amg::Vector3D & position() const
Access method for the position.
const Trk::Perigee & perigeeParameters() const
Returns the Trk::MeasuredPerigee track parameters.
const Trk::CurvilinearParameters curvilinearParameters(unsigned int index) const
Returns a curvilinear representation of the parameters at 'index'.
xAOD::ParameterPosition parameterPosition(unsigned int index) const
Return the ParameterPosition of the parameters at 'index'.
bool summaryValue(uint8_t &value, const SummaryType &information) const
Accessor for TrackSummary values.
size_t numberOfParameters() const
Returns the number of additional parameters stored in the TrackParticle.
void clearTracks()
Remove all tracks from the vertex.
void addTrackAtVertex(const ElementLink< TrackParticleContainer > &tr, float weight=1.0)
Add a new track to the vertex.
void setVertexType(VxType::VertexType vType)
Set the type of the vertex.
Eigen::Matrix< double, 3, 1 > Vector3D
Primary Vertex Finder.
ParametersT< TrackParametersDim, Charged, PerigeeSurface > Perigee
CurvilinearParametersT< TrackParametersDim, Charged, PlaneSurface > CurvilinearParameters
Definition index.py:1
@ V0Vtx
Vertex from V0 decay.
@ ConvVtx
Conversion vertex.
VertexAuxContainer_v1 VertexAuxContainer
Definition of the current jet auxiliary container.
TrackParticle_v1 TrackParticle
Reference the current persistent version:
VertexContainer_v1 VertexContainer
Definition of the current "Vertex container version".
Vertex_v1 Vertex
Define the latest version of the vertex class.
TrackParticleContainer_v1 TrackParticleContainer
Definition of the current "TrackParticle container version".
@ numberOfSCTHits
number of hits in SCT [unit8_t].
@ numberOfPixelHits
these are the pixel hits, including the b-layer [unit8_t].
@ FirstMeasurement
Parameter defined at the position of the 1st measurement.