ATLAS Offline Software
Loading...
Searching...
No Matches
SiTrajectoryElement_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
15
18
20
21#include <cmath>
22#include <memory>
23#include <stdexcept>
24
26// Set work dead trajectory element
28
30{
31 m_fieldMode = false;
32 if(m_tools->fieldTool().magneticFieldMode()!=0) m_fieldMode = true;
33 m_status = 0 ;
34 m_detstatus = 0 ;
35 m_nMissing = 0 ;
36 m_nlinksForward = 0 ;
38 m_nholesForward = 0 ;
40 m_dholesForward = 0 ;
45 m_ndfForward = 0 ;
46 m_ndfBackward = 0 ;
47 m_ntsos = 0 ;
48 m_detelement = nullptr ;
49 m_detlink = nullptr ;
50 m_surface = SU ;
51 m_cluster = nullptr ;
52 m_clusterOld = nullptr ;
53 m_clusterNoAdd = nullptr ;
55 m_radlength = -1. ;
56 m_inside = -1 ;
57 m_localDir[0] = 1.;
58 m_localDir[1] = 0.;
59 m_localDir[2] = 0.;
60 return true;
61}
62
64// Set passive material contribution in radiation lengths
65// Contribution increases as a function of z to mimic the
66// routing of additional services along z
69{
70 if(m_radlength >= 0.) return;
71 double z = std::abs(Tp.parameters()[1]);
72 if (z < 50.) m_radlength = .0075;
73 else if(z < 205.) m_radlength = .02;
74 else if(z < 360.) m_radlength = .03+(z-205.)*0.000129032;
75 else if(z < 570.) m_radlength = .035+(z-360.)*9.04762e-05;
76 else if(z < 1500.) m_radlength = .054+(z-570.)*1.82796e-05;
77 else if(z < 2400.) m_radlength = .071+(z-1500.)*7.14286e-06;
78 else m_radlength = .078;
79
80}
81
82
84// Set work information to trajectory
86
88{
89 m_tools = t ;
90 m_prdToTrackMap= m_tools->PRDtoTrackMap();
91 m_useassoTool = m_tools->usePRDtoTrackAssociation() ;
92 m_updatorTool = m_tools->updatorTool ();
93 m_proptool = m_tools->propTool ();
94 m_riotool = m_tools->rioTool ();
95 m_tools->fieldCondObj()->getInitializedCache (m_fieldCache);
96}
97
99{
100 m_maxholes = m_tools->maxholes () ;
101 m_maxdholes = m_tools->maxdholes () ;
102 m_xi2max = m_tools->xi2max () ;
103 m_xi2maxNoAdd = m_tools->xi2maxNoAdd() ;
104 m_xi2maxlink = m_tools->xi2maxlink () ;
105 m_xi2multi = m_tools->xi2multi () ;
106}
107
109// Initiate first element of trajectory using external
110// track parameters
112
114(const Trk::TrackParameters& startingParameters, const EventContext& ctx)
115{
117 if(!m_cluster) return false;
118
120 Trk::PatternTrackParameters startingPatternPars;
121 if(!startingPatternPars.production(&startingParameters)) return false;
122
124 const Trk::Surface* pl = &startingPatternPars.associatedSurface();
125
128 if(m_surface==pl) m_parametersPredForward = startingPatternPars;
130 else if(!propagate(startingPatternPars,m_parametersPredForward,m_step,ctx)) return false;
131
132 // Initiate track parameters without initial covariance
133 //
134 double cv[15]={
135 1. ,
136 0. , 1.,
137 0. , 0.,.001,
138 0. , 0., 0.,.001,
139 0. , 0., 0., 0.,.00001};
140
141 if (m_tools->isITkGeometry()) {
142 cv[5] = m_ndf==2 ? .1 : .01;
143 cv[9] = cv[5];
144 }
145
147 m_parametersPredForward.setCovariance(cv);
153
155 if(!m_tools->isITkGeometry()) noiseProduction(1,m_parametersUpdatedForward);
157
159 m_dist = -10. ;
160 m_step = 0. ;
161 m_xi2Forward = 0. ;
162 m_xi2totalForward = 0. ;
163 m_status = 1 ;
164 m_inside = -1 ;
165 m_nMissing = 0 ;
166 m_nlinksForward = 0 ;
167 m_nholesForward = 0 ;
168 m_dholesForward = 0 ;
169 m_clusterNoAdd = nullptr ;
172 return true;
173}
174
176// Initiate first element of trajectory using smoother result
178
180{
181
182 if(!m_cluster || !m_status) return false;
184
185 if(correction){
186 m_parametersPredForward.diagonalization(10.);
188 }
189 else{
191 m_parametersPredForward.diagonalization(100.);
193 }
194
195 m_invMoment = std::abs(m_parametersUpdatedBackward.parameters()[4]);
197
198 m_dist = -10. ;
199 m_xi2Forward = 0. ;
200 m_xi2totalForward = 0. ;
201 m_status = 1 ;
202 m_inside = -1 ;
203 m_nMissing = 0 ;
204 m_nlinksForward = 0 ;
205 m_nholesForward = 0 ;
206 m_dholesForward = 0 ;
207 m_clusterNoAdd = nullptr ;
210 return true;
211}
212
214// Initiate last element of trajectory
216
242
244// Initiate last element of trajectory
246
248{
249 if(m_status==0 || !m_cluster) return false;
250 m_radlength = .04;
252
255 m_parametersPredBackward.diagonalization(10.);
257 m_status = 3;
258 m_inside = -1;
259 m_nMissing = 0;
263 m_clusterNoAdd = nullptr;
265 m_clusterNoAdd = nullptr;
266 m_npixelsBackward = m_ndf==2 ? 1 : 0;
269 m_xi2totalBackward = m_xi2Forward; // As in 21.9, should this be m_xi2totalForward instead?
270 m_dist = -10.;
271 return true;
272}
273
275// Propagate information in forward direction without closest
276// clusters search
278
280(InDet::SiTrajectoryElement_xk& TE, const EventContext& ctx)
281{
284 if(TE.m_cluster) {
292 m_dholesForward = 0;
293 }
294 else {
303 }
304
311 m_step += TE.m_step ;
312
315 if(!m_tools->isITkGeometry() || m_detelement){
316 if( m_cluster) {
320 m_inside = -1;
326 }
328 else {
332 if( m_detstatus >=0) {
334 if(m_inside < 0 ) {
338 }
340 if(m_dist < -2.) ++m_nMissing;
341 }
342 }
344
345
348 if(m_inside<=0) {
353 }
355 else {
357 }
358 m_status = 1;
359 m_nlinksForward = 0;
360 m_clusterNoAdd = nullptr;
361 return true;
362}
363
365// Propagate information in forward direction without closest
366// clusters search
368
370(InDet::SiTrajectoryElement_xk& TE, const EventContext& ctx)
371{
373
374 if(TE.m_cluster) {
376 m_dholesForward = 0;
377 }
378 else {
381 }
383
384 // Track propagation
385 //
386 P.addNoise(TE.m_noise,Trk::alongMomentum);
387 if(!propagate(P,m_parametersPredForward,m_step,ctx)) return false;
388
394 m_step += TE.m_step ;
395 m_inside = -1 ;
396
397 // Track update
398 //
399 if(!m_tools->isITkGeometry() || m_detelement){
400 if( m_cluster) {
403 }
404 else {
405 if( m_detstatus >=0) {
407 }
408 }
409 }
411
412 // Noise production
413 //
414 m_radlength = .04;
416 m_status = 1;
417 m_nlinksForward = 0;
418 m_clusterNoAdd = nullptr;
419 return true;
420}
421
423// Propagate information in forward direction with closest
424// clusters search
426
428(InDet::SiTrajectoryElement_xk& TE, const EventContext& ctx)
429{
433 if(TE.m_cluster) {
434
439 m_dholesForward = 0;
440 }
441 else {
442
447 }
448
450 m_status = 1 ;
451 m_nlinksForward = 0 ;
454 m_cluster = nullptr ;
455 m_clusterNoAdd = nullptr ;
456 m_xi2Forward = 10000. ;
457
464 m_step += TE.m_step ;
465
466 if(m_tools->isITkGeometry() && !m_detelement) {
469 return true;
470 }
471
474
476 if(m_inside > 0) {
477 noiseInitiate(); return true;
478 }
479
483 if(m_nlinksForward!=0) {
485 m_xi2Forward = m_linkForward[0].xi2();
486
488 if (m_xi2Forward <= m_xi2max ) {
490 m_cluster = m_linkForward[0].cluster();
501 }
503 else if(m_xi2Forward <= m_xi2maxNoAdd) {
505 m_clusterNoAdd = m_linkForward[0].cluster();
508 }
509 }
510 else {
513 }
515 if(m_detstatus >=0 && !m_cluster) {
517 if(m_inside < 0 && !m_clusterNoAdd) {
520 }
522 if(m_dist < -2. ) ++m_nMissing;
523 }
524 return true;
525}
526
528// Backward propagation for filter
530
532(InDet::SiTrajectoryElement_xk& TE, const EventContext& ctx)
533{
534 // Track propagation
535 //
536 if(TE.m_noise.correctionIMom() < 1.) {
537
538 if(TE.m_cluster) {
539
544 }
545 else {
546
551 }
552 }
553 else {
554
555 if(TE.m_cluster) {
556
559 }
560 else {
561
564 }
565 }
566 m_status = 2;
569 m_cluster = nullptr;
570 m_clusterNoAdd = nullptr;
571 m_xi2Backward = 10000.;
578 m_step += TE.m_step;
579
580 if(m_tools->isITkGeometry() && !m_detelement) {
583 return true;
584 }
586
587 if(m_inside >0 ) {noiseInitiate(); return true;}
588
590
591 m_xi2Backward = m_linkBackward[0].xi2();
592
593 if (m_xi2Backward <= m_xi2max ) {
594
595 m_cluster = m_linkBackward[0].cluster();
599 }
600 else if(m_xi2Backward <= m_xi2maxNoAdd) {
601
602 m_clusterNoAdd = m_linkBackward[0].cluster();
604 }
605 }
606 else {
608 }
609
610 if(m_detstatus >=0 && !m_cluster){
612 if(m_dist < -2.) ++m_nMissing;
613 }
614 return true;
615}
616
618// Backward propagation for smoother
620
622(InDet::SiTrajectoryElement_xk& TE,bool isTwoSpacePointsSeed, const EventContext& ctx)
623{
624
625 // Track propagation
626 //
627 double step;
628 if(TE.m_cluster) {
631 }
632 else {
635 }
636
644
645 // remove case if you have trajectory element without actual detector element
646 // this happens if you have added a dead cylinder
647 if(!m_detelement) {
648 m_status = 2;
649 return true;
650 }
651
652 // Forward-backward predict parameters
653 //
655
656 m_cluster ? m_status = 3 : m_status = 2;
657
658 double Xi2max = m_xi2max; if( isTwoSpacePointsSeed) Xi2max*=2.;
662 m_cluster = nullptr;
663 m_clusterNoAdd = nullptr;
664 m_xi2Backward = 10000.;
665
666 //m_step += TE.m_step ;
667 if(m_inside> 0 ) return true;
668
669
670 // For not first cluster on trajectory
671 //
673
675
676 m_xi2Backward = m_linkBackward[0].xi2();
677
678
679 if (m_xi2Backward <= Xi2max) {
680
681 m_cluster = m_linkBackward[0].cluster();
682
685 }
686 else if(m_xi2Backward <= m_xi2maxNoAdd) {
687
688 m_clusterNoAdd = m_linkBackward[0].cluster();
689 }
690 }
691 if(m_detstatus >=0 && !m_cluster) {
693 if(m_dist < -2.) ++m_nMissing;
694 }
695 return true;
696 }
697
698 // For first cluster of short trajectory
699 //
702
705 else {m_cluster = nullptr; }
706
707 if(!m_cluster) {
709 if(m_dist < -2.) ++m_nMissing;
710
711 }
712 return true;
713}
714
716// Backward propagation with precise information
718
720(InDet::SiTrajectoryElement_xk& TE, const EventContext& ctx)
721{
722
723 // Track propagation
724 //
725 double step;
726 if(TE.m_cluster) {
727
729 }
730 else {
731
733 }
734
736
737 // Forward-backward predict parameters
738 //
739 if(m_cluster) {
740 m_status = 3 ;
742 }
743 else {
744 m_status = 2 ;
745 }
746 return true;
747}
748
750// Add next cluster for backward propagation
752
754{
755 if(m_nlinksBackward <= 0) return false;
756
758
759 if(m_nlinksBackward > 1 && m_linkBackward[1].xi2() <= m_xi2max) {
760
761 int n = 0;
762 for(; n!=m_nlinksBackward-1; ++n) m_linkBackward[n]=m_linkBackward[n+1];
764
765 m_cluster = m_linkBackward[0].cluster();
766 m_xi2Backward = m_linkBackward[0].xi2() ;
769 }
770 else {
774 if(m_dist < -2.) ++m_nMissing;
775 }
776 return true;
777}
778
780// Add next cluster for forward propagation
782
784{
785 if(m_nlinksForward <= 0) return false;
786
788
789 if(m_nlinksForward > 1 && m_linkForward[1].xi2() <= m_xi2max) {
790
791 int n = 0;
792 for(; n!=m_nlinksForward-1; ++n) m_linkForward[n]=m_linkForward[n+1];
794
795 m_cluster = m_linkForward[0].cluster();
796 m_xi2Forward = m_linkForward[0].xi2() ;
799 }
800 else {
801 m_nlinksForward = 0;
804 if(m_dist < -2.) ++m_nMissing;
805 }
806 return true;
807}
808
810// Add next cluster for backward propagation
812
842
844// Add next cluster for forward propagation
846
896
898// TrackStateOnSurface production
900
902InDet::SiTrajectoryElement_xk::trackStateOnSurface (bool change,bool cov,bool multi,int Q,const EventContext& ctx)
903{
904 std::unique_ptr<Trk::TrackParameters> tp = nullptr;
905 if (!change) {
906 tp = trackParameters(cov, Q);
907 } else {
909 }
910 if (!tp) {
911 return nullptr;
912 }
913 if (&tp->associatedSurface() != m_surface) {
914 return nullptr;
915 }
916
918 std::unique_ptr<Trk::MeasurementBase> ro{};
919
920 if (m_status == 1) {
922 } else {
924 }
925
926 std::bitset<Trk::TrackStateOnSurface::NumberOfTrackStateOnSurfaceTypes> pat(
927 0);
928
929 if (m_cluster) {
930 ro.reset(m_riotool->correct(*m_cluster, *tp, ctx));
932 } else {
933 ro.reset(m_riotool->correct(*m_clusterNoAdd, *tp, ctx));
935 }
936 auto sa = Trk::ScatteringAngles(
937 0., 0., std::sqrt(m_noise.covarianceAzim()), std::sqrt(m_noise.covariancePola()));
938
939 auto meTemplate = std::make_unique<Trk::MaterialEffectsOnTrack>(
940 m_radlengthN, sa, tp->associatedSurface());
941
944 new Trk::TrackStateOnSurface(fq, std::move(ro), std::move(tp), meTemplate->uniqueClone(), pat);
945
946 m_tsos[0] = sos;
947 m_utsos[0] = true;
948 m_ntsos = 1;
949
950 if (multi && m_cluster && m_ndf == 2 && m_nlinksBackward > 1) {
951 for(int i=1; i!= m_nlinksBackward; ++i) {
952 if(m_linkBackward[i].xi2() > m_xi2multi) break;
953 std::unique_ptr<Trk::TrackParameters> tpn{};
954 if (!change) {
955 tpn = trackParameters(cov, Q);
956 } else {
958 }
959 if (!tpn){
960 break;
961 }
962 auto fqn = Trk::FitQualityOnSurface(m_linkBackward[i].xi2(),m_ndf);
963 std::unique_ptr<Trk::MeasurementBase> ron(m_riotool->correct(
964 *m_linkBackward[i].cluster(), *(sos->trackParameters()), ctx) );
966 fqn, std::move(ron), std::move(tpn), meTemplate->uniqueClone(), pat);
967 m_utsos[m_ntsos] = false;
968 if(++m_ntsos == 3) break;
969 }
970 }
971 return sos;
972}
973
975// TrackStateOnSurface production for simple track
977
980(bool change,bool cov,int Q)
981{
982 if(!m_detelement) {
983 return nullptr;
984 }
985
986 std::unique_ptr<Trk::TrackParameters> tp = nullptr;
987
988 if (Q) {
989 if (!change) {
990 tp = trackParameters(cov, Q);
991 } else {
993 }
994 if (!tp) {
995 return nullptr;
996 }
997 if (&tp->associatedSurface() != m_surface) {
998 return nullptr;
999 }
1000 }
1001
1002 IdentifierHash iH = m_detelement->identifyHash();
1003 std::unique_ptr<Trk::MeasurementBase> ro{};
1004 std::bitset<Trk::TrackStateOnSurface::NumberOfTrackStateOnSurfaceTypes> pat(
1005 0);
1006
1007 const InDet::SiCluster* cl = nullptr;
1008 if (m_cluster) {
1009 cl = m_cluster;
1011 } else {
1012 cl = m_clusterNoAdd;
1014 }
1016
1017 Trk::LocalParameters locp = Trk::LocalParameters(cl->localPosition());
1018 //coverity[NULL_FIELD:FALSE]
1019 Amg::MatrixX cv = cl->localCovariance();
1020
1024
1025 if (m_ndf == 1) {
1026 const InDet::SCT_Cluster* sc = static_cast<const InDet::SCT_Cluster*>(cl);
1027 if (sc)
1028 ro = std::make_unique<InDet::SCT_ClusterOnTrack>(sc, std::move(locp), std::move(cv), iH, sc->globalPosition());
1029 } else {
1030 const InDet::PixelCluster* pc = static_cast<const InDet::PixelCluster*>(cl);
1031 if (pc)
1032 ro = std::make_unique<InDet::PixelClusterOnTrack>(
1033 pc, std::move(locp), std::move(cv), iH, pc->globalPosition(), pc->gangedPixel());
1034 }
1035 return new Trk::TrackStateOnSurface(fq, std::move(ro), std::move(tp), nullptr, pat);
1036}
1037
1039// TrackStateOnSurface production for perigee
1041
1044{
1045 if(&m_parametersUpdatedBackward.associatedSurface()!=m_surface) return nullptr;
1046
1047 double step ;
1049
1051
1052 bool Q = m_proptool->propagate
1053 (ctx,
1055
1056 if(Q) {
1057 std::bitset<Trk::TrackStateOnSurface::NumberOfTrackStateOnSurfaceTypes> typePattern;
1058 typePattern.set(Trk::TrackStateOnSurface::Perigee);
1059 return new Trk::TrackStateOnSurface(nullptr,Tp.convert(true),nullptr,typePattern);
1060 }
1061 return nullptr;
1062}
1063
1065// TrackParameters production
1066// Q = 0 no first or last element of the trajectory
1067// Q = 1 first element of the trajectory
1068// Q = 2 last element of the trajectory
1070
1071std::unique_ptr<Trk::TrackParameters>
1073{
1074 if (m_status == 1) {
1075 if (m_cluster) {
1076 return m_parametersUpdatedForward.convert(cov);
1077 } else {
1078 return m_parametersPredForward.convert(cov);
1079 }
1080 } else if (m_status == 2) {
1081 if (m_cluster) {
1082 return m_parametersUpdatedBackward.convert(cov);
1083 } else {
1084 return m_parametersPredBackward.convert(cov);
1085 }
1086 } else if (m_status == 3) {
1087 if (Q == 0) {
1088 if (m_cluster) {
1090 return m_parametersSM.convert(cov);
1091 } else if ((*m_parametersUpdatedBackward.covariance())(4, 4) <
1092 (*m_parametersPredForward.covariance())(4, 4)) {
1093 return m_parametersUpdatedBackward.convert(cov);
1094 } else {
1095 return m_parametersPredForward.convert(cov);
1096 }
1097 } else
1098 return m_parametersSM.convert(cov);
1099 }
1100 if (Q == 1) {
1101 if (m_cluster) {
1102 return m_parametersUpdatedBackward.convert(cov);
1103 }
1104 }
1105 if (Q == 2) {
1106 if (m_cluster) {
1107 return m_parametersUpdatedForward.convert(cov);
1108 }
1109 }
1110 }
1111 return nullptr;
1112}
1113
1115// Noise production
1116// Dir = +1 along momentum , -1 opposite momentum
1117// Model = 1 - muon, 2 - electron
1118// useMomentum = true - use m_invMoment instead of Tp.par()[4]
1120
1122(int Dir,const Trk::PatternTrackParameters& Tp,double rad_length, bool useMomentum)
1123{
1124
1125 int Model = m_noisemodel;
1126 if(Model < 1 || Model > 2) return;
1127 if (rad_length<0.) rad_length=m_radlength;
1128
1129 double q = useMomentum ? m_invMoment : std::abs(Tp.parameters()[4]);
1130
1132 double s = std::abs(m_localDir[0]*m_localTransform[6]+
1135 if(m_tools->isITkGeometry() && !m_detelement) s = sqrt(m_localDir[0]*m_localDir[0]+m_localDir[1]*m_localDir[1]);
1136
1137 if(m_tools->isITkGeometry()){
1138 if (s < .01) s = 100.;
1139 else s = 1./s;
1140 }
1141 else{
1142 if (s < .05) s = 20.;
1143 else s = 1./s;
1144 }
1145
1151 double covariancePola = (134.*m_radlengthN)*(q*q);
1152 if(m_tools->isITkGeometry()){
1153 double qc = (1.+.038*log(m_radlengthN))*q;
1154 covariancePola = (185.*m_radlengthN)*qc*qc;
1155 }
1156
1158 double d = (1.-m_localDir[2])*(1.+m_localDir[2]);
1160 if(d < 1.e-5) d = 1.e-5;
1162 double covarianceAzim = covariancePola/d;
1163
1164 double covarianceIMom;
1165 double correctionIMom;
1166
1168 if(Model==1) {
1170 double dp = m_energylose*q*s;
1172 covarianceIMom = (.2*dp*dp)*(q*q);
1174 correctionIMom = 1.-dp;
1175 }
1177 else {
1178 correctionIMom = .70;
1179 covarianceIMom = (correctionIMom-1.)*(correctionIMom-1.)*(q*q);
1180 }
1182 if(Dir>0) correctionIMom = 1./correctionIMom;
1184 m_noise.set(covarianceAzim,covariancePola,covarianceIMom,correctionIMom);
1185}
1186
1187
1189// TrackParameters production with new direction
1190// Q = 0 no first or last element of the trajectory
1191// Q = 1 first element of the trajectory
1192// Q = 2 last element of the trajectory
1194
1195std::unique_ptr<Trk::TrackParameters>
1197{
1198 if (m_status == 1) {
1199 if (m_cluster) {
1201 } else {
1203 }
1204
1205 } else if (m_status == 2) {
1206 if (m_cluster) {
1208 } else {
1210 }
1211 } else if (m_status == 3) {
1212
1213 if (Q == 0) {
1214 if (m_cluster) {
1216 return trackParameters(m_parametersSM, cov);
1217 else if ((*m_parametersUpdatedBackward.covariance())(4, 4) <
1218 (*m_parametersPredForward.covariance())(4, 4)) {
1220 } else {
1222 }
1223 } else {
1224 return trackParameters(m_parametersSM, cov);
1225 }
1226 }
1227 if (Q == 1) {
1228 if (m_cluster){
1230 }
1231 }
1232 if (Q == 2) {
1233 if (m_cluster){
1235 }
1236 }
1237 }
1238 return nullptr;
1239}
1240
1242// TrackParameters production with new direction
1244std::unique_ptr<Trk::TrackParameters>
1247{
1248 Tp.changeDirection();
1249 return Tp.convert(cov);
1250}
1251
1252
1254// Step calculation
1256
1259{
1261
1262 if (TE.m_status == 1) {
1264 else Ta = TE.m_parametersPredForward;
1265 }
1266 else if(TE.m_status == 2) {
1268 else Ta = TE.m_parametersPredBackward;
1269 }
1270 else if(TE.m_status == 3) {
1271 Ta = TE.m_parametersSM;
1272 }
1273 double step = 0.;
1274 bool Q = propagateParameters(Ta,Tb,step);
1275 if(Q) return step;
1276 return 0.;
1277}
1278
1280// Global position of track parameters
1282
1284{
1285 if (m_status == 1) {
1286 if(m_cluster) return m_parametersUpdatedForward.position();
1287 else return m_parametersPredForward.position();
1288 }
1289 else if(m_status == 2) {
1290 if(m_cluster) return m_parametersUpdatedBackward.position();
1291 else return m_parametersPredBackward.position();
1292 }
1293 else if(m_status == 3) {
1294
1295 Amg::Vector3D gp(0.,0.,0.);
1297
1298 if(m_cluster) S1 = parametersUB();
1299 else S1 = parametersPB();
1300
1301 QA = m_updatorTool->combineStates(S1,S2,SM);
1302
1303 if(QA) {
1304 gp = SM.position();
1305 }
1306 return gp;
1307 }
1308 Amg::Vector3D gp(0.,0.,0.);
1309 return gp;
1310}
1311
1313// Step estimation to 0,0,0
1315
1317{
1318 Amg::Vector3D M;
1320
1321 if(m_cluster) {
1322 M = m_parametersUpdatedBackward.momentum();
1323 P = m_parametersUpdatedBackward.position();
1324 }
1325 else {
1326 M = m_parametersPredBackward.momentum();
1327 P = m_parametersPredBackward.position();
1328 }
1329
1330 return -(P[0]*M[0]+P[1]*M[1]);
1331}
1332
1334// Errase cluster fo forward propagation
1336
1344
1346// Quality of the trajectory element
1348
1350{
1351
1352 if(!m_cluster && !m_clusterNoAdd) {
1353
1354 if(m_detstatus < 0) return 0.;
1355
1356 if (m_inside < 0) {
1357 double w = 2.-m_xi2max; if(++holes > 1) w*=2.; return w;
1358 }
1359 else if(m_inside == 0) return -1.;
1360 else return 0.;
1361 }
1362
1363 double w,X,Xc = m_xi2max+2.;
1364 m_status == 1 ? X = m_xi2Forward : X = m_xi2Backward;
1365 m_ndf == 2 ? w = 1.2*(Xc-X*.5) : w = Xc-X ; if(w < -1.) w = -1.;
1366 holes = 0;
1367
1368 return w;
1369}
1370
1372// Main function for pattern track parameters and covariance matrix propagation
1373// to PlaneSurface.
1378bool
1380 Trk::PatternTrackParameters & outputParameters,
1381 double & StepLength,
1382 const EventContext& ctx ) {
1383 if (Trk::SurfaceType::Plane == m_surface->type() and
1384 Trk::SurfaceType::Plane == startingParameters.associatedSurface().type()) {
1385 bool useJac = (startingParameters.iscovariance());
1386 double globalParameters[64];
1394
1396 if(!transformPlaneToGlobal(useJac,startingParameters,globalParameters)) return false;
1398 if( m_fieldMode) {
1399 if(!rungeKuttaToPlane (useJac,globalParameters)) return false;
1400 }
1402 else {
1403 if(!straightLineStepToPlane(useJac,globalParameters)) return false;
1404 }
1406 StepLength = globalParameters[45];
1408 return transformGlobalToPlane(useJac,globalParameters,startingParameters,outputParameters);
1409 } else {
1410 if (!m_proptool->propagate (ctx,
1411 startingParameters, *m_surface, outputParameters,
1412 Trk::anyDirection, m_tools->fieldTool(), StepLength, Trk::pion))
1413 return false;
1414
1415 double sinPhi,cosPhi,sinTheta,cosTheta;
1416 sincos(outputParameters.parameters()[2],&sinPhi,&cosPhi);
1417 sincos(outputParameters.parameters()[3],&sinTheta,&cosTheta);
1418 m_localDir[0] = cosPhi*sinTheta;
1419 m_localDir[1] = sinPhi*sinTheta;
1420 m_localDir[2] = cosTheta;
1421 return true;
1422 }
1423}
1424
1426// Main function for pattern track parameters propagation without covariance.
1431
1432bool
1434 Trk::PatternTrackParameters & outputParameters,
1435 double & StepLength ) {
1436 bool useJac = false;
1437 double globalParameters[64];
1445 if(!transformPlaneToGlobal(useJac,startingParameters,globalParameters)) return false;
1448 if( m_fieldMode) {
1449 if(!rungeKuttaToPlane (useJac,globalParameters)) return false;
1450 }
1452 else {
1453 if(!straightLineStepToPlane(useJac,globalParameters)) return false;
1454 }
1456 StepLength = globalParameters[45];
1458 return transformGlobalToPlane(useJac,globalParameters,startingParameters,outputParameters);
1459}
1460
1475// /////////////////////////////////////////////////////////////////////////////////
1476
1478 Trk::PatternTrackParameters& localParameters,
1479 double* globalPars) {
1481 double sinPhi,cosPhi,cosTheta,sintheta;
1482 sincos(localParameters.parameters()[2],&sinPhi,&cosPhi);
1483 sincos(localParameters.parameters()[3],&sintheta,&cosTheta);
1484 if (m_tools->isITkGeometry()) {
1485 if(std::abs(sintheta) < std::abs(localParameters.parameters()[4])*50.) return false;
1486 }
1488 const Trk::Surface* pSurface=&localParameters.associatedSurface();
1489 if (!pSurface){
1490 throw(std::runtime_error("TrackParameters associated surface is null pointer in InDet::SiTrajectoryElement_xk::transformPlaneToGlobal"));
1491 }
1493 const Amg::Transform3D& T = pSurface->transform();
1494
1496 double Ax[3] = {T(0,0),T(1,0),T(2,0)};
1497 double Ay[3] = {T(0,1),T(1,1),T(2,1)};
1498
1500 globalPars[ 0] = localParameters.parameters()[0]*Ax[0]+localParameters.parameters()[1]*Ay[0]+T(0,3); // X
1501 globalPars[ 1] = localParameters.parameters()[0]*Ax[1]+localParameters.parameters()[1]*Ay[1]+T(1,3); // Y
1502 globalPars[ 2] = localParameters.parameters()[0]*Ax[2]+localParameters.parameters()[1]*Ay[2]+T(2,3); // Z
1504 globalPars[ 3] = cosPhi*sintheta; // Ax
1505 globalPars[ 4] = sinPhi*sintheta; // Ay
1506 globalPars[ 5] = cosTheta;
1508 globalPars[ 6] = localParameters.parameters()[4]; // CM
1510 if(std::abs(globalPars[6])<1.e-20) {
1511 if (globalPars[6] < 0){
1512 globalPars[6]=-1.e-20;
1513 }
1514 else globalPars[6]= 1.e-20;
1515 }
1516
1518 if(useJac) {
1519
1520 // /dL1 | /dL2 | /dPhi | /dThe | /dCM |
1521 globalPars[ 7] = Ax[0]; globalPars[14] = Ay[0]; globalPars[21] = 0.; globalPars[28] = 0.; globalPars[35] = 0.; // dX /
1522 globalPars[ 8] = Ax[1]; globalPars[15] = Ay[1]; globalPars[22] = 0.; globalPars[29] = 0.; globalPars[36] = 0.; // dY /
1523 globalPars[ 9] = Ax[2]; globalPars[16] = Ay[2]; globalPars[23] = 0.; globalPars[30] = 0.; globalPars[37] = 0.; // dZ /
1524 globalPars[10] = 0.; globalPars[17] = 0.; globalPars[24] =-globalPars[4]; globalPars[31] = cosPhi*cosTheta; globalPars[38] = 0.; // dAx/
1525 globalPars[11] = 0.; globalPars[18] = 0.; globalPars[25] = globalPars[3]; globalPars[32] = sinPhi*cosTheta; globalPars[39] = 0.; // dAy/
1526 globalPars[12] = 0.; globalPars[19] = 0.; globalPars[26] = 0.; globalPars[33] = -sintheta; globalPars[40] = 0.; // dAz/
1527
1529 globalPars[42] = 0.;
1530 globalPars[43] = 0.;
1531 globalPars[44] = 0.;
1532 }
1534 globalPars[45] = 0.;
1535 return true;
1536}
1537
1551// /////////////////////////////////////////////////////////////////////////////////
1553(bool useJac,double* globalPars,Trk::PatternTrackParameters& startingParameters,Trk::PatternTrackParameters& outputParameters)
1554{
1556 double Ax[3] = {m_localTransform[0],m_localTransform[1],m_localTransform[2]};
1557 double Ay[3] = {m_localTransform[3],m_localTransform[4],m_localTransform[5]};
1558 double Az[3] = {m_localTransform[6],m_localTransform[7],m_localTransform[8]};
1560 double d [3] = {globalPars[0]-m_localTransform[ 9],
1561 globalPars[1]-m_localTransform[10],
1562 globalPars[2]-m_localTransform[11]};
1563
1565 double p[5] = {
1566 d[0]*Ax[0]+d[1]*Ax[1]+d[2]*Ax[2],
1567 d[0]*Ay[0]+d[1]*Ay[1]+d[2]*Ay[2],
1568 atan2(globalPars[4],globalPars[3]),
1569 acos(globalPars[5]),
1570 globalPars[6]
1571 };
1572
1574 m_localDir[0] = globalPars[3];
1575 m_localDir[1] = globalPars[4];
1576 m_localDir[2] = globalPars[5];
1577
1578 if (useJac) {
1580 double A = Az[0]*globalPars[3]+Az[1]*globalPars[4]+Az[2]*globalPars[5];
1581 if(A!=0.) A=1./A;
1582 double s0 = Az[0]*globalPars[ 7]+Az[1]*globalPars[ 8]+Az[2]*globalPars[ 9];
1583 double s1 = Az[0]*globalPars[14]+Az[1]*globalPars[15]+Az[2]*globalPars[16];
1584 double s2 = Az[0]*globalPars[21]+Az[1]*globalPars[22]+Az[2]*globalPars[23];
1585 double s3 = Az[0]*globalPars[28]+Az[1]*globalPars[29]+Az[2]*globalPars[30];
1586 double s4 = Az[0]*globalPars[35]+Az[1]*globalPars[36]+Az[2]*globalPars[37];
1587 double T0 =(Ax[0]*globalPars[ 3]+Ax[1]*globalPars[ 4]+Ax[2]*globalPars[ 5])*A;
1588 double T1 =(Ay[0]*globalPars[ 3]+Ay[1]*globalPars[ 4]+Ay[2]*globalPars[ 5])*A;
1589 double n = 1./globalPars[6];
1590
1591 double Jac[21];
1592
1593 // Jacobian production
1594 //
1595 Jac[ 0] = (Ax[0]*globalPars[ 7]+Ax[1]*globalPars[ 8])+(Ax[2]*globalPars[ 9]-s0*T0); // dL0/dL0
1596 Jac[ 1] = (Ax[0]*globalPars[14]+Ax[1]*globalPars[15])+(Ax[2]*globalPars[16]-s1*T0); // dL0/dL1
1597 Jac[ 2] = (Ax[0]*globalPars[21]+Ax[1]*globalPars[22])+(Ax[2]*globalPars[23]-s2*T0); // dL0/dPhi
1598 Jac[ 3] = (Ax[0]*globalPars[28]+Ax[1]*globalPars[29])+(Ax[2]*globalPars[30]-s3*T0); // dL0/dThe
1599 Jac[ 4] =((Ax[0]*globalPars[35]+Ax[1]*globalPars[36])+(Ax[2]*globalPars[37]-s4*T0))*n; // dL0/dCM
1600
1601 Jac[ 5] = (Ay[0]*globalPars[ 7]+Ay[1]*globalPars[ 8])+(Ay[2]*globalPars[ 9]-s0*T1); // dL1/dL0
1602 Jac[ 6] = (Ay[0]*globalPars[14]+Ay[1]*globalPars[15])+(Ay[2]*globalPars[16]-s1*T1); // dL1/dL1
1603 Jac[ 7] = (Ay[0]*globalPars[21]+Ay[1]*globalPars[22])+(Ay[2]*globalPars[23]-s2*T1); // dL1/dPhi
1604 Jac[ 8] = (Ay[0]*globalPars[28]+Ay[1]*globalPars[29])+(Ay[2]*globalPars[30]-s3*T1); // dL1/dThe
1605 Jac[ 9] =((Ay[0]*globalPars[35]+Ay[1]*globalPars[36])+(Ay[2]*globalPars[37]-s4*T1))*n; // dL1/dCM
1606
1607 double P3=0;
1608 double P4=0;
1610 double C = globalPars[3]*globalPars[3]+globalPars[4]*globalPars[4];
1611 if(C > 1.e-20) {
1612 C= 1./C ;
1614 P3 = globalPars[3]*C;
1615 P4 =globalPars[4]*C;
1616 C =-sqrt(C);
1617 }
1618 else{
1619 C=-1.e10;
1620 P3 = 1.;
1621 P4 =0.;
1622 }
1623
1624 double T2 =(P3*globalPars[43]-P4*globalPars[42])*A;
1625 double C44 = C*globalPars[44] *A;
1626
1627 Jac[10] = P3*globalPars[11]-P4*globalPars[10]-s0*T2; // dPhi/dL0
1628 Jac[11] = P3*globalPars[18]-P4*globalPars[17]-s1*T2; // dPhi/dL1
1629 Jac[12] = P3*globalPars[25]-P4*globalPars[24]-s2*T2; // dPhi/dPhi
1630 Jac[13] = P3*globalPars[32]-P4*globalPars[31]-s3*T2; // dPhi/dThe
1631 Jac[14] =(P3*globalPars[39]-P4*globalPars[38]-s4*T2)*n; // dPhi/dCM
1632
1633 Jac[15] = C*globalPars[12]-s0*C44; // dThe/dL0
1634 Jac[16] = C*globalPars[19]-s1*C44; // dThe/dL1
1635 Jac[17] = C*globalPars[26]-s2*C44; // dThe/dPhi
1636 Jac[18] = C*globalPars[33]-s3*C44; // dThe/dThe
1637 Jac[19] =(C*globalPars[40]-s4*C44)*n; // dThe/dCM
1638 Jac[20] = 1.; // dCM /dCM
1639
1641 AmgSymMatrix(5) newCov = Trk::RungeKuttaUtils::newCovarianceMatrix(Jac, *startingParameters.covariance());
1642 outputParameters.setParametersWithCovariance(m_surface, p, newCov);
1643
1645 const AmgSymMatrix(5) & t = *outputParameters.covariance();
1646 if(t(0, 0)<=0. || t(1, 1)<=0. || t(2, 2)<=0. || t(3, 3)<=0. || t(4, 4)<=0.) return false;
1647 } else {
1649 outputParameters.setParameters(m_surface,p);
1650 }
1651
1652 return true;
1653}
1654
1660
1662(bool Jac,double* globalPars)
1663{
1665 const double Smin = .1 ;
1668 const double Shel = 5. ;
1670 const double dlt = .001 ;
1671
1673 if(std::abs(globalPars[6]) > .05) return false;
1674
1675
1676 int it = 0;
1677 double* R = &globalPars[ 0]; // Coordinates
1678
1679 double* A = &globalPars[ 3]; // Directions
1680
1681 double* sA = &globalPars[42];
1682 double Pi = 149.89626*globalPars[6];
1684 double Pa = std::abs (globalPars[6]);
1685
1687 double a = A[0]*m_localTransform[6]+A[1]*m_localTransform[7]+A[2]*m_localTransform[8];
1688 if(a==0.) return false;
1690 double S = ((m_localTransform[12]-R[0]*m_localTransform[6])-(R[1]*m_localTransform[7]+R[2]*m_localTransform[8]))/a;
1691 double S0 = std::abs(S) ;
1692
1696 if(S0 <= Smin) {
1697 R[0]+=(A[0]*S);
1698 R[1]+=(A[1]*S);
1699 R[2]+=(A[2]*S);
1700 globalPars[45]+=S;
1701 return true;
1702 }
1705 else if( (Pa*S0) > .3) {
1706 if (S >0) S = 0.3 / Pa;
1707 else S = -0.3/Pa;
1708 }
1709
1710 bool ste = false;
1711
1713 double f0[3];
1714 double f[3];
1715
1717 m_fieldCache.getFieldZR(R,f0);
1718
1719
1720 while(true) {
1721
1722 bool Helix = false;
1724 if(std::abs(S) < Shel) Helix = true;
1725 double S3=(1./3.)*S;
1726 double S4=.25*S;
1727 double PS2=Pi*S;
1728
1731 double H0[3] = {f0[0]*PS2,
1732 f0[1]*PS2,
1733 f0[2]*PS2};
1734
1735 double A0 = A[1]*H0[2]-A[2]*H0[1] ;
1736 double B0 = A[2]*H0[0]-A[0]*H0[2] ;
1737 double C0 = A[0]*H0[1]-A[1]*H0[0] ;
1738
1739 double A2 = A0+A[0] ;
1740 double B2 = B0+A[1] ;
1741 double C2 = C0+A[2] ;
1742
1743 double A1 = A2+A[0] ;
1744 double B1 = B2+A[1] ;
1745 double C1 = C2+A[2] ;
1746
1747 // Second point
1748 //
1749 if(!Helix) {
1750 double gP[3]={R[0]+A1*S4,
1751 R[1]+B1*S4,
1752 R[2]+C1*S4};
1753
1754 m_fieldCache.getFieldZR(gP,f);
1755
1756 }
1758 else {
1759 f[0]=f0[0];
1760 f[1]=f0[1];
1761 f[2]=f0[2];
1762 }
1763
1764 double H1[3] = {f[0]*PS2,
1765 f[1]*PS2,
1766 f[2]*PS2};
1767 double A3 = (A[0]+B2*H1[2])-C2*H1[1] ;
1768 double B3 = (A[1]+C2*H1[0])-A2*H1[2] ;
1769 double C3 = (A[2]+A2*H1[1])-B2*H1[0] ;
1770
1771 double A4 = (A[0]+B3*H1[2])-C3*H1[1] ;
1772 double B4 = (A[1]+C3*H1[0])-A3*H1[2] ;
1773 double C4 = (A[2]+A3*H1[1])-B3*H1[0] ;
1774
1775 double A5 = 2.*A4-A[0] ;
1776 double B5 = 2.*B4-A[1] ;
1777 double C5 = 2.*C4-A[2] ;
1778
1779 // Last point
1780 //
1781 if(!Helix) {
1782 double gP[3]={R[0]+S*A4,
1783 R[1]+S*B4,
1784 R[2]+S*C4};
1785
1786 m_fieldCache.getFieldZR(gP,f);
1787
1788 }
1789 else{
1790 f[0]=f0[0];
1791 f[1]=f0[1];
1792 f[2]=f0[2];
1793 }
1794
1795 double H2[3] = {f[0]*PS2,
1796 f[1]*PS2,
1797 f[2]*PS2};
1798
1799 double A6 = B5*H2[2]-C5*H2[1] ;
1800 double B6 = C5*H2[0]-A5*H2[2] ;
1801 double C6 = A5*H2[1]-B5*H2[0] ;
1802
1803 // Test approximation quality on give step and possible step reduction
1804 //
1805 if(!ste) {
1806 double EST = std::abs((A1+A6)-(A3+A4))+std::abs((B1+B6)-(B3+B4))+std::abs((C1+C6)-(C3+C4));
1807 if(EST>dlt) {
1808 S*=.6;
1809 continue;
1810 }
1811 }
1812
1815 if((!ste && S0 > std::abs(S)*100.) || std::abs(globalPars[45]+=S) > 2000.) return false;
1816 ste = true;
1817
1818 double A0arr[3]{A0,B0,C0};
1819 double A3arr[3]{A3,B3,C3};
1820 double A4arr[3]{A4,B4,C4};
1821 double A6arr[3]{A6,B6,C6};
1822
1823 if(Jac) {
1824 Trk::propJacobian(globalPars,H0,H1,H2,A,A0arr,A3arr,A4arr,A6arr,S3);
1825 }
1826
1827 R[0]+=(A2+A3+A4)*S3;
1828 A[0] = ((A0+2.*A3)+(A5+A6));
1829 R[1]+=(B2+B3+B4)*S3;
1830 A[1] = ((B0+2.*B3)+(B5+B6));
1831 R[2]+=(C2+C3+C4)*S3;
1832 A[2] = ((C0+2.*C3)+(C5+C6));
1833 if(!m_tools->isITkGeometry()){
1834 A[0] *= 1./3.;
1835 A[1] *= 1./3.;
1836 A[2] *= 1./3.;
1837 }
1838
1839 double D = 1./sqrt(A[0]*A[0]+A[1]*A[1]+A[2]*A[2]);
1840 A[0]*=D; A[1]*=D; A[2]*=D;
1841
1844 double a = A[0]*m_localTransform[6]+A[1]*m_localTransform[7]+A[2]*m_localTransform[8];
1845 if(a==0.) return false;
1846 double Sn = ((m_localTransform[12]-R[0]*m_localTransform[6])-(R[1]*m_localTransform[7]+R[2]*m_localTransform[8]))/a;
1847 double aSn = std::abs(Sn);
1848
1851 if(aSn <= Smin) {
1852 double Sl = 2./S;
1853 sA[0] = A6*Sl;
1854 sA[1] = B6*Sl;
1855 sA[2] = C6*Sl;
1856
1857 R[0]+=(A[0]*Sn);
1858 R[1]+=(A[1]*Sn);
1859 R[2]+=(A[2]*Sn);
1860 globalPars[45]+=Sn;
1861
1862 return true;
1863 }
1864
1865 double aS = std::abs(S);
1866
1868 if ( S*Sn < 0. ) {
1869 if(++it > 2) return false;
1871 if (aSn < aS) S = Sn;
1873 else S =-S;
1874 }
1876 else if( aSn < aS ) S = Sn;
1877
1879 f0[0]=f[0];
1880 f0[1]=f[1];
1881 f0[2]=f[2];
1882 }
1883 return false;
1884}
1885
1887// Straight line step to plane
1889
1891(bool Jac,double* globalPars)
1892{
1893 double* R = &globalPars[ 0]; // Start coordinates
1894 double* A = &globalPars[ 3]; // Start directions
1896 double a = A[0]*m_localTransform[6]+A[1]*m_localTransform[7]+A[2]*m_localTransform[8];
1897 if(a==0.) return false;
1898 double S = ((m_localTransform[12]-R[0]*m_localTransform[6])-(R[1]*m_localTransform[7]+R[2]*m_localTransform[8]))/a;
1899 globalPars[45] = S;
1900
1901 // Track parameters in last point
1902 //
1903 R[0]+=(A[0]*S); R[1]+=(A[1]*S); R[2]+=(A[2]*S); if(!Jac) return true;
1904
1905 // Derivatives of track parameters in last point
1906 //
1907 for(int i=7; i<42; i+=7) {
1908
1909 double* dR = &globalPars[i ];
1910 double* dA = &globalPars[i+3];
1911 dR[0]+=(dA[0]*S); dR[1]+=(dA[1]*S); dR[2]+=(dA[2]*S);
1912 }
1913 return true;
1914}
1915
1917{
1918 m_detstatus =-1 ;
1919 m_status = 0 ;
1920 m_nlinksForward = 0 ;
1921 m_nlinksBackward = 0 ;
1922 m_nMissing = 0 ;
1923 m_radlength = .03;
1924 m_radlengthN = .03;
1925 m_energylose = .4 ;
1926 m_tools = nullptr ;
1927 m_noisemodel = 0 ;
1928 m_covariance.resize(2,2);
1929 m_covariance<<0.,0.,0.,0.;
1930 m_ndf = 0 ;
1931 m_ndfBackward = 0 ;
1932 m_ndfForward = 0 ;
1933 m_ntsos = 0 ;
1934 m_maxholes = 0 ;
1935 m_maxdholes = 0 ;
1936 m_xi2Forward = 0.;
1937 m_xi2Backward = 0.;
1938 m_xi2totalForward = 0.;
1939 m_xi2totalBackward = 0.;
1940 m_halflength = 0.;
1941 m_step = 0.;
1942 m_xi2max = 0.;
1943 m_dist = 0.;
1944 m_xi2maxNoAdd = 0.;
1945 m_xi2maxlink = 0.;
1946 m_xi2multi = 0.;
1947 m_invMoment = 0.;
1948 m_detelement = nullptr ;
1949 m_detlink = nullptr ;
1950 m_surface = nullptr ;
1951 m_cluster = nullptr ;
1952 m_clusterOld = nullptr ;
1953 m_clusterNoAdd = nullptr ;
1954 m_updatorTool = nullptr ;
1955 m_proptool = nullptr ;
1956 m_riotool = nullptr ;
1957 m_inside = 0 ;
1958 m_nholesForward = 0 ;
1959 m_nholesBackward = 0 ;
1960 m_dholesForward = 0 ;
1961 m_dholesBackward = 0 ;
1962 m_nclustersForward = 0 ;
1964 m_npixelsBackward = 0 ;
1965 m_stereo = false ;
1966 m_fieldMode = false ;
1967
1968 m_tsos[0]=m_tsos[1]=m_tsos[2]=nullptr;
1969}
1970
1975
1976// deliberately not assigning all variables?
1977// cppcheck-suppress operatorEqVarError
1978InDet::SiTrajectoryElement_xk& InDet::SiTrajectoryElement_xk::operator =
1980{
1981 if(&E==this) return(*this);
1982
1983 m_fieldMode = E.m_fieldMode ;
1984 m_status = E.m_status ;
1985 m_detstatus = E.m_detstatus ;
1986 m_inside = E.m_inside ;
1987 m_nMissing = E.m_nMissing ;
1988 m_stereo = E.m_stereo ;
1989 m_detelement = E.m_detelement ;
1990 m_detlink = E.m_detlink ;
1991 m_surface = E.m_surface ;
1992 m_sibegin = E.m_sibegin ;
1993 m_siend = E.m_siend ;
1994 m_cluster = E.m_cluster ;
1995 m_clusterOld = E.m_clusterOld ;
1996 m_clusterNoAdd = E.m_clusterNoAdd;
1997 m_parametersPredForward = E.m_parametersPredForward;
1998 m_parametersUpdatedForward = E.m_parametersUpdatedForward;
1999 m_parametersPredBackward = E.m_parametersPredBackward;
2000 m_parametersUpdatedBackward = E.m_parametersUpdatedBackward;
2001 m_parametersSM = E.m_parametersSM;
2002 m_dist = E.m_dist ;
2003 m_xi2Forward = E.m_xi2Forward ;
2004 m_xi2Backward = E.m_xi2Backward ;
2005 m_xi2totalForward = E.m_xi2totalForward ;
2006 m_xi2totalBackward = E.m_xi2totalBackward;
2007 m_radlength = E.m_radlength ;
2008 m_radlengthN = E.m_radlengthN ;
2009 m_energylose = E.m_energylose ;
2010 m_halflength = E.m_halflength ;
2011 m_step = E.m_step ;
2012 m_nlinksForward = E.m_nlinksForward ;
2013 m_nlinksBackward = E.m_nlinksBackward ;
2014 m_nholesForward = E.m_nholesForward ;
2015 m_nholesBackward = E.m_nholesBackward ;
2016 m_dholesForward = E.m_dholesForward ;
2017 m_dholesBackward = E.m_dholesBackward ;
2018 m_noisemodel = E.m_noisemodel ;
2019 m_ndf = E.m_ndf ;
2020 m_ndfForward = E.m_ndfForward ;
2021 m_ndfBackward = E.m_ndfBackward ;
2022 m_ntsos = E.m_ntsos ;
2023 m_nclustersForward = E.m_nclustersForward ;
2024 m_nclustersBackward = E.m_nclustersBackward ;
2025 m_npixelsBackward = E.m_npixelsBackward ;
2026 m_noise = E.m_noise ;
2027 m_tools = E.m_tools ;
2028 m_covariance = E.m_covariance ;
2029 m_position = E.m_position ;
2030 m_invMoment = E.m_invMoment ;
2031 for(int i=0; i!=m_nlinksForward; ++i) {m_linkForward[i]=E.m_linkForward[i];}
2032 for(int i=0; i!=m_nlinksBackward; ++i) {m_linkBackward[i]=E.m_linkBackward[i];}
2033 for(int i=0; i!=m_ntsos ; ++i) {m_tsos [i]=E.m_tsos [i];}
2034 for(int i=0; i!=m_ntsos ; ++i) {m_utsos[i]=E.m_utsos [i];}
2035 return(*this);
2036}
2037
2039{
2040 int n = 0;
2041 if (m_detstatus<=0) return n;
2042
2044 const InDet::PixelClusterCollection::const_iterator* sibegin
2045 = std::any_cast<const InDet::PixelClusterCollection::const_iterator>(&m_sibegin);
2046 const InDet::PixelClusterCollection::const_iterator* siend
2047 = std::any_cast<const InDet::PixelClusterCollection::const_iterator>(&m_siend);
2048 if (sibegin==nullptr or siend==nullptr) return 0;
2049 for (InDet::PixelClusterCollection::const_iterator p = *sibegin; p!=*siend; ++p) {
2050 ++n;
2051 }
2052 } else if (m_itType==SCT_ClusterColl) {
2053 const InDet::SCT_ClusterCollection::const_iterator* sibegin
2054 = std::any_cast<const InDet::SCT_ClusterCollection::const_iterator>(&m_sibegin);
2055 const InDet::SCT_ClusterCollection::const_iterator* siend
2056 = std::any_cast<const InDet::SCT_ClusterCollection::const_iterator>(&m_siend);
2057 if (sibegin==nullptr or siend==nullptr) return 0;
2058 for (InDet::SCT_ClusterCollection::const_iterator p = *sibegin; p!=*siend; ++p) {
2059 ++n;
2060 }
2061 } else {
2062 const InDet::SiClusterCollection::const_iterator* sibegin
2063 = std::any_cast<const InDet::SiClusterCollection::const_iterator>(&m_sibegin);
2064 const InDet::SiClusterCollection::const_iterator* siend
2065 = std::any_cast<const InDet::SiClusterCollection::const_iterator>(&m_siend);
2066 if (sibegin==nullptr or siend==nullptr) return 0;
2067 for (InDet::SiClusterCollection::const_iterator p = *sibegin; p!=*siend; ++p) {
2068 ++n;
2069 }
2070 }
2071 return n;
2072}
2073
2075{
2076 return m_cluster != m_clusterOld || m_status != 3;
2077}
2078
2080// Test for next compatible cluster
2082
2084{
2085 cl = false ;
2087
2088 if(m_nlinksBackward > 1 && m_linkBackward[1].xi2() <= m_xi2max) {
2089 X+=m_linkBackward[1].xi2();
2090 cl = true; return true;
2091 }
2092
2093 if(m_inside < 0) {
2095 }
2096 return true;
2097}
2098
2105{
2106 cl = false ;
2110 if(m_detstatus == 2) return false;
2113 if(m_nlinksForward > 1 && m_linkForward[1].xi2() <= m_xi2max) {
2115 X+=m_linkForward[1].xi2();
2117 cl = true;
2118 return true;
2119 }
2121 if(m_inside < 0) {
2125 return false;
2126 }
2128 return true;
2129}
2130
2135
2137{
2138 m_cluster = Cl ;
2139 m_status = 2 ;
2140 m_xi2Backward = Xi2;
2141}
2142
2143
2148
2153
2155{
2156 m_nMissing = n;
2157}
2158
2160// Add pixel or SCT cluster to pattern track parameters with Xi2 calculation
2162
2165{
2166 int N;
2168 if(!m_stereo) {
2173 if(m_detelement->isSCT()) {
2174 return m_updatorTool->addToStateOneDimension
2175 (Ta,m_cluster->localPosition(),m_covariance,Tb,Xi2,N);
2176 }
2177 return m_updatorTool->addToState
2178 (Ta,m_cluster->localPosition(),m_covariance,Tb,Xi2,N);
2179 }
2181 return m_updatorTool->addToStateOneDimension
2182 (Ta,m_cluster->localPosition(),m_cluster->localCovariance(),Tb,Xi2,N);
2183}
2184
2186// Add pixel or SCT cluster to pattern track parameters without Xi2 calculation
2188
2191{
2192 if(!m_stereo) {
2193
2196 if(m_detelement->isSCT()) {
2197 return m_updatorTool->addToStateOneDimension
2198 (Ta,m_cluster->localPosition(),m_covariance,Tb);
2199 }
2200 return m_updatorTool->addToState
2201 (Ta,m_cluster->localPosition(),m_covariance,Tb);
2202 }
2203 return m_updatorTool->addToStateOneDimension
2204 (Ta,m_cluster->localPosition(),m_cluster->localCovariance(),Tb);
2205}
2206
2208// Add pixel or SCT cluster to pattern track parameters with Xi2 calculation
2209// using precise error
2211
2214 double& Xi2) {
2215 int N;
2216 if(m_ndf==1) {
2217 return m_updatorTool->addToStateOneDimension(Ta,m_position,m_covariance,Tb,Xi2,N);
2218 }
2219 else {
2220 return m_updatorTool->addToState (Ta,m_position,m_covariance,Tb,Xi2,N);
2221 }
2222}
2223
2225// Add two pattern track parameters without Xi2 calculation
2227
2235
2237// Propagate pattern track parameters to surface
2239
2244
2246// Initiate state
2248
2251{
2254 if (m_tools->isITkGeometry()) {
2255 // using pattern covariance for all clusters for ITk
2256 Amg::MatrixX cov(2,2);
2257 patternCovariances(m_cluster,cov(0,0),cov(1,0),cov(1,1));
2258 return outputPars.initiate(inputPars,m_cluster->localPosition(),cov);
2259 }
2260 return outputPars.initiate(inputPars,m_cluster->localPosition(),m_cluster->localCovariance());
2261}
2262
2264// Initiate state with cluster correction
2266
2272
2274// Pattern covariances
2276
2278(const InDet::SiCluster* c,double& covX,double& covXY,double& covY) const
2279{
2280 const Amg::MatrixX& v = c->localCovariance();
2281 if (m_tools->useFastTracking() and m_stereo) {
2282 // in fast tracking mode, endcap strip clusters use cluster covariance terms
2283 covX=v(0,0);
2284 covY=v(1,1);
2285 covXY=v(1,0);
2286 return;
2287 }
2288 covX = c->width().phiR();
2289 covX*=(covX*s_oneOverTwelve);
2290 covXY = c->localCovariance()(1,0);
2291
2292 if(!m_tools->useFastTracking()){
2293 if(covX < v(0,0)) covX=v(0,0);
2294 covXY = 0.;
2295 }
2296
2297 if(m_ndf==1) {
2298 covY=v(1,1);
2299 }
2300 else {
2302 covY=c->width().z();
2303 covY*=(covY*s_oneOverTwelve);
2304 if(!m_tools->useFastTracking()){
2305 if(covY < v(1,1)) covY=v(1,1);
2306 }
2307 }
2308}
2309
2311// Last detector elements with clusters
2313
2318
2320{
2321 if(i<0 || i>2) return nullptr;
2322
2323 bool us = m_utsos[i];
2324 m_utsos[i] = true;
2325
2326 if(us) return new Trk::TrackStateOnSurface(*m_tsos[i]);
2327
2328 return m_tsos[i];
2329}
2330
2332// Set electron noise model
2334
2339
2341// Initiate state with cluster correction
2343
2351
2353// Add pixel or SCT cluster to pattern track parameters with Xi2 calculation
2354// using precise error
2356
2360 double& Xi2)
2361{
2362 int N;
2364
2365 if(m_ndf==1) {
2366 return m_updatorTool->addToStateOneDimension(Ta,m_position,m_covariance,Tb,Xi2,N);
2367 }
2368 else {
2369 return m_updatorTool->addToState(Ta,m_position,m_covariance,Tb,Xi2,N);
2370 }
2371}
2372
2374// Precise cluster position and covariance calculation
2376
2378{
2379
2380 m_position = m_cluster->localPosition ();
2381 m_covariance = m_cluster->localCovariance();
2382
2383 if(m_ndf==1) return;
2384
2385 const Amg::Vector2D& colRow = m_cluster->width().colRow();
2386 if(colRow.x()==1. && colRow.y()==1.) return;
2387
2388 std::unique_ptr<Trk::TrackParameters> tr = Tc.convert(true);
2389 std::unique_ptr<const Trk::RIO_OnTrack> ri(m_riotool->correct(*m_cluster, *tr, Gaudi::Hive::currentContext()));
2390
2391 m_position = ri->localParameters();
2392 m_covariance = ri->localCovariance();
2393
2394}
2395
2397// Search clusters compatible with track
2399
static const int B0
Definition AtlasPID.h:122
#define AmgSymMatrix(dim)
static const double Pi
static Double_t Tc(Double_t t)
static Double_t s0
static Double_t a
static Double_t Tp(Double_t *t, Double_t *par)
static Double_t P(Double_t *tt, Double_t *par)
static Double_t sc
#define H2(x, y, z)
Definition MD5.cxx:115
static const int qc[]
struct TBPatternUnitContext S2
struct TBPatternUnitContext S3
struct TBPatternUnitContext S1
#define z
This is a "hash" representation of an Identifier.
bool ForwardPropagationWithSearch(SiTrajectoryElement_xk &, const EventContext &)
Trk::TrackStateOnSurface * m_tsos[3]
int searchClustersSub(Trk::PatternTrackParameters &, SiClusterLink_xk *)
void precisePosCov(Trk::PatternTrackParameters &)
Trk::PatternTrackParameters m_parametersPredForward
Pattern track parameters.
double m_localDir[3]
the transform for this element
bool BackwardPropagationFilter(SiTrajectoryElement_xk &, const EventContext &ctx)
bool BackwardPropagationSmoother(SiTrajectoryElement_xk &, bool, const EventContext &ctx)
int searchClusters(Trk::PatternTrackParameters &, SiClusterLink_xk *)
std::unique_ptr< Trk::TrackParameters > trackParameters(bool, int)
bool ForwardPropagationWithoutSearch(SiTrajectoryElement_xk &, const EventContext &)
const Trk::IPatternParametersPropagator * m_proptool
const Trk::IRIO_OnTrackCreator * m_riotool
const Trk::PatternTrackParameters & parametersUB() const
observed
void setCluster(const InDet::SiCluster *)
Trk::TrackStateOnSurface * trackSimpleStateOnSurface(bool, bool, int)
const InDetDD::SiDetectorElement * m_detelement
void setTools(const InDet::SiTools_xk *)
Trk::PatternTrackParameters m_parametersPredBackward
For backward filtering / smoothing Predicted state, backward.
Trk::PatternTrackParameters m_parametersSM
bool initiateStatePrecise(Trk::PatternTrackParameters &, Trk::PatternTrackParameters &)
const InDet::SiCluster * m_clusterOld
bool rungeKuttaToPlane(bool updateJacobian, double *globalPars)
Runge Kutta step to plane Updates the "globalPars" array, which is also used to pass the input.
const Trk::IPatternParametersUpdator * m_updatorTool
bool firstTrajectorElement(const Trk::TrackParameters &, const EventContext &ctx)
void checkBoundaries(const Trk::PatternTrackParameters &pars)
bool initiateStateWithCorrection(Trk::PatternTrackParameters &, Trk::PatternTrackParameters &, Trk::PatternTrackParameters &)
const Trk::PatternTrackParameters & parametersPB() const
predicted
void setParametersB(Trk::PatternTrackParameters &)
std::unique_ptr< Trk::TrackParameters > trackParametersWithNewDirection(bool, int)
void setDeadRadLength(Trk::PatternTrackParameters &)
bool addClusterPreciseWithCorrection(Trk::PatternTrackParameters &, Trk::PatternTrackParameters &, Trk::PatternTrackParameters &, double &)
bool addCluster(Trk::PatternTrackParameters &, Trk::PatternTrackParameters &, double &)
bool combineStates(Trk::PatternTrackParameters &, Trk::PatternTrackParameters &, Trk::PatternTrackParameters &)
const InDet::SiDetElementBoundaryLink_xk * m_detlink
bool transformGlobalToPlane(bool updateJacobian, double *globalPars, Trk::PatternTrackParameters &startingParameters, Trk::PatternTrackParameters &outputParameters)
Tramsform from global to plane surface Will take the global parameters in globalPars,...
bool ForwardPropagationWithoutSearchPreciseWithCorrection(SiTrajectoryElement_xk &, const EventContext &)
bool transformPlaneToGlobal(bool, Trk::PatternTrackParameters &localParameters, double *globalPars)
Tramsform from plane to global Will take the surface and parameters from localParameters and populate...
bool addClusterPrecise(Trk::PatternTrackParameters &, Trk::PatternTrackParameters &, double &)
void setClusterB(const InDet::SiCluster *, double)
bool BackwardPropagationPrecise(SiTrajectoryElement_xk &, const EventContext &ctx)
Trk::TrackStateOnSurface * trackStateOnSurface(bool, bool, bool, int, const EventContext &ctx)
bool initiateState(Trk::PatternTrackParameters &inputPars, Trk::PatternTrackParameters &outputPars)
inputPars: input parameters.
static constexpr double s_oneOverTwelve
Trk::PatternTrackParameters m_parametersUpdatedForward
Updated state, forward.
bool propagateParameters(Trk::PatternTrackParameters &startingParameters, Trk::PatternTrackParameters &outParameters, double &step)
Start from 'startingParameters', propagate to current surface.
const InDet::SiCluster * m_clusterNoAdd
Trk::PatternTrackParameters m_parametersUpdatedBackward
Updated state, backward.
void setParametersF(Trk::PatternTrackParameters &)
void patternCovariances(const InDet::SiCluster *, double &, double &, double &) const
Private Methods.
const Trk::PRDtoTrackMap * m_prdToTrackMap
void noiseProduction(int, const Trk::PatternTrackParameters &, double rad_length=-1., bool useMomentum=false)
bool setDead(const Trk::Surface *)
MagField::AtlasFieldCache m_fieldCache
Trk::TrackStateOnSurface * tsos(int i)
const Trk::PatternTrackParameters & parametersPF() const
track parameters for forward filter / smoother predicted
InDet::SiClusterLink_xk m_linkBackward[10]
bool isNextClusterHoleF(bool &, double &)
checks if removing this cluster from the forward propagation would result in a critical number of hol...
bool propagate(Trk::PatternTrackParameters &startingParameters, Trk::PatternTrackParameters &outParameters, double &step, const EventContext &ctx)
Will propagate the startingParameters from their reference to the surface associated with this elemen...
const InDet::SiTools_xk * m_tools
Trk::TrackStateOnSurface * trackPerigeeStateOnSurface(const EventContext &ctx)
InDet::SiClusterLink_xk m_linkForward[10]
bool difference() const
check for a difference between forward and back propagation
bool straightLineStepToPlane(bool updateJacobian, double *globalPars)
Straight line step to plane Updates the "globalPars" array, which is also used to pass the input.
const double & correctionIMom() const
bool production(const TrackParameters *)
void addNoise(const NoiseOnSurface &, PropDirection)
void setParametersWithCovariance(const Surface *, const double *, const double *)
virtual const Surface & associatedSurface() const override final
Access to the Surface associated to the Parameters.
void setParameters(const Surface *, const double *)
void removeNoise(const NoiseOnSurface &, PropDirection)
bool initiate(PatternTrackParameters &, const Amg::Vector2D &, const Amg::MatrixX &)
Class describing the Line to which the Perigee refers to.
represents a deflection of the track caused through multiple scattering in material.
Abstract Base Class for tracking surfaces.
Definition Surface.h:79
const Amg::Transform3D & transform() const
Returns HepGeom::Transform3D by reference.
virtual constexpr SurfaceType type() const =0
Returns the Surface type to avoid dynamic casts.
represents the track state (measurement, material, fit parameters and quality) at a surface.
const TrackParameters * trackParameters() const
return ptr to trackparameters const overload
@ Measurement
This is a measurement, and will at least contain a Trk::MeasurementBase.
@ Perigee
This represents a perigee, and so will contain a Perigee object only.
@ Outlier
This TSoS contains an outlier, that is, it contains a MeasurementBase/RIO_OnTrack which was not used ...
@ Scatterer
This represents a scattering point on the track, and so will contain TrackParameters and MaterialEffe...
struct color C
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Dynamic Matrix - dynamic allocation.
Eigen::Affine3d Transform3D
Eigen::Matrix< double, 2, 1 > Vector2D
Eigen::Matrix< double, 3, 1 > Vector3D
@ oppositeMomentum
@ alongMomentum
@ anyDirection
ATH_ALWAYS_INLINE void propJacobian(double *ATH_RESTRICT P, const double *ATH_RESTRICT H0, const double *ATH_RESTRICT H1, const double *ATH_RESTRICT H2, const double *ATH_RESTRICT A, const double *ATH_RESTRICT A0, const double *ATH_RESTRICT A3, const double *ATH_RESTRICT A4, const double *ATH_RESTRICT A6, const double S3)
This provides an inline helper function for updating the jacobian during Runge-Kutta propagation.
ParametersBase< TrackParametersDim, Charged > TrackParameters
hold the test vectors and ease the comparison