ATLAS Offline Software
Loading...
Searching...
No Matches
SiTrajectoryElement_xk.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2023 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)
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, Gaudi::Hive::currentContext()));
932 } else {
933 ro.reset(m_riotool->correct(*m_clusterNoAdd, *tp, Gaudi::Hive::currentContext()));
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()), Gaudi::Hive::currentContext()) );
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 Amg::MatrixX cv = cl->localCovariance();
1019
1023
1024 if (m_ndf == 1) {
1025 const InDet::SCT_Cluster* sc = static_cast<const InDet::SCT_Cluster*>(cl);
1026 if (sc)
1027 ro = std::make_unique<InDet::SCT_ClusterOnTrack>(sc, std::move(locp), std::move(cv), iH, sc->globalPosition());
1028 } else {
1029 const InDet::PixelCluster* pc = static_cast<const InDet::PixelCluster*>(cl);
1030 if (pc)
1031 ro = std::make_unique<InDet::PixelClusterOnTrack>(
1032 pc, std::move(locp), std::move(cv), iH, pc->globalPosition(), pc->gangedPixel());
1033 }
1034 return new Trk::TrackStateOnSurface(fq, std::move(ro), std::move(tp), nullptr, pat);
1035}
1036
1038// TrackStateOnSurface production for perigee
1040
1043{
1044 if(&m_parametersUpdatedBackward.associatedSurface()!=m_surface) return nullptr;
1045
1046 double step ;
1048
1050
1051 bool Q = m_proptool->propagate
1052 (ctx,
1054
1055 if(Q) {
1056 std::bitset<Trk::TrackStateOnSurface::NumberOfTrackStateOnSurfaceTypes> typePattern;
1057 typePattern.set(Trk::TrackStateOnSurface::Perigee);
1058 return new Trk::TrackStateOnSurface(nullptr,Tp.convert(true),nullptr,typePattern);
1059 }
1060 return nullptr;
1061}
1062
1064// TrackParameters production
1065// Q = 0 no first or last element of the trajectory
1066// Q = 1 first element of the trajectory
1067// Q = 2 last element of the trajectory
1069
1070std::unique_ptr<Trk::TrackParameters>
1072{
1073 if (m_status == 1) {
1074 if (m_cluster) {
1075 return m_parametersUpdatedForward.convert(cov);
1076 } else {
1077 return m_parametersPredForward.convert(cov);
1078 }
1079 } else if (m_status == 2) {
1080 if (m_cluster) {
1081 return m_parametersUpdatedBackward.convert(cov);
1082 } else {
1083 return m_parametersPredBackward.convert(cov);
1084 }
1085 } else if (m_status == 3) {
1086 if (Q == 0) {
1087 if (m_cluster) {
1089 return m_parametersSM.convert(cov);
1090 } else if ((*m_parametersUpdatedBackward.covariance())(4, 4) <
1091 (*m_parametersPredForward.covariance())(4, 4)) {
1092 return m_parametersUpdatedBackward.convert(cov);
1093 } else {
1094 return m_parametersPredForward.convert(cov);
1095 }
1096 } else
1097 return m_parametersSM.convert(cov);
1098 }
1099 if (Q == 1) {
1100 if (m_cluster) {
1101 return m_parametersUpdatedBackward.convert(cov);
1102 }
1103 }
1104 if (Q == 2) {
1105 if (m_cluster) {
1106 return m_parametersUpdatedForward.convert(cov);
1107 }
1108 }
1109 }
1110 return nullptr;
1111}
1112
1114// Noise production
1115// Dir = +1 along momentum , -1 opposite momentum
1116// Model = 1 - muon, 2 - electron
1117// useMomentum = true - use m_invMoment instead of Tp.par()[4]
1119
1121(int Dir,const Trk::PatternTrackParameters& Tp,double rad_length, bool useMomentum)
1122{
1123
1124 int Model = m_noisemodel;
1125 if(Model < 1 || Model > 2) return;
1126 if (rad_length<0.) rad_length=m_radlength;
1127
1128 double q = useMomentum ? m_invMoment : std::abs(Tp.parameters()[4]);
1129
1131 double s = std::abs(m_localDir[0]*m_localTransform[6]+
1134 if(m_tools->isITkGeometry() && !m_detelement) s = sqrt(m_localDir[0]*m_localDir[0]+m_localDir[1]*m_localDir[1]);
1135
1136 if(m_tools->isITkGeometry()){
1137 if (s < .01) s = 100.;
1138 else s = 1./s;
1139 }
1140 else{
1141 if (s < .05) s = 20.;
1142 else s = 1./s;
1143 }
1144
1150 double covariancePola = (134.*m_radlengthN)*(q*q);
1151 if(m_tools->isITkGeometry()){
1152 double qc = (1.+.038*log(m_radlengthN))*q;
1153 covariancePola = (185.*m_radlengthN)*qc*qc;
1154 }
1155
1157 double d = (1.-m_localDir[2])*(1.+m_localDir[2]);
1159 if(d < 1.e-5) d = 1.e-5;
1161 double covarianceAzim = covariancePola/d;
1162
1163 double covarianceIMom;
1164 double correctionIMom;
1165
1167 if(Model==1) {
1169 double dp = m_energylose*q*s;
1171 covarianceIMom = (.2*dp*dp)*(q*q);
1173 correctionIMom = 1.-dp;
1174 }
1176 else {
1177 correctionIMom = .70;
1178 covarianceIMom = (correctionIMom-1.)*(correctionIMom-1.)*(q*q);
1179 }
1181 if(Dir>0) correctionIMom = 1./correctionIMom;
1183 m_noise.set(covarianceAzim,covariancePola,covarianceIMom,correctionIMom);
1184}
1185
1186
1188// TrackParameters production with new direction
1189// Q = 0 no first or last element of the trajectory
1190// Q = 1 first element of the trajectory
1191// Q = 2 last element of the trajectory
1193
1194std::unique_ptr<Trk::TrackParameters>
1196{
1197 if (m_status == 1) {
1198 if (m_cluster) {
1200 } else {
1202 }
1203
1204 } else if (m_status == 2) {
1205 if (m_cluster) {
1207 } else {
1209 }
1210 } else if (m_status == 3) {
1211
1212 if (Q == 0) {
1213 if (m_cluster) {
1215 return trackParameters(m_parametersSM, cov);
1216 else if ((*m_parametersUpdatedBackward.covariance())(4, 4) <
1217 (*m_parametersPredForward.covariance())(4, 4)) {
1219 } else {
1221 }
1222 } else {
1223 return trackParameters(m_parametersSM, cov);
1224 }
1225 }
1226 if (Q == 1) {
1227 if (m_cluster){
1229 }
1230 }
1231 if (Q == 2) {
1232 if (m_cluster){
1234 }
1235 }
1236 }
1237 return nullptr;
1238}
1239
1241// TrackParameters production with new direction
1243std::unique_ptr<Trk::TrackParameters>
1246{
1247 Tp.changeDirection();
1248 return Tp.convert(cov);
1249}
1250
1251
1253// Step calculation
1255
1258{
1260
1261 if (TE.m_status == 1) {
1263 else Ta = TE.m_parametersPredForward;
1264 }
1265 else if(TE.m_status == 2) {
1267 else Ta = TE.m_parametersPredBackward;
1268 }
1269 else if(TE.m_status == 3) {
1270 Ta = TE.m_parametersSM;
1271 }
1272 double step = 0.;
1273 bool Q = propagateParameters(Ta,Tb,step);
1274 if(Q) return step;
1275 return 0.;
1276}
1277
1279// Global position of track parameters
1281
1283{
1284 if (m_status == 1) {
1285 if(m_cluster) return m_parametersUpdatedForward.position();
1286 else return m_parametersPredForward.position();
1287 }
1288 else if(m_status == 2) {
1289 if(m_cluster) return m_parametersUpdatedBackward.position();
1290 else return m_parametersPredBackward.position();
1291 }
1292 else if(m_status == 3) {
1293
1294 Amg::Vector3D gp(0.,0.,0.);
1296
1297 if(m_cluster) S1 = parametersUB();
1298 else S1 = parametersPB();
1299
1300 QA = m_updatorTool->combineStates(S1,S2,SM);
1301
1302 if(QA) {
1303 gp = SM.position();
1304 }
1305 return gp;
1306 }
1307 Amg::Vector3D gp(0.,0.,0.);
1308 return gp;
1309}
1310
1312// Step estimation to 0,0,0
1314
1316{
1317 Amg::Vector3D M;
1319
1320 if(m_cluster) {
1321 M = m_parametersUpdatedBackward.momentum();
1322 P = m_parametersUpdatedBackward.position();
1323 }
1324 else {
1325 M = m_parametersPredBackward.momentum();
1326 P = m_parametersPredBackward.position();
1327 }
1328
1329 return -(P[0]*M[0]+P[1]*M[1]);
1330}
1331
1333// Errase cluster fo forward propagation
1335
1343
1345// Quality of the trajectory element
1347
1349{
1350
1351 if(!m_cluster && !m_clusterNoAdd) {
1352
1353 if(m_detstatus < 0) return 0.;
1354
1355 if (m_inside < 0) {
1356 double w = 2.-m_xi2max; if(++holes > 1) w*=2.; return w;
1357 }
1358 else if(m_inside == 0) return -1.;
1359 else return 0.;
1360 }
1361
1362 double w,X,Xc = m_xi2max+2.;
1363 m_status == 1 ? X = m_xi2Forward : X = m_xi2Backward;
1364 m_ndf == 2 ? w = 1.2*(Xc-X*.5) : w = Xc-X ; if(w < -1.) w = -1.;
1365 holes = 0;
1366
1367 return w;
1368}
1369
1371// Main function for pattern track parameters and covariance matrix propagation
1372// to PlaneSurface.
1377bool
1379 Trk::PatternTrackParameters & outputParameters,
1380 double & StepLength,
1381 const EventContext& ctx ) {
1382 if (Trk::SurfaceType::Plane == m_surface->type() and
1383 Trk::SurfaceType::Plane == startingParameters.associatedSurface().type()) {
1384 bool useJac = (startingParameters.iscovariance());
1385 double globalParameters[64];
1393
1395 if(!transformPlaneToGlobal(useJac,startingParameters,globalParameters)) return false;
1397 if( m_fieldMode) {
1398 if(!rungeKuttaToPlane (useJac,globalParameters)) return false;
1399 }
1401 else {
1402 if(!straightLineStepToPlane(useJac,globalParameters)) return false;
1403 }
1405 StepLength = globalParameters[45];
1407 return transformGlobalToPlane(useJac,globalParameters,startingParameters,outputParameters);
1408 } else {
1409 if (!m_proptool->propagate (ctx,
1410 startingParameters, *m_surface, outputParameters,
1411 Trk::anyDirection, m_tools->fieldTool(), StepLength, Trk::pion))
1412 return false;
1413
1414 double sinPhi,cosPhi,sinTheta,cosTheta;
1415 sincos(outputParameters.parameters()[2],&sinPhi,&cosPhi);
1416 sincos(outputParameters.parameters()[3],&sinTheta,&cosTheta);
1417 m_localDir[0] = cosPhi*sinTheta;
1418 m_localDir[1] = sinPhi*sinTheta;
1419 m_localDir[2] = cosTheta;
1420 return true;
1421 }
1422}
1423
1425// Main function for pattern track parameters propagation without covariance.
1430
1431bool
1433 Trk::PatternTrackParameters & outputParameters,
1434 double & StepLength ) {
1435 bool useJac = false;
1436 double globalParameters[64];
1444 if(!transformPlaneToGlobal(useJac,startingParameters,globalParameters)) return false;
1447 if( m_fieldMode) {
1448 if(!rungeKuttaToPlane (useJac,globalParameters)) return false;
1449 }
1451 else {
1452 if(!straightLineStepToPlane(useJac,globalParameters)) return false;
1453 }
1455 StepLength = globalParameters[45];
1457 return transformGlobalToPlane(useJac,globalParameters,startingParameters,outputParameters);
1458}
1459
1474// /////////////////////////////////////////////////////////////////////////////////
1475
1477 Trk::PatternTrackParameters& localParameters,
1478 double* globalPars) {
1480 double sinPhi,cosPhi,cosTheta,sintheta;
1481 sincos(localParameters.parameters()[2],&sinPhi,&cosPhi);
1482 sincos(localParameters.parameters()[3],&sintheta,&cosTheta);
1483 if (m_tools->isITkGeometry()) {
1484 if(std::abs(sintheta) < std::abs(localParameters.parameters()[4])*50.) return false;
1485 }
1487 const Trk::Surface* pSurface=&localParameters.associatedSurface();
1488 if (!pSurface){
1489 throw(std::runtime_error("TrackParameters associated surface is null pointer in InDet::SiTrajectoryElement_xk::transformPlaneToGlobal"));
1490 }
1492 const Amg::Transform3D& T = pSurface->transform();
1493
1495 double Ax[3] = {T(0,0),T(1,0),T(2,0)};
1496 double Ay[3] = {T(0,1),T(1,1),T(2,1)};
1497
1499 globalPars[ 0] = localParameters.parameters()[0]*Ax[0]+localParameters.parameters()[1]*Ay[0]+T(0,3); // X
1500 globalPars[ 1] = localParameters.parameters()[0]*Ax[1]+localParameters.parameters()[1]*Ay[1]+T(1,3); // Y
1501 globalPars[ 2] = localParameters.parameters()[0]*Ax[2]+localParameters.parameters()[1]*Ay[2]+T(2,3); // Z
1503 globalPars[ 3] = cosPhi*sintheta; // Ax
1504 globalPars[ 4] = sinPhi*sintheta; // Ay
1505 globalPars[ 5] = cosTheta;
1507 globalPars[ 6] = localParameters.parameters()[4]; // CM
1509 if(std::abs(globalPars[6])<1.e-20) {
1510 if (globalPars[6] < 0){
1511 globalPars[6]=-1.e-20;
1512 }
1513 else globalPars[6]= 1.e-20;
1514 }
1515
1517 if(useJac) {
1518
1519 // /dL1 | /dL2 | /dPhi | /dThe | /dCM |
1520 globalPars[ 7] = Ax[0]; globalPars[14] = Ay[0]; globalPars[21] = 0.; globalPars[28] = 0.; globalPars[35] = 0.; // dX /
1521 globalPars[ 8] = Ax[1]; globalPars[15] = Ay[1]; globalPars[22] = 0.; globalPars[29] = 0.; globalPars[36] = 0.; // dY /
1522 globalPars[ 9] = Ax[2]; globalPars[16] = Ay[2]; globalPars[23] = 0.; globalPars[30] = 0.; globalPars[37] = 0.; // dZ /
1523 globalPars[10] = 0.; globalPars[17] = 0.; globalPars[24] =-globalPars[4]; globalPars[31] = cosPhi*cosTheta; globalPars[38] = 0.; // dAx/
1524 globalPars[11] = 0.; globalPars[18] = 0.; globalPars[25] = globalPars[3]; globalPars[32] = sinPhi*cosTheta; globalPars[39] = 0.; // dAy/
1525 globalPars[12] = 0.; globalPars[19] = 0.; globalPars[26] = 0.; globalPars[33] = -sintheta; globalPars[40] = 0.; // dAz/
1526
1528 globalPars[42] = 0.;
1529 globalPars[43] = 0.;
1530 globalPars[44] = 0.;
1531 }
1533 globalPars[45] = 0.;
1534 return true;
1535}
1536
1550// /////////////////////////////////////////////////////////////////////////////////
1552(bool useJac,double* globalPars,Trk::PatternTrackParameters& startingParameters,Trk::PatternTrackParameters& outputParameters)
1553{
1555 double Ax[3] = {m_localTransform[0],m_localTransform[1],m_localTransform[2]};
1556 double Ay[3] = {m_localTransform[3],m_localTransform[4],m_localTransform[5]};
1557 double Az[3] = {m_localTransform[6],m_localTransform[7],m_localTransform[8]};
1559 double d [3] = {globalPars[0]-m_localTransform[ 9],
1560 globalPars[1]-m_localTransform[10],
1561 globalPars[2]-m_localTransform[11]};
1562
1564 double p[5] = {
1565 d[0]*Ax[0]+d[1]*Ax[1]+d[2]*Ax[2],
1566 d[0]*Ay[0]+d[1]*Ay[1]+d[2]*Ay[2],
1567 atan2(globalPars[4],globalPars[3]),
1568 acos(globalPars[5]),
1569 globalPars[6]
1570 };
1571
1573 m_localDir[0] = globalPars[3];
1574 m_localDir[1] = globalPars[4];
1575 m_localDir[2] = globalPars[5];
1576
1577 if (useJac) {
1579 double A = Az[0]*globalPars[3]+Az[1]*globalPars[4]+Az[2]*globalPars[5];
1580 if(A!=0.) A=1./A;
1581 double s0 = Az[0]*globalPars[ 7]+Az[1]*globalPars[ 8]+Az[2]*globalPars[ 9];
1582 double s1 = Az[0]*globalPars[14]+Az[1]*globalPars[15]+Az[2]*globalPars[16];
1583 double s2 = Az[0]*globalPars[21]+Az[1]*globalPars[22]+Az[2]*globalPars[23];
1584 double s3 = Az[0]*globalPars[28]+Az[1]*globalPars[29]+Az[2]*globalPars[30];
1585 double s4 = Az[0]*globalPars[35]+Az[1]*globalPars[36]+Az[2]*globalPars[37];
1586 double T0 =(Ax[0]*globalPars[ 3]+Ax[1]*globalPars[ 4]+Ax[2]*globalPars[ 5])*A;
1587 double T1 =(Ay[0]*globalPars[ 3]+Ay[1]*globalPars[ 4]+Ay[2]*globalPars[ 5])*A;
1588 double n = 1./globalPars[6];
1589
1590 double Jac[21];
1591
1592 // Jacobian production
1593 //
1594 Jac[ 0] = (Ax[0]*globalPars[ 7]+Ax[1]*globalPars[ 8])+(Ax[2]*globalPars[ 9]-s0*T0); // dL0/dL0
1595 Jac[ 1] = (Ax[0]*globalPars[14]+Ax[1]*globalPars[15])+(Ax[2]*globalPars[16]-s1*T0); // dL0/dL1
1596 Jac[ 2] = (Ax[0]*globalPars[21]+Ax[1]*globalPars[22])+(Ax[2]*globalPars[23]-s2*T0); // dL0/dPhi
1597 Jac[ 3] = (Ax[0]*globalPars[28]+Ax[1]*globalPars[29])+(Ax[2]*globalPars[30]-s3*T0); // dL0/dThe
1598 Jac[ 4] =((Ax[0]*globalPars[35]+Ax[1]*globalPars[36])+(Ax[2]*globalPars[37]-s4*T0))*n; // dL0/dCM
1599
1600 Jac[ 5] = (Ay[0]*globalPars[ 7]+Ay[1]*globalPars[ 8])+(Ay[2]*globalPars[ 9]-s0*T1); // dL1/dL0
1601 Jac[ 6] = (Ay[0]*globalPars[14]+Ay[1]*globalPars[15])+(Ay[2]*globalPars[16]-s1*T1); // dL1/dL1
1602 Jac[ 7] = (Ay[0]*globalPars[21]+Ay[1]*globalPars[22])+(Ay[2]*globalPars[23]-s2*T1); // dL1/dPhi
1603 Jac[ 8] = (Ay[0]*globalPars[28]+Ay[1]*globalPars[29])+(Ay[2]*globalPars[30]-s3*T1); // dL1/dThe
1604 Jac[ 9] =((Ay[0]*globalPars[35]+Ay[1]*globalPars[36])+(Ay[2]*globalPars[37]-s4*T1))*n; // dL1/dCM
1605
1606 double P3=0;
1607 double P4=0;
1609 double C = globalPars[3]*globalPars[3]+globalPars[4]*globalPars[4];
1610 if(C > 1.e-20) {
1611 C= 1./C ;
1613 P3 = globalPars[3]*C;
1614 P4 =globalPars[4]*C;
1615 C =-sqrt(C);
1616 }
1617 else{
1618 C=-1.e10;
1619 P3 = 1.;
1620 P4 =0.;
1621 }
1622
1623 double T2 =(P3*globalPars[43]-P4*globalPars[42])*A;
1624 double C44 = C*globalPars[44] *A;
1625
1626 Jac[10] = P3*globalPars[11]-P4*globalPars[10]-s0*T2; // dPhi/dL0
1627 Jac[11] = P3*globalPars[18]-P4*globalPars[17]-s1*T2; // dPhi/dL1
1628 Jac[12] = P3*globalPars[25]-P4*globalPars[24]-s2*T2; // dPhi/dPhi
1629 Jac[13] = P3*globalPars[32]-P4*globalPars[31]-s3*T2; // dPhi/dThe
1630 Jac[14] =(P3*globalPars[39]-P4*globalPars[38]-s4*T2)*n; // dPhi/dCM
1631
1632 Jac[15] = C*globalPars[12]-s0*C44; // dThe/dL0
1633 Jac[16] = C*globalPars[19]-s1*C44; // dThe/dL1
1634 Jac[17] = C*globalPars[26]-s2*C44; // dThe/dPhi
1635 Jac[18] = C*globalPars[33]-s3*C44; // dThe/dThe
1636 Jac[19] =(C*globalPars[40]-s4*C44)*n; // dThe/dCM
1637 Jac[20] = 1.; // dCM /dCM
1638
1640 AmgSymMatrix(5) newCov = Trk::RungeKuttaUtils::newCovarianceMatrix(Jac, *startingParameters.covariance());
1641 outputParameters.setParametersWithCovariance(m_surface, p, newCov);
1642
1644 const AmgSymMatrix(5) & t = *outputParameters.covariance();
1645 if(t(0, 0)<=0. || t(1, 1)<=0. || t(2, 2)<=0. || t(3, 3)<=0. || t(4, 4)<=0.) return false;
1646 } else {
1648 outputParameters.setParameters(m_surface,p);
1649 }
1650
1651 return true;
1652}
1653
1659
1661(bool Jac,double* globalPars)
1662{
1664 const double Smin = .1 ;
1667 const double Shel = 5. ;
1669 const double dlt = .001 ;
1670
1672 if(std::abs(globalPars[6]) > .05) return false;
1673
1674
1675 int it = 0;
1676 double* R = &globalPars[ 0]; // Coordinates
1677
1678 double* A = &globalPars[ 3]; // Directions
1679
1680 double* sA = &globalPars[42];
1681 double Pi = 149.89626*globalPars[6];
1683 double Pa = std::abs (globalPars[6]);
1684
1686 double a = A[0]*m_localTransform[6]+A[1]*m_localTransform[7]+A[2]*m_localTransform[8];
1687 if(a==0.) return false;
1689 double S = ((m_localTransform[12]-R[0]*m_localTransform[6])-(R[1]*m_localTransform[7]+R[2]*m_localTransform[8]))/a;
1690 double S0 = std::abs(S) ;
1691
1695 if(S0 <= Smin) {
1696 R[0]+=(A[0]*S);
1697 R[1]+=(A[1]*S);
1698 R[2]+=(A[2]*S);
1699 globalPars[45]+=S;
1700 return true;
1701 }
1704 else if( (Pa*S0) > .3) {
1705 if (S >0) S = 0.3 / Pa;
1706 else S = -0.3/Pa;
1707 }
1708
1709 bool ste = false;
1710
1712 double f0[3];
1713 double f[3];
1714
1716 m_fieldCache.getFieldZR(R,f0);
1717
1718
1719 while(true) {
1720
1721 bool Helix = false;
1723 if(std::abs(S) < Shel) Helix = true;
1724 double S3=(1./3.)*S;
1725 double S4=.25*S;
1726 double PS2=Pi*S;
1727
1730 double H0[3] = {f0[0]*PS2,
1731 f0[1]*PS2,
1732 f0[2]*PS2};
1733
1734 double A0 = A[1]*H0[2]-A[2]*H0[1] ;
1735 double B0 = A[2]*H0[0]-A[0]*H0[2] ;
1736 double C0 = A[0]*H0[1]-A[1]*H0[0] ;
1737
1738 double A2 = A0+A[0] ;
1739 double B2 = B0+A[1] ;
1740 double C2 = C0+A[2] ;
1741
1742 double A1 = A2+A[0] ;
1743 double B1 = B2+A[1] ;
1744 double C1 = C2+A[2] ;
1745
1746 // Second point
1747 //
1748 if(!Helix) {
1749 double gP[3]={R[0]+A1*S4,
1750 R[1]+B1*S4,
1751 R[2]+C1*S4};
1752
1753 m_fieldCache.getFieldZR(gP,f);
1754
1755 }
1757 else {
1758 f[0]=f0[0];
1759 f[1]=f0[1];
1760 f[2]=f0[2];
1761 }
1762
1763 double H1[3] = {f[0]*PS2,
1764 f[1]*PS2,
1765 f[2]*PS2};
1766 double A3 = (A[0]+B2*H1[2])-C2*H1[1] ;
1767 double B3 = (A[1]+C2*H1[0])-A2*H1[2] ;
1768 double C3 = (A[2]+A2*H1[1])-B2*H1[0] ;
1769
1770 double A4 = (A[0]+B3*H1[2])-C3*H1[1] ;
1771 double B4 = (A[1]+C3*H1[0])-A3*H1[2] ;
1772 double C4 = (A[2]+A3*H1[1])-B3*H1[0] ;
1773
1774 double A5 = 2.*A4-A[0] ;
1775 double B5 = 2.*B4-A[1] ;
1776 double C5 = 2.*C4-A[2] ;
1777
1778 // Last point
1779 //
1780 if(!Helix) {
1781 double gP[3]={R[0]+S*A4,
1782 R[1]+S*B4,
1783 R[2]+S*C4};
1784
1785 m_fieldCache.getFieldZR(gP,f);
1786
1787 }
1788 else{
1789 f[0]=f0[0];
1790 f[1]=f0[1];
1791 f[2]=f0[2];
1792 }
1793
1794 double H2[3] = {f[0]*PS2,
1795 f[1]*PS2,
1796 f[2]*PS2};
1797
1798 double A6 = B5*H2[2]-C5*H2[1] ;
1799 double B6 = C5*H2[0]-A5*H2[2] ;
1800 double C6 = A5*H2[1]-B5*H2[0] ;
1801
1802 // Test approximation quality on give step and possible step reduction
1803 //
1804 if(!ste) {
1805 double EST = std::abs((A1+A6)-(A3+A4))+std::abs((B1+B6)-(B3+B4))+std::abs((C1+C6)-(C3+C4));
1806 if(EST>dlt) {
1807 S*=.6;
1808 continue;
1809 }
1810 }
1811
1814 if((!ste && S0 > std::abs(S)*100.) || std::abs(globalPars[45]+=S) > 2000.) return false;
1815 ste = true;
1816
1817 double A0arr[3]{A0,B0,C0};
1818 double A3arr[3]{A3,B3,C3};
1819 double A4arr[3]{A4,B4,C4};
1820 double A6arr[3]{A6,B6,C6};
1821
1822 if(Jac) {
1823 Trk::propJacobian(globalPars,H0,H1,H2,A,A0arr,A3arr,A4arr,A6arr,S3);
1824 }
1825
1826 R[0]+=(A2+A3+A4)*S3;
1827 A[0] = ((A0+2.*A3)+(A5+A6));
1828 R[1]+=(B2+B3+B4)*S3;
1829 A[1] = ((B0+2.*B3)+(B5+B6));
1830 R[2]+=(C2+C3+C4)*S3;
1831 A[2] = ((C0+2.*C3)+(C5+C6));
1832 if(!m_tools->isITkGeometry()){
1833 A[0] *= 1./3.;
1834 A[1] *= 1./3.;
1835 A[2] *= 1./3.;
1836 }
1837
1838 double D = 1./sqrt(A[0]*A[0]+A[1]*A[1]+A[2]*A[2]);
1839 A[0]*=D; A[1]*=D; A[2]*=D;
1840
1843 double a = A[0]*m_localTransform[6]+A[1]*m_localTransform[7]+A[2]*m_localTransform[8];
1844 if(a==0.) return false;
1845 double Sn = ((m_localTransform[12]-R[0]*m_localTransform[6])-(R[1]*m_localTransform[7]+R[2]*m_localTransform[8]))/a;
1846 double aSn = std::abs(Sn);
1847
1850 if(aSn <= Smin) {
1851 double Sl = 2./S;
1852 sA[0] = A6*Sl;
1853 sA[1] = B6*Sl;
1854 sA[2] = C6*Sl;
1855
1856 R[0]+=(A[0]*Sn);
1857 R[1]+=(A[1]*Sn);
1858 R[2]+=(A[2]*Sn);
1859 globalPars[45]+=Sn;
1860
1861 return true;
1862 }
1863
1864 double aS = std::abs(S);
1865
1867 if ( S*Sn < 0. ) {
1868 if(++it > 2) return false;
1870 if (aSn < aS) S = Sn;
1872 else S =-S;
1873 }
1875 else if( aSn < aS ) S = Sn;
1876
1878 f0[0]=f[0];
1879 f0[1]=f[1];
1880 f0[2]=f[2];
1881 }
1882 return false;
1883}
1884
1886// Straight line step to plane
1888
1890(bool Jac,double* globalPars)
1891{
1892 double* R = &globalPars[ 0]; // Start coordinates
1893 double* A = &globalPars[ 3]; // Start directions
1895 double a = A[0]*m_localTransform[6]+A[1]*m_localTransform[7]+A[2]*m_localTransform[8];
1896 if(a==0.) return false;
1897 double S = ((m_localTransform[12]-R[0]*m_localTransform[6])-(R[1]*m_localTransform[7]+R[2]*m_localTransform[8]))/a;
1898 globalPars[45] = S;
1899
1900 // Track parameters in last point
1901 //
1902 R[0]+=(A[0]*S); R[1]+=(A[1]*S); R[2]+=(A[2]*S); if(!Jac) return true;
1903
1904 // Derivatives of track parameters in last point
1905 //
1906 for(int i=7; i<42; i+=7) {
1907
1908 double* dR = &globalPars[i ];
1909 double* dA = &globalPars[i+3];
1910 dR[0]+=(dA[0]*S); dR[1]+=(dA[1]*S); dR[2]+=(dA[2]*S);
1911 }
1912 return true;
1913}
1914
1916{
1917 m_detstatus =-1 ;
1918 m_status = 0 ;
1919 m_nlinksForward = 0 ;
1920 m_nlinksBackward = 0 ;
1921 m_nMissing = 0 ;
1922 m_radlength = .03;
1923 m_radlengthN = .03;
1924 m_energylose = .4 ;
1925 m_tools = nullptr ;
1926 m_noisemodel = 0 ;
1927 m_covariance.resize(2,2);
1928 m_covariance<<0.,0.,0.,0.;
1929 m_ndf = 0 ;
1930 m_ndfBackward = 0 ;
1931 m_ndfForward = 0 ;
1932 m_ntsos = 0 ;
1933 m_maxholes = 0 ;
1934 m_maxdholes = 0 ;
1935 m_xi2Forward = 0.;
1936 m_xi2Backward = 0.;
1937 m_xi2totalForward = 0.;
1938 m_xi2totalBackward = 0.;
1939 m_halflength = 0.;
1940 m_step = 0.;
1941 m_xi2max = 0.;
1942 m_dist = 0.;
1943 m_xi2maxNoAdd = 0.;
1944 m_xi2maxlink = 0.;
1945 m_xi2multi = 0.;
1946 m_invMoment = 0.;
1947 m_detelement = nullptr ;
1948 m_detlink = nullptr ;
1949 m_surface = nullptr ;
1950 m_cluster = nullptr ;
1951 m_clusterOld = nullptr ;
1952 m_clusterNoAdd = nullptr ;
1953 m_updatorTool = nullptr ;
1954 m_proptool = nullptr ;
1955 m_riotool = nullptr ;
1956 m_inside = 0 ;
1957 m_nholesForward = 0 ;
1958 m_nholesBackward = 0 ;
1959 m_dholesForward = 0 ;
1960 m_dholesBackward = 0 ;
1961 m_nclustersForward = 0 ;
1963 m_npixelsBackward = 0 ;
1964 m_stereo = false ;
1965 m_fieldMode = false ;
1966
1967 m_tsos[0]=m_tsos[1]=m_tsos[2]=nullptr;
1968}
1969
1974
1975// deliberately not assigning all variables?
1976// cppcheck-suppress operatorEqVarError
1977InDet::SiTrajectoryElement_xk& InDet::SiTrajectoryElement_xk::operator =
1979{
1980 if(&E==this) return(*this);
1981
1982 m_fieldMode = E.m_fieldMode ;
1983 m_status = E.m_status ;
1984 m_detstatus = E.m_detstatus ;
1985 m_inside = E.m_inside ;
1986 m_nMissing = E.m_nMissing ;
1987 m_stereo = E.m_stereo ;
1988 m_detelement = E.m_detelement ;
1989 m_detlink = E.m_detlink ;
1990 m_surface = E.m_surface ;
1991 m_sibegin = E.m_sibegin ;
1992 m_siend = E.m_siend ;
1993 m_cluster = E.m_cluster ;
1994 m_clusterOld = E.m_clusterOld ;
1995 m_clusterNoAdd = E.m_clusterNoAdd;
1996 m_parametersPredForward = E.m_parametersPredForward;
1997 m_parametersUpdatedForward = E.m_parametersUpdatedForward;
1998 m_parametersPredBackward = E.m_parametersPredBackward;
1999 m_parametersUpdatedBackward = E.m_parametersUpdatedBackward;
2000 m_parametersSM = E.m_parametersSM;
2001 m_dist = E.m_dist ;
2002 m_xi2Forward = E.m_xi2Forward ;
2003 m_xi2Backward = E.m_xi2Backward ;
2004 m_xi2totalForward = E.m_xi2totalForward ;
2005 m_xi2totalBackward = E.m_xi2totalBackward;
2006 m_radlength = E.m_radlength ;
2007 m_radlengthN = E.m_radlengthN ;
2008 m_energylose = E.m_energylose ;
2009 m_halflength = E.m_halflength ;
2010 m_step = E.m_step ;
2011 m_nlinksForward = E.m_nlinksForward ;
2012 m_nlinksBackward = E.m_nlinksBackward ;
2013 m_nholesForward = E.m_nholesForward ;
2014 m_nholesBackward = E.m_nholesBackward ;
2015 m_dholesForward = E.m_dholesForward ;
2016 m_dholesBackward = E.m_dholesBackward ;
2017 m_noisemodel = E.m_noisemodel ;
2018 m_ndf = E.m_ndf ;
2019 m_ndfForward = E.m_ndfForward ;
2020 m_ndfBackward = E.m_ndfBackward ;
2021 m_ntsos = E.m_ntsos ;
2022 m_nclustersForward = E.m_nclustersForward ;
2023 m_nclustersBackward = E.m_nclustersBackward ;
2024 m_npixelsBackward = E.m_npixelsBackward ;
2025 m_noise = E.m_noise ;
2026 m_tools = E.m_tools ;
2027 m_covariance = E.m_covariance ;
2028 m_position = E.m_position ;
2029 m_invMoment = E.m_invMoment ;
2030 for(int i=0; i!=m_nlinksForward; ++i) {m_linkForward[i]=E.m_linkForward[i];}
2031 for(int i=0; i!=m_nlinksBackward; ++i) {m_linkBackward[i]=E.m_linkBackward[i];}
2032 for(int i=0; i!=m_ntsos ; ++i) {m_tsos [i]=E.m_tsos [i];}
2033 for(int i=0; i!=m_ntsos ; ++i) {m_utsos[i]=E.m_utsos [i];}
2034 return(*this);
2035}
2036
2038{
2039 int n = 0;
2040 if (m_detstatus<=0) return n;
2041
2043 const InDet::PixelClusterCollection::const_iterator* sibegin
2044 = std::any_cast<const InDet::PixelClusterCollection::const_iterator>(&m_sibegin);
2045 const InDet::PixelClusterCollection::const_iterator* siend
2046 = std::any_cast<const InDet::PixelClusterCollection::const_iterator>(&m_siend);
2047 if (sibegin==nullptr or siend==nullptr) return 0;
2048 for (InDet::PixelClusterCollection::const_iterator p = *sibegin; p!=*siend; ++p) {
2049 ++n;
2050 }
2051 } else if (m_itType==SCT_ClusterColl) {
2052 const InDet::SCT_ClusterCollection::const_iterator* sibegin
2053 = std::any_cast<const InDet::SCT_ClusterCollection::const_iterator>(&m_sibegin);
2054 const InDet::SCT_ClusterCollection::const_iterator* siend
2055 = std::any_cast<const InDet::SCT_ClusterCollection::const_iterator>(&m_siend);
2056 if (sibegin==nullptr or siend==nullptr) return 0;
2057 for (InDet::SCT_ClusterCollection::const_iterator p = *sibegin; p!=*siend; ++p) {
2058 ++n;
2059 }
2060 } else {
2061 const InDet::SiClusterCollection::const_iterator* sibegin
2062 = std::any_cast<const InDet::SiClusterCollection::const_iterator>(&m_sibegin);
2063 const InDet::SiClusterCollection::const_iterator* siend
2064 = std::any_cast<const InDet::SiClusterCollection::const_iterator>(&m_siend);
2065 if (sibegin==nullptr or siend==nullptr) return 0;
2066 for (InDet::SiClusterCollection::const_iterator p = *sibegin; p!=*siend; ++p) {
2067 ++n;
2068 }
2069 }
2070 return n;
2071}
2072
2074{
2075 return m_cluster != m_clusterOld || m_status != 3;
2076}
2077
2079// Test for next compatible cluster
2081
2083{
2084 cl = false ;
2086
2087 if(m_nlinksBackward > 1 && m_linkBackward[1].xi2() <= m_xi2max) {
2088 X+=m_linkBackward[1].xi2();
2089 cl = true; return true;
2090 }
2091
2092 if(m_inside < 0) {
2094 }
2095 return true;
2096}
2097
2104{
2105 cl = false ;
2109 if(m_detstatus == 2) return false;
2112 if(m_nlinksForward > 1 && m_linkForward[1].xi2() <= m_xi2max) {
2114 X+=m_linkForward[1].xi2();
2116 cl = true;
2117 return true;
2118 }
2120 if(m_inside < 0) {
2124 return false;
2125 }
2127 return true;
2128}
2129
2134
2136{
2137 m_cluster = Cl ;
2138 m_status = 2 ;
2139 m_xi2Backward = Xi2;
2140}
2141
2142
2147
2152
2154{
2155 m_nMissing = n;
2156}
2157
2159// Add pixel or SCT cluster to pattern track parameters with Xi2 calculation
2161
2164{
2165 int N;
2167 if(!m_stereo) {
2172 if(m_detelement->isSCT()) {
2173 return m_updatorTool->addToStateOneDimension
2174 (Ta,m_cluster->localPosition(),m_covariance,Tb,Xi2,N);
2175 }
2176 return m_updatorTool->addToState
2177 (Ta,m_cluster->localPosition(),m_covariance,Tb,Xi2,N);
2178 }
2180 return m_updatorTool->addToStateOneDimension
2181 (Ta,m_cluster->localPosition(),m_cluster->localCovariance(),Tb,Xi2,N);
2182}
2183
2185// Add pixel or SCT cluster to pattern track parameters without Xi2 calculation
2187
2190{
2191 if(!m_stereo) {
2192
2195 if(m_detelement->isSCT()) {
2196 return m_updatorTool->addToStateOneDimension
2197 (Ta,m_cluster->localPosition(),m_covariance,Tb);
2198 }
2199 return m_updatorTool->addToState
2200 (Ta,m_cluster->localPosition(),m_covariance,Tb);
2201 }
2202 return m_updatorTool->addToStateOneDimension
2203 (Ta,m_cluster->localPosition(),m_cluster->localCovariance(),Tb);
2204}
2205
2207// Add pixel or SCT cluster to pattern track parameters with Xi2 calculation
2208// using precise error
2210
2213 double& Xi2) {
2214 int N;
2215 if(m_ndf==1) {
2216 return m_updatorTool->addToStateOneDimension(Ta,m_position,m_covariance,Tb,Xi2,N);
2217 }
2218 else {
2219 return m_updatorTool->addToState (Ta,m_position,m_covariance,Tb,Xi2,N);
2220 }
2221}
2222
2224// Add two pattern track parameters without Xi2 calculation
2226
2234
2236// Propagate pattern track parameters to surface
2238
2243
2245// Initiate state
2247
2250{
2253 if (m_tools->isITkGeometry()) {
2254 // using pattern covariance for all clusters for ITk
2255 Amg::MatrixX cov(2,2);
2256 patternCovariances(m_cluster,cov(0,0),cov(1,0),cov(1,1));
2257 return outputPars.initiate(inputPars,m_cluster->localPosition(),cov);
2258 }
2259 return outputPars.initiate(inputPars,m_cluster->localPosition(),m_cluster->localCovariance());
2260}
2261
2263// Initiate state with cluster correction
2265
2271
2273// Pattern covariances
2275
2277(const InDet::SiCluster* c,double& covX,double& covXY,double& covY) const
2278{
2279 const Amg::MatrixX& v = c->localCovariance();
2280 if (m_tools->useFastTracking() and m_stereo) {
2281 // in fast tracking mode, endcap strip clusters use cluster covariance terms
2282 covX=v(0,0);
2283 covY=v(1,1);
2284 covXY=v(1,0);
2285 return;
2286 }
2287 covX = c->width().phiR();
2288 covX*=(covX*s_oneOverTwelve);
2289 covXY = c->localCovariance()(1,0);
2290
2291 if(!m_tools->useFastTracking()){
2292 if(covX < v(0,0)) covX=v(0,0);
2293 covXY = 0.;
2294 }
2295
2296 if(m_ndf==1) {
2297 covY=v(1,1);
2298 }
2299 else {
2301 covY=c->width().z();
2302 covY*=(covY*s_oneOverTwelve);
2303 if(!m_tools->useFastTracking()){
2304 if(covY < v(1,1)) covY=v(1,1);
2305 }
2306 }
2307}
2308
2310// Last detector elements with clusters
2312
2317
2319{
2320 if(i<0 || i>2) return nullptr;
2321
2322 bool us = m_utsos[i];
2323 m_utsos[i] = true;
2324
2325 if(us) return new Trk::TrackStateOnSurface(*m_tsos[i]);
2326
2327 return m_tsos[i];
2328}
2329
2331// Set electron noise model
2333
2338
2340// Initiate state with cluster correction
2342
2350
2352// Add pixel or SCT cluster to pattern track parameters with Xi2 calculation
2353// using precise error
2355
2359 double& Xi2)
2360{
2361 int N;
2363
2364 if(m_ndf==1) {
2365 return m_updatorTool->addToStateOneDimension(Ta,m_position,m_covariance,Tb,Xi2,N);
2366 }
2367 else {
2368 return m_updatorTool->addToState(Ta,m_position,m_covariance,Tb,Xi2,N);
2369 }
2370}
2371
2373// Precise cluster position and covariance calculation
2375
2377{
2378
2379 m_position = m_cluster->localPosition ();
2380 m_covariance = m_cluster->localCovariance();
2381
2382 if(m_ndf==1) return;
2383
2384 const Amg::Vector2D& colRow = m_cluster->width().colRow();
2385 if(colRow.x()==1. && colRow.y()==1.) return;
2386
2387 std::unique_ptr<Trk::TrackParameters> tr = Tc.convert(true);
2388 std::unique_ptr<const Trk::RIO_OnTrack> ri(m_riotool->correct(*m_cluster, *tr, Gaudi::Hive::currentContext()));
2389
2390 m_position = ri->localParameters();
2391 m_covariance = ri->localCovariance();
2392
2393}
2394
2396// Search clusters compatible with track
2398
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
Trk::TrackStateOnSurface * trackStateOnSurface(bool, bool, bool, int)
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)
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.
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