ATLAS Offline Software
Loading...
Searching...
No Matches
SiTrajectory_xk.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
6
7#include <format>
8#include <iostream>
9
11// Set work information to trajectory
13
15{
16 m_tools = t;
17 for (int i=0; i!=300; ++i) m_elements[i].setTools(t);
18}
19
21{
22 for (int i=0; i!=300; ++i) m_elements[i].setParameters();
23}
24
26// Erase trajector element
28
30{
31 if (n>=0 && n<m_nElements) {
32 for (int i=n; i!=m_nElements-1; ++i) m_elementsMap[i] = m_elementsMap[i+1];
34 }
35}
36
38// Trajectory conversion to TrackStateOnSurface
40
43{
44 if (!cosmic || m_elements[m_elementsMap[m_firstElement]].parametersUB().parameters()[2] < 0.) {
46 }
48}
49
51// Trajectory conversion to TrackStateOnSurface with old direction
53
56{
57
58 auto dtsos = Trk::TrackStates();
59
60 bool multi = m_tools->multiTrack();
61 if (m_nclusters <= m_tools->clustersmin() ||
62 pTfirst() < m_tools->pTmin()) multi = false;
63
64 int i = m_firstElement;
65
67 tsos = m_elements[m_elementsMap[i]].trackStateOnSurface(false,true,multi,1,ctx);
68
69 if (tsos) dtsos.push_back(tsos);
70
71 for (++i; i!=m_lastElement; ++i) {
72
73 int m = m_elementsMap[i];
74 if (m_elements[m].cluster() || m_elements[m].clusterNoAdd() ) {
75 tsos = m_elements[m].trackStateOnSurface(false,false,multi,0,ctx);
76 if (tsos) dtsos.push_back(tsos);
77 }
78 }
79
80 i = m_lastElement;
81 tsos = m_elements[m_elementsMap[i]].trackStateOnSurface(false,false,multi,2,ctx);
82 if (tsos) dtsos.push_back(tsos);
83
84 if (multi) {
85 m_ntos = 0;
86 for (int i=m_firstElement; i<=m_lastElement; ++i) {
87
88 int m = m_elementsMap[i];
89 if (!m_elements[m].ntsos()) continue;
90 m_atos[m_ntos ] = m;
91 m_itos[m_ntos++] = 0;
92 }
93 }
94 return dtsos;
95}
96
98// Trajectory conversion to TrackStateOnSurface with new direction
100
103{
104
105 auto dtsos = Trk::TrackStates();
106
107 bool multi = m_tools->multiTrack();
108 if (pTfirst() < m_tools->pTmin()) multi = false;
109
110 int i = m_lastElement;
111
113 tsos = m_elements[m_elementsMap[i]].trackStateOnSurface(true,true,multi,2,ctx);
114
115 if (tsos) dtsos.push_back(tsos);
116
117 for (--i; i!=m_firstElement; --i) {
118
119 int m = m_elementsMap[i];
120 if (m_elements[m].cluster() || m_elements[m].clusterNoAdd() ) {
121 tsos = m_elements[m].trackStateOnSurface(true,false,multi,0,ctx);
122 if (tsos) dtsos.push_back(tsos);
123 }
124 }
125
126 i = m_firstElement;
127 tsos = m_elements[m_elementsMap[i]].trackStateOnSurface(true,false,multi,1,ctx);
128 if (tsos) dtsos.push_back(tsos);
129
130 return dtsos;
131}
132
134// Trajectory conversion to simple TrackStateOnSurface
136
139{
140 if (!cosmic || m_elements[m_elementsMap[m_firstElement]].parametersUB().parameters()[2] < 0.) {
142 }
144}
145
147// Trajectory conversion to simple TrackStateOnSurface with old direction
149
152{
153 auto dtsos = Trk::TrackStates();
154
155 int i = m_firstElement;
156
158 tsos = m_elements[m_elementsMap[i]].trackPerigeeStateOnSurface(ctx);
159
160 if (tsos) dtsos.push_back(tsos);
161
162 tsos = m_elements[m_elementsMap[i]].trackSimpleStateOnSurface(false,m_tools->useFastTracking(),m_tools->useFastTracking());
163
164 if (tsos) dtsos.push_back(tsos);
165
166 int lastClusterElement = 0;
167 for (int j=m_lastElement; j>=i; j--) {
168 int m = m_elementsMap[j];
169 if (m_elements[m].cluster()) {
170 lastClusterElement = j;
171 break;
172 }
173 }
174 if( lastClusterElement==0 || lastClusterElement==i ) return dtsos;
175
176 for (++i; i<std::min(lastClusterElement,m_lastElement); ++i) {
177
178 int m = m_elementsMap[i];
179 if (m_elements[m].cluster()) {
180 tsos = m_elements[m].trackSimpleStateOnSurface(false,false,0);
181 if (tsos) dtsos.push_back(tsos);
182 }
183 }
184
185 i = std::min(lastClusterElement,m_lastElement);
186 tsos = m_elements[m_elementsMap[i]].trackSimpleStateOnSurface(false,true,2);
187 if (tsos) dtsos.push_back(tsos);
188
189 return dtsos;
190}
191
193// Trajectory conversion to simple TrackStateOnSurface with new direction
195
198{
199 auto dtsos = Trk::TrackStates();
200
201 int i = m_lastElement;
202
204 tsos = m_elements[m_elementsMap[i]].trackSimpleStateOnSurface(true,true,2);
205
206 if (tsos) dtsos.push_back(tsos);
207
208 for (--i; i!=m_firstElement; --i) {
209
210 int m = m_elementsMap[i];
211 if (m_elements[m].cluster() || m_elements[m].clusterNoAdd() ) {
212 tsos = m_elements[m].trackSimpleStateOnSurface(true,false,0);
213 if (tsos) dtsos.push_back(tsos);
214 }
215 }
216
217 i = m_firstElement;
218 tsos = m_elements[m_elementsMap[i]].trackSimpleStateOnSurface(true,false,1);
219 if (tsos) dtsos.push_back(tsos);
220
221 return dtsos;
222}
223
225// Trajectory conversion to simple TrackStateOnSurface
226// Only for Disappearing Track Trigger that uses also failed tracks
228
237
239// Trajectory conversion to simple TrackStateOnSurface with old direction
240// Only for Disappearing Track Trigger that uses also failed tracks
242
245{
246 auto dtsos = Trk::TrackStates();
247
248 int i = m_firstElement;
249
251 tsos = m_elements[m_elementsMap[i]].trackPerigeeStateOnSurface(ctx);
252
253 if (tsos) dtsos.push_back(tsos);
254
255 tsos = m_elements[m_elementsMap[i]].trackSimpleStateOnSurface(false,false,0);
256
257 if (tsos) dtsos.push_back(tsos);
258
259 int lastClusterElement = 0;
260 for (int j=m_lastElement; j>=i; j--) {
261 int m = m_elementsMap[j];
262 if (m_elements[m].cluster()) {
263 lastClusterElement = j;
264 break;
265 }
266 }
267 if( lastClusterElement==0 || lastClusterElement==i ) return dtsos;
268
269 for (++i; i<std::min(lastClusterElement,m_lastElement); ++i) {
270
271 int m = m_elementsMap[i];
272 if (m_elements[m].cluster()) {
273 tsos = m_elements[m].trackSimpleStateOnSurface(false,false,0);
274 if (tsos) dtsos.push_back(tsos);
275 }
276 }
277
278 i = std::min(lastClusterElement,m_lastElement);
279 tsos = m_elements[m_elementsMap[i]].trackSimpleStateOnSurface(false,true,2);
280 if (tsos) dtsos.push_back(tsos);
281
282 return dtsos;
283}
284
286// FitQuality production
288
289std::unique_ptr<Trk::FitQuality> InDet::SiTrajectory_xk::convertToFitQuality() const{
290 double xi2 = m_elements[m_elementsMap[m_firstElement]].xi2totalB();
291 return std::make_unique<Trk::FitQuality>(xi2, (m_ndf - 5));
292}
293
295// Test is it new track
297
299(std::multimap<const Trk::PrepRawData*,const Trk::Track*>& map) const
300{
301 if (m_firstElement==-100) return false;//i.e. the int array never had elements inserted
302 const Trk::PrepRawData* prd [100];
303 std::multimap<const Trk::PrepRawData*,const Trk::Track*>::const_iterator
304 ti,t[100],te = map.end();
305 int n = 0 ;
306 for (int i=m_firstElement; i<=m_lastElement; ++i) {
307 if (n >= 100) break;
308 int m = m_elementsMap[i];
309
310 if (m_elements[m].cluster()) {
311 prd[n] = m_elements[m].cluster();
312 t[n] = map.find(prd[n]);
313 if (t[n]==te) return true;
314 ++n;
315 } else if (m_elements[m].clusterNoAdd()) {
316 prd[n] = m_elements[m].clusterNoAdd();
317 t[n] = map.find(prd[n]);
318 if (t[n]==te) return true;
319 ++n;
320 }
321 }
322
323 int nclt = m_nclusters + m_nclustersNoAdd;
324
325 for (int i=0; i!=n; ++i) {
326 int nclmax = 0;
327 for (ti=t[i]; ti!=te; ++ti) {
328 if ( (*ti).first != prd[i] ) break;
329 int ncl = (*ti).second->measurementsOnTrack()->size();
330 if (ncl > nclmax) nclmax = ncl;
331 }
332 if (nclt > nclmax) return true;
333 }
334 return false;
335}
336
338// Overload of << operator std::ostream
340
341std::ostream& InDet::operator <<
342(std::ostream& sl,const InDet::SiTrajectory_xk& se)
343{
344 return se.dump(sl);
345}
346
348// Dumps relevant information into the ostream
350
351std::ostream& InDet::SiTrajectory_xk::dump( std::ostream& out ) const
352{
353 if (m_nElements <=0 ) {
354 out<<"Trajectory does not exist"<<std::endl;
355 return out;
356 }
358 out<<"Trajectory is wrong"<<std::endl;
359 return out;
360 }
361
362 out<<"|--------------------------------------------------------------------------------------------------------|"
363 <<std::endl;
364 out<<"| TRAJECTORY "
365 <<" |"
366 <<std::endl;
367
368 out << std::format("| Has{:>3} ({:>3}) elements and {:>2} ({:>2}) clusters and {:>2} weighted clusters and quality = {:>12.5g} |\n",
373 m_ndf,
374 quality());
375 out << std::format("| Has number of holes before, inside, after and gap= {:>2}{:>2}{:>2}{:>3} |\n",
377 m_nholes,
379 m_dholes);
380 out<<"| F B |"
381 <<std::endl;
382
383 out<<"|---|--|---|-----|-|-|---------|---------|---------|---------|----------|---------|-|--|--|--|-|-|-|-|-|-|---------|"
384 <<std::endl;
385 out<<"| # |SS| D| Ncl |C|O| Xi2F | Xi2B | Az.Angle| Radius | pT(GeV) | dZ/dR |N|In|Lf|Lb|S|D|H|G|H|G| Step |"
386 <<std::endl;
387 out<<"|---|--|---|-----|-|-|---------|---------|---------|---------|----------|---------|-|--|--|--|-|-|-|-|-|-|---------|"
388 <<std::endl;
389
390 for (int i=0; i!=m_nElements; ++i) {
391
392 int m = m_elementsMap[i];
393
394 std::string DET = "D ";
395 const InDetDD::SiDetectorElement* D = m_elements[m].detElement();
396 std::string DE = " ";
397 if (m_elements[m].detstatus() < 0) DE = "-";
398 if (D) {
399 if (D->isPixel()) {
400 if (D->isBarrel()) DET = "Pb"; else DET = "Pe";
401 }
402 else if (D->isSCT()) {
403 if (D->isBarrel()) DET = "Sb"; else DET = "Se";
404 }
405 }
406 int c = 0;
407 if (m_elements[m].detstatus() > 0) c = m_elements[m].numberClusters();
408
409 out << std::format("|{:>3}", static_cast<unsigned>(i));
410
411 std::string S0=" ";
412 if (m_firstElement == i) S0="=>";
413 if (m_lastElement == i) S0="=>";
414
415 std::string S1=" ";
416 std::string S2=" ";
417 if (m_elements[m].cluster ()) S1="+";
418 if (m_elements[m].clusterNoAdd()) S2="+";
419
420 out << std::format("|{}|{:>1}{:>2}|{:>5}|{}|{}|", S0, DE, DET, c, S1, S2);
421
422 if (m_elements[m].status()) {
423
424 out << std::format("{:>9.3g}|{:>9.3g}|", m_elements[m].xi2F(), m_elements[m].xi2B());
425
426 double ra = 0.;
427 double pt = 0.;
428 double tz = 0.;
429 double fa = 0.;
430
431 if (m_elements[m].status()==1) {
432
433 if (m_elements[m].cluster()) {
434
435 Amg::Vector3D gp = m_elements[m].parametersUF().position();
436 ra = sqrt(gp.x()*gp.x()+gp.y()*gp.y());
437 fa = atan2(gp.y(),gp.x());
438 pt = m_elements[m].parametersUF().momentum().perp();
439 tz = m_elements[m].parametersUF().cotTheta();
440 }
441 else {
442
443 Amg::Vector3D gp = m_elements[m].parametersPF().position();
444 ra = sqrt(gp.x()*gp.x()+gp.y()*gp.y());
445 fa = atan2(gp.y(),gp.x());
446 pt = m_elements[m].parametersPF().momentum().perp();
447 tz = m_elements[m].parametersPF().cotTheta();
448 }
449 }
450 else if ((m_tools->useFastTracking() and m_elements[m].status()>2) or m_elements[m].status()==2) {
451
452 if (m_elements[m].cluster()) {
453
454 Amg::Vector3D gp = m_elements[m].parametersUB().position();
455 ra = sqrt(gp.x()*gp.x()+gp.y()*gp.y());
456 fa = atan2(gp.y(),gp.x());
457 pt = m_elements[m].parametersUB().momentum().perp();
458 tz = m_elements[m].parametersUB().cotTheta();
459 }
460 else {
461
462 Amg::Vector3D gp = m_elements[m].parametersPB().position();
463 ra = sqrt(gp.x()*gp.x()+gp.y()*gp.y());
464 fa = atan2(gp.y(),gp.x());
465 pt = m_elements[m].parametersPB().momentum().perp();
466 tz = m_elements[m].parametersPB().cotTheta();
467 }
468 }
469 else {
470
471 Trk::PatternTrackParameters S1,SM,S2(m_elements[m].parametersPF());
472
473 if (m_elements[m].cluster()) S1 = m_elements[m].parametersUB();
474 else S1 = m_elements[m].parametersPB();
475
476 bool QA = m_tools->updatorTool()->combineStates(S1,S2,SM);
477
478 if (QA) {
479
480 Amg::Vector3D gp = SM.position();
481 ra = sqrt(gp.x()*gp.x()+gp.y()*gp.y());
482 fa = atan2(gp.y(),gp.x());
483 pt = SM.momentum().perp();
484 tz = SM.cotTheta();
485 }
486 }
487 out << std::format("{:>9.4g}|{:>9.4g}|{:>10.4g}|{:>9.4g}|{:>1}|{:>2}|{:>2}|{:>2}|{:>1}|{:>1}|{:>1}|{:>1}|{:>1}|{:>1}|{:>9.4g}|",
488 fa,
489 ra,
490 pt*0.001,
491 tz,
492 static_cast<unsigned>(m_elements[m].noiseModel()),
493 m_elements[m].inside(),
494 static_cast<unsigned>(m_elements[m].nlinksF()),
495 static_cast<unsigned>(m_elements[m].nlinksB()),
496 static_cast<unsigned>(m_elements[m].status()),
497 static_cast<unsigned>(m_elements[m].difference()),
498 static_cast<unsigned>(m_elements[m].nholesF()),
499 static_cast<unsigned>(m_elements[m].dholesF()),
500 static_cast<unsigned>(m_elements[m].nholesB()),
501 static_cast<unsigned>(m_elements[m].dholesB()),
502 m_elements[m].step());
503 }
504 else {
505 out<<" |";
506 out<<" |";
507 out<<" |";
508 out<<" |";
509 out<<" |";
510 out<<" |";
511 out<<" |";
512 out<<" |";
513 out<<" |";
514 out<<" |";
515 out<<" |";
516 out<<" |";
517 out<<" |";
518 out<<" |";
519 out<<" |";
520 out<<" |";
521 out << std::format("{:>9.4g}|", m_elements[m].step());
522 }
523 out<<std::endl;
524 }
525 out<<"|---|--|---|-----|-|-|---------|---------|---------|---------|----------|---------|-|--|--|--|-|-|-|-|-|-|---------|"
526 <<std::endl;
527 return out;
528}
529
531// pT seed estimation
533
535 (const Trk::TrackParameters & Tp,
536 std::vector<const InDet::SiCluster*> & Cl,
537 std::vector<const InDet::SiDetElementBoundaryLink_xk*>& DE,
538 const EventContext & ctx)
539{
540 double Xi2cut = 30.;
541
542 InDet::SiClusterCollection::const_iterator sib,sie;
543 std::vector<const InDet::SiDetElementBoundaryLink_xk*>::iterator r=DE.begin(),re=DE.end();
544 std::vector<const InDet::SiCluster*> ::iterator s=Cl.begin();
545
546 int n = 0;
547 if(!m_elements[n].set(1,(*r),sib,sie,(*s),ctx) ) return 0.;
548 if(!m_elements[n].firstTrajectorElement(Tp,ctx)) return 0.;
549
550 for(++r; r!=re; ++r) {
551 ++n; ++s;
552 if(!m_elements[n].set(1,(*r),sib,sie,(*s),ctx) ) return 0.;
553 if(!m_elements[n].ForwardPropagationWithoutSearch(m_elements[n-1], ctx)) return 0.;
554 if( m_elements[n].xi2F() > Xi2cut ) return 0.;
555 }
556 return m_elements[n].parametersUF().momentum().perp();
557}
558
559
561// Initiate trajectory
563
565(bool PIX,
566 bool SCT,
567 const InDet::PixelClusterContainer* PIXc ,
568 const InDet::SCT_ClusterContainer* SCTc ,
569 const Trk::TrackParameters & Tp ,
570 std::vector<const InDet::SiCluster*> & lSiCluster,
571 std::vector<const InDet::SiDetElementBoundaryLink_xk*>& DE ,
572 bool & rquality ,
573 const EventContext & ctx )
574{
576 m_nholes = 0;
577 m_nHolesBefore = 0;
578 m_nHolesAfter = 0;
579 m_dholes = 0;
580 m_nclusters = 0;
582 m_nElements = 0;
584 m_firstElement = -100;
585 m_lastElement = 0;
586 m_ndfcut = 0;
587 rquality = true;
588 m_ntos = 0;
589 int ndfwrong = 0;
590 double Xi2cut = 2.*m_tools->xi2max();
591
592 // radius of the dead cylinder
593 double Rdead = 142.5;
594 // boolean to decide if initialisation is needed or not
595 // initDeadMaterial is False (which means dead material needs be initialised)
596 // for ITk fast tracking configuration
597 bool initDeadMaterial = not(m_tools->isITkGeometry() and m_tools->useFastTracking());
598
599 if(!initDeadMaterial and !m_surfacedead) m_surfacedead = std::make_unique<const Trk::CylinderSurface>(Rdead,5000.);
600
601 std::vector<const InDet::SiCluster*>::iterator iter_cluster;
602 if (lSiCluster.size() < 2) return false;
603
604 std::vector<const InDet::SiDetElementBoundaryLink_xk*>::iterator iter_boundaryLink,endBoundaryLinks=DE.end();
605
606 int up = 0;
607 int last = 0;
608
611 for (iter_boundaryLink=DE.begin(); iter_boundaryLink!=endBoundaryLinks; ++iter_boundaryLink) {
612
614 const InDetDD::SiDetectorElement* detectorElement = (*iter_boundaryLink)->detElement();
615 IdentifierHash id = detectorElement->identifyHash();
616
618 const InDet::SiCluster* theCluster = nullptr;
619
621 if (detectorElement->isPixel()) {
622 if (PIX) {
623
624 // Set dead material
625 //
626 // if already initialised, not doing it again
627 if(not initDeadMaterial) {
628 const Trk::PlaneSurface* pla = static_cast<const Trk::PlaneSurface*>(&detectorElement->surface());
629 double R = pla->center().perp();
630 if(R > Rdead) {
631 initDeadMaterial = true;
632 if(!m_elements[m_nElements].setDead(m_surfacedead.get())) return false;
634 if(m_nclusters && !lSiCluster.empty()) {
635 if(!m_elements[m_nElements].ForwardPropagationWithoutSearch(m_elements[up], ctx)) return false;
636 up = m_nElements;
637 }
638 if(++m_nElements==300) break;
639 }
640 }
641
642 InDet::PixelClusterCollection::const_iterator iter_PixelClusterColl, iter_PixelClusterCollEnd;
644 const InDet::PixelClusterCollection *clustersOnElement = (*PIXc).indexFindPtr(id);
646 if (clustersOnElement!=nullptr && clustersOnElement->begin()!=clustersOnElement->end()) {
647
649 iter_PixelClusterColl = clustersOnElement->begin();
650 iter_PixelClusterCollEnd = clustersOnElement->end();
651
654 for (iter_cluster=lSiCluster.begin(); iter_cluster!=lSiCluster.end(); ++iter_cluster) {
656 if ((*iter_cluster)->detectorElement()==detectorElement) {
658 if (m_nclusters==0){
660 }
662 else{
664 }
666 ++m_nclusters;
668 m_ndfcut+=2;
670 theCluster=(*iter_cluster);
672 iter_cluster=lSiCluster.erase(iter_cluster);
676 break;
677 }
678 }
681 bool valid_set = m_elements[m_nElements].set(1,(*iter_boundaryLink),iter_PixelClusterColl,iter_PixelClusterCollEnd,theCluster,ctx);
682 if(m_tools->isITkGeometry() && !valid_set) return false;
685 }
687 else if (m_nActiveElements) {
689 bool valid_set = m_elements[m_nElements].set(0,(*iter_boundaryLink),iter_PixelClusterColl,iter_PixelClusterCollEnd,theCluster,ctx);
690 if(m_tools->isITkGeometry() && !valid_set) return false;
691 }
693 else {
694
695 continue;
696 }
702 if (++m_nElements==300) break;
703 }
704 }
706 else if (SCT) {
707 InDet::SCT_ClusterCollection::const_iterator iter_stripClusterColl, iter_StripClusterCollEnd;
709 const InDet::SCT_ClusterCollection *clustersOnElement = (*SCTc).indexFindPtr(id);
710
712 if (clustersOnElement!=nullptr && clustersOnElement->begin()!=clustersOnElement->end()) {
713
714 iter_stripClusterColl = clustersOnElement->begin();
715 iter_StripClusterCollEnd = clustersOnElement->end();
716
718 for (iter_cluster=lSiCluster.begin(); iter_cluster!=lSiCluster.end(); ++iter_cluster) {
719 if ((*iter_cluster)->detectorElement()==detectorElement) {
721 if (m_nclusters==0){
724 }
726 else{
728 }
730 ++m_nclusters;
732 m_ndfcut+=1;
734 theCluster=(*iter_cluster);
735 iter_cluster=lSiCluster.erase(iter_cluster);
738 break;
739 }
740 }
742 bool valid_set = m_elements[m_nElements].set(1,(*iter_boundaryLink),iter_stripClusterColl,iter_StripClusterCollEnd,theCluster,ctx);
743 if(m_tools->isITkGeometry() && !valid_set) return false;
746 }
748 else if (m_nActiveElements) {
750 bool valid_set = m_elements[m_nElements].set(0,(*iter_boundaryLink),iter_stripClusterColl,iter_StripClusterCollEnd,theCluster,ctx);
751 if(m_tools->isITkGeometry() && !valid_set) return false;
752 }
754 else {
756 continue;
757 }
762 if (++m_nElements==300) break;
763 }
764
766 if (m_firstElement == m_nElements-1) {
767 up = m_nElements-1;
768 if (!m_elements[up].firstTrajectorElement(Tp, ctx)) return false;
772 }
774 else if (theCluster) {
775
777 if (!m_elements[m_nElements-1].ForwardPropagationWithoutSearch(m_elements[up],ctx)) {
778 return false;
779 }
781 up = m_nElements-1;
783 if (m_elements[m_nElements-1].xi2F() <= Xi2cut) {
784 last=up;
785 }
787 else {
788 if (m_tools->isITkGeometry()) return false;
789 else{
791 ndfwrong+=m_elements[m_nElements-1].ndf();
793 if (ndfwrong > 3) return false;
797 --m_nclusters;
799 m_elements[m_nElements-1].eraseClusterForwardPropagation();
800 }
801 }
802 }
806 else if (m_nclusters && !lSiCluster.empty()) {
809 if (!m_elements[m_nElements-1].ForwardPropagationWithoutSearch(m_elements[up], ctx)) {
811 if(not m_tools->isITkGeometry() and m_elements[m_nElements-1].cluster()) return false;
814 --m_nElements;
816 if (m_elements[m_nElements-1].detstatus()) --m_nActiveElements;
817 }
819 else {
821 if (m_elements[m_nElements-1].inside()<0) ++m_nholes;
823 up = m_nElements-1;
824 }
825 }
826 }
827
829 if (!lSiCluster.empty()) {
831 rquality = false;
832 return false;
833 }
836 if (not m_tools->isITkGeometry() && ndfwrong && m_ndfcut < 6) return false;
837
839 m_ndf = m_ndfcut;
841 if (m_tools->isITkGeometry() || m_ndfcut > 6) m_ndfcut = 6;
842
844 int n = m_nElements-1;
846 for (; n>0; --n) {
848 if (m_elements[n].detstatus()>=0) break;
849 }
852 m_nElements = n+1;
853
855 for (; n>0; --n) {
856 if (m_elements[n].detstatus() == 1) {
857 m_elements[n].lastActive();
858 break;
859 }
860 }
861
864 int m = m_firstElement+1;
865 m_lastElement = last ;
868 for (n = m; n!=m_lastElement; ++n) {
872 if (En.cluster() || En.inside() <= 0) m_elementsMap[m++] = m_elementsMap[n];
873 }
875
877 if (m!=n) {
879 m_lastElement = m;
881 for (; n!=m_nElements; ++n){
883 }
884 m_nElements = m;
885 }
886 if (!m_tools->bremNoise()) return true;
887
889 for (n=m_lastElement; n!=m_nElements; ++n) {
890 m_elements[m_elementsMap[n]].bremNoiseModel();
891 }
892 return true;
893}
894
896// Seacrh cluster compatible with track parameters
898
900(const InDet::PixelClusterContainer* PIXc ,
901 const InDet::SCT_ClusterContainer* SCTc ,
902 const Trk::TrackParameters & Tp ,
903 std::vector<const InDet::SiDetElementBoundaryLink_xk*> & DE ,
904 std::multimap<const Trk::PrepRawData*,const Trk::Track*>& PT ,
905 std::vector<const InDet::SiCluster*> & lSiCluster,
906 const EventContext& ctx)
907{
908 m_nElements = 0;
909 m_ndf = 0;
910
911 std::multimap<double,const InDet::SiCluster*> xi2cluster;
912
913 std::vector<const InDet::SiDetElementBoundaryLink_xk*>::iterator iter_boundaryLink,endBoundaryLinks=DE.end();
914 std::multimap<const Trk::PrepRawData*,const Trk::Track*>::const_iterator t, te =PT.end();
915
916 double xi2Cut = .5;
917 int ndfCut = 6;
918
919 for (iter_boundaryLink=DE.begin(); iter_boundaryLink!=endBoundaryLinks; ++iter_boundaryLink) {
920
921 const InDetDD::SiDetectorElement* detectorElement = (*iter_boundaryLink)->detElement();
922 IdentifierHash id = detectorElement->identifyHash();
923
924 bool sct = detectorElement->isSCT();
925
926 if (!sct) {
927 InDet::PixelClusterCollection::const_iterator sib, sie;
928 const InDet::PixelClusterCollection *w = (*PIXc).indexFindPtr(id);
929
930 if (w!=nullptr && w->begin()!=w->end()) {
931 sib = w->begin();
932 sie = w->end ();
933 } else {
934 continue;
935 }
936 if (!m_elements[0].ForwardPropagationForClusterSeach(m_nElements,Tp,(*iter_boundaryLink),sib,sie,ctx)) return false;
937 } else {
938 InDet::SCT_ClusterCollection::const_iterator sib, sie;
939 const InDet::SCT_ClusterCollection *w = (*SCTc).indexFindPtr(id);
940
941 if (w!=nullptr && w->begin()!=w->end()) {
942 sib = w->begin();
943 sie = w->end ();
944 } else {
945 continue;
946 }
947 if (!m_elements[0].ForwardPropagationForClusterSeach(m_nElements,Tp,(*iter_boundaryLink),sib,sie,ctx)) return false;
948 }
949
950 for (int i=0; i!=m_elements[0].nlinksF(); ++i) {
951
952 double x = m_elements[0].linkF(i).xi2();
953
954 if (sct) {
955 t = PT.find(m_elements[0].linkF(i).cluster());
956 if (t!=te && (*t).second->measurementsOnTrack()->size() >= 10) continue;
957 } else {
958 x*=.5;
959 }
960
961 if (x <= xi2Cut) xi2cluster.insert(std::make_pair(x,m_elements[0].linkF(i).cluster()));
962 break;
963 }
964 ++m_nElements;
965 }
966
967 if (xi2cluster.size() < 3) return false;
968
969 std::multimap<double,const InDet::SiCluster*>::iterator xc = xi2cluster.begin(), xce = xi2cluster.end();
970
971 for (; xc!=xce; ++xc) {
972 lSiCluster.push_back((*xc).second);
973 (*xc).second->detectorElement()->isSCT() ? m_ndf+=1 : m_ndf+=2;
974 if ( m_ndf >= ndfCut ) break;
975 }
976
977 return m_ndf >= 6;
978}
979
981// Seacrh cluster compatible with global positions
983
985(const InDet::PixelClusterContainer* PIXc ,
986 const InDet::SCT_ClusterContainer* SCTc ,
987 const std::vector<Amg::Vector3D> & Gp ,
988 std::vector<const InDet::SiDetElementBoundaryLink_xk*> & DE ,
989 std::multimap<const Trk::PrepRawData*,const Trk::Track*>& PT ,
990 std::vector<const InDet::SiCluster*> & lSiCluster)
991{
992 std::vector<const InDet::SiDetElementBoundaryLink_xk*>::iterator iter_boundaryLink = DE.begin(), endBoundaryLinks = DE.end();
993 std::vector<Amg::Vector3D>::const_iterator g,gb = Gp.begin(), ge = Gp.end();
994 InDet::PixelClusterCollection::const_iterator pib, pie;
995 InDet::SCT_ClusterCollection::const_iterator sib, sie;
996 std::multimap<const Trk::PrepRawData*,const Trk::Track*>::const_iterator t, te =PT.end();
997
999
1000 double pv[ 5]={0.,0.,0.,0.,0.};
1001 double cv[15]={ .1 ,
1002 0. , .1,
1003 0. , 0.,.001,
1004 0. , 0., 0.,.001,
1005 0. , 0., 0., 0.,.00001};
1006
1007 double xi2Cut = 10.;
1008 m_ndf = 0 ;
1009
1010 for (; iter_boundaryLink!=endBoundaryLinks; ++iter_boundaryLink) {
1011
1012 const InDetDD::SiDetectorElement* d = (*iter_boundaryLink)->detElement();
1013 IdentifierHash id = d->identifyHash ();
1014 const Trk::Surface* su = &d->surface();
1015 const Trk::PlaneSurface* pla = static_cast<const Trk::PlaneSurface*>(su);
1016 if (!pla) continue;
1017
1018 const Amg::Transform3D& tr = pla->transform();
1019 double Ax[3] = {tr(0,0),tr(1,0),tr(2,0)};
1020 double Ay[3] = {tr(0,1),tr(1,1),tr(2,1)};
1021 double Az[3] = {tr(0,2),tr(1,2),tr(2,2)};
1022 double x0 = tr(0,3);
1023 double y0 = tr(1,3);
1024 double z0 = tr(2,3);
1025 double zcut = .001 ;
1026
1027 bool sct = d->isSCT();
1028 if (!sct) {
1029 const InDet::PixelClusterCollection *w = (*PIXc).indexFindPtr(id);
1030 if (w!=nullptr && w->begin()!=w->end()) {
1031 pib = w->begin();
1032 pie = w->end ();
1033 } else {
1034 continue;
1035 }
1036 } else {
1037 zcut = 1.;
1038 const InDet::SCT_ClusterCollection *w = (*SCTc).indexFindPtr(id);
1039 if (w!=nullptr && w->begin()!=w->end()) {
1040 sib = w->begin();
1041 sie = w->end ();
1042 } else {
1043 continue;
1044 }
1045 }
1046
1047 for (g=gb; g!=ge; ++g) {
1048
1049 double dx = (*g).x()-x0;
1050 double dy = (*g).y()-y0;
1051 double dz = (*g).z()-z0;
1052 double z = dx*Az[0]+dy*Az[1]+dz*Az[2];
1053 if (std::abs(z) > zcut) continue;
1054
1055 pv[0] = dx*Ax[0]+dy*Ax[1]+dz*Ax[2];
1056 pv[1] = dx*Ay[0]+dy*Ay[1]+dz*Ay[2];
1057 //setParametersWithCovariance detects whether su is 'owned' elsewhere
1058 //the ownership patterns could be improved, though.
1059 //coverity[MULTIPLE_INIT_SMART_PTRS]
1060 Tp.setParametersWithCovariance(su,pv,cv);
1061
1062 if (!sct) m_elements[0].CloseClusterSeach(Tp, (*iter_boundaryLink), pib, pie);
1063 else m_elements[0].CloseClusterSeach(Tp, (*iter_boundaryLink), sib, sie);
1064 const InDet::SiCluster* c = m_elements[0].cluster();
1065 if (!c || m_elements[0].xi2F() > xi2Cut) continue;
1066 if (sct) {
1067 t = PT.find(c);
1068 if (t!=te && (*t).second->measurementsOnTrack()->size() >= 10) continue;
1069 }
1070 sct ? m_ndf+=1 : m_ndf+=2;
1071 lSiCluster.push_back(c);
1072 }
1073 }
1074 return m_ndf >= 6;
1075}
1076
1078// Backward test initial trajectory
1080
1081bool InDet::SiTrajectory_xk::backwardSmoother(bool TWO, const EventContext& ctx)
1082{
1083 if (m_firstElement >= m_lastElement) return false;
1084
1085 // Trajectory difference test
1086 //
1087 int m = m_lastElement;
1088 for (; m>=m_firstElement; --m) {
1089 if (m_elements[m_elementsMap[m]].difference()) break;
1090 }
1091 if (m < m_firstElement) return true;
1092
1093 if (!m_elements[m_elementsMap[m_lastElement]].lastTrajectorElement()) return false;
1094
1095 int firstElement = m_lastElement ;
1096 int maxholes = m_tools->maxholes ();
1097 int maxdholes = m_tools->maxdholes();
1098 m_nclustersNoAdd = 0 ;
1099 m_difference = 0 ;
1100
1101 m = m_lastElement-1;
1102 int n = m ;
1103
1104 for (; m>=m_firstElement; --m) {
1105
1108
1109 if (!Em.BackwardPropagationSmoother(En,TWO,ctx)) {
1110
1111 if (m == m_firstElement) break;
1112
1113 for (int i=m+1; i!=m_nElements; ++i) m_elementsMap[i-1] = m_elementsMap[i];
1114 --m_lastElement;
1115 --m_nElements;
1116 --firstElement;
1117 continue;
1118 }
1119
1120 if ((Em.cluster() && Em.clusterOld()) && (Em.cluster()!=Em.clusterOld())) ++m_difference;
1121
1122 if (Em.cluster()) {
1123 firstElement = m;
1124 }
1125 else {
1126 n=m;
1127 if (Em.clusterNoAdd()) ++m_nclustersNoAdd;
1128 if (Em.nholesB() > maxholes || Em.dholesB() > maxdholes) {
1129 ++m_difference; break;
1130 }
1131 }
1132 }
1133
1134 m_firstElement = firstElement ;
1135 m = m_elementsMap[firstElement] ;
1136 n = m_elementsMap[ n ] ;
1137 m_nclusters = m_elements[m].nclustersB() ;
1138 m_nholes = m_elements[m].nholesB () ;
1139 m_nHolesBefore = m_elements[n].nholesB ()-m_nholes;
1140 m_ndf = m_elements[m].ndfB() ;
1141 if (m_ndf < m_ndfcut) return false;
1142
1143 // Erase trajectory elements with big distance from the track
1144 //
1145 m = firstElement+1;
1146 n = m;
1147 for (; m!=m_lastElement; ++m) {
1148
1150 if (Em.inside() > 0) {
1151 if (Em.detstatus() > 0) --m_nActiveElements;
1152 }
1153 else {
1154 m_elementsMap[n++] = m_elementsMap[m];
1155 }
1156 }
1157 m_lastElement = n;
1158
1159 // Test number trajector elemenst with clusters
1160 //
1161 if (m_nActiveElements < m_tools->clustersmin() && m_nholes+m_nHolesAfter) return false;
1162 if (n!=m) {
1163 for (; m!=m_nElements; ++m) m_elementsMap[n++] = m_elementsMap[m];
1164 m_nElements = n;
1165 }
1166 return true;
1167}
1168
1170// Backward trajectory extension
1172
1173bool InDet::SiTrajectory_xk::backwardExtension(int itmax, const EventContext& ctx)
1174{
1175 if (m_firstElement >= m_lastElement) return false;
1176 int L = m_firstElement;
1177 if (L==0) return true;
1178
1179 int MPbest[300] ;
1180 int TE [100] ;
1181 const InDet::SiCluster* CL [100] ;
1182 double XI2B [100] ;
1183 //Local variable PUB uses 27200 bytes of stack space
1184 //coverity[STACK_USE]
1187
1188 int maxholes = m_tools->maxholes ();
1189 int maxdholes = m_tools->maxdholes();
1190 const int itm = itmax-1 ;
1191 int it = 0 ;
1192 int itbest = 0 ;
1193 int qbest =-100 ;
1194 int nbest = 0 ;
1195 int ndfbest = 0 ;
1196 int lbest = L ;
1197 int hbest = 0 ;
1198 int hbestb = 0 ;
1199 int nclbest = 0 ;
1200 int ndcut = 3 ;
1201 int F = L ;
1202 double Xi2best = 0. ;
1203
1204 m_elements[m_elementsMap[F]].setNdist(0);
1205
1206 for (; it!=itmax; ++it) {
1207
1208 int l = F;
1209 int lastElementWithExpHit = F;
1210
1211 for (--F; F>=0; --F) {
1212
1215
1216 if (!Ef.BackwardPropagationFilter(El, ctx)) break;
1217
1218 if (Ef.cluster()) {
1219 lastElementWithExpHit = F;
1220 l = F;
1221 }
1222 else if (Ef.inside() < 0) {
1223 lastElementWithExpHit = F;
1224 if (Ef.nholesB() > maxholes || Ef.dholesB() > maxdholes) break;
1225 }
1226
1227 int nm = Ef.nclustersB()+F;
1228 if (Ef.ndist() > ndcut ||
1229 nm < nclbest ||
1230 (nm == nclbest && Ef.xi2totalB() > Xi2best) ) break;
1231 }
1232
1233 int fl = F;
1234 if (fl<0) fl = 0;
1235
1236 int m = m_elementsMap.at(l);
1237 int nc = m_elements[m].nclustersB();
1238
1239 if (it==0 && nc==m_nclusters) return true;
1240
1241 int np = m_elements[m].npixelsB();
1242 int nh = m_elements[m].nholesB();
1243 int nd = m_elements[m_elementsMap[fl]].ndist();
1244 int q = nc-nh;
1245 double X = m_elements[m].xi2totalB();
1246
1247 if ( (q > qbest) || (q==qbest && X < Xi2best ) ) {
1248
1249 qbest = q ;
1250 nbest = 0 ;
1251 ndfbest = 0 ;
1252 hbest = nh ;
1253 hbestb = m_elements[m_elementsMap[lastElementWithExpHit]].nholesB()-nh ;
1254 itbest = it ;
1255 Xi2best = X ;
1256 PA = m_elements[m_elementsMap.at(l)].parametersUB();
1257
1258 if (fl==0 && nd < ndcut) ndcut = nd;
1259
1260 if (fl!=0 || nd > 0 || np < 3) {
1261
1262 lbest = l-1;
1263 for (int i=l; i!=L; ++i) {
1264
1266
1267 if (Ei.inside() <= 0 ) {
1268 MPbest[++lbest] = i;
1269 if (Ei.cluster()) {
1270 CL[nbest] = Ei.cluster();
1271 XI2B[nbest] = Ei.xi2B();
1272 PUB[nbest] = Ei.parametersUB();
1273 TE[nbest++] = lbest;
1274 ndfbest += Ei.ndf();
1275 }
1276 }
1277 }
1278 }
1279 else {
1280
1281 l = -1;
1282 lbest = fl-1;
1283 for (int i=fl; i!=L; ++i) {
1284
1286
1287 if (Ei.inside() <= 0 && ++lbest >=0 ) {
1288 MPbest[lbest] = lbest;
1289 if (Ei.cluster()) {
1290 CL[nbest] = Ei.cluster();
1291 XI2B[nbest] = Ei.xi2B();
1292 PUB[nbest] = Ei.parametersUB();
1293 TE[nbest++] = lbest;
1294 ndfbest += Ei.ndf();
1295 if (l<0) l=lbest;
1296 }
1297 m_elementsMap.at(lbest) = m_elementsMap.at(i);
1298 }
1299
1300 }
1301
1302 int dn = L-1-lbest;
1303
1304 if (dn!=0) {
1305
1306 for (int i=L; i!= m_nElements; ++i) {
1307 m_elementsMap.at(i-dn)=m_elementsMap.at(i);
1308 }
1309
1310 L -=dn;
1311 m_nElements -=dn;
1312 m_lastElement-=dn;
1313 }
1314 }
1315 nclbest = m_nclusters+nbest;
1316 }
1317
1318 F = -1;
1319 if (l<=0) l=1;
1320 bool cl = false;
1321 double Xn = 0.;
1322
1323 for (; l < L; ++l) {
1325
1326 if (Ei.cluster() && Ei.isNextClusterHoleB(cl,Xn)) {
1327 int nm = l+Ei.nclustersB();
1328 if (!cl) {
1329 if (Ei.dist() < -2. && Ei.ndist() > ndcut-1 ) continue;
1330 --nm;
1331 }
1332 if (nm < nclbest || (nm == nclbest && Xn > Xi2best)) continue;
1333 F=l; break;
1334 }
1335 }
1336
1337 if (F < 0 ) break;
1338 if (it!=itm) if (!m_elements[m_elementsMap[F]].addNextClusterB()) break;
1339 }
1340 if (it == itmax) --it;
1341 if (!nbest) return true;
1342
1343 m_nholes = hbest ;
1344 m_nHolesBefore = hbestb;
1345 m_nclusters += nbest ;
1346 m_ndf += ndfbest;
1347 m_firstElement = TE[0] ;
1348 m_elements[m_elementsMap[TE[0]]].setParametersB(PA);
1349
1350 int dn = L-1-lbest;
1351
1352 if (dn != 0) {
1353
1354 m_nElements -=dn;
1355 m_lastElement-=dn;
1356
1357 int n = m_firstElement;
1358 for (; n <= lbest ; ++n) m_elementsMap[n]=m_elementsMap[MPbest[n]];
1359 for (; n!= m_nElements; ++n) m_elementsMap[n]=m_elementsMap[n +dn ];
1360 }
1361
1362 if (itbest==it) return true;
1363
1364 for (int n = L-1-dn; n>=0; --n) {
1365
1367 int m = nbest-1;
1368 for (; m>=0; --m) if (TE[m]==n) break;
1369
1370 if (m>=0) {
1371 if (m_tools->useFastTracking()) {
1372 En.setClusterB(CL[m],XI2B[m]);
1373 En.setParametersB(PUB[m]);
1374 }
1375 else En.setCluster(CL[m]);
1376 if (--nbest==0) break;
1377 }
1378 else {
1379 if (m_tools->useFastTracking()) En.setClusterB( nullptr ,10000.);
1380 else En.setCluster( nullptr );
1381 }
1382 }
1383 return true;
1384}
1385
1387// Forward trajectory extension
1389
1390bool InDet::SiTrajectory_xk::forwardExtension(bool smoother,int itmax, const EventContext& ctx)
1391{
1392 const double pi2 = 2.*M_PI;
1393 const double pi = M_PI;
1394
1395 if (m_firstElement >= m_lastElement) return false;
1396
1398 int extensionStartIndex = m_lastElement;
1400 int lastElementOnTraj = m_nElements-1;
1401
1404 if (smoother) {
1405
1406 extensionStartIndex = m_firstElement;
1407
1410 if (m_elements[m_elementsMap[extensionStartIndex]].difference()) {
1413
1415 if (!m_elements[m_elementsMap[extensionStartIndex]].firstTrajectorElement(false)) return false;
1417 for (++extensionStartIndex; extensionStartIndex<=m_lastElement; ++extensionStartIndex) {
1418 InDet::SiTrajectoryElement_xk& previousElement = m_elements[m_elementsMap[extensionStartIndex-1]];
1419 InDet::SiTrajectoryElement_xk& thisElement = m_elements[m_elementsMap[extensionStartIndex ]];
1421 if (!thisElement.ForwardPropagationWithoutSearch(previousElement,ctx)) return false;
1422 }
1423 }
1426 else{
1427 bool diff = false;
1429 for (++extensionStartIndex; extensionStartIndex<=m_lastElement; ++extensionStartIndex) {
1430
1431 InDet::SiTrajectoryElement_xk& previousElement = m_elements[m_elementsMap[extensionStartIndex-1]];
1432 InDet::SiTrajectoryElement_xk& thisElement = m_elements[m_elementsMap[extensionStartIndex ]];
1435 if (!diff) {
1437 diff = thisElement.difference();
1439 if (diff) {
1441 if (!thisElement.addNextClusterF(previousElement,thisElement.cluster())) return false;
1442 }
1443 }
1445 else {
1447 if (!thisElement.ForwardPropagationWithoutSearch(previousElement,ctx)) return false;
1448 }
1449 }
1450 }
1451 --extensionStartIndex;
1452 }
1453
1455 if ( extensionStartIndex== lastElementOnTraj) return true;
1456
1457 // Search best forward trajectory prolongation
1460 int MP [300] ;
1461 int MPbest[300] ;
1463 int TE [100] ;
1465 const InDet::SiCluster* CL [100] ;
1466
1468 int maxholes = m_tools->maxholes () ;
1469 int maxdholes = m_tools->maxdholes() ;
1471 const int itm = itmax-1 ;
1473 int iteration = 0 ;
1475 int itbest = 0 ;
1477 int qbest =-100 ;
1479 int nbest = 0 ;
1480 int ndfbest = 0 ;
1482 int hbest = 0 ;
1484 int hbeste = 0 ;
1486 int ndbest = 0 ;
1488 int ndcut = 3 ;
1490 int nclbest = 0 ;
1492 int lbest = extensionStartIndex ;
1494 int index_currentElement = extensionStartIndex ;
1496 int M = extensionStartIndex ;
1498 MP [M] = extensionStartIndex ;
1499 double Xi2best = 0. ;
1501 const double dfmax = 2.2 ;
1502
1504 double f0 = m_elements[m_elementsMap[m_firstElement]].parametersUF().parameters()[2];
1505
1506
1507 m_elements[m_elementsMap.at(index_currentElement)].setNdist(0);
1508
1510 for (; iteration!=itmax; ++iteration) {
1511
1512 int lastElementWithSeenHit = index_currentElement;
1513 int lastElementWithExpHit = index_currentElement;
1515 int index_previousElement = index_currentElement;
1517 int mLastCluster = M;
1519 int Cm = nclbest-lastElementOnTraj;
1521 bool haveHole = false;
1522
1525 for (++index_currentElement; index_currentElement!=m_nElements; ++index_currentElement) {
1526
1528 InDet::SiTrajectoryElement_xk& prevElement = m_elements[m_elementsMap.at(index_previousElement)];
1529 InDet::SiTrajectoryElement_xk& currentElement = m_elements[m_elementsMap.at(index_currentElement )];
1530
1532 if (!currentElement.ForwardPropagationWithSearch(prevElement, ctx)) {
1534
1536 if (!currentElement.isBarrel() || index_previousElement!=index_currentElement-1) break;
1537
1541 int index_auxElement = index_currentElement;
1542 for (; index_auxElement!=m_nElements; ++index_auxElement) {
1543 if (!m_elements[m_elementsMap[index_auxElement]].isBarrel() ) break;
1544 }
1546 if (index_auxElement==m_nElements) break;
1547
1551 index_currentElement = index_auxElement-1;
1552 continue;
1553 }
1554
1557 else {
1560 index_previousElement = index_currentElement;
1561 }
1563
1565 MP[++M] = index_currentElement;
1566
1568 if (currentElement.cluster()) {
1569 if (not m_tools->isITkGeometry()) {
1571 double df = std::abs(currentElement.parametersUF().parameters()[2]-f0);
1573 if (df > pi) df = pi2-df;
1575 if (df > dfmax) break;
1576 }
1578 lastElementWithExpHit = index_currentElement;
1579 lastElementWithSeenHit = index_currentElement;
1580 mLastCluster = M;
1581 haveHole = false;
1582 }
1583
1585 else if (currentElement.inside() < 0 ) {
1586 lastElementWithExpHit=index_currentElement;
1588 if (currentElement.nholesF() > maxholes || currentElement.dholesF() > maxdholes) break;
1589
1590 haveHole = true;
1591 if (not m_tools->isITkGeometry()) {
1593 double df = std::abs(currentElement.parametersPF().parameters()[2]-f0);
1594 if (df > pi) df = pi2-df;
1595 if (df > dfmax ) break;
1596 }
1597 }
1598
1600 else if (not m_tools->isITkGeometry()) {
1602 double df = std::abs(currentElement.parametersPF().parameters()[2]-f0);
1603 if (df > pi) df = pi2-df;
1604 if (df > dfmax) break;
1605 }
1608 int nm = currentElement.nclustersF()-index_currentElement;
1610 if ( currentElement.ndist() > ndcut
1611 || nm < Cm
1612 || (nm == Cm && currentElement.xi2totalF() > Xi2best)
1613 ) break;
1614 }
1615
1617
1619 int m = m_elementsMap[lastElementWithSeenHit];
1621 int nc = m_elements[m].nclustersF();
1623 int nh = m_elements[m].nholesF();
1625 m_nHolesAfter = m_elements[m_elementsMap[lastElementWithExpHit]].nholesF()-nh;
1626
1629 if (iteration==0 && nc==m_nclusters) return true;
1630
1632 int lastElementProcessed = index_currentElement;
1634 if (lastElementProcessed==m_nElements) --lastElementProcessed;
1635
1637 int nd = m_elements[m_elementsMap[lastElementProcessed]].ndist();
1640 int q = nc-nh;
1642 double X = m_elements[m].xi2totalF();
1644 if ( (q > qbest) || (q==qbest && X < Xi2best ) ) {
1646 qbest = q;
1648 nbest = 0;
1650 ndfbest = 0;
1652 hbest = nh;
1654 hbeste = m_elements[m_elementsMap[lastElementWithExpHit]].nholesF()-nh;
1656 itbest = iteration;
1659 lbest = extensionStartIndex ;
1661 Xi2best = X ;
1663 ndbest = nd;
1666 if (lastElementProcessed==lastElementOnTraj && nd < ndcut) ndcut = nd;
1667
1669 for (int j=extensionStartIndex+1; j<=mLastCluster; ++j) {
1671 int i = MP[j];
1674 if (Ei.inside() <= 0) {
1676 MPbest[++lbest] = i;
1678 if (Ei.cluster()) {
1680 CL[nbest] = Ei.cluster();
1681 TE[nbest++] = lbest;
1683 ndfbest += Ei.ndf();
1684 }
1685 }
1686 }
1688 nclbest = m_nclusters+nbest;
1691 if ( (nclbest >= 14 && !haveHole) || (lastElementProcessed==lastElementOnTraj && ndbest == 0)) break;
1692 }
1693
1695 index_currentElement = -1;
1697 bool cl = false;
1699 int nb = lastElementOnTraj-nclbest-1;
1701 double Xn;
1702
1708
1710 for (int j=mLastCluster; j!=extensionStartIndex; --j) {
1712 int i = MP[j];
1714
1716 if (i!=lastElementOnTraj && Ei.cluster() && Ei.isNextClusterHoleF(cl,Xn)) {
1717
1721 int nm = nb-i+Ei.nclustersF();
1722
1724 if (!cl) {
1727 if (Ei.dist() < -2. && Ei.ndist() > ndcut-1) continue;
1728 }
1730 else ++nm;
1731
1734 if (nm < 0 || (nm == 0 && Xn > Xi2best)) continue;
1736 index_currentElement = i;
1737 M = j;
1738 break;
1739 }
1740 }
1741
1743 if (index_currentElement < 0 ) break;
1746 if (iteration!=itm && !m_elements.at(m_elementsMap.at(index_currentElement)).addNextClusterF()) break;
1747 }
1748
1750 if (iteration == itmax) --iteration;
1751
1753 if (!nbest) return true;
1754
1756 m_nholes = hbest ;
1757 m_nHolesAfter = hbeste ;
1758 m_nclusters += nbest ;
1759 m_ndf += ndfbest ;
1760 m_lastElement = TE[nbest-1];
1762
1764 if (m_lastElement != MPbest[m_lastElement]) {
1766 for (int n = extensionStartIndex+1; n<=m_lastElement; ++n){
1767 m_elementsMap[n]=m_elementsMap[MPbest[n]];
1768 }
1769 }
1771 if (itbest==iteration) return true;
1772
1774 int mb = 0;
1776 index_currentElement = -1;
1777
1779 for (int n = extensionStartIndex+1; n!=m_nElements; ++n) {
1782
1783 int m = mb;
1785 for (; m!=nbest; ++m) if (TE[m]==n) break;
1787 if (m!=nbest) {
1789 if (CL[m]!=En.cluster()) {
1791 if (index_currentElement<0) {
1793 index_currentElement=n;
1797 }
1800 else {
1801 En.setCluster(CL[m]);
1802 }
1803 }
1805 if (++mb == nbest) break;
1806 }
1808 else {
1810 if (En.cluster()) {
1812 if (index_currentElement<0) {
1813 index_currentElement = n;
1815 En.addNextClusterF(m_elements[m_elementsMap[n-1]],nullptr);
1816 }
1819 else {
1821 En.setCluster(nullptr);
1822 }
1823 }
1824 }
1825 }
1826
1829 if (index_currentElement < 0 || m_lastElement == index_currentElement) {
1830 return true;
1831 }
1832
1835 for (++index_currentElement; index_currentElement<=m_lastElement; ++index_currentElement) {
1836 InDet::SiTrajectoryElement_xk& prevElement = m_elements[m_elementsMap.at(index_currentElement-1)];
1837 InDet::SiTrajectoryElement_xk& currentElement = m_elements[m_elementsMap.at(index_currentElement)];
1838 if (!currentElement.ForwardPropagationWithoutSearch(prevElement, ctx)) return false;
1839 }
1841 return true;
1842}
1843
1845// Get clusters list from trajectory
1847
1849(std::vector<const InDet::SiCluster*>& Cl) const
1850{
1851 for (int i = m_firstElement; i<=m_lastElement; ++i) {
1852 int m = m_elementsMap[i];
1853 if (m_elements[m].cluster()) Cl.push_back(m_elements[m].cluster());
1854 }
1855}
1856
1858// Forward filter without search
1860
1861bool InDet::SiTrajectory_xk::forwardFilter(const EventContext& ctx)
1862{
1863 int L = m_firstElement;
1864
1865 if (!m_elements[m_elementsMap[L]].firstTrajectorElement(false)) return false;
1866
1867 for (++L; L<=m_lastElement; ++L) {
1868
1871 if (!Ef.ForwardPropagationWithoutSearch(El,ctx)) return false;
1872 }
1873 return true;
1874}
1875
1876
1878// Filter with precise clusters error
1880
1882{
1883 int L = m_firstElement;
1884 int I = 0 ;
1885
1886 if(!m_elements[m_elementsMap[L]].cluster()) return false;
1888
1889 for(++L; L<=m_lastElement; ++L) {
1890
1891 int K = m_elementsMap[L];
1892 if(m_elements[K].cluster() ||
1893 m_elements[K].clusterNoAdd() ||
1894 m_elements[K].inside() < 0 ) m_elementsMap[++I] = K;
1895 }
1896 m_firstElement = 0 ;
1897 m_lastElement = I ;
1898 m_nElements = I+1;
1899
1900 // Forward filter
1901 //
1902 L = 0;
1903
1904 // firstTrajectorElement with correction = true
1905 if(!m_elements[m_elementsMap[L]].firstTrajectorElement(true)) return false;
1906
1907 for(++L; L<=m_lastElement; ++L) {
1908
1911
1912 if(!Ef.ForwardPropagationWithoutSearchPreciseWithCorrection(El, ctx)) return false;
1913 }
1914
1915 // Backward smoother
1916 //
1917 if(!m_elements[m_elementsMap[m_lastElement]].lastTrajectorElementPrecise()) return false;
1918
1919 int m = m_lastElement-1;
1920 for(; m>=0; --m) {
1921
1924
1925 if(!Em.BackwardPropagationPrecise(En, ctx)) return false;
1926 }
1927
1928 return true;
1929}
1930
1931
1933// Test order of detector elements
1935
1937{
1938 int L = m_firstElement ;
1939 int n = m_elementsMap[L];
1940 double step = 0. ;
1941 bool order = true ;
1942
1943 for (++L; L<=m_lastElement; ++L) {
1944
1945 int m = m_elementsMap[L];
1946 if (!m_elements[m].cluster() &&
1947 !m_elements[m].clusterNoAdd() &&
1948 m_elements[m].inside()>=0) continue;
1949
1950 double stp = m_elements[m].step(m_elements[n]);
1951 if ( step == 0.) step = stp ;
1952 else if ((step*stp) < 0.) {order = false; break;}
1953 n = m;
1954 }
1955 if (order) return true;
1956
1957 L = m_firstElement ;
1958 n = m_elementsMap[L];
1959 Amg::Vector3D gp = m_elements[n].globalPosition();
1960 double rad = gp.x()*gp.x()+gp.y()*gp.y();
1961 for (++L; L<=m_lastElement; ++L) {
1962
1963 int m = m_elementsMap[L];
1964 if (!m_elements[m].cluster() &&
1965 !m_elements[m].clusterNoAdd() &&
1966 m_elements[m].inside()>=0) continue;
1967
1968 gp = m_elements[m].globalPosition();
1969 double R = gp.x()*gp.x()+gp.y()*gp.y();
1970 if (R < rad) return false;
1971 rad = R;
1972 n=m;
1973 }
1974 return true;
1975}
1976
1978// Sort of detector elements in step order
1980
1982{
1983 int L = m_firstElement;
1984 int LA = m_firstElement;
1985
1986 for (++L; L<=m_lastElement; ++L) {
1987
1988 int m = m_elementsMap[L];
1989 if (!m_elements[m].cluster() &&
1990 !m_elements[m].clusterNoAdd() &&
1991 m_elements[m].inside()>=0) continue;
1992
1993 m_elementsMap[++LA] = m;
1994 }
1995
1996 m_lastElement = LA;
1997 L = m_firstElement;
1998 m_nElements = LA+1;
1999
2000 bool nc = true;
2001 bool so = true;
2002 double ds = m_elements[m_elementsMap[LA]].step()-m_elements[m_elementsMap[L]].step();
2003
2004 if (ds > 0.) { // Sort in increase order
2005
2006 while(nc) {
2007 nc = false;
2008 int m = L, n = L+1;
2009 for (; n<=LA; ++n) {
2010
2011 int Mn = m_elementsMap[n];
2012 int Mm = m_elementsMap[m];
2013
2014 if (m_elements[Mn].step() < m_elements[Mm].step()) {
2015 if (m_elements[Mn].step(m_elements[Mm]) < 0.) {
2016 m_elementsMap[m] = Mn;
2017 m_elementsMap[n] = Mm;
2018 nc = true; so = false;
2019 }
2020 }
2021 ++m;
2022 }
2023 }
2024 }
2025 else {
2026
2027 while(nc) { // Sort in decrease order
2028 nc = false;
2029 int m = L, n = L+1;
2030 for (; n<=LA; ++n) {
2031
2032 int Mn = m_elementsMap[n];
2033 int Mm = m_elementsMap[m];
2034
2035 if (m_elements[Mn].step() > m_elements[Mm].step()) {
2036 if (m_elements[Mn].step(m_elements[Mm]) > 0.) {
2037 m_elementsMap[m] = Mn;
2038 m_elementsMap[n] = Mm;
2039 nc = true; so = false;
2040 }
2041 }
2042 ++m;
2043 }
2044 }
2045 }
2046 if (so) return;
2047
2048 // Search first detector elements with cluster
2049 //
2050 int n = L;
2051 for (; n<= LA; ++n) {
2052
2053 int e = m_elementsMap[n];
2054 if (m_elements[e].cluster()) break;
2055 if (m_elements[e].clusterNoAdd()) --m_nclustersNoAdd;
2056 else if (m_elements[e].inside() < 0 &&
2057 m_elements[e].detstatus()>=0) {--m_nholes; ++m_nHolesBefore;}
2058 }
2059
2060 // Search last detector elements with cluster
2061 //
2062 int m = LA;
2063 for (; m>=n ; --m) {
2064
2065 int e = m_elementsMap[m];
2066 if (m_elements[e].cluster()) break;
2067 if (m_elements[e].clusterNoAdd()) --m_nclustersNoAdd;
2068 else if (m_elements[e].inside() < 0 &&
2069 m_elements[e].detstatus()>=0) {--m_nholes; ++m_nHolesAfter;}
2070 }
2071 m_firstElement = n;
2072 m_lastElement = m;
2073
2074}
2075
2077// Test possibility for trajectory to jump through perigee
2079
2081{
2082 int i = m_firstElement;
2083 double St = m_elements[m_elementsMap[m_lastElement]].step()-m_elements[m_elementsMap[i]].step();
2084
2085 for (; i<=m_lastElement; ++i) {
2086 int m = m_elementsMap[i];
2087 if (m_elements[m].cluster() &&
2088 (m_elements[m].ndf()!=2 || (m_elements[m].stepToPerigee()*St) <= 0.)) break;
2089
2090 if (m_elements[m].cluster()){
2091 --m_nclusters;
2092 m_ndf -= m_elements[m].ndf();
2093 }
2094 else if (m_elements[m].clusterNoAdd()) --m_nclustersNoAdd;
2095 else --m_nholes ;
2096 }
2097
2098 if (i == m_firstElement) return false;
2099 m_firstElement = i;
2100 return true;
2101}
2102
2104// Trajectory quality without optimization
2106
2108{
2109 int holes = 0 ;
2110 double quality = 0.;
2111
2112 for (int i = m_firstElement; i<=m_lastElement; ++i) {
2113 quality+=m_elements[m_elementsMap[i]].quality(holes);
2114 }
2115 return quality;
2116}
2117
2119// Trajectory quality with otimization
2121
2123{
2124 int lE = m_firstElement;
2125 int h = 0 ;
2126 double q = 0 ;
2127 double qM = 0. ;
2128
2129 for (int i = m_firstElement; i<=m_lastElement; ++i) {
2130 int m = m_elementsMap[i];
2131 q+=m_elements[m].quality(h);
2132 if (m_elements[m].cluster() && q > qM) {
2133 qM = q;
2134 lE = i;
2135 }
2136 }
2137
2138 if (lE == m_firstElement) return -100;
2139
2140 int fE = lE;
2141 int nclustersNoAdd = 0 ;
2142 int nclusters = 0 ;
2143 int nholes = 0 ;
2144 int dholes = 0 ;
2145 int ndf = 0 ;
2146 h = 0 ;
2147 q = 0.;
2148 qM = 0.;
2149
2150 for (int i = lE; i>=m_firstElement; --i) {
2151
2152 int m = m_elementsMap[i];
2153 q+=m_elements[m].quality(h);
2154
2155 if (m_elements[m].cluster()) {
2156
2157 ++nclusters;
2158 ndf+=m_elements[m].ndf();
2159
2160 if (q > qM) {
2161 qM = q;
2162 fE = i;
2165 m_nholes = nholes ;
2166 m_dholes = dholes ;
2167 m_ndf = ndf ;
2168 }
2169
2170 }
2171 else if (m_elements[m].clusterNoAdd()) {
2173 }
2174 else if (m_elements[m].inside() < 0 && m_elements[m].detstatus() >=0) {
2175 ++nholes;
2176 if (h > dholes) dholes = h;
2177 }
2178 }
2179
2180 if (fE==lE || m_nclusters+m_nclustersNoAdd < m_tools->clustersmin()) return -100.;
2181 m_firstElement = fE;
2182 m_lastElement = lE;
2183 return qM;
2184}
2185
2187// Trajectory conversion to TrackStateOnSurface for next tracks
2189
2192{
2193 int i=0;
2194 for (; i!=m_ntos; ++i) {
2195 if (m_itos[i]+1 < m_elements[m_atos[i]].ntsos()) {++m_itos[i]; break;}
2196 m_itos[i] = 0;
2197 }
2198 if (i==m_ntos) {
2199 return Trk::TrackStates();
2200 }
2201
2202 auto dtsos = Trk::TrackStates();
2203
2204 for (i=0; i!=m_ntos; ++i) {
2205
2206 Trk::TrackStateOnSurface* tsos = m_elements[m_atos[i]].tsos(m_itos[i]);
2207 if (tsos) dtsos.push_back(tsos);
2208 }
2209 return dtsos;
2210}
2211
2213// pT of the first elementtrajectory
2215
2217{
2218 int n = m_firstElement ; if (n <0 || n>=300) return 0.;
2219 n = m_elementsMap[n]; if (n <0 || n>=300) return 0.;
2220 int s = m_elements[n].status();
2221 if (s<=1) return 0.;
2222 return m_elements[n].parametersUB().momentum().perp();
2223}
2224
2227
2230
2232 bool prevIsSctHole = false;
2233
2235
2236 for (int theEle = m_firstElement+1; theEle<m_lastElement; ++theEle) {
2238 int m = m_elementsMap[theEle];
2239 InDet::SiTrajectoryElement_xk & theElement = m_elements[m];
2241 bool isPix = theElement.ndf() == 2;
2242 bool isSCTHole=false;
2243
2246 if (theElement.cluster() || theElement.clusterNoAdd()) {
2247 prevIsSctHole = false;
2248 continue;
2249 }
2250
2252 else {
2253 std::unique_ptr<const Trk::TrackParameters> pars {theElement.trackParameters(true,0)};
2254 Trk::BoundaryCheckResult boundaryStatus = m_tools->boundaryCheckTool()->boundaryCheck(*pars);
2255 switch (boundaryStatus){
2259 if (isPix) {
2260 ++m_patternHoleOutcome.nPixelHoles;
2261 }
2262 else {
2263 ++m_patternHoleOutcome.nSCTHoles;
2264 isSCTHole=true;
2265 }
2266 break;
2273 break;
2276 if (isPix){
2277 ++m_patternHoleOutcome.nPixelDeads;
2278 }
2279 else{
2280 ++m_patternHoleOutcome.nSCTDeads;
2281 }
2282 break;
2283 }
2284 }
2285
2288 if (isSCTHole && prevIsSctHole){
2289 prevIsSctHole = false;
2290 ++m_patternHoleOutcome.nSCTDoubleHoles;
2291 }
2292 else {
2293 prevIsSctHole = isSCTHole;
2294 }
2295 }
2296 if (m_patternHoleOutcome.nPixelHoles+m_patternHoleOutcome.nSCTHoles > m_tools->maxholes()
2297 || m_patternHoleOutcome.nSCTDoubleHoles > m_tools->maxdholes()){
2298 m_patternHoleOutcome.passPatternHoleCut = false;
2299 }
2300}
const std::regex re(r_e)
#define M_PI
static Double_t Tp(Double_t *t, Double_t *par)
#define F(x, y, z)
Definition MD5.cxx:112
#define I(x, y, z)
Definition MD5.cxx:116
void diff(const Jet &rJet1, const Jet &rJet2, std::map< std::string, double > varDiff)
Difference between jets - Non-Class function required by trigger.
Definition Jet.cxx:631
@ cosmic
struct TBPatternUnitContext S2
struct TBPatternUnitContext S1
#define pi
#define x
#define z
Header file for AthHistogramAlgorithm.
This is a "hash" representation of an Identifier.
Class to hold geometrical description of a silicon detector element.
virtual IdentifierHash identifyHash() const override final
identifier hash (inline)
Trk::Surface & surface()
Element Surface.
bool ForwardPropagationWithSearch(SiTrajectoryElement_xk &, const EventContext &)
const Trk::PatternTrackParameters & parametersUF() const
updated
bool BackwardPropagationFilter(SiTrajectoryElement_xk &, const EventContext &ctx)
bool BackwardPropagationSmoother(SiTrajectoryElement_xk &, bool, const EventContext &ctx)
std::unique_ptr< Trk::TrackParameters > trackParameters(bool, int)
bool ForwardPropagationWithoutSearch(SiTrajectoryElement_xk &, const EventContext &)
const InDet::SiCluster * clusterOld() const
const Trk::PatternTrackParameters & parametersUB() const
observed
const InDet::SiCluster * cluster() const
void setCluster(const InDet::SiCluster *)
const InDet::SiCluster * clusterNoAdd() const
void setParametersB(Trk::PatternTrackParameters &)
bool ForwardPropagationWithoutSearchPreciseWithCorrection(SiTrajectoryElement_xk &, const EventContext &)
void setClusterB(const InDet::SiCluster *, double)
bool BackwardPropagationPrecise(SiTrajectoryElement_xk &, const EventContext &ctx)
const Trk::PatternTrackParameters & parametersPF() const
track parameters for forward filter / smoother predicted
const int & ndist() const
number of crossed without hit - dead + holes
bool isNextClusterHoleF(bool &, double &)
checks if removing this cluster from the forward propagation would result in a critical number of hol...
bool difference() const
check for a difference between forward and back propagation
void updateHoleSearchResult()
Helper method to determine the hole search outcome for use in the later reco.
Trk::TrackStates convertToSimpleTrackStateOnSurface(const EventContext &ctx)
std::array< SiTrajectoryElement_xk, 300 > m_elements
PatternHoleSearchOutcome m_patternHoleOutcome
int m_nclustersNoAdd
Number of clusters on trajectory.
bool globalPositionsToClusters(const PixelClusterContainer *, const SCT_ClusterContainer *, const std::vector< Amg::Vector3D > &, std::vector< const InDet::SiDetElementBoundaryLink_xk * > &, std::multimap< const Trk::PrepRawData *, const Trk::Track * > &, std::vector< const InDet::SiCluster * > &)
bool backwardExtension(int, const EventContext &)
bool initialize(bool, bool, const PixelClusterContainer *, const SCT_ClusterContainer *, const Trk::TrackParameters &, std::vector< const InDet::SiCluster * > &, std::vector< const InDet::SiDetElementBoundaryLink_xk * > &, bool &, const EventContext &)
bool isNewTrack(std::multimap< const Trk::PrepRawData *, const Trk::Track * > &) const
bool forwardExtension(bool, int, const EventContext &)
Trk::TrackStates convertToNextTrackStateOnSurface()
double pTseed(const Trk::TrackParameters &, std::vector< const InDet::SiCluster * > &, std::vector< const InDet::SiDetElementBoundaryLink_xk * > &, const EventContext &)
const int & nholes() const
std::unique_ptr< const Trk::Surface > m_surfacedead
const InDet::SiTools_xk * m_tools
Trajectory elements on this trajectory.
int m_nElements
count active elements
const int & difference() const
Trk::TrackStates convertToTrackStateOnSurface(const EventContext &ctx)
std::ostream & dump(std::ostream &out) const
bool forwardFilter(const EventContext &)
Trk::TrackStates convertToTrackStateOnSurfaceWithNewDirection(const EventContext &ctx)
const int & nclustersNoAdd() const
Trk::TrackStates convertToSimpleTrackStateOnSurfaceWithNewDirection()
Trk::TrackStates convertToSimpleTrackStateOnSurfaceForDisTrackTrigger(const EventContext &ctx)
void getClusters(std::vector< const InDet::SiCluster * > &) const
int m_nclusters
index of the last element where we have
void setTools(const InDet::SiTools_xk *)
const int & ndf() const
const int & nclusters() const
bool backwardSmoother(bool, const EventContext &)
bool trackParametersToClusters(const PixelClusterContainer *, const SCT_ClusterContainer *, const Trk::TrackParameters &, std::vector< const InDet::SiDetElementBoundaryLink_xk * > &, std::multimap< const Trk::PrepRawData *, const Trk::Track * > &, std::vector< const InDet::SiCluster * > &, const EventContext &ctx)
std::array< int, 300 > m_elementsMap
int m_lastElement
index of the first element where we have
bool filterWithPreciseClustersError(const EventContext &)
std::unique_ptr< Trk::FitQuality > convertToFitQuality() const
const int & dholes() const
Class for a planaer rectangular or trapezoidal surface in the ATLAS detector.
Abstract Base Class for tracking surfaces.
Definition Surface.h:79
const Amg::Transform3D & transform() const
Returns HepGeom::Transform3D by reference.
const Amg::Vector3D & center() const
Returns the center position of the Surface.
represents the track state (measurement, material, fit parameters and quality) at a surface.
STL class.
STL class.
int r
Definition globals.cxx:22
Eigen::Affine3d Transform3D
Eigen::Matrix< double, 3, 1 > Vector3D
DataVector< const Trk::TrackStateOnSurface > TrackStates
@ OnEdge
within the sensitive area of an active element
@ DeadElement
outside the element
@ Insensitive
close to the edge of an active element
@ Outside
with the insensitive area of an active element
@ Error
within the nominally active area of a dead element
ParametersBase< TrackParametersDim, Charged > TrackParameters
Helper struct for hole search results from the pattern recognition.