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