ATLAS Offline Software
Loading...
Searching...
No Matches
TRT_Trajectory_xk.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include <iostream>
6#include <iomanip>
12#include "TrkTrack/Track.h"
13
15// Set TRT detector manager
17
19(const TRT_ID * m,
22 const Trk::IRIO_OnTrackCreator * riod,
23 const Trk::IRIO_OnTrackCreator * rion,
24 double roadwidth ,
25 double zvertexwidth ,
26 double impact ,
27 double scale ,
28 double minTRTSegmentpT )
29{
30 m_proptool = pr ;
31 m_updatortool = up ;
32 m_roadwidth2 = roadwidth*roadwidth;
33 m_zVertexWidth = std::abs(zvertexwidth) ;
34 m_impact = std::abs(impact ) ;
35 m_scale_error = std::abs(scale ) ;
36 for(auto & element : m_elements) element.set(m,pr,up,riod,rion,m_scale_error);
37 m_minTRTSegmentpT = minTRTSegmentpT ;
38}
39
42
43{
44 m_fieldprop = mp;
45 for(auto & element : m_elements) element.set(mp, condObj);
46}
47
49// Initiate trajectory for precision seed
51
53 std::vector<std::pair<Amg::Vector3D, double> >& Gp,
54 const std::vector<const InDetDD::TRT_BaseElement*>& De,
55 const TRT_DriftCircleContainer*& TRTc,
57 m_ndf = 0;
58 m_nholes = 0;
59 m_nholesb = 0;
60 m_nholese = 0;
61 m_dholes = 0;
62 m_nclusters = 0;
63 m_ntclusters = 0;
64 m_nElements = 0;
65 m_naElements = 0;
66 m_xi2 = 0.;
68
69 InDet::TRT_DriftCircleCollection::const_iterator ti,te;
70
71 std::vector<const InDetDD::TRT_BaseElement*>::const_iterator d=De.begin(),de=De.end();
72
73 std::vector< std::pair<Amg::Vector3D,double> >::iterator i=Gp.begin(),i0=Gp.begin(),ie=Gp.end();
74 // At least two elements are needed for the direction computation.
75 // So, return immediately if there are no elements, or if the next
76 // element is already the end.
77 if(Gp.empty() || ++i==ie) {
78 m_firstRoad = 0;
79 m_lastRoad = 0;
82 return;
83 }
84
85 // Primary trajectory direction calculation
86 // Tp.parameters()[4] is the (signed) q/p
87 double A[4]={0., 0., 0., Tp.parameters()[4]};
88 for(; i!=ie; ++i) {
89 if((*i).second-(*i0).second > 1.) {
90 A[0] = (*i).first.x()-(*i0).first.x();
91 A[1] = (*i).first.y()-(*i0).first.y();
92 A[2] = (*i).first.z()-(*i0).first.z();
93 double As = 1./std::sqrt(A[0]*A[0]+A[1]*A[1]+A[2]*A[2]);
94 A[0]*=As; A[1]*=As; A[2]*=As;
95 i0=i;
96 break;
97 }
98 }
99
100 for(i=Gp.begin(); i!=ie; ++i) {
101 IdentifierHash id = (*d)->identifyHash();
102 const auto *w=(*TRTc).indexFindPtr(id);
103 bool q;
104 if(w!=nullptr && w->begin()!=w->end()) {
105 ti = w->begin(); te = w->end ();
106 q = m_elements[m_nElements].initiateForPrecisionSeed(true,(*d),ti,te,(*i),A,m_roadwidth2);
107 if(q && m_elements[m_nElements].isCluster()) ++m_naElements;
108 } else {
109 q = m_elements[m_nElements].initiateForPrecisionSeed(false,(*d),ti,te,(*i),A,m_roadwidth2);
110 }
111 if(q && m_elements[m_nElements].nlinks()) ++m_nElements;
112 if(++d==de) break;
113
114 // New trajectory direction calculation
115 //
116 if( (*i).second-(*i0).second > 50.) {
117 A[0] = (*i).first.x()-(*i0).first.x();
118 A[1] = (*i).first.y()-(*i0).first.y();
119 A[2] = (*i).first.z()-(*i0).first.z();
120 double As = 1./std::sqrt(A[0]*A[0]+A[1]*A[1]+A[2]*A[2]);
121 A[0]*=As; A[1]*=As; A[2]*=As; i0=i;
122 }
123 }
124 m_firstRoad = 0 ;
128}
129
131// Initiate trajectory for TRT seed
133
135 std::vector<std::pair<Amg::Vector3D, double> >& Gp,
136 const std::vector<const InDetDD::TRT_BaseElement*>& De,
137 const TRT_DriftCircleContainer*& TRTc,
139 m_ndf = 0;
140 m_nholes = 0;
141 m_nholesb = 0;
142 m_nholese = 0;
143 m_dholes = 0;
144 m_nclusters = 0;
145 m_ntclusters = 0;
146 m_nElements = 0;
147 m_naElements = 0;
148 m_firstRoad = 0;
151 m_xi2 = 0.;
153
154 InDet::TRT_DriftCircleCollection::const_iterator ti,te;
155
156 std::vector<const InDetDD::TRT_BaseElement*>::const_iterator d=De.begin(),de=De.end();
157
158 std::vector< std::pair<Amg::Vector3D,double> >::iterator i=Gp.begin(),i0=Gp.begin(),ie=Gp.end();
159 if(i0==ie) return;
160 // At least two elements are needed for the direction computation.
161 // So, return immediately if there are no elements, or if the next
162 // element is already the end.
163 if(Gp.empty() || ++i==ie) {
164 m_lastTrajectory = -1;
165 return;
166 }
167
168 // Primary trajectory direction calculation
169 //
170 double A[4]={0.,0.,0.,Tp.parameters()[4]};
171 for(; i!=ie; ++i) {
172 if( (*i).second-(*i0).second > 1.) {
173 A[0] = (*i).first.x()-(*i0).first.x();
174 A[1] = (*i).first.y()-(*i0).first.y();
175 A[2] = (*i).first.z()-(*i0).first.z();
176 double As = 1./std::sqrt(A[0]*A[0]+A[1]*A[1]+A[2]*A[2]);
177 A[0]*=As; A[1]*=As; A[2]*=As; i0=i; break;
178 }
179 }
180
181 for (i = Gp.begin(); i != ie; ++i) {
182
183 IdentifierHash id = (*d)->identifyHash();
184 const auto* w = (*TRTc).indexFindPtr(id);
185 bool q;
186 if (w != nullptr && w->begin() != w->end()) {
187
188 ti = w->begin();
189 te = w->end();
190 q = m_elements[m_lastRoad].initiateForTRTSeed(1, (*d), ti, te, (*i), A,
192 if (m_elements[m_lastRoad].isCluster())
193 ++m_naElements;
194
195 } else {
196 q = m_elements[m_lastRoad].initiateForTRTSeed(0, (*d), ti, te, (*i), A,
198 }
199
200 if (m_elements[m_lastRoad].nlinks()) {
201
202 if (q) {
203 if (m_firstTrajectory < 0) {
205 } else {
207 }
208 }
209 ++m_lastRoad;
210 }
211 if (++d == de)
212 break;
213
214 // New trajectory direction calculation
215 //
216 if ((*i).second - (*i0).second > 50.) {
217
218 A[0] = (*i).first.x() - (*i0).first.x();
219 A[1] = (*i).first.y() - (*i0).first.y();
220 A[2] = (*i).first.z() - (*i0).first.z();
221 double As = 1. / std::sqrt(A[0] * A[0] + A[1] * A[1] + A[2] * A[2]);
222 A[0] *= As;
223 A[1] *= As;
224 A[2] *= As;
225 i0 = i;
226 }
227 }
229 m_lastRoad -= 1;
230 if (m_firstTrajectory < 0)
231 m_naElements = 0;
232}
233
235// Track finding with drift time information
237
239{
240 const double rcut = 2.2;
241 double rs = 2.0;
242 int n = 0 ;
243
244 for(int i=m_firstTrajectory; i<=m_lastTrajectory; ++i) {
245
246 if(!m_elements[i].isCluster()) continue;
247 int nl = m_elements[i].nlinks();
248
249 double dmin = m_elements[i].dnegative()-.01;
250 double dmax = m_elements[i].dpositive()+.01;
251 if(std::abs(dmin) < rcut || std::abs(dmax) < rcut) {dmin = -rcut; dmax = rcut;}
252
253 for(int j=0; j!=nl; ++j) {
254
255 if(!m_elements[i].link(j).cluster()) continue;
256 double u = m_elements[i].link(j).way(); if( u==0. ) continue;
257 double d = m_elements[i].link(j).distance(); if(d < dmin || d > dmax) continue;
258 double ui= 1./u;
259 double s = rs*ui;
260 double v = d *ui;
261 m_U[n] = u; m_V[n++] = v-s; m_U[n] = u; m_V[n++] = v+s;
262
263 double r = m_elements[i].link(j).cluster()->localPosition()(Trk::driftRadius);
264 double e = .35;
265
266 if(r>rs) r=rs;
267
268 double r2 = r+e; if(r2 > rs) r2 = rs;
269 double r1 = r-e; if(r1 >= r2) r1 = r2-2.*e;
270 r1 *= ui;
271 r2 *= ui;
272 if( r<e ) {
273 m_U[n] = u; m_V[n++] = v-r2; m_U[n] = u; m_V[n++] = v+r2;
274 }
275 else {
276 m_U[n] = u; m_V[n++] = v-r2; m_U[n] = u; m_V[n++] = v-r1;
277 m_U[n] = u; m_V[n++] = v+r1; m_U[n] = u; m_V[n++] = v+r2;
278 }
279 if(n>4990) goto stab;
280 }
281 }
282 stab:
283 stabline(n,DA);
284}
285
287// Track finding without drift time information
289
291{
292 const double rcut = 2.2 ;
293 const double rs = 2.00;
294 const double sr = 50 ;
295 int n = 0 ;
296
297 for(int i=m_firstTrajectory; i<=m_lastTrajectory; ++i) {
298
299 if(!m_elements[i].isCluster()) continue;
300 int nl = m_elements[i].nlinks();
301
302 double dmin = m_elements[i].dnegative()-.01;
303 double dmax = m_elements[i].dpositive()+.01;
304 if(std::abs(dmin) < rcut || std::abs(dmax) < rcut) {dmin = -rcut; dmax = rcut;}
305
306 for(int j=0; j!=nl; ++j) {
307
308 if(!m_elements[i].link(j).cluster()) continue;
309
310 double u = m_elements[i].link(j).way(); if(u==0.) continue; double ui = 1./u;
311
312 double di= m_elements[i].link(j).distance(); if(di < dmin || di > dmax) continue;
313
314 double d = rs+std::abs(m_elements[i].link(j).sdistance()*sr);
315 double s = d *ui;
316 double v = di*ui;
317 m_U[n] = u; m_V[n++] = v-s; m_U[n] = u; m_V[n++] = v+s;
318 if(n>4990) goto stab;
319 }
320 }
321 stab:
322 stabline(n,DA);
323}
324
326// Track finding with drift time information for best link
328
330{
331 double rs = 2.0;
332 int n = 0 ;
333
334 for(int i=m_firstTrajectory; i<=m_lastTrajectory; ++i) {
335
336 int l = m_elements[i].bestlink();
337 if( l<0 || !m_elements[i].link(l).cluster()) continue;
338
339 double u = m_elements[i].link(l).way(); if(u==0.) continue; double ui = 1./u;
340 double s = rs*ui;
341 double v = m_elements[i].link(l).distance()*ui;
342 m_U[n] = u; m_V[n++] = v-s; m_U[n] = u; m_V[n++] = v+s;
343
344 double r = m_elements[i].link(l).cluster()->localPosition()(Trk::driftRadius);
345 double e = .35;
346
347 if(r>rs) r=rs;
348
349 double r2 = r+e; if(r2 > rs) r2 = rs;
350 double r1 = r-e; if(r1 >= r2) r1 = r2-2.*e;
351 r1 *= ui;
352 r2 *= ui;
353 if( r<e ) {
354 m_U[n] = u; m_V[n++] = v-r2; m_U[n] = u; m_V[n++] = v+r2;
355 }
356 else {
357 m_U[n] = u; m_V[n++] = v-r2; m_U[n] = u; m_V[n++] = v-r1;
358 m_U[n] = u; m_V[n++] = v+r1; m_U[n] = u; m_V[n++] = v+r2;
359 }
360 if(n>4990) break;
361 }
362 stabline(n,DA);
363}
364
366// Track finding without drift time information for best links
368
370{
371 const double rs = 2.00;
372 const double sr = 50 ;
373 int n = 0 ;
374
375 for(int i=m_firstTrajectory; i<=m_lastTrajectory; ++i) {
376
377 int l = m_elements[i].bestlink();
378 if( l<0 || !m_elements[i].link(l).cluster()) continue;
379
380 double u = m_elements[i].link(l).way(); if(u==0.) continue; double ui = 1./u;
381 double d = rs+std::abs(m_elements[i].link(l).sdistance()*sr);
382 double s = d*ui;
383 double v = m_elements[i].link(l).distance()*ui;
384 m_U[n] = u; m_V[n++] = v-s; m_U[n] = u; m_V[n++] = v+s;
385 if(n>4990) break;
386 }
387 stabline(n,DA);
388}
389
391// Search start and stop trajectory for endcap TRT
393
395{
396 if (m_lastRoad<1) return false;
397 if (m_lastRoad>399){
398 throw std::runtime_error("Too many roads in InDet::TRT_Trajectory_xk::searchStartStop");
399 }
400 const double rs = 2.00, rse = 1.85, sr = 40;
401
402 int w[400]={};
403 int W = 0;
404
405 for(int e = m_firstRoad; e<=m_lastRoad; ++e) {
406 double D = m_elements[e].findCloseLink(m_A,m_B);
407 int b = m_elements[e].bestlink();
408 if( D < rs+std::abs(m_elements[e].link(b).sdistance()*sr)) {
409 if (m_elements[e].link(b).cluster()) w[e] = 1;
410 else if( D < rse ) w[e] =-1;
411 }
412 W+=w[e];
413 }
414
415 // Search first element trajectory
416 //
417 int Wm = W;
419 for(int e = m_firstRoad; e < m_lastRoad; ++e ) {
420 if(w[e]>0) {if(W>Wm) {Wm=W; m_firstTrajectory=e;} --W;} else if(w[e]<0) ++W;
421 }
422
423 // Search last element trajectory
424 //
425 W = Wm;
427 for(int e = m_lastRoad; e > m_firstTrajectory; --e) {
428 if(w[e]>0) {if(W>Wm) {Wm=W; m_lastTrajectory=e;} --W;} else if(w[e]<0) ++W;
429 }
431}
432
434// Trajectory building without propagation for precision seeds
436
438(bool useDritRadius)
439{
441
442 int e = m_firstTrajectory;
443 int el = m_lastTrajectory ;
444
445 for(; e<=el; ++e) {
446
447 bool q = useDritRadius;
448 bool h = false ;
449 if (m_elements[e].buildForPrecisionSeed(m_A,m_B,q,h)) { // Cluster
450
453 if(q) ++m_ntclusters;
455 }
456 else if(h) { // Hole
458 }
459 }
461}
462
464// Trajectory building without propagation for TRT seeds
466
468(bool useDritRadius)
469{
470
472 int e = m_firstTrajectory;
473 int el = m_lastTrajectory ;
474
475 for(; e<=el; ++e) {
476
477 bool q = useDritRadius;
478 bool h = false ;
479 if (m_elements[e].buildForTRTSeed(m_A,m_B,q,h)) { // Cluster
480
483 if(q) ++m_ntclusters;
485 }
486 else if(h) { // Hole
488 }
489 }
491}
492
494// Trajectory correction for new polar angle
496
498{
499 if(isFirstElementBarrel()) return;
500
501 int e = m_firstTrajectory;
502 int el = m_lastTrajectory ;
503 double r0 = m_elements[e ].radiusMin();
504 double z0 = m_elements[e ].z ();
505 double r1 = m_elements[el].radiusMax();
506 double z1 = m_elements[el].z ();
507 double dz = z1-z0; if(std::abs(dz) < 1.) return;
508 double rz = (r1-r0)/dz;
509 double zv = z0 - r0/rz;
510
511 if (zv > m_zVertexWidth) zv = m_zVertexWidth;
512 else if(zv < -m_zVertexWidth) zv =-m_zVertexWidth;
513 rz = r0/(z0-zv);
514
515 for (; e<=el; ++e) {
516 double dr = r0+(m_elements[e].z()-z0)*rz-m_elements[e].radius();
517 m_elements[e].radiusCorrection(dr);
518 }
519}
520
522// Trajectory conversion to MeasurementBase
524
526(std::vector<const Trk::MeasurementBase*>& MB)
527{
528 for(int e = m_firstTrajectory; e<=m_lastTrajectory; ++e) {
529
530 const Trk::MeasurementBase* mb = m_elements[e].rioOnTrack();
531 if(mb) MB.push_back(mb);
532 }
533}
534
536// Trajectory conversion to TrackSegment
538
540{
541
542 // Test quality of propagation to perigee
543 if(std::abs(m_parameters.momentum().perp()) < m_minTRTSegmentpT) return nullptr;
544
545 const Trk::Surface* sur = &m_parameters.associatedSurface();
546
548
549 // Pseudo-measurement production
550 //
551 std::pair<const Trk::PseudoMeasurementOnTrack*,const Trk::PseudoMeasurementOnTrack* > pms;
552
553 // Vector of TRT_DriftCircleOnTrack production
554 //
555 int nbarrel=0,nendcap=0;
556 //const Trk::Surface *lastbarrelsurf=0;
557
558 for(int e = m_firstTrajectory; e<=m_lastTrajectory; ++e) {
559
560 const Trk::MeasurementBase* r = m_elements[e].rioOnTrack();
561 if(r) {
562 if (std::abs(r->associatedSurface().transform()(2,2)) <.5) nendcap++;
563 else {
564 nbarrel++;
565 //lastbarrelsurf=&r->associatedSurface();
566 }
567
568 rio.push_back(r);
569 }
570 }
571 if(rio.empty()) {return nullptr;}
572 int bec=0;
573 if (nbarrel>0 && nendcap>0) bec=1;
574 else if (nbarrel==0 && nendcap>0) bec=2;
575 pms=pseudoMeasurements(&(**rio.begin()).associatedSurface(),&(**rio.rbegin()).associatedSurface(),bec);
576 if(pms.first) rio.insert(rio.begin(),pms.first);
577 if(pms.second) {
578 if (std::abs((**rio.rbegin()).associatedSurface().center().z())<2650.) rio.push_back(pms.second);
579 else rio.insert(rio.begin()+1,pms.second);
580 }
581 // Track segment production
582 //
583 const AmgVector(5) & p = m_parameters.parameters();
584 double P[5]={p[0],
585 p[1],
586 p[2],
587 p[3],
588 p[4]};
589
590 if(!m_ndf) {m_ndf = rio.size()-5; m_xi2 = 0.;}
591
592 if(!sur) {
593 Amg::Vector3D GP(0.,0.,0.); sur = new Trk::PerigeeSurface(GP);
594 }
596
597 return new Trk::TrackSegment(
598 Trk::LocalParameters(P[0], P[1], P[2], P[3], P[4]),
599 *m_parameters.covariance(),
600 sur,
601 std::move(rio),
602 fqu,
604}
605
607// Pseudo-measurement production
609
610std::pair<const Trk::PseudoMeasurementOnTrack* , const Trk::PseudoMeasurementOnTrack*>
612{
613 const Trk::PseudoMeasurementOnTrack *pmon=nullptr,*pmon2=nullptr;
614 if(!firstsurf || !lastsurf) return std::make_pair(pmon,pmon2);
615 double pseudotheta=0;
616 const Trk::CylinderBounds *cylb=dynamic_cast<const Trk::CylinderBounds *>(&lastsurf->bounds());
617 if(!cylb) return std::make_pair(pmon,pmon2);
618
619 double halfz=cylb->halflengthZ();
620 cylb=dynamic_cast<const Trk::CylinderBounds *>(&firstsurf->bounds());
621 if(!cylb) return std::make_pair(pmon,pmon2);
622
623 double halfzfirst=cylb->halflengthZ();
624 double tempz=lastsurf->center().z();
625 double tempr=0;
626 //double pseudoz=0;
627 Amg::Vector3D pseudopoint;
628 Amg::RotationMatrix3D pseudorot;
629 if (bec==0) {
630 //pseudotheta=M_PI/2.;
631 tempr=lastsurf->center().perp();
632 if (tempr<1000.) tempz+= (lastsurf->center().z()>0) ? halfz : -halfz;
633 pseudopoint = Amg::Vector3D(lastsurf->center().x(),lastsurf->center().y(),tempz);
634 pseudorot = lastsurf->transform().rotation();
635 }
636 else if (std::abs(lastsurf->center().z())<2650.) {
637 //std::cout << "sur center: " << sur->center() << " halfz: " << halfz << " firstsur center: " << firstsur->center() << " halfzfirst: " << halfzfirst << std::endl;
638 tempr= lastsurf->center().perp()+halfz;
639 tempz=lastsurf->center().z();
640 pseudopoint = Amg::Vector3D(lastsurf->center().x(),lastsurf->center().y(),tempz)-halfz*lastsurf->transform().rotation().col(2);
641 pseudorot = lastsurf->transform().rotation();
642
643 }
644 else {
645 tempr=firstsurf->center().perp()-halfzfirst;
646 tempz=firstsurf->center().z();
647 pseudopoint = Amg::Vector3D(firstsurf->center().x(),firstsurf->center().y(),tempz)+halfz*firstsurf->transform().rotation().col(2);
648 pseudorot = firstsurf->transform().rotation();
649
650 }
651 pseudotheta=atan2(tempr,std::abs(tempz));
652 //std::cout << "bec: " << bec << " pseudotheta: " << pseudotheta << std::endl;
653 if (lastsurf->center().z()<0) pseudotheta=M_PI-pseudotheta;
654
655 Amg::Transform3D T = Amg::Transform3D(Amg::Translation3D(Amg::Vector3D::Zero())*Amg::RotationMatrix3D::Identity());
656 Trk::StraightLineSurface surn(T,100.,1000.);
657
659 bool Q = m_proptool->propagateParameters
660 (Gaudi::Hive::currentContext(),m_parameters,surn,P,Trk::anyDirection,m_fieldprop,Trk::pion);
661 if(!Q) return std::make_pair(pmon,pmon2);
662
663
664 Amg::MatrixX cov = (bec==0) ? Amg::MatrixX(2,2): Amg::MatrixX(1,1);
665 cov(0,0)= 100.;
666 if (bec==0) {
667 cov(1,0) = 0.;
668 cov(0,1) = 0.;
669 cov(1,1) = .00001;
670 }
672 (bec == 0)
674 std::make_pair(0, Trk::locZ), std::make_pair(pseudotheta, Trk::theta))
675 : Trk::LocalParameters(std::make_pair(0, Trk::locZ));
676
677 pmon = new Trk::PseudoMeasurementOnTrack(std::move(par), std::move(cov), surn);
678
679 if (bec==0) return std::make_pair(pmon,pmon2);
680 cov = Amg::MatrixX(1,1);
681 cov(0,0) = 100.;
682 par = Trk::LocalParameters(std::make_pair(0,Trk::locZ));
683 T = Amg::Transform3D(Amg::Translation3D(pseudopoint)*pseudorot);
684 Trk::StraightLineSurface surn2(T,100.,1000.);
685
686 pmon2 = new Trk::PseudoMeasurementOnTrack(std::move(par),
687 std::move(cov),
688 surn2);
689
690 //delete surn;
691 return std::make_pair(pmon,pmon2);
692}
693
695// Track parameters estimation for last point of the trajectory
697
699{
700 int n1 = 0;
701
702 for(int e = (m_lastTrajectory+m_firstTrajectory)/2; e < m_lastTrajectory; ++e) {
703 if(m_elements[e].status() >= 0) {n1=e; break;}
704 }
705 if(!n1) return false;
706 return m_elements[m_lastTrajectory].trackParametersEstimation
708
709}
710
712// Track parameters estimation for first point of the trajectory
714
716{
717 int n1 = 0;
718
719 for(int e = (m_lastTrajectory+m_firstTrajectory)/2; e < m_lastTrajectory; ++e) {
720 if(m_elements[e].status() >= 0) {n1=e; break;}
721 }
722 if(!n1) return false;
723 return m_elements[m_firstTrajectory].trackParametersEstimation
725}
726
728// Track parameters estimation for first point of the trajectory
729// with vertex constraint
731
738
740// Track parameters estimation for perigee with vertex constraint
742
748
750// Trajectory fitter
752
754{
755 const double trad = .003;
756 double rad = 0. ;
757
758 if(!trackParametersEstimationForLastPoint() || std::abs(m_parameters.momentum().perp()) < m_minTRTSegmentpT) return false;
759 double sin2 = 1./sin(m_parameters.parameters()[3]); sin2*= sin2 ;
760 double P42 = m_parameters.parameters()[4] ; P42 = P42*P42*134.;
761
762 if(!m_elements[m_lastTrajectory].addCluster(m_parameters,m_parameters,m_xi2)) return false;
763
764
766
767 m_ndf =-4;
768 bool barrel = false;
769 for(int e = m_lastTrajectory-1; e>=m_firstTrajectory; --e) {
770
771 rad+=trad;
772 bool br = m_elements[e].isBarrel();
773 if( (br && !barrel) || (!br && barrel) ) rad+=.1;
774 barrel = br;
775
776 if(m_elements[e].status() > 0) {
777
778 // Add noise contribution
779 //
780 double covP = rad*P42; noise.set(covP*sin2,covP,0.,1.);
781
782 m_parameters.addNoise(noise,Trk::oppositeMomentum);
783
784 // Propagate to straw surface
785 //
786 if(!m_elements[e].propagate(m_parameters,m_parameters)) return false;
787
788 // Update with straw information
789 //
790 double xi;
791 if(!m_elements[e].addCluster(m_parameters,m_parameters,xi)) return false;
792 m_xi2+=xi; ++m_ndf;
793 rad = 0.;
794 }
795 }
796 return true;
797}
798
800// Search a stright line Y = A*X+B crossed max number segments
802
803
805
806 m_A=m_B=0; if(Np<2) return;
807 double Amax =std::abs(DA);
808
809 int i=0;
810
811 while(i!=Np) {m_SS[i].m_NA=i; m_SS[i].m_F=m_V[i]; ++i; m_SS[i].m_NA=i; m_SS[i].m_F=m_V[i]; ++i;}
812 sort(m_SS,Np);
813
814 // Search B with A = 0
815 //
816 i=0; int sm=0, s=0, l=0;
817 while(i!=Np) {
818 if((m_SS[i ].m_NA&1)==(m_MA[i ]=0)) {if(++s>sm) {sm=s; l= i;}} else --s;
819 if((m_SS[i+1].m_NA&1)==(m_MA[i+1]=0)) {if(++s>sm) {sm=s; l=1+i;}} else --s; i+=2;
820 }
821
822 m_B = .5*(m_V[m_SS[l].m_NA]+m_V[m_SS[l+1].m_NA]);
823
824 // Search A and B
825 //
826 while(1) {
827
828 i=(l=m_SS[l].m_NA); double u0=m_U[l], v0=m_V[l];
829
830 // Vector slopes preparation
831 //
832 while(++i!=Np) {if(m_U[i]!=u0) {break;}}
833 double U1=-1000., d=0.; int m=0;
834 while(i<Np-1) {
835 if (m_U[i]==U1) {
836 if(std::abs(m_SS[m].m_F=(m_V[i ]-v0)*d)<Amax) m_SS[m++].m_NA=i;
837 if(std::abs(m_SS[m].m_F=(m_V[i+1]-v0)*d)<Amax) m_SS[m++].m_NA=i+1;
838 }
839 else {
840 d=1./((U1=m_U[i])-u0);
841 if(std::abs(m_SS[m].m_F=(m_V[i ]-v0)*d)<Amax) m_SS[m++].m_NA=i;
842 if(std::abs(m_SS[m].m_F=(m_V[i+1]-v0)*d)<Amax) m_SS[m++].m_NA=i+1;
843 }
844 i+=2;
845 }
846 (i=l); while(--i>0) {if(m_U[i]!=u0) {break;}} U1=-1000.;
847 while(i>0) {
848 if (m_U[i]==U1) {
849 if(std::abs(m_SS[m].m_F=(m_V[i ]-v0)*d)<Amax) m_SS[m++].m_NA=i;
850 if(std::abs(m_SS[m].m_F=(m_V[i-1]-v0)*d)<Amax) m_SS[m++].m_NA=i-1;
851 }
852 else {
853 d=1./((U1=m_U[i])-u0);
854 if(std::abs(m_SS[m].m_F=(m_V[i ]-v0)*d)<Amax) m_SS[m++].m_NA=i;
855 if(std::abs(m_SS[m].m_F=(m_V[i-1]-v0)*d)<Amax) m_SS[m++].m_NA=i-1;
856 }
857 i-=2;
858 }
859
860 if(m<=4) break;
861 sort(m_SS,m);
862
863 int nm = 0; s = 0; sm=-1000;
864 for(int i=0; i!=m-1; ++i) {
865
866 int na = m_SS[i].m_NA;
867
868 if((na&1)==0) {if(na>l) {if(++s>sm) {sm=s; nm=i;}} else --s;}
869 else {if(na<l) {if(++s>sm) {sm=s; nm=i;}} else --s;}
870 }
871 if(nm==0) break;
872 m_B = v0-(m_A=.5*(m_SS[nm].m_F+m_SS[nm+1].m_F))*u0; m_MA[l]=1;
873
874 if (m_MA[m_SS[nm ].m_NA]==0) l = nm;
875 else if(m_MA[m_SS[nm+1].m_NA]==0) l = nm+1;
876 else break;
877 }
878}
879
881// The procedure sorts the elements into ascending order.
883
885 std::sort(s,s+n,[](const samiStruct &a,const samiStruct&b)->bool {return a.m_F<b.m_F;});
886}
887
889// Trajectory conversion to track
891
893{
894 const double trad = .003;
895 double rad = 0. ;
896
897 const Trk::TrackStates*
898 tsos = Tr.trackStateOnSurfaces();
899
900 if(!m_parameters.production((*(tsos->rbegin()))->trackParameters())) return nullptr;
901
902 double sin2 = 1./sin(m_parameters.parameters()[3]); sin2*= sin2 ;
903 double P42 = m_parameters.parameters()[4] ; P42 = P42*P42*134.;
904
906
907 m_xi2 = 0. ;
908 m_ndf = 0 ;
909 bool barrel = false ;
910 int nworse = 0 ;
911 int lastTrajectory = m_firstTrajectory;
914
915 for(int e = m_firstTrajectory; e<=m_lastTrajectory; ++e) {
916
917 rad+=trad;
918 bool br = m_elements[e].isBarrel();
919 if( (br && !barrel) || (!br && barrel) ) rad+=.1;
920 barrel = br;
921
922 if(m_elements[e].status() > 0) {
923
924 // Add noise contribution
925 //
926 double covP = rad*P42; noise.set(covP*sin2,covP,0.,1.);
927 m_parameters.addNoise(noise,Trk::alongMomentum);
928
929 // Propagate to straw surface
930 //
931 if(!m_elements[e].propagate(m_parameters,m_parameters)) break;
932
933 // Update with straw information
934 //
935 double xi;
936 if(!m_elements[e].addCluster(m_parameters,Tp,xi)) break;
937
938 if(xi < 5.) {
939 m_xi2+=xi; ++m_ndf ;
940 lastTrajectory = e ;
942 Tpl = Tp;
943 nworse = 0 ;
944 }
945 else {
946 if(++nworse > 2) break;
947 }
948 rad = 0.;
949 }
950 }
951
952 if(lastTrajectory == m_firstTrajectory || m_ndf < 5 || m_xi2 > 2.*double(m_ndf)) return nullptr;
953 m_lastTrajectory = lastTrajectory;
954
956 s = tsos->begin(), se = tsos->end();
957
958 // Change first track parameters of the track
959 //
960 if(!Tp.production((*s)->trackParameters())) return nullptr;
962
963 // Fill new track information
964 //
965 auto tsosn = std::make_unique<Trk::TrackStates>();
966
967 tsosn->push_back(new Trk::TrackStateOnSurface(nullptr,Tp.convert(true),nullptr,(*s)->types()));
968
969 // Copy old information to new track
970 //
971 for(++s; s!=se; ++s) {
972 tsosn->push_back(new Trk::TrackStateOnSurface(*(*s)));
973 }
974
975 // Add new information from TRT without parameters
976 //
977 for(int e = m_firstTrajectory; e < m_lastTrajectory; ++e) {
978 auto mb = m_elements[e].rioOnTrackSimple();
979 if(mb) {
980 std::bitset<Trk::TrackStateOnSurface::NumberOfTrackStateOnSurfaceTypes> typePattern;
982 tsosn->push_back(new Trk::TrackStateOnSurface(std::move(mb),nullptr,nullptr,typePattern));
983 }
984 }
985
986 // For last points add new information from TRT with parameters
987 //
988 auto mb(m_elements[m_lastTrajectory].rioOnTrackSimple());
989 if(mb) {
990 std::bitset<Trk::TrackStateOnSurface::NumberOfTrackStateOnSurfaceTypes> typePattern;
992 tsosn->push_back
993 (new Trk::TrackStateOnSurface(std::move(mb),m_parameters.convert(true),nullptr,typePattern));
994 }
995
996 // New fit quality production
997 //
998 const Trk::FitQuality* fqo = Tr.fitQuality();
999 if(fqo) {
1000 m_xi2+= fqo->chiSquared();
1001 m_ndf+= fqo->numberDoF ();
1002 }
1003 auto fq = std::make_unique<Trk::FitQuality>(m_xi2,m_ndf);
1004 return new Trk::Track (Tr.info(),std::move(tsosn),std::move(fq));
1005}
1006
1008// Helix updating according new invert momentum information
1009// Pi New invert momentum
1010// CovPi New covariance of invert momentum
1012
1014{
1015 const AmgSymMatrix(5)& v = *T.covariance();
1016 const AmgSymMatrix(5)& w = *m_parameters.covariance();
1017
1018 if(w(4, 4) >= v(4, 4)) return;
1019
1020 double Pi = m_parameters.parameters()[ 4];
1021 double CovPi = w(4, 4);
1022
1023 const AmgVector(5)& p = T.parameters();
1024
1025 double V[15] = {v(0, 0),
1026 v(0, 1),v(1, 1),
1027 v(0, 2),v(1, 2),v(2, 2),
1028 v(0, 3),v(1, 3),v(2, 3),v(3, 3),
1029 v(0, 4),v(1, 4),v(2, 4),v(3, 4),v(4, 4)};
1030 double P[ 5] = {p[ 0],p[ 1],p[ 2],p[ 3],p[ 4]};
1031
1032
1033 double W = (1./CovPi-1./V[14]), det = V[14]/CovPi, Wd = W/det;
1034 double a0 = -V[10]*Wd;
1035 double a1 = -V[11]*Wd;
1036 double a2 = -V[12]*Wd;
1037 double a3 = -V[13]*Wd;
1038 double a4 = 1./det;
1039
1040 // New covariance matrix
1041 //
1042 V[ 0] +=V[10]*a0;
1043 V[ 1] +=V[10]*a1;
1044 V[ 2] +=V[11]*a1;
1045 V[ 3] +=V[10]*a2;
1046 V[ 4] +=V[11]*a2;
1047 V[ 5] +=V[12]*a2;
1048 V[ 6] +=V[10]*a3;
1049 V[ 7] +=V[11]*a3;
1050 V[ 8] +=V[12]*a3;
1051 V[ 9] +=V[13]*a3;
1052 V[10] *=a4;
1053 V[11] *=a4;
1054 V[12] *=a4;
1055 V[13] *=a4;
1056 V[14] =CovPi;
1057
1058 // New parameters
1059 //
1060 Wd = (Pi-P[4])*W;
1061 P[ 0] +=V[10]*Wd;
1062 P[ 1] +=V[11]*Wd;
1063 P[ 2] +=V[12]*Wd;
1064 P[ 3] +=V[13]*Wd;
1065 P[ 4] = Pi;
1066 T.setParametersWithCovariance(&T.associatedSurface(),P,V);
1067}
1068
1069
1071// Overload of << operator std::ostream
1073
1074std::ostream& InDet::operator <<
1075 (std::ostream& sl,const InDet::TRT_Trajectory_xk& se)
1076{
1077 return se.dump(sl);
1078}
1079
1081// Dumps relevant information into the ostream
1083
1084std::ostream& InDet::TRT_Trajectory_xk::dump( std::ostream& out ) const
1085{
1086
1087 if(m_nElements <=0 ) {
1088 out<<"Trajectory does not exist"<<std::endl;
1089 }
1090 out<<"|-------------------------------------------------------------------------|"
1091 <<std::endl;
1092 out<<"| TRAJECTORY "
1093 <<" |"
1094 <<std::endl;
1095
1096 out<<"| Has"<<std::setw(3)<<m_nElements
1097 <<" ("
1098 <<std::setw(3)<<m_naElements
1099 <<")"
1100 <<" elements and "
1101 <<std::setw(3)<<m_nclusters
1102 <<" ("<<std::setw(3)<<m_ntclusters<<")"<<" clusters "
1103 <<" and "
1104 <<std::setw(3)<<m_nholesb
1105 <<std::setw(3)<<m_nholes
1106 <<std::setw(3)<<m_nholese
1107 <<" holes |"
1108 <<std::endl;
1109 out<<"| First and last elements of the road "
1110 <<std::setw(3)<<m_firstRoad<<" "
1111 <<std::setw(3)<<m_lastRoad
1112 <<" |"
1113 <<std::endl;
1114
1115 out<<"| First and last elements of the trajectory "
1116 <<std::setw(3)<<m_firstTrajectory<<" "
1117 <<std::setw(3)<<m_lastTrajectory
1118 <<" |"
1119 <<std::endl;
1120
1121
1122 out<<"|-------------------------------------------------------------------------|"
1123 <<std::endl;
1124 out<<"| n | b| c| nlinks | best | status | impact | zlocal | way |"
1125 <<std::endl;
1126 out<<"|-------------------------------------------------------------------------|"
1127 <<std::endl;
1128
1129 for(int e = m_firstRoad; e<=m_lastRoad; ++e) {
1130
1131 if(m_elements[e].status()<0) continue;
1132
1133 int l = m_elements[e].bestlink();
1134 double im = m_elements[e].link(l).impact();
1135 double zl = m_elements[e].link(l).zlocal();
1136 double w = m_elements[e].link(l).way ();
1137 std::string ss;
1138 if (m_elements[e].status()==1) ss =" +- ";
1139 else if(m_elements[e].status()==2) ss =" ++ ";
1140 else ss =" -- ";
1141
1142 out<<"| "
1143 <<std::setw(3)<<e
1144 <<std::setw(3)<<m_elements[e].isBarrel ()
1145 <<std::setw(3)<<m_elements[e].isCluster()
1146 <<std::setw(7)<<m_elements[e].nlinks ()
1147 <<std::setw(7)<<m_elements[e].bestlink ()
1148 <<std::setw(4)<<ss
1149 <<std::setw(13)<<std::setprecision(6)<<im
1150 <<std::setw(13)<<std::setprecision(6)<<zl
1151 <<std::setw(13)<<std::setprecision(6)<<w
1152 <<" |"
1153 <<std::endl;
1154 }
1155 out<<"|-------------------------------------------------------------------------|"
1156 <<std::endl;
1157 return out;
1158}
#define M_PI
#define AmgSymMatrix(dim)
#define AmgVector(rows)
static const double Pi
static Double_t rs
static Double_t a
static Double_t ss
static Double_t Tp(Double_t *t, Double_t *par)
static Double_t P(Double_t *tt, Double_t *par)
static Double_t rz
#define z
Header file for AthHistogramAlgorithm.
Derived DataVector<T>.
Definition DataVector.h:795
DataModel_detail::const_iterator< DataVector > const_iterator
Definition DataVector.h:838
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
const_reverse_iterator rbegin() const noexcept
Return a const_reverse_iterator pointing past the end of the collection.
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
This is a "hash" representation of an Identifier.
void set(const TRT_ID *, const Trk::IPatternParametersPropagator *, const Trk::IPatternParametersUpdator *, const Trk::IRIO_OnTrackCreator *, const Trk::IRIO_OnTrackCreator *, double, double, double, double, double)
Trk::MagneticFieldProperties m_fieldprop
Trk::PatternTrackParameters m_parameters
Trk::TrackSegment * convert()
std::ostream & dump(std::ostream &out) const
const Trk::IPatternParametersPropagator * m_proptool
void updateTrackParameters(Trk::PatternTrackParameters &)
void initiateForPrecisionSeed(std::vector< std::pair< Amg::Vector3D, double > > &, const std::vector< const InDetDD::TRT_BaseElement * > &, const TRT_DriftCircleContainer *&, const Trk::PatternTrackParameters &)
const Trk::IPatternParametersUpdator * m_updatortool
void trackFindingWithoutDriftTimeBL(double)
bool trackParametersEstimationForFirstPointWithVertexConstraint()
static void sort(samiStruct *, int)
bool trackParametersEstimationForPerigeeWithVertexConstraint()
std::pair< const Trk::PseudoMeasurementOnTrack *, const Trk::PseudoMeasurementOnTrack * > pseudoMeasurements(const Trk::Surface *, const Trk::Surface *, int bec)
void initiateForTRTSeed(std::vector< std::pair< Amg::Vector3D, double > > &, const std::vector< const InDetDD::TRT_BaseElement * > &, const TRT_DriftCircleContainer *&, const Trk::PatternTrackParameters &)
TRT_TrajectoryElement_xk m_elements[400]
This is an Identifier helper class for the TRT subdetector.
Definition TRT_ID.h:82
Bounds for a cylindrical Surface.
double halflengthZ() const
This method returns the halflengthZ.
Class to represent and store fit qualities from track reconstruction in terms of and number of degre...
Definition FitQuality.h:97
int numberDoF() const
returns the number of degrees of freedom of the overall track or vertex fit as integer
Definition FitQuality.h:60
double chiSquared() const
returns the of the overall track fit
Definition FitQuality.h:56
interface for track parameter propagation through the magnetic field, using the Trk::PatternTrackPara...
Interface for updating Trk::PatternTrackParameters, the fast internal representation of track paramet...
Interface class for transforming Trk::PrepRawData to Trk::RIO_OnTrack using a local track hypothesis.
magnetic field properties to steer the behavior of the extrapolation
This class is the pure abstract base class for all fittable tracking measurements.
Class describing the Line to which the Perigee refers to.
Class to handle pseudo-measurements in fitters and on track objects.
Class for a StraightLineSurface in the ATLAS detector to describe dirft tube and straw like detectors...
Abstract Base Class for tracking surfaces.
const Amg::Transform3D & transform() const
Returns HepGeom::Transform3D by reference.
virtual const SurfaceBounds & bounds() const =0
Surface Bounds method.
const Amg::Vector3D & center() const
Returns the center position of the Surface.
Class for a generic track segment that holdes polymorphic Trk::MeasurementBase objects,...
represents the track state (measurement, material, fit parameters and quality) at a surface.
@ Measurement
This is a measurement, and will at least contain a Trk::MeasurementBase.
const Trk::TrackStates * trackStateOnSurfaces() const
return a pointer to a const DataVector of const TrackStateOnSurfaces.
const TrackInfo & info() const
Returns a const ref to info of a const tracks.
const FitQuality * fitQuality() const
return a pointer to the fit quality const-overload
int r
Definition globals.cxx:22
double a0
Definition globals.cxx:27
Eigen::Matrix< double, 3, 3 > RotationMatrix3D
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Dynamic Matrix - dynamic allocation.
Eigen::Affine3d Transform3D
Eigen::Matrix< double, 3, 1 > Vector3D
Eigen::Translation< double, 3 > Translation3D
@ oppositeMomentum
@ alongMomentum
@ anyDirection
DataVector< const Trk::TrackStateOnSurface > TrackStates
@ driftRadius
trt, straws
Definition ParamDefs.h:53
@ theta
Definition ParamDefs.h:66
@ locZ
local cylindrical
Definition ParamDefs.h:42
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
hold the test vectors and ease the comparison