ATLAS Offline Software
TrigInDetTrackFollowingTool.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 <cmath>
6 #include <iostream>
7 #include <memory>
8 #include "GaudiKernel/SystemOfUnits.h"
9 
10 #include "TrkTrack/Track.h"
11 #include "TrkTrack/TrackInfo.h"
14 
17 
20 
23 
27 
28 #include "TrkSurfaces/Surface.h"
29 
31 
35 
37 
38 
39 TrigFTF_ExtendedTrackState::TrigFTF_ExtendedTrackState(double const* P, const Trk::PlaneSurface* pS) : m_chi2(0), m_ndof(-5), m_pS(pS), m_pO(pS), m_nClusters(0), m_nHoles(0), m_isSwapped(false) {
40 
41  for(int i=0;i<5;i++) m_Xk[i] = m_Xk[i+5] = P[i];//duplicate the lower half of the state vector
42 
43  memset(&m_Gk[0][0],0,sizeof(m_Gk));
44 
45  //covariance block C
46 
47  m_Gk[0][0] = 1.0;
48  m_Gk[1][1] = 1.0;
49  m_Gk[2][2] = 0.0001;
50  m_Gk[3][3] = 0.0001;
51  m_Gk[4][4] = P[5];
52 
53  //triplicate the lower block
54  for(int i=0;i<5;i++) {
55  m_Gk[i+5][i+5] = m_Gk[i][i+5] = m_Gk[i+5][i] = m_Gk[i][i];
56  }
57 
58  m_track.clear();
59 }
60 
62  if(m_isSwapped) {
63  m_track.emplace_front(nullptr, nullptr, nullptr, 0, -1);
64  }
65  else {
66  m_track.emplace_back(nullptr, nullptr, nullptr, 0, -1);
67  }
68  m_nHoles++;
69 }
70 
72  if (m_Xk[2] > M_PI) m_Xk[2] -= 2 * M_PI;
73  if (m_Xk[2] < -M_PI) m_Xk[2] += 2 * M_PI;
74  if (m_Xk[3] < 0.0) m_Xk[3] += M_PI;
75  if (m_Xk[3] > M_PI) m_Xk[3] -= M_PI;
76  if (m_Xk[7] > M_PI) m_Xk[7] -= 2 * M_PI;
77  if (m_Xk[7] < -M_PI) m_Xk[7] += 2 * M_PI;
78  if (m_Xk[8] < 0.0) m_Xk[8] += M_PI;
79  if (m_Xk[8] > M_PI) m_Xk[8] -= M_PI;
80 
81 }
82 
83 void TrigFTF_ExtendedTrackState::AddHit(const Trk::PrepRawData* pPRD, double dchi2, int ndof) {
84 
85  correctAngles();
86 
87  double cov[15];
88  int idx=0;
89  for(int i=0;i<5;i++)
90  for(int j=0;j<=i;j++)
91  cov[idx++] = m_Gk[i][j];
92 
93  if(m_isSwapped) {
94  m_track.emplace_front(pPRD, m_Xk, &cov[0], dchi2, ndof);
95  }
96  else {
97  m_track.emplace_back(pPRD, m_Xk, &cov[0], dchi2, ndof);
98  }
99 
100  m_chi2 += dchi2;
101  m_ndof += ndof;
102  m_nClusters++;
103  m_nHoles = 0;//reset the counter
104 }
105 
107 
109 
110  std::swap(m_pS, m_pO);
111 
112  double tmpX[10];
113  memcpy(&tmpX[0], &m_Xk[0], sizeof(tmpX));
114 
115  for(int i=0;i<5;i++) {
116  m_Xk[i] = tmpX[i+5];
117  m_Xk[i+5] = tmpX[i];
118  }
119 
120  double tmpG[10][10];
121  memcpy(&tmpG[0][0], &m_Gk[0][0], sizeof(tmpG));
122 
123  //covariance blocks are moved around to reflect the state vectors swap done above
124 
125  for(int i=0;i<5;i++) {
126  for(int j=0;j<5;j++) {
127  m_Gk[i+5][j+5] = tmpG[i][j]; //C -> E
128  m_Gk[i][j] = tmpG[i+5][j+5];//E -> C
129  m_Gk[i][j+5] = tmpG[i+5][j]; //D -> B
130  m_Gk[i+5][j] = tmpG[i][j+5]; //B -> D
131  }
132  }
133 }
134 
136  std::cout<<"L: ";
137  for(int i=0;i<4;i++) std::cout<<m_Xk[i]<<" ";
138  std::cout<<1/m_Xk[4]<<" "<<std::sin(m_Xk[3])/m_Xk[4]<<std::endl;
139 
140 
141  std::cout<<"Covariance at last point:"<<std::endl;
142 
143  for(int i=0;i<5;i++) {
144  for(int j=0;j<5;j++) std::cout<<m_Gk[i][j]<<" ";
145  std::cout<<std::endl;
146  }
147 
148  std::cout<<"F: ";
149  for(int i=0;i<4;i++) std::cout<<m_Xk[i+5]<<" ";
150  std::cout<<1/m_Xk[4+5]<<" "<<std::sin(m_Xk[3+5])/m_Xk[4+5]<<std::endl;
151  std::cout<<std::endl;
152 
153  std::cout<<"Covariance at the first point:"<<std::endl;
154 
155  for(int i=0;i<5;i++) {
156  for(int j=0;j<5;j++) std::cout<<m_Gk[i+5][j+5]<<" ";
157  std::cout<<std::endl;
158  }
159 
160  std::cout<<"chi2="<<m_chi2<<" ndof="<<m_ndof<<" nClusters="<<m_nClusters<<" nHoles="<<m_nHoles<<std::endl;
161 
162 }
163 
164 
166  const std::string& n,
167  const IInterface* p ): AthAlgTool(t,n,p)
168 {
169  declareInterface< ITrigInDetTrackFollowingTool >( this );
170 }
171 
173 
177 
178  return StatusCode::SUCCESS;
179 }
180 
182  return StatusCode::SUCCESS;
183 }
184 
185 
186 double TrigInDetTrackFollowingTool::processHit(const InDet::PixelCluster* pPRD, double* resid, double* invcov, const TrigFTF_ExtendedTrackState& ets) const {
187 
188  double cluster_cov[2];
189 
190  if(m_useHitErrors) {
191  cluster_cov[0] = pPRD->localCovariance()(0,0);
192  cluster_cov[1] = pPRD->localCovariance()(1,1);
193  }
194  else {
195  cluster_cov[0] = pPRD->width().phiR();
196  cluster_cov[1] = pPRD->width().z();
197  for(int i=0;i<2;i++) cluster_cov[i] *= cluster_cov[i]/12.0;
198  }
199 
200  double covsum[2][2] = {{ets.m_Gk[0][0] + cluster_cov[0], ets.m_Gk[0][1]}, {ets.m_Gk[0][1], ets.m_Gk[1][1] + cluster_cov[1]}};
201 
202  double detr = 1/(covsum[0][0]*covsum[1][1] - covsum[0][1]*covsum[1][0]);
203 
204  invcov[0] = detr*covsum[1][1];
205  invcov[1] = -detr*covsum[1][0];
206  invcov[2] = detr*covsum[0][0];
207 
208  resid[0] = pPRD->localPosition().x() - ets.m_Xk[0];
209  resid[1] = pPRD->localPosition().y() - ets.m_Xk[1];
210 
211  return (resid[0]*(resid[0]*invcov[0] + resid[1]*invcov[1]) + resid[1]*(resid[0]*invcov[1] + resid[1]*invcov[2]));
212 
213 }
214 
215 double TrigInDetTrackFollowingTool::processHit(const InDet::SCT_Cluster* pPRD, int shape, double& resid, double& invcov, double* H, const TrigFTF_ExtendedTrackState& ets) const {
216 
217  if(shape==InDetDD::Box) {
218 
219  resid = pPRD->localPosition().x() - ets.m_Xk[0];
220 
221  double covX = pPRD->localCovariance()(0, 0);
222 
223  if(!m_useHitErrors) {
224  covX = pPRD->width().phiR();
225  covX *= (covX/12);
226  }
227 
228  invcov = 1/(ets.m_Gk[0][0] + covX);
229  H[0] = 1;
230  H[1] = 0;
231  }
232 
233  else {
234 
235  double meas_x = pPRD->localPosition().x();
236  double meas_y = pPRD->localPosition().y();
237 
238  double e00 = pPRD->localCovariance()(0, 0);
239  double e01 = pPRD->localCovariance()(0, 1);
240  double e11 = pPRD->localCovariance()(1, 1);
241 
242  double beta = 0.5*std::atan(2*e01/(e00-e11));
243  double sinB, cosB;
244  sincos(beta, &sinB, &cosB);
245 
246  resid = (meas_x - ets.m_Xk[0])*cosB + (meas_y - ets.m_Xk[1])*sinB;
247 
248  H[0] = cosB;
249  H[1] = sinB;
250 
251  double track_cov = cosB*cosB*(ets.m_Gk[0][0]+e00) + 2*cosB*sinB*(ets.m_Gk[0][1]+e01) + sinB*sinB*(ets.m_Gk[1][1]+e11);
252 
253  invcov = 1/track_cov;
254  }
255 
256  return (resid * resid * invcov);
257 
258 }
259 
260 
262 
263  const InDet::PixelCluster* bestHit = pInputHit;
264  if(pColl == nullptr && pInputHit == nullptr) return nullptr;
265  double resid[2];
266  double invcov[3];
267 
268  if(pColl != nullptr) {
269 
270  double bestChi2Dist = m_maxChi2Dist_Pixels;
271 
272  for(const auto pPRD : *pColl) {
273 
274  double dchi2 = processHit(pPRD, resid, invcov, ets);
275 
276  if(dchi2 < bestChi2Dist) {
277  bestHit = pPRD;
278  bestChi2Dist = dchi2;
279  }
280  }
281  }
282 
283  if(bestHit == nullptr) return bestHit;
284 
285  const InDet::PixelCluster* pPRD = bestHit;
286 
287  double dchi2 = processHit(pPRD, resid, invcov, ets);
288 
289  double CHT[10][2];
290 
291  for(int i=0;i<10;i++) {
292  CHT[i][0] = ets.m_Gk[i][0];
293  CHT[i][1] = ets.m_Gk[i][1];
294  }
295 
296  double Gain[10][2];
297  double V[2][2] = {{invcov[0], invcov[1]}, {invcov[1], invcov[2]}};
298 
299  for(int i=0;i<10;i++)
300  for(int j=0;j<2;j++) Gain[i][j] = CHT[i][0]*V[0][j] + CHT[i][1]*V[1][j];
301 
302  for(int i=0;i<10;i++) {
303  ets.m_Xk[i] += Gain[i][0]*resid[0] + Gain[i][1]*resid[1];
304 
305  for(int j=0;j<=i;j++) {
306  ets.m_Gk[i][j] = ets.m_Gk[i][j] - (Gain[i][0]*CHT[j][0] + Gain[i][1]*CHT[j][1]);
307  ets.m_Gk[j][i] = ets.m_Gk[i][j];
308  }
309  }
310 
311  ets.AddHit(pPRD, dchi2, 2);
312 
313  return pPRD;
314 }
315 
316 
318 
319  const InDet::SCT_Cluster* bestHit = pInputHit;
320  if(pColl == nullptr && pInputHit == nullptr) return nullptr;
321  double resid, invcov;
322  double H[2];//linearized observation matrix
323 
324  if(pColl && !pColl->empty()) {
325 
326  double bestChi2Dist = m_maxChi2Dist_Strips;
327 
328  for(const auto pPRD : *pColl) {
329 
330  double dchi2 = processHit(pPRD, shape, resid, invcov, H, ets);
331 
332  if(dchi2 < bestChi2Dist) {
333  bestHit = pPRD;
334  bestChi2Dist = dchi2;
335  }
336  }
337  }
338 
339  if(bestHit == nullptr) return bestHit;
340 
341  const InDet::SCT_Cluster* pPRD = bestHit;
342 
343  double dchi2 = 0.0;
344 
345  if(shape == InDetDD::Box) {
346 
347  dchi2 = processHit(pPRD, shape, resid, invcov, H, ets);
348 
349  double CHT[10], Gain[10];
350 
351  for(int i=0;i<10;i++) {
352  CHT[i] = ets.m_Gk[i][0];
353  Gain[i] = CHT[i] * invcov;
354  }
355 
356  for(int i=0;i<10;i++) {
357  ets.m_Xk[i] += Gain[i]*resid;
358  for(int j=0;j<=i;j++) {
359  ets.m_Gk[i][j] = ets.m_Gk[i][j] - Gain[i]*CHT[j];
360  ets.m_Gk[j][i] = ets.m_Gk[i][j];
361  }
362  }
363 
364  //boundary check
365 
366  double covY = pPRD->localCovariance()(1, 1);
367  double stripCentre = pPRD->localPosition().y();
368  double stripHalfLength = std::sqrt(3*covY);
369 
370  double dY = ets.m_Xk[1] - stripCentre;
371 
372  if(dY > stripHalfLength) {
373  ets.m_Xk[1] = stripCentre + stripHalfLength;
374  }
375 
376  if(dY < -stripHalfLength) {
377  ets.m_Xk[1] = stripCentre - stripHalfLength;
378  }
379  }
380  else { //Annulus
381 
382  dchi2 = processHit(pPRD, shape, resid, invcov, H, ets);
383 
384  double CHT[10], Gain[10];
385 
386  for(int i=0;i<10;i++) {
387  CHT[i] = H[0]*ets.m_Gk[i][0] + H[1]*ets.m_Gk[i][1];
388  Gain[i] = CHT[i] * invcov;
389  }
390 
391  for(int i=0;i<10;i++) {
392  ets.m_Xk[i] += Gain[i]*resid;
393  for(int j=0;j<=i;j++) {
394  ets.m_Gk[i][j] = ets.m_Gk[i][j] - Gain[i]*CHT[j];
395  ets.m_Gk[j][i] = ets.m_Gk[i][j];
396  }
397  }
398  }
399 
400  ets.AddHit(pPRD, dchi2, 1);
401 
402  return pPRD;
403 }
404 
405 std::unique_ptr<TrigFTF_ExtendedTrackState> TrigInDetTrackFollowingTool::fitTheSeed(const std::vector<const Trk::SpacePoint*>& seed, MagField::AtlasFieldCache& fieldCache) const {
406 
407  //track parameters are estimated at the last point of the seed (inside-out approach)
408 
409  const Trk::SpacePoint& SPb = *seed.at(0);
410  const Trk::SpacePoint& SPm = *seed.at(1);
411  const Trk::SpacePoint& SPe = *seed.at(seed.size()-1);
412 
413  double pb[3] = {SPb.globalPosition().x(), SPb.globalPosition().y(), SPb.globalPosition().z()};
414  double pm[3] = {SPm.globalPosition().x(), SPm.globalPosition().y(), SPm.globalPosition().z()};
415  double pe[3] = {SPe.globalPosition().x(), SPe.globalPosition().y(), SPe.globalPosition().z()};
416 
417  double dsp[2] = {pe[0]-pb[0], pe[1]-pb[1]};
418  double Lsp = std::sqrt(dsp[0]*dsp[0] + dsp[1]*dsp[1]);
419  double cosA = dsp[0]/Lsp;
420  double sinA = dsp[1]/Lsp;
421  double tau0 = (pe[2]-pb[2])/(SPe.globalPosition().perp()-SPb.globalPosition().perp());
422 
423  double dxm = pm[0] - pb[0];
424  double dym = pm[1] - pb[1];
425 
426  double x1 = dxm*cosA + dym*sinA;
427  double m1 = -dxm*sinA + dym*cosA;
428 
429  double a_parab = -2*m1/(x1*(Lsp-x1));
430  double b_parab = -0.5*a_parab*Lsp;
431 
432  double Rx[3] = {0,b_parab,a_parab};
433  double Ry[2] = {pb[2],tau0};
434 
435  double Cx[3][3];
436  double Cy[2][2];
437 
438  memset(&Cx[0][0],0,sizeof(Cx));
439  Cx[0][0] = 0.1;
440  Cx[1][1] = 0.001;
441  Cx[2][2] = 0.001;
442 
443  memset(&Cy[0][0],0,sizeof(Cy));
444  Cy[0][0] = 0.25;
445  Cy[1][1] = 0.001;
446 
447  double path = -Lsp;
448  path = 0.0;
449  double radius= SPb.globalPosition().perp();
450 
451  double Fx[3][3];
452  double Fy[2][2];
453 
454  memset(&Fx[0][0],0,sizeof(Fx));
455  Fx[0][0] = 1.0;
456  Fx[1][1] = 1.0;
457  Fx[2][2] = 1.0;
458 
459  memset(&Fy[0][0],0,sizeof(Fy));
460  Fy[0][0] = 1.0;
461  Fy[1][1] = 1.0;
462 
463  double sigma_x2 = std::pow(0.08,2);
464  double sigma_y2 = std::pow(0.3,2);
465 
466  for(const auto& sp : seed) {
467 
468  //1. extrapolate
469 
470  double pk[3] = {sp->globalPosition().x(), sp->globalPosition().y(), sp->globalPosition().z()};
471 
472  double dx = pk[0] - pb[0];
473  double dy = pk[1] - pb[1];
474 
475  double dist = dx*cosA + dy*sinA;
476  double measx =-dx*sinA + dy*cosA;
477  double measy = pk[2];
478 
479  double ds = dist - path;
480 
481  path = dist;
482 
483  double rk = sp->globalPosition().perp();
484  double dr = rk - radius;
485  radius = rk;
486 
487  //update Jacobians
488  Fx[0][1] = ds;
489  Fx[0][2] = 0.5*ds*ds;
490  Fx[1][2] = ds;
491 
492  Fy[0][1] = dr;
493 
494  Cx[1][1] += 1e-7;
495  Cy[1][1] += 1e-7;
496 
497  double Rex[3] = {Rx[0], Rx[1], Rx[2]};
498 
499  Rex[0] += Fx[0][1]*Rx[1] + Fx[0][2]*Rx[2];
500  Rex[1] += Fx[1][2]*Rx[2];
501 
502  double Cex[3][3], CFT[3][3];
503 
504  for(int i=0;i<3;i++) {
505  for(int j=0;j<3;j++) {
506  CFT[i][j] = 0;
507  for(int m=0;m<3;m++) CFT[i][j] += Cx[i][m]*Fx[j][m];
508  }
509  }
510  for(int i=0;i<3;i++) {
511  for(int j=0;j<3;j++) {
512  Cex[i][j] = 0;
513  for(int m=0;m<3;m++) Cex[i][j] += Fx[i][m]*CFT[m][j];
514  }
515  }
516 
517  double Rey[2] = {Ry[0], Ry[1]};
518 
519  Rey[0] += Fy[0][1]*Ry[1];
520 
521  double Cey[3][3];
522 
523  for(int i=0;i<2;i++) {
524  for(int j=0;j<2;j++) {
525  CFT[i][j] = 0;
526  for(int m=0;m<2;m++) CFT[i][j] += Cy[i][m]*Fy[j][m];
527  }
528  }
529  for(int i=0;i<2;i++) {
530  for(int j=0;j<2;j++) {
531  Cey[i][j] = 0;
532  for(int m=0;m<2;m++) Cey[i][j] += Fy[i][m]*CFT[m][j];
533  }
534  }
535 
536  //2. update
537 
538  double CHTx[3] = {Cex[0][0], Cex[0][1], Cex[0][2]};
539  double Dx = 1/(Cex[0][0] + sigma_x2);
540 
541  double resid = measx - Rex[0];
542 
543  double Kx[3] = {Dx*CHTx[0], Dx*CHTx[1], Dx*CHTx[2]};
544 
545  for(int i=0;i<3;i++) Rx[i] = Rex[i] + Kx[i]*resid;
546  for(int i=0;i<3;i++) {
547  for(int j=0;j<3;j++) {
548  Cx[i][j] = Cex[i][j] - Kx[i]*CHTx[j];
549  }
550  }
551 
552  double CHTy[2] = {Cey[0][0], Cey[0][1]};
553  double Dy = 1/(Cey[0][0] + sigma_y2);
554 
555  resid = measy - Rey[0];
556 
557  double Ky[2] = {Dy*CHTy[0], Dy*CHTy[1]};
558 
559  for(int i=0;i<2;i++) Ry[i] = Rey[i] + Ky[i]*resid;
560  for(int i=0;i<2;i++) {
561  for(int j=0;j<2;j++) {
562  Cy[i][j] = Cey[i][j] - Ky[i]*CHTy[j];
563  }
564  }
565  }
566 
567  //create initial track state at the last spacepoint of the seed
568 
569  double B0[3];
570 
571  fieldCache.getField(pe, B0);
572 
573  double P0[6];
574 
575  const Trk::PrepRawData* cle = SPe.clusterList().first;
576 
577  const Trk::PlaneSurface* thePlane = static_cast<const Trk::PlaneSurface*>(&cle->detectorElement()->surface());
578 
579  if(thePlane == nullptr) return nullptr;
580 
581  P0[0] = cle->localPosition()[0];
582  P0[1] = cle->localPosition()[1];
583  P0[2] = std::atan2(sinA - Rx[1]*cosA, cosA - Rx[1]*sinA);//phi in the global c.s.
584  P0[3] = std::atan2(1, Ry[1]);//theta in the global c.s.
585  double coeff = 1.0/(300.0*B0[2]*std::sqrt(1+Ry[1]*Ry[1]));
586  P0[4] = -Rx[2]*coeff;//qOverP estimate
587  P0[5] = Cx[2][2]*coeff*coeff;//qOverP covariance
588 
589  return std::make_unique<TrigFTF_ExtendedTrackState>(P0, thePlane);
590 
591 }
592 
593 Trk::Track* TrigInDetTrackFollowingTool::getTrack(const std::vector<const Trk::SpacePoint*>& seed, const std::vector<const InDetDD::SiDetectorElement*>& road, const EventContext& ctx) const {
594 
595  //1. get magnetic field
596 
597  MagField::AtlasFieldCache fieldCache;
598 
600  if (!fieldCondObj.isValid()) {
601  ATH_MSG_ERROR("Failed to retrieve AtlasFieldCacheCondObj with key " << m_fieldCondObjInputKey.key());
602  return nullptr;
603  }
604 
605  fieldCondObj->getInitializedCache (fieldCache);
606 
607  //2. get hits
608 
610 
611  if (!pixcontainer.isValid()) {
612  ATH_MSG_ERROR("Failed to retrieve Pixel Cluster Container with key " << m_pixcontainerkey.key());
613  return nullptr;
614  }
615 
616  const InDet::PixelClusterContainer* p_pixcontainer = pixcontainer.ptr();
617 
619 
620  if (!sctcontainer.isValid()) {
621  ATH_MSG_ERROR("Failed to retrieve Strip Cluster Container with key " << m_sctcontainerkey.key());
622  return nullptr;
623  }
624 
625  const InDet::SCT_ClusterContainer* p_sctcontainer = sctcontainer.ptr();
626 
627  //3. prepare the initial track state
628 
629  int nModules = road.size();
630 
631  std::vector<const Trk::PrepRawData*> assignedHits(nModules, nullptr);//assuming maximum one assigned hit per detector element
632 
633  std::vector<int> moduleStatus(nModules, 0);//initial status: unchecked
634 
635  unsigned int seedSize = seed.size();
636 
637  std::vector<unsigned int> seedHashes(seedSize,0);
638 
639  for(unsigned int spIdx=0;spIdx<seedSize;spIdx++) {
640  const Trk::PrepRawData* prd = seed.at(spIdx)->clusterList().first;
641  seedHashes[spIdx] = prd->detectorElement()->identifyHash();
642  }
643 
644  //pre-assigning the hits contained in the input track seed
645 
646  int nUnassigned = seedSize;
647 
648  int startModuleIdx = -1;
649 
650  for(int moduleIdx = 0;moduleIdx<nModules;moduleIdx++) {
651  unsigned int hash = road.at(moduleIdx)->identifyHash();
652  for(unsigned int spIdx=0;spIdx<seedSize;spIdx++) {
653  if(seedHashes[spIdx] != hash) continue;
654 
655  assignedHits[moduleIdx] = seed.at(spIdx)->clusterList().first;
656  moduleStatus[moduleIdx] = 1;//seed hit assigned
657 
658  startModuleIdx = moduleIdx;
659  --nUnassigned;
660  break;
661  }
662  if(nUnassigned == 0) break;
663  }
664 
665  if(nUnassigned > 0) return nullptr;//bad road or bad seed
666 
667  std::unique_ptr<TrigFTF_ExtendedTrackState> initialState = fitTheSeed(seed, fieldCache);
668 
669  if(initialState == nullptr) return nullptr;
670 
671  initialState->correctAngles();
672 
673  TrigFTF_ExtendedTrackState& theState = *initialState;
674 
675  std::vector<int> moduleIndexSequence(nModules);//the order in which modules will be explored to find hits
676 
677  int modCounter = 0;
678 
679  for(int moduleIdx = startModuleIdx + 1;moduleIdx<nModules;moduleIdx++, modCounter++) {//forward pass
680  moduleIndexSequence[modCounter] = moduleIdx;
681  }
682  for(int moduleIdx = startModuleIdx;moduleIdx>=0;moduleIdx--, modCounter++) {//backward pass
683  moduleIndexSequence[modCounter] = moduleIdx;
684  }
685 
686  //4. The track following loop
687 
688  for(auto const moduleIdx : moduleIndexSequence) {
689 
690  if(theState.m_nHoles > m_nHolesMax) { //bailing-out early to save CPU time
691  return nullptr;
692  }
693 
694  if(moduleStatus[moduleIdx] < 0) continue;//checked and rejected
695 
696  const InDetDD::SiDetectorElement* de = road.at(moduleIdx);//next module
697 
698  //4a. extrapolation to the target surface
699 
700  const Trk::PrepRawData* pPRD = assignedHits[moduleIdx];
701 
702  if(moduleIdx == startModuleIdx) {
703  theState.SwapTheEnds();//no extrapolation is needed (apart from the material effects)
704  }
705  else {
706 
707  const Trk::PlaneSurface* plane = static_cast<const Trk::PlaneSurface*>(&de->surface());
708 
709  if(pPRD == nullptr) {//no hit assigned yet, check if we can cross the module first
710  //tentative extrapolation
711  bool inBounds = checkIntersection(theState.m_Xk, theState.m_pS, plane, fieldCache);
712  if(!inBounds) {
713  moduleStatus[moduleIdx] = -2;//miss
714  continue;
715  }
716  }
717 
718  //precise extrapolation
719  int rkCode = extrapolateTrackState(theState, plane, fieldCache);
720 
721  if(rkCode!=0) {
722  moduleStatus[moduleIdx] = -2;//miss
723  if(pPRD != nullptr) {
724  theState.AddHole();//because we were expecting the pre-assigned hit
725  }
726  continue;
727  }
728  }
729 
730  //4b. search for the best hit and update the track state
731 
732  unsigned int moduleHash = de->identifyHash();
733 
734  unsigned int nHits = 0;
735 
736  const Trk::PrepRawData* selectedHit = nullptr;
737 
738  if(de->isPixel()) {//Pixel module
739 
740  const InDet::PixelClusterCollection *clustersOnElement = nullptr;
741  const InDet::PixelCluster* pPixelHit = nullptr;
742 
743  if(pPRD == nullptr) {
744  if(p_pixcontainer != nullptr) {
745  clustersOnElement = (*p_pixcontainer).indexFindPtr(moduleHash);
746  if(clustersOnElement != nullptr) {
747  nHits = clustersOnElement->size();
748  }
749  }
750  }
751  else {
752  pPixelHit = dynamic_cast<const InDet::PixelCluster*>(pPRD);
753  nHits = 1;
754  }
755 
756  if(nHits > 0) {
757  selectedHit = updateTrackState(pPixelHit, clustersOnElement, theState);
758  }
759 
760  }
761  else {//Strip module
762 
763  const InDet::SCT_ClusterCollection *clustersOnElement = nullptr;
764  const InDet::SCT_Cluster* pStripHit = nullptr;
765 
766  if(pPRD == nullptr) {
767  if(p_sctcontainer != nullptr) {
768  clustersOnElement = (*p_sctcontainer).indexFindPtr(moduleHash);
769  if(clustersOnElement != nullptr) {
770  nHits = clustersOnElement->size();
771  }
772  }
773  }
774  else {
775  pStripHit = dynamic_cast<const InDet::SCT_Cluster*>(pPRD);
776  nHits = 1;
777  }
778 
779  if(nHits > 0) {
780  selectedHit = updateTrackState(pStripHit, clustersOnElement, de->design().shape(), theState);
781  }
782 
783  }
784 
785  if(nHits == 0) {// dead module?
786  theState.AddHole();
787  moduleStatus[moduleIdx] = -3;//dead module
788  continue;
789  }
790 
791  if(pPRD == nullptr) {
792  if(selectedHit == nullptr) {
793  theState.AddHole();
794  moduleStatus[moduleIdx] = -4;//all hits rejected
795  }
796  else {
797  assignedHits[moduleIdx] = selectedHit;
798  moduleStatus[moduleIdx] = de->isPixel() ? 2 : 3;//a new Pixel/Strip hit assigned
799  }
800  }
801  } //end of the track following loop
802 
803  //5. create output track
804 
805  int nClusters = theState.m_nClusters;
806  int nHoles = theState.m_nHoles;
807  double chi2tot = theState.m_chi2;
808 
809  if(nClusters < m_nClustersMin) {
810  return nullptr;
811  }
812 
813  if(nHoles > m_nHolesMax) {
814  return nullptr;
815  }
816 
817  int rkCode = extrapolateTrackState(theState, nullptr, fieldCache);//to perigee
818 
819  if(rkCode !=0) {
820  return nullptr;
821  }
822 
823  int ndoftot = theState.m_ndof;
824  double qOverP = theState.m_Xk[4];
825  double pt = std::sin(theState.m_Xk[3])/qOverP;
826  double phi0 = theState.m_Xk[2];
827  double theta = theState.m_Xk[3];
828 
829  double z0 = theState.m_Xk[1];
830  double d0 = theState.m_Xk[0];
831 
832  bool bad_cov = false;
833 
834  auto cov = AmgSymMatrix(5){};
835 
836  for(int i=0;i<5;i++) {
837  for(int j=0;j<=i;j++) {
838  double c = theState.m_Gk[i][j];
839  if (i == j && c < 0) {
840  bad_cov = true;//Diagonal elements must be positive
841  ATH_MSG_DEBUG("REGTEST: cov(" << i << "," << i << ") =" << c << " < 0, reject track");
842  break;
843  }
844  cov.fillSymmetric(i,j, c);
845  }
846  }
847 
848  if((ndoftot<0) || (fabs(pt)<100.0) || (std::isnan(pt)) || bad_cov) {
849  ATH_MSG_DEBUG("Track following failed - possibly floating point problem");
850  return nullptr;
851  }
852 
853  Trk::PerigeeSurface perigeeSurface;
854 
855  std::unique_ptr<Trk::TrackParameters> pPP = perigeeSurface.createUniqueTrackParameters(d0, z0, phi0, theta, qOverP, cov);
856 
857  std::bitset<Trk::TrackStateOnSurface::NumberOfTrackStateOnSurfaceTypes> perType;
859 
860  auto pParVec = std::make_unique<Trk::TrackStates>();
861 
862  pParVec->reserve(50);
863  pParVec->push_back(new Trk::TrackStateOnSurface(nullptr, std::move(pPP), nullptr, perType));
864 
865  std::bitset<Trk::TrackStateOnSurface::NumberOfTrackStateOnSurfaceTypes> rioType(0);
868 
869  for(const auto& ha : theState.m_track) {//loop over hit assignments
870 
871  const Trk::PrepRawData* pPRD = ha.m_pPRD;
872 
873  if(pPRD == nullptr) continue;//skip holes
874 
875  //create track states on surface
876 
877  int ndof = ha.m_ndof;
878 
879  const Trk::PlaneSurface* pPS = dynamic_cast<const Trk::PlaneSurface*>(&pPRD->detectorElement()->surface());
880 
881  if(pPS==nullptr) continue;
882 
883  const InDet::SiCluster* pCL = dynamic_cast<const InDet::SiCluster*>(pPRD);
884 
886 
887  const Amg::MatrixX& cov = pCL->localCovariance();
888 
890 
891  std::unique_ptr<Trk::MeasurementBase> pRIO{};
892 
893  if(ndof == 2) {
894  const InDet::PixelCluster* pPixel = static_cast<const InDet::PixelCluster*>(pCL);
895  if(pPixel) {
896  pRIO = std::make_unique<InDet::PixelClusterOnTrack>(pPixel, std::move(locPos), Amg::MatrixX(cov),
897  hash, pPixel->globalPosition(), pPixel->gangedPixel());
898  }
899  }
900  else {
901  const InDet::SCT_Cluster* pStrip = static_cast<const InDet::SCT_Cluster*>(pCL);
902  if(pStrip) {
903  pRIO = std::make_unique<InDet::SCT_ClusterOnTrack>(pStrip, std::move(locPos), Amg::MatrixX(cov),
904  hash, pStrip->globalPosition());
905  }
906  }
907 
908  auto pM = AmgSymMatrix(5){};
909 
910  int idx = 0;
911  for(int i=0;i<5;i++) {
912  for(int j=0;j<=i;j++) {
913  pM.fillSymmetric(i,j,ha.m_Ck[idx++]);
914  }
915  }
916 
917  std::unique_ptr<Trk::TrackParameters> pTP = pPS->createUniqueTrackParameters(ha.m_Xk[0], ha.m_Xk[1], ha.m_Xk[2], ha.m_Xk[3], ha.m_Xk[4], pM);
918 
920 
921  Trk::TrackStateOnSurface* pTSS = new Trk::TrackStateOnSurface(FQ, std::move(pRIO), std::move(pTP), nullptr, rioType);
922 
923  pParVec->push_back(pTSS);
924  }
925 
926  auto pFQ = std::make_unique<Trk::FitQuality>(chi2tot, ndoftot);
927 
929 
930  info.setParticleHypothesis(Trk::pion);
931  info.setPatternRecognitionInfo(Trk::TrackInfo::strategyC);
932 
933  Trk::Track* foundTrack = new Trk::Track(info, std::move(pParVec), std::move(pFQ));
934 
935  return foundTrack;
936 }
937 
939 
940  double Re[5];
941 
942  memcpy(&Re[0], &ETS.m_Xk[0], sizeof(Re));
943 
944  double P[8]; //parameters + path
945  double Jm[40];//Jacobian
946 
947  memset(&P[0],0,sizeof(P));
948 
949  const Amg::Transform3D& Trf = ETS.m_pS->transform();
950  double Ax[3] = {Trf(0,0),Trf(1,0),Trf(2,0)}; //loc1-axis in the global frame
951  double Ay[3] = {Trf(0,1),Trf(1,1),Trf(2,1)}; //loc2-axis in the global frame
952 
953  double gP[3];
954  gP[0] = Trf(0,3) + Ax[0]*Re[0] + Ay[0]*Re[1];
955  gP[1] = Trf(1,3) + Ax[1]*Re[0] + Ay[1]*Re[1];
956  gP[2] = Trf(2,3) + Ax[2]*Re[0] + Ay[2]*Re[1];
957 
958  double sinf, cosf;
959  double sint, cost;
960 
961  sincos(Re[2], &sinf, &cosf);
962  sincos(Re[3], &sint, &cost);
963 
964  double gV[3] = {cosf*sint, sinf*sint, cost};
965 
966  memset(&Jm[0],0,sizeof(Jm));
967 
968  //Track state and Jacobian initialization
969 
970  P[6] = Re[4];
971  P[7] = 0.0;
972 
973  for(int i=0;i<3;i++) {
974  P[i] = gP[i];
975  P[i+3] = gV[i];
976  Jm[i] = Ax[i];
977  Jm[7+i] = Ay[i];
978  }
979 
980  Jm[17] =-P[4];//17
981  Jm[18] = P[3];//18
982  Jm[24] = cosf*cost;//24
983  Jm[25] = sinf*cost;//25
984  Jm[26] =-sint;//26
985  Jm[34] = 1.0;//34
986 
987  int code = RungeKutta34(P, Jm, pN, fieldCache, true);
988 
989  if(code!=0) return code;
990 
991  double J[21];
992  memset(&J[0],0,sizeof(J));
993 
994  double BigP[45];
995  memset(&BigP[0],0,sizeof(BigP));
996 
997  for(int i=0;i<7;i++) BigP[i] = P[i];
998  for(int i=0;i<35;i++) BigP[i+7] = Jm[i];
999 
1000  if(pN == nullptr) {//special case: to perigee
1001  Trk::PerigeeSurface perSurf;
1002  Trk::RungeKuttaUtils::transformGlobalToLocal(&perSurf, true, BigP, Re, J);
1003  }
1004  else {//from plane to plane
1005  Trk::RungeKuttaUtils::transformGlobalToLocal(pN, true, BigP, Re, J);
1006  }
1007 
1008  const double* Az = Trf.matrix().col(2).data();
1009 
1010  // z-component of track direction vector in the local c.s.
1011 
1012  double lV = Az[0]*gV[0] + Az[1]*gV[1] + Az[2]*gV[2];
1013 
1014  double xOverX0 = 0.0;
1015 
1017  const InDetDD::SiDetectorElement* pDE = dynamic_cast<const InDetDD::SiDetectorElement*>(ETS.m_pS->associatedDetectorElement());
1018  if(pDE!=nullptr) {
1019  xOverX0 = pDE->design().thickness()/93.7;//Radiation length of silicon according to PDG
1020  }
1021  }
1022  else {
1023  xOverX0 = m_nominalRadLength;
1024  }
1025 
1026  double radLength = xOverX0/std::fabs(lV);
1027 
1028  double sigmaMS = 13.6 * std::fabs(Re[4]) * std::sqrt(radLength) * (1.0 + 0.038 * std::log(radLength));
1029  double s2 = sigmaMS * sigmaMS;
1030  double a = 1.0 / sint;
1031  double a2 = a * a;
1032 
1033  //multiple scattering
1034 
1035  ETS.m_Gk[2][2] += s2 * a2;
1036  ETS.m_Gk[3][3] += s2;
1037  ETS.m_Gk[2][3] += s2 * a;
1038  ETS.m_Gk[3][2] = ETS.m_Gk[2][3];
1039 
1040  //energy loss
1041 
1042  ETS.m_Gk[4][4] += Re[4] * Re[4] * radLength * (0.415 - 0.744 * radLength);
1043 
1044  //Sym. product J*C*J^T
1045 
1046  double Be[5][5];//upper off-diagonal block
1047 
1048  memset(&Be[0][0],0,sizeof(Be));
1049 
1050  for(int i=0;i<4;i++) {
1051  for(int j=0;j<5;j++) {
1052  for(int k=0;k<5;k++) Be[i][j] += J[k+i*5]*ETS.m_Gk[k][j+5];
1053  }
1054  }
1055  for(int j=0;j<5;j++) {
1056  Be[4][j] = ETS.m_Gk[4][j+5];
1057  }
1058 
1059  double JC[5][5];
1060  double Ce[5][5];//"running" diagonal block
1061 
1062  memset(&JC[0][0],0,sizeof(JC));
1063  memset(&Ce[0][0],0,sizeof(Ce));
1064 
1065  for(int i=0;i<4;i++) {
1066  for(int j=0;j<5;j++) {
1067  for(int k=0;k<5;k++) JC[i][j] += J[k+i*5]*ETS.m_Gk[k][j];
1068  }
1069  }
1070  for(int j=0;j<5;j++) {
1071  JC[4][j] = ETS.m_Gk[4][j];
1072  }
1073 
1074  for(int i=0;i<5;i++) {
1075  for(int j=0;j<=i;j++) {
1076  if(j<4) {
1077  for(int k=0;k<5;k++) Ce[i][j] += JC[i][k]*J[k+j*5];
1078  Ce[j][i] = Ce[i][j];
1079  }
1080  else {
1081  Ce[i][4] = Ce[4][i] = JC[i][4];
1082  }
1083  }
1084  }
1085 
1086  //copy back to the state
1087 
1088  ETS.m_pS = pN;//moving forward
1089 
1090  for(int i=0;i<5;i++) {
1091  ETS.m_Xk[i] = Re[i];
1092  for(int j=0;j<5;j++) {
1093  ETS.m_Gk[i][j] = Ce[i][j];
1094  ETS.m_Gk[i][j+5] = Be[i][j];
1095  ETS.m_Gk[j+5][i] = Be[i][j];
1096  }
1097  }
1098  return 0;
1099 }
1100 
1102 
1103  const double C = 299.9975;
1104  const double minStep = 100.0;
1105  const double bound_tol = 0.2;
1106 
1107  double Re[5];
1108 
1109  memcpy(&Re[0], &Rk[0], sizeof(Re));
1110 
1111  const Amg::Transform3D& Trf = pS->transform();
1112 
1113  double Ax[3] = {Trf(0,0),Trf(1,0),Trf(2,0)}; //loc1-axis in the global frame
1114 
1115  double Ay[3] = {Trf(0,1),Trf(1,1),Trf(2,1)}; //loc2-axis in the global frame
1116 
1117  double gP[3];
1118 
1119  gP[0] = Trf(0,3) + Ax[0]*Re[0] + Ay[0]*Re[1];
1120  gP[1] = Trf(1,3) + Ax[1]*Re[0] + Ay[1]*Re[1];
1121  gP[2] = Trf(2,3) + Ax[2]*Re[0] + Ay[2]*Re[1];
1122 
1123  double sinf, cosf;
1124  double sint, cost;
1125 
1126  sincos(Re[2], &sinf, &cosf);
1127  sincos(Re[3], &sint, &cost);
1128 
1129  double gV[3] = {cosf*sint, sinf*sint, cost};
1130 
1131  const Amg::Vector3D& normal = pN->normal();
1132  const Amg::Vector3D& center = pN->center();
1133 
1134  double D[4] = {normal[0], normal[1], normal[2], 0.0};
1135 
1136  for(int i=0;i<3;i++) D[3] += -normal[i]*center[i];
1137 
1138  double CQ = C*Re[4];
1139 
1140  double gB[3];
1141 
1142  fieldCache.getField(gP, gB);
1143 
1144  double c = D[0]*gP[0] + D[1]*gP[1] + D[2]*gP[2] + D[3];
1145  double b = D[0]*gV[0] + D[1]*gV[1] + D[2]*gV[2];
1146  double a = 0.5*CQ*(gB[0]*(D[1]*gV[2]-D[2]*gV[1]) + gB[1]*(D[2]*gV[0]-D[0]*gV[2]) + gB[2]*(D[0]*gV[1]-D[1]*gV[0]));
1147 
1148  double ratio = 4*a*c/(b*b);
1149 
1150  bool useExpansion = std::fabs(ratio)<0.1;
1151 
1152  double sl = 0.0;
1153 
1154  if(useExpansion) {
1155  sl = -c/b;
1156  sl = sl*(1-a*sl/b);
1157  }
1158  else {
1159 
1160  double discr = b*b-4.0*a*c;
1161 
1162  if(discr<0.0) {
1163  return false;
1164  }
1165 
1166  int signb = (b<0.0)?-1:1;
1167  sl = (-b + signb*std::sqrt(discr))/(2*a);
1168  }
1169 
1170  int nStepMax = 1;
1171 
1172  if(std::fabs(sl)>=minStep) {
1173  nStepMax = (int)(std::fabs(sl)/minStep)+1;
1174  }
1175 
1176  if((nStepMax<0)||(nStepMax>100)) {
1177  return false;
1178  }
1179 
1180  double Av = sl*CQ;
1181  double Ac = 0.5*sl*Av;
1182  double DVx = gV[1]*gB[2] - gV[2]*gB[1];
1183  double DVy = gV[2]*gB[0] - gV[0]*gB[2];
1184  double DVz = gV[0]*gB[1] - gV[1]*gB[0];
1185 
1186  double E[3] = {gP[0]+gV[0]*sl+Ac*DVx, gP[1]+gV[1]*sl+Ac*DVy, gP[2]+gV[2]*sl+Ac*DVz};
1187 
1188  if(nStepMax == 1) {
1189  for(int i=0;i<3;i++) gP[i] = E[i];
1190  }
1191  else {
1192  double gBe[3];
1193 
1194  fieldCache.getField(E, gBe);
1195 
1196  double inv_step = 1/sl;
1197 
1198  double dBds[3] = {inv_step*(gBe[0]-gB[0]),inv_step*(gBe[1]-gB[1]),inv_step*(gBe[2]-gB[2])};
1199 
1200  int nStep = nStepMax;
1201 
1202  while(nStep > 0) {
1203 
1204  c = D[0]*gP[0] + D[1]*gP[1] + D[2]*gP[2] + D[3];
1205  b = D[0]*gV[0] + D[1]*gV[1] + D[2]*gV[2];
1206  a = 0.5*CQ*(gB[0]*(D[1]*gV[2]-D[2]*gV[1])+gB[1]*(D[2]*gV[0]-D[0]*gV[2])+gB[2]*(D[0]*gV[1]-D[1]*gV[0]));
1207 
1208  ratio = 4*a*c/(b*b);
1209  useExpansion = std::fabs(ratio) < 0.1;
1210 
1211  if(useExpansion) {
1212  sl = -c/b;
1213  sl = sl*(1-a*sl/b);
1214  }
1215  else {
1216  double discr=b*b-4.0*a*c;
1217  if(discr<0.0) {
1218  return false;
1219  }
1220  int signb = (b<0.0)?-1:1;
1221  sl = (-b+signb*std::sqrt(discr))/(2*a);
1222  }
1223 
1224  double ds = sl/nStep;
1225  Av = ds*CQ;
1226  Ac = 0.5*ds*Av;
1227 
1228  DVx = gV[1]*gB[2] - gV[2]*gB[1];
1229  DVy = gV[2]*gB[0] - gV[0]*gB[2];
1230  DVz = gV[0]*gB[1] - gV[1]*gB[0];
1231 
1232  E[0] = gP[0] + gV[0]*ds + Ac*DVx;
1233  E[1] = gP[1] + gV[1]*ds + Ac*DVy;
1234  E[2] = gP[2] + gV[2]*ds + Ac*DVz;
1235 
1236  double V[3];
1237 
1238  V[0] = gV[0] + Av*DVx;
1239  V[1] = gV[1] + Av*DVy;
1240  V[2] = gV[2] + Av*DVz;
1241 
1242  for(int i=0;i<3;i++) {
1243  gV[i] = V[i];gP[i] = E[i];
1244  }
1245 
1246  for(int i=0;i<3;i++) gB[i] += dBds[i]*ds;//field interpolation
1247 
1248  nStep--;
1249  }
1250  }
1251 
1252  //global to local
1253 
1254  const Amg::Transform3D& Trf2 = pN->transform();
1255 
1256  const double* Ax2 = Trf2.matrix().col(0).data();
1257  const double* Ay2 = Trf2.matrix().col(1).data();
1258 
1259  const double d[3] = { gP[0] - Trf2(0, 3), gP[1] - Trf2(1, 3), gP[2] - Trf2(2, 3) };
1260 
1261  double locX = d[0] * Ax2[0] + d[1] * Ax2[1] + d[2] * Ax2[2];
1262  double locY = d[0] * Ay2[0] + d[1] * Ay2[1] + d[2] * Ay2[2];
1263 
1264  const InDetDD::SiDetectorElement* pDE = dynamic_cast<const InDetDD::SiDetectorElement*>(pN->associatedDetectorElement());
1265  if(!pDE) return false;
1266 
1267  InDetDD::SiIntersect intersection = pDE->inDetector(Amg::Vector2D(locX, locY), bound_tol, bound_tol);
1268 
1269  if (intersection.out()) return false;
1270 
1271  return true;
1272 
1273 }
1274 
1275 double TrigInDetTrackFollowingTool::estimateRK_Step(const Trk::PlaneSurface* pN, double const * P) const {
1276 
1277  double Step = 1e8;
1278 
1279  if(pN == nullptr) { //step to perigee "surface" assuming the global c.s. origin at (0,0)
1280 
1281  Step = -(P[0]*P[3] + P[1]*P[4])/(1 - P[5]*P[5]);
1282  return Step;
1283  }
1284 
1285  const Amg::Vector3D& normal = pN->normal();
1286  const Amg::Vector3D& center = pN->center();
1287 
1288  double D = 0.0;// -(r0,n)
1289 
1290  for(int i=0;i<3;i++) D += -normal[i]*center[i];
1291 
1292  double Sum = D;
1293  double a = 0.0;
1294 
1295  for(int i=0;i<3;i++) {
1296  a += normal[i]*P[i+3];
1297  Sum += normal[i]*P[i];
1298  }
1299  if(a==0.0) return Step;
1300 
1301  Step = -Sum/a;
1302 
1303  return Step;
1304 }
1305 
1306 int TrigInDetTrackFollowingTool::RungeKutta34(double* P, double* J, const Trk::PlaneSurface* pN, MagField::AtlasFieldCache& fieldCache, bool withJacobian) const {
1307 
1308  const double coeff = 299.7;
1309  const double min_step = 3.0;
1310  const double const_field_step = 30.0;
1311  const double maxPath = 3000.0;
1312  const double minQp = 0.01; //100 MeV cut
1313  const double minRad = 300.0;
1314 
1315  const int maxIter = 10;
1316 
1317  double exStep = 0.0;
1318 
1319  if(std::fabs(P[6]) > minQp) return -1;
1320 
1321  double Step = estimateRK_Step(pN, P);
1322 
1323  if(Step > 1e7) return -2;
1324 
1325  double absStep = fabs(Step);
1326 
1327  if(absStep <= min_step) {
1328  for(int i=0;i<3;i++) P[i] += Step*P[i+3];
1329  P[7] += Step;
1330  return 0;
1331  }
1332 
1333  if(fabs(P[6]*Step) > minRad) {
1334  Step = (Step > 0.0 ? minRad : -minRad)/fabs(P[6]);
1335  }
1336 
1337  int nFlips = 0;
1338 
1339  double mom = P[6];
1340 
1341  double Y[6];
1342 
1343  memcpy(&Y[0], P, sizeof(Y));
1344 
1345  double B[3];
1346 
1347  fieldCache.getField(Y, B);
1348 
1349  for(int i=0;i<3;i++) B[i] *= coeff;
1350 
1351  if(exStep != 0) {
1352  if(absStep > fabs(exStep))
1353  Step = exStep;
1354  }
1355 
1356  for(int iter=0;iter<maxIter;iter++) {//solving single-value boundary problem
1357 
1358  bool useConstField = fabs(Step) < const_field_step;
1359 
1360  if(!useConstField) {
1361  fieldCache.getField(Y, B);
1362  for(int i=0;i<3;i++) B[i] *= coeff;
1363  }
1364 
1365  double B2[3], B3[3];
1366 
1367  double H = Step;
1368  double H3 = H/3;
1369  double H23 = 2*H3;
1370  double H4 = 0.25*H;
1371  double H34 = 3*H4;
1372 
1373  double H3mom = mom*H3;
1374  double H23mom = mom*H23;
1375  double H4mom = mom*H4;
1376  double H34mom = mom*H34;
1377 
1378  double YB[3];
1379 
1380  crossProduct(B, Y+3, YB);
1381 
1382  //second point
1383 
1384  double Y2[6];
1385 
1386  for(int i=0;i<3;i++) Y2[i] = Y[i] + H3*Y[i+3];
1387  for(int i=3;i<6;i++) Y2[i] = Y[i] + H3mom*YB[i-3];
1388 
1389  double YB2[3];
1390 
1391  if(useConstField) {
1392  crossProduct(B, Y2+3, YB2);
1393  }
1394  else {
1395  fieldCache.getField(Y2, B2);
1396  for(int i=0;i<3;i++) B2[i] *= coeff;
1397  crossProduct(B2, Y2+3, YB2);
1398  }
1399 
1400  //last point
1401 
1402  double Y3[6];
1403 
1404  for(int i=0;i<3;i++) Y3[i] = Y[i] + H23*Y2[i+3];
1405  for(int i=3;i<6;i++) Y3[i] = Y[i] + H23mom*YB2[i-3];
1406 
1407  double YB3[3];
1408 
1409  if(useConstField) {
1410  crossProduct(B, Y3+3, YB3);
1411  }
1412  else {
1413  fieldCache.getField(Y3, B3);
1414  for(int i=0;i<3;i++) B3[i] *= coeff;
1415  crossProduct(B3, Y3+3, YB3);
1416  }
1417 
1418  double Y1[6];
1419 
1420  for(int i=3;i<6;i++) Y1[i-3] = Y[i-3] + H4*(Y[i] + 3*Y3[i]);
1421  for(int i=0;i<3;i++) Y1[i+3] = Y[i+3] + H4mom*(YB[i] + 3*YB3[i]);
1422 
1423  if(fabs(Y1[5])>1) return -10;
1424 
1425  //Jacobian calculations go here ...
1426 
1427  if(withJacobian) {
1428 
1429  double J1C[9], L2C[9], J2C[9], L3C[9], J3C[9];
1430 
1431  double CqB3H34[3];
1432  double CqB2H23[3];
1433  double CqBH3[3];
1434 
1435  if(!useConstField) {
1436  for(int i=0;i<3;i++) CqBH3[i] = H3mom*B[i];
1437  for(int i=0;i<3;i++) CqB2H23[i] = H23mom*B2[i];
1438  for(int i=0;i<3;i++) CqB3H34[i] = H34mom*B3[i];
1439  }
1440  else {
1441  for(int i=0;i<3;i++) CqBH3[i] = H3mom*B[i];
1442  for(int i=0;i<3;i++) CqB2H23[i] = H23mom*B[i];
1443  for(int i=0;i<3;i++) CqB3H34[i] = H34mom*B[i];
1444  }
1445 
1446  crossProduct(CqBH3, J+17, J1C);
1447  crossProduct(CqBH3, J+24, J1C+3);
1448  crossProduct(CqBH3, J+31, J1C+6);
1449 
1450  J1C[6] += H3*YB[0];
1451  J1C[7] += H3*YB[1];
1452  J1C[8] += H3*YB[2];
1453 
1454  L2C[0] = J[17] + J1C[0];
1455  L2C[1] = J[18] + J1C[1];
1456  L2C[2] = J[19] + J1C[2];
1457 
1458  L2C[3] = J[24] + J1C[3];
1459  L2C[4] = J[25] + J1C[4];
1460  L2C[5] = J[26] + J1C[5];
1461 
1462  L2C[6] = J[31] + J1C[6];
1463  L2C[7] = J[32] + J1C[7];
1464  L2C[8] = J[33] + J1C[8];
1465 
1466  crossProduct(CqB2H23, L2C, J2C);
1467  crossProduct(CqB2H23, L2C+3, J2C+3);
1468  crossProduct(CqB2H23, L2C+6, J2C+6);
1469 
1470  J2C[6] += H23*YB2[0];
1471  J2C[7] += H23*YB2[1];
1472  J2C[8] += H23*YB2[2];
1473 
1474  L3C[0] = J[17] + J2C[0];
1475  L3C[1] = J[18] + J2C[1];
1476  L3C[2] = J[19] + J2C[2];
1477 
1478  L3C[3] = J[24] + J2C[3];
1479  L3C[4] = J[25] + J2C[4];
1480  L3C[5] = J[26] + J2C[5];
1481 
1482  L3C[6] = J[31] + J2C[6];
1483  L3C[7] = J[32] + J2C[7];
1484  L3C[8] = J[33] + J2C[8];
1485 
1486  crossProduct(CqB3H34, L3C, J3C);
1487  crossProduct(CqB3H34, L3C+3, J3C+3);
1488  crossProduct(CqB3H34, L3C+6, J3C+6);
1489 
1490  J3C[6] += H34*YB3[0];
1491  J3C[7] += H34*YB3[1];
1492  J3C[8] += H34*YB3[2];
1493 
1494  for(int i=0;i<9;i++) J1C[i] = 0.75*J1C[i] + J3C[i];
1495 
1496  for(int i=0;i<9;i++) J2C[i] *= H34;
1497 
1498  J[14] += H*J[17];
1499  J[15] += H*J[18];
1500  J[16] += H*J[19];
1501 
1502  J[21] += H*J[24];
1503  J[22] += H*J[25];
1504  J[23] += H*J[26];
1505 
1506  J[28] += H*J[31];
1507  J[29] += H*J[32];
1508  J[30] += H*J[33];
1509 
1510  J[14] += J2C[0];
1511  J[15] += J2C[1];
1512  J[16] += J2C[2];
1513 
1514  J[21] += J2C[3];
1515  J[22] += J2C[4];
1516  J[23] += J2C[5];
1517 
1518  J[28] += J2C[6];
1519  J[29] += J2C[7];
1520  J[30] += J2C[8];
1521 
1522  J[17] += J1C[0];
1523  J[18] += J1C[1];
1524  J[19] += J1C[2];
1525 
1526  J[24] += J1C[3];
1527  J[25] += J1C[4];
1528  J[26] += J1C[5];
1529 
1530  J[31] += J1C[6];
1531  J[32] += J1C[7];
1532  J[33] += J1C[8];
1533 
1534  }
1535 
1536  P[7] += Step;
1537 
1538  if(fabs(P[7]) > maxPath) return -3;
1539 
1540  double norm = 1/std::sqrt(Y1[3]*Y1[3]+Y1[4]*Y1[4]+Y1[5]*Y1[5]);
1541 
1542  Y1[3] *= norm; Y1[4] *= norm; Y1[5] *= norm;
1543 
1544  double newStep = estimateRK_Step(pN, Y1);
1545 
1546  if(newStep > 1e7) return -4;
1547 
1548  double absNewStep = fabs(newStep);
1549 
1550  if(absNewStep <= min_step) {//the boundary is too close, using straight line
1551 
1552  if(withJacobian) {
1553  if(!useConstField) {
1554  crossProduct(B3, Y1+3, J+35);
1555  }
1556  else {
1557  crossProduct(B, Y1+3, J+35);
1558  }
1559  }
1560 
1561  for(int i=0;i<3;i++) {
1562  P[i+3] = Y1[i+3];
1563  P[i] = Y1[i] + newStep*Y1[i+3];
1564  }
1565  P[7] += newStep;
1566 
1567  return 0;
1568  }
1569 
1570  double absStep = fabs(Step);
1571 
1572  if(Step*newStep < 0.0) {//the boundary is overshot
1573  if(++nFlips > 2) return -5;//oscillations
1574  Step = absNewStep < absStep ? newStep : -Step;
1575  }
1576  else {
1577  if(absNewStep < absStep) Step = newStep;
1578  }
1579 
1580  for(int i=0;i<6;i++) Y[i] = Y1[i];
1581  }
1582 
1583  return -11;//max. number of iteration reached
1584 
1585 }
1586 
1587 void TrigInDetTrackFollowingTool::crossProduct(double const * B, double const * V, double* A) const {
1588  A[0] = -B[1]*V[2] + B[2]*V[1];
1589  A[1] = B[0]*V[2] - B[2]*V[0];
1590  A[2] = -B[0]*V[1] + B[1]*V[0];
1591 }
grepfile.info
info
Definition: grepfile.py:38
Trk::SpacePoint::clusterList
const std::pair< const PrepRawData *, const PrepRawData * > & clusterList() const
return the pair of cluster pointers by reference
Definition: Tracking/TrkEvent/TrkSpacePoint/TrkSpacePoint/SpacePoint.h:127
TrigInDetTrackFollowingTool::finalize
virtual StatusCode finalize()
Definition: TrigInDetTrackFollowingTool.cxx:181
LArNewCalib_Delay_OFC_Cali.Gain
Gain
Definition: LArNewCalib_Delay_OFC_Cali.py:81
Trk::SpacePoint
Definition: Tracking/TrkEvent/TrkSpacePoint/TrkSpacePoint/SpacePoint.h:35
IDTPM::ndof
float ndof(const U &p)
Definition: TrackParametersHelper.h:142
Trk::LocalParameters
Definition: LocalParameters.h:98
SCT_ClusterOnTrack.h
cost
int cost(std::vector< std::string > &files, node &n, const std::string &directory="", bool deleteref=false, bool relocate=false)
Definition: hcg.cxx:921
plotBeamSpotCompare.x1
x1
Definition: plotBeamSpotCompare.py:216
Trk::TrackInfo
Contains information about the 'fitter' of this track.
Definition: Tracking/TrkEvent/TrkTrack/TrkTrack/TrackInfo.h:32
Trk::TrackStateOnSurface::Perigee
@ Perigee
This represents a perigee, and so will contain a Perigee object only.
Definition: TrackStateOnSurface.h:117
PlotCalibFromCool.norm
norm
Definition: PlotCalibFromCool.py:100
checkxAOD.ds
ds
Definition: Tools/PyUtils/bin/checkxAOD.py:257
ITrigInDetTrackFollowingTool.h
TrigFTF_ExtendedTrackState::m_pS
const Trk::PlaneSurface * m_pS
Definition: TrigInDetTrackFollowingTool.h:70
Amg::MatrixX
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Dynamic Matrix - dynamic allocation.
Definition: EventPrimitives.h:29
Trk::Surface::associatedDetectorElement
const TrkDetElementBase * associatedDetectorElement() const
return associated Detector Element
python.SystemOfUnits.m
int m
Definition: SystemOfUnits.py:91
InDetDD::DetectorDesign::thickness
double thickness() const
Method which returns thickness of the silicon wafer.
Definition: DetectorDesign.h:271
python.PerfMonSerializer.p
def p
Definition: PerfMonSerializer.py:743
athena.path
path
python interpreter configuration --------------------------------------—
Definition: athena.py:126
TrackParameters.h
AthCheckMacros.h
SG::ReadCondHandle
Definition: ReadCondHandle.h:44
keylayer_zslicemap.pb
pb
Definition: keylayer_zslicemap.py:188
Trk::locX
@ locX
Definition: ParamDefs.h:43
AthMsgStreamMacros.h
Trk::locY
@ locY
local cartesian
Definition: ParamDefs.h:44
Surface.h
Trk::Track
The ATLAS Track class.
Definition: Tracking/TrkEvent/TrkTrack/TrkTrack/Track.h:73
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
TrigFTF_ExtendedTrackState::SwapTheEnds
void SwapTheEnds()
Definition: TrigInDetTrackFollowingTool.cxx:106
Trk::SpacePoint::globalPosition
virtual const Amg::Vector3D & globalPosition() const override final
Interface method to get the global Position.
Definition: Tracking/TrkEvent/TrkSpacePoint/TrkSpacePoint/SpacePoint.h:146
InDetDD::SolidStateDetectorElementBase::inDetector
SiIntersect inDetector(const Amg::Vector2D &localPosition, double phiTol, double etaTol) const
Test that it is in the active region.
Definition: SolidStateDetectorElementBase.cxx:204
Trk::PerigeeSurface
Definition: PerigeeSurface.h:43
AtlasFieldCacheCondObj.h
Amg::Vector2D
Eigen::Matrix< double, 2, 1 > Vector2D
Definition: GeoPrimitives.h:48
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:70
TrigFTF_ExtendedTrackState::m_nClusters
int m_nClusters
Definition: TrigInDetTrackFollowingTool.h:75
hist_file_dump.d
d
Definition: hist_file_dump.py:137
InDetDD::DetectorDesign::shape
virtual DetectorShape shape() const
Shape of element.
Definition: DetectorDesign.cxx:96
InDetAccessor::phi0
@ phi0
Definition: InDetAccessor.h:33
theta
Scalar theta() const
theta method
Definition: AmgMatrixBasePlugin.h:71
conifer::pow
constexpr int pow(int x)
Definition: conifer.h:20
TrigInDetTrackFollowingTool::m_useDetectorThickness
Gaudi::Property< bool > m_useDetectorThickness
Definition: TrigInDetTrackFollowingTool.h:116
DMTest::C
C_v1 C
Definition: C.h:26
xAOD::JetInput::Track
@ Track
Definition: JetContainerInfo.h:61
Trk::PrepRawData::localCovariance
const Amg::MatrixX & localCovariance() const
return const ref to the error matrix
plotBeamSpotVxVal.cov
cov
Definition: plotBeamSpotVxVal.py:201
test_pyathena.pt
pt
Definition: test_pyathena.py:11
TrigInDetTrackFollowingTool::m_useHitErrors
Gaudi::Property< bool > m_useHitErrors
Definition: TrigInDetTrackFollowingTool.h:115
M_PI
#define M_PI
Definition: ActiveFraction.h:11
TrigInDetTrackFollowingTool::crossProduct
void crossProduct(double const *, double const *, double *) const
Definition: TrigInDetTrackFollowingTool.cxx:1587
InDetDD::SolidStateDetectorElementBase::surface
Trk::Surface & surface()
Element Surface.
PixelModuleFeMask_create_db.nModules
nModules
Definition: PixelModuleFeMask_create_db.py:47
InDet::SCT_ClusterContainer
Trk::PrepRawDataContainer< SCT_ClusterCollection > SCT_ClusterContainer
Definition: SCT_ClusterContainer.h:27
FitQualityOnSurface.h
TrigInDetTrackFollowingTool::RungeKutta34
int RungeKutta34(double *, double *, const Trk::PlaneSurface *, MagField::AtlasFieldCache &, bool) const
Definition: TrigInDetTrackFollowingTool.cxx:1306
python.TurnDataReader.dr
dr
Definition: TurnDataReader.py:112
InDet::PixelClusterContainer
Trk::PrepRawDataContainer< PixelClusterCollection > PixelClusterContainer
Definition: InnerDetector/InDetRecEvent/InDetPrepRawData/InDetPrepRawData/PixelClusterContainer.h:28
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
SG::VarHandleKey::key
const std::string & key() const
Return the StoreGate ID for the referenced object.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:141
InDetAccessor::qOverP
@ qOverP
perigee
Definition: InDetAccessor.h:35
Trk::Surface::center
const Amg::Vector3D & center() const
Returns the center position of the Surface.
TrigInDetTrackFollowingTool::m_sctcontainerkey
SG::ReadHandleKey< InDet::SCT_ClusterContainer > m_sctcontainerkey
Definition: TrigInDetTrackFollowingTool.h:121
LArG4AODNtuplePlotter.pe
pe
Definition: LArG4AODNtuplePlotter.py:116
intersection
std::vector< std::string > intersection(std::vector< std::string > &v1, std::vector< std::string > &v2)
Definition: compareFlatTrees.cxx:25
AmgSymMatrix
#define AmgSymMatrix(dim)
Definition: EventPrimitives.h:52
PrepRawData.h
InDetDD::SolidStateDetectorElementBase::identifyHash
virtual IdentifierHash identifyHash() const override final
identifier hash (inline)
LArGeo::Fx
GeoGenfun::FunctionNoop Fx(double r, GeoGenfun::GENFUNCTION G, const double Cenx[], const double Ceny[])
Definition: BarrelAuxFunctions.cxx:16
Trk::RungeKuttaUtils::transformGlobalToLocal
void transformGlobalToLocal(double *ATH_RESTRICT, double *ATH_RESTRICT)
drawFromPickle.atan
atan
Definition: drawFromPickle.py:36
TrigFTF_ExtendedTrackState::AddHit
void AddHit(const Trk::PrepRawData *, double, int)
Definition: TrigInDetTrackFollowingTool.cxx:83
Track.h
dqt_zlumi_alleff_HIST.A
A
Definition: dqt_zlumi_alleff_HIST.py:110
TrigFTF_ExtendedTrackState::AddHole
void AddHole()
Definition: TrigInDetTrackFollowingTool.cxx:61
Trk::FitQualityOnSurface
Definition: FitQualityOnSurface.h:19
TrigInDetTrackFollowingTool::processHit
double processHit(const InDet::PixelCluster *, double *, double *, const TrigFTF_ExtendedTrackState &) const
Definition: TrigInDetTrackFollowingTool.cxx:186
H
#define H(x, y, z)
Definition: MD5.cxx:114
ParticleGun_EoverP_Config.mom
mom
Definition: ParticleGun_EoverP_Config.py:63
TrigInDetTrackFollowingTool.h
python.changerun.m1
m1
Definition: changerun.py:32
Trk::TrackInfo::strategyC
@ strategyC
Definition: Tracking/TrkEvent/TrkTrack/TrkTrack/TrackInfo.h:246
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
TrigFTF_ExtendedTrackState::m_isSwapped
bool m_isSwapped
Definition: TrigInDetTrackFollowingTool.h:78
TrigFTF_ExtendedTrackState::m_Xk
double m_Xk[10]
Definition: TrigInDetTrackFollowingTool.h:65
lumiFormat.i
int i
Definition: lumiFormat.py:92
beamspotman.n
n
Definition: beamspotman.py:731
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
SpacePoint.h
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
TrigFTF_ExtendedTrackState
Definition: TrigInDetTrackFollowingTool.h:51
TrigFTF_ExtendedTrackState::m_ndof
double m_ndof
Definition: TrigInDetTrackFollowingTool.h:68
Trk::pion
@ pion
Definition: ParticleHypothesis.h:29
Amg::Transform3D
Eigen::Affine3d Transform3D
Definition: GeoPrimitives.h:46
TRT::Track::d0
@ d0
Definition: InnerDetector/InDetCalibEvent/TRT_CalibData/TRT_CalibData/TrackInfo.h:62
Trk::TrkDetElementBase::surface
virtual const Surface & surface() const =0
Return surface associated with this detector element.
Trk::Surface::normal
virtual const Amg::Vector3D & normal() const
Returns the normal vector of the Surface (i.e.
TrigInDetTrackFollowingTool::fitTheSeed
std::unique_ptr< TrigFTF_ExtendedTrackState > fitTheSeed(const std::vector< const Trk::SpacePoint * > &, MagField::AtlasFieldCache &) const
Definition: TrigInDetTrackFollowingTool.cxx:405
TrigFTF_ExtendedTrackState::m_pO
const Trk::PlaneSurface * m_pO
Definition: TrigInDetTrackFollowingTool.h:71
TrigFTF_ExtendedTrackState::m_Gk
double m_Gk[10][10]
Definition: TrigInDetTrackFollowingTool.h:66
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
SG::VarHandleKey::initialize
StatusCode initialize(bool used=true)
If this object is used as a property, then this should be called during the initialize phase.
Definition: AthToolSupport/AsgDataHandles/Root/VarHandleKey.cxx:103
TRT::Track::z0
@ z0
Definition: InnerDetector/InDetCalibEvent/TRT_CalibData/TRT_CalibData/TrackInfo.h:63
InDet::SCT_Cluster
Definition: InnerDetector/InDetRecEvent/InDetPrepRawData/InDetPrepRawData/SCT_Cluster.h:34
ParticleHypothesis.h
WriteCalibToCool.swap
swap
Definition: WriteCalibToCool.py:94
TrigFTF_ExtendedTrackState::report
void report() const
Definition: TrigInDetTrackFollowingTool.cxx:135
SG::ReadHandle::isValid
virtual bool isValid() override final
Can the handle be successfully dereferenced?
TrigInDetTrackFollowingTool::m_nHolesMax
Gaudi::Property< int > m_nHolesMax
Definition: TrigInDetTrackFollowingTool.h:112
TrigInDetTrackFollowingTool::m_fieldCondObjInputKey
SG::ReadCondHandleKey< AtlasFieldCacheCondObj > m_fieldCondObjInputKey
Definition: TrigInDetTrackFollowingTool.h:119
TrigInDetTrackFollowingTool::TrigInDetTrackFollowingTool
TrigInDetTrackFollowingTool(const std::string &, const std::string &, const IInterface *)
Definition: TrigInDetTrackFollowingTool.cxx:165
TrigInDetTrackFollowingTool::estimateRK_Step
double estimateRK_Step(const Trk::PlaneSurface *, double const *) const
Definition: TrigInDetTrackFollowingTool.cxx:1275
InDetDD::SiDetectorElement::isPixel
bool isPixel() const
Trk::PrepRawData
Definition: PrepRawData.h:62
Monitored::Y
@ Y
Definition: HistogramFillerUtils.h:24
TrigInDetTrackFollowingTool::checkIntersection
bool checkIntersection(double const *, const Trk::PlaneSurface *, const Trk::PlaneSurface *, MagField::AtlasFieldCache &) const
Definition: TrigInDetTrackFollowingTool.cxx:1101
TrigFTF_ExtendedTrackState::correctAngles
void correctAngles()
Definition: TrigInDetTrackFollowingTool.cxx:71
pmontree.code
code
Definition: pmontree.py:443
InDet::SiCluster::gangedPixel
bool gangedPixel() const
return the flag of this cluster containing a gangedPixel
Trk::TrackStateOnSurface
represents the track state (measurement, material, fit parameters and quality) at a surface.
Definition: TrackStateOnSurface.h:71
Trk::PlaneSurface::createUniqueTrackParameters
virtual Surface::ChargedTrackParametersUniquePtr createUniqueTrackParameters(double l1, double l2, double phi, double theta, double qop, std::optional< AmgSymMatrix(5)> cov=std::nullopt) const override final
Use the Surface as a ParametersBase constructor, from local parameters - charged.
Definition: PlaneSurface.cxx:149
TrackInfo.h
RIO_OnTrack.h
VP1PartSpect::E
@ E
Definition: VP1PartSpectFlags.h:21
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:77
TrigInDetTrackFollowingTool::m_maxChi2Dist_Strips
Gaudi::Property< double > m_maxChi2Dist_Strips
Definition: TrigInDetTrackFollowingTool.h:114
Trk::PrepRawData::localPosition
const Amg::Vector2D & localPosition() const
return the local position reference
InDetDD::SiDetectorElement
Definition: SiDetectorElement.h:109
SG::CondHandleKey::initialize
StatusCode initialize(bool used=true)
dqt_zlumi_alleff_HIST.B
B
Definition: dqt_zlumi_alleff_HIST.py:110
TrigInDetTrackFollowingTool::getTrack
virtual Trk::Track * getTrack(const std::vector< const Trk::SpacePoint * > &, const std::vector< const InDetDD::SiDetectorElement * > &, const EventContext &) const
Definition: TrigInDetTrackFollowingTool.cxx:593
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
ParticleGun_SamplingFraction.radius
radius
Definition: ParticleGun_SamplingFraction.py:96
TrigInDetTrackFollowingTool::m_nominalRadLength
Gaudi::Property< double > m_nominalRadLength
Definition: TrigInDetTrackFollowingTool.h:117
TrigFTF_ExtendedTrackState::m_chi2
double m_chi2
Definition: TrigInDetTrackFollowingTool.h:67
InDetDD::SiIntersect
Definition: SiIntersect.h:23
SG::ReadHandle::ptr
const_pointer_type ptr()
Dereference the pointer.
InDet::PixelCluster
Definition: InnerDetector/InDetRecEvent/InDetPrepRawData/InDetPrepRawData/PixelCluster.h:49
makeTRTBarrelCans.dy
tuple dy
Definition: makeTRTBarrelCans.py:21
InDet::SiCluster::globalPosition
const Amg::Vector3D & globalPosition() const
return global position reference
LArGeo::Fy
GeoGenfun::FunctionNoop Fy(double r, GeoGenfun::GENFUNCTION G, const double Cenx[], const double Ceny[])
Definition: BarrelAuxFunctions.cxx:25
InDet::SiCluster::width
const InDet::SiWidth & width() const
return width class reference
TrigInDetTrackFollowingTool::m_maxChi2Dist_Pixels
Gaudi::Property< double > m_maxChi2Dist_Pixels
Definition: TrigInDetTrackFollowingTool.h:113
DiTauMassTools::MaxHistStrategyV2::e
e
Definition: PhysicsAnalysis/TauID/DiTauMassTools/DiTauMassTools/HelperFunctions.h:26
a
TList * a
Definition: liststreamerinfos.cxx:10
Trk::PerigeeSurface::createUniqueTrackParameters
virtual Surface::ChargedTrackParametersUniquePtr createUniqueTrackParameters(double l1, double l2, double phi, double theta, double qop, std::optional< AmgSymMatrix(5)> cov=std::nullopt) const override final
Use the Surface as a ParametersBase constructor, from local parameters - charged.
Definition: PerigeeSurface.cxx:98
python.compareTCTs.ratio
ratio
Definition: compareTCTs.py:295
CaloCondBlobAlgs_fillNoiseFromASCII.hash
dictionary hash
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:109
BindingsTest.ha
ha
Definition: BindingsTest.py:22
Trk::PlaneSurface
Definition: PlaneSurface.h:64
RungeKuttaUtils.h
TrigInDetTrackFollowingTool::updateTrackState
const Trk::PrepRawData * updateTrackState(const InDet::PixelCluster *, const InDet::PixelClusterCollection *, TrigFTF_ExtendedTrackState &) const
Definition: TrigInDetTrackFollowingTool.cxx:261
ReadCellNoiseFromCoolCompare.s2
s2
Definition: ReadCellNoiseFromCoolCompare.py:379
makeTRTBarrelCans.dx
tuple dx
Definition: makeTRTBarrelCans.py:20
MagField::AtlasFieldCache
Local cache for magnetic field (based on MagFieldServices/AtlasFieldSvcTLS.h)
Definition: AtlasFieldCache.h:43
python.CaloCondTools.log
log
Definition: CaloCondTools.py:20
TrigFTF_ExtendedTrackState::m_track
std::list< TrigFTF_HitAssignment > m_track
Definition: TrigInDetTrackFollowingTool.h:73
LArNewCalib_DelayDump_OFC_Cali.idx
idx
Definition: LArNewCalib_DelayDump_OFC_Cali.py:69
Trk::TrackStateOnSurface::Scatterer
@ Scatterer
This represents a scattering point on the track, and so will contain TrackParameters and MaterialEffe...
Definition: TrackStateOnSurface.h:113
TrigFTF_ExtendedTrackState::m_nHoles
int m_nHoles
Definition: TrigInDetTrackFollowingTool.h:76
MagField::AtlasFieldCache::getField
void getField(const double *ATH_RESTRICT xyz, double *ATH_RESTRICT bxyz, double *ATH_RESTRICT deriv=nullptr)
get B field value at given position xyz[3] is in mm, bxyz[3] is in kT if deriv[9] is given,...
Definition: AtlasFieldCache.cxx:42
Trk::TrkDetElementBase::identifyHash
virtual IdentifierHash identifyHash() const =0
Identifier hash.
InDetDD::Box
@ Box
Definition: DetectorDesign.h:42
InDet::SiWidth::phiR
double phiR() const
Definition: SiWidth.h:126
drawFromPickle.sin
sin
Definition: drawFromPickle.py:36
TrigInDetTrackFollowingTool::m_pixcontainerkey
SG::ReadHandleKey< InDet::PixelClusterContainer > m_pixcontainerkey
Definition: TrigInDetTrackFollowingTool.h:120
AthAlgTool
Definition: AthAlgTool.h:26
IdentifierHash
Definition: IdentifierHash.h:38
MuonParameters::beta
@ beta
Definition: MuonParamDefs.h:144
FitQuality.h
PixelClusterOnTrack.h
InDetDD::SiDetectorElement::design
virtual const SiDetectorDesign & design() const override final
access to the local description (inline):
InDet::SCT_ClusterCollection
Trk::PrepRawDataCollection< SCT_Cluster > SCT_ClusterCollection
Definition: SCT_ClusterCollection.h:26
SG::AllowEmpty
@ AllowEmpty
Definition: StoreGate/StoreGate/VarHandleKey.h:30
Trk::Surface::transform
const Amg::Transform3D & transform() const
Returns HepGeom::Transform3D by reference.
python.compressB64.c
def c
Definition: compressB64.py:93
TrigInDetTrackFollowingTool::extrapolateTrackState
int extrapolateTrackState(TrigFTF_ExtendedTrackState &, const Trk::PlaneSurface *, MagField::AtlasFieldCache &) const
Definition: TrigInDetTrackFollowingTool.cxx:938
TrigInDetTrackFollowingTool::initialize
virtual StatusCode initialize()
Definition: TrigInDetTrackFollowingTool.cxx:172
TrigInDetTrackFollowingTool::m_nClustersMin
Gaudi::Property< int > m_nClustersMin
Definition: TrigInDetTrackFollowingTool.h:111
InDet::SiWidth::z
double z() const
Definition: SiWidth.h:131
InDet::SiCluster
Definition: InnerDetector/InDetRecEvent/InDetPrepRawData/InDetPrepRawData/SiCluster.h:40
Trk::TrackStateOnSurface::Measurement
@ Measurement
This is a measurement, and will at least contain a Trk::MeasurementBase.
Definition: TrackStateOnSurface.h:101
InDet::PixelClusterCollection
Trk::PrepRawDataCollection< PixelCluster > PixelClusterCollection
Definition: PixelClusterCollection.h:26
TrackStateOnSurface.h
fitman.k
k
Definition: fitman.py:528
Trk::PrepRawData::detectorElement
virtual const TrkDetElementBase * detectorElement() const =0
return the detector element corresponding to this PRD The pointer will be zero if the det el is not d...
TrigFTF_ExtendedTrackState::TrigFTF_ExtendedTrackState
TrigFTF_ExtendedTrackState()=delete