Class Reference for E1039 Core & Analysis Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
FastTracklet.cxx
Go to the documentation of this file.
1 /*
2 FastTracklet.cxx
3 
4 Implementation of class Tracklet
5 
6 Author: Kun Liu, liuk@fnal.gov
7 Created: 05-28-2013
8 */
9 
10 #include <phool/recoConsts.h>
11 
12 #include <iostream>
13 #include <algorithm>
14 #include <cmath>
15 
16 #include <TMath.h>
17 #include <TMatrixD.h>
18 
19 #include "FastTracklet.h"
20 #include "TriggerRoad.h"
21 
26 
27 namespace
28 {
29  //static flag to indicate the initialized has been done
30  static bool inited = false;
31 
32  //static pointer to geomtry service
33  static GeomSvc* p_geomSvc = nullptr;
34 
35  //static flag of kmag on/off
36  static bool KMAG_ON;
37 
38  //corase geometry
39  static bool COARSE_MODE;
40 
41  //static flag of kmag strength
42  static double FMAGSTR;
43  static double KMAGSTR;
44 
45  static double PT_KICK_FMAG;
46  static double PT_KICK_KMAG;
47 
48  //Track quality cuts
49  static double TX_MAX;
50  static double TY_MAX;
51  static double X0_MAX;
52  static double Y0_MAX;
53  static double INVP_MAX;
54  static double INVP_MIN;
55  static double PROB_LOOSE;
56  static double PROB_TIGHT;
57 
58  //Geometric positions
59  static double Z_KMAG_BEND;
60  static double Z_ABSORBER;
61  static double Z_FMAG_BEND;
62  static double Z_KFMAG_BEND;
63  static double ELOSS_KFMAG;
64  static double ELOSS_ABSORBER;
65 
66  //initialize global variables
67  void initGlobalVariables()
68  {
69  if(!inited)
70  {
71  inited = true;
72  p_geomSvc = GeomSvc::instance();
73 
75  KMAG_ON = rc->get_BoolFlag("KMAG_ON");
76  COARSE_MODE = rc->get_BoolFlag("COARSE_MODE");
77 
78  FMAGSTR = rc->get_DoubleFlag("FMAGSTR");
79  KMAGSTR = rc->get_DoubleFlag("KMAGSTR");
80  PT_KICK_FMAG = rc->get_DoubleFlag("PT_KICK_FMAG")*FMAGSTR;
81  PT_KICK_KMAG = rc->get_DoubleFlag("PT_KICK_KMAG")*KMAGSTR;
82 
83  TX_MAX = rc->get_DoubleFlag("TX_MAX");
84  TY_MAX = rc->get_DoubleFlag("TY_MAX");
85  X0_MAX = rc->get_DoubleFlag("X0_MAX");
86  Y0_MAX = rc->get_DoubleFlag("Y0_MAX");
87  INVP_MAX = rc->get_DoubleFlag("INVP_MAX");
88  INVP_MIN = rc->get_DoubleFlag("INVP_MIN");
89  PROB_LOOSE = rc->get_DoubleFlag("PROB_LOOSE");
90  PROB_TIGHT = rc->get_DoubleFlag("PROB_TIGHT");
91 
92  Z_KMAG_BEND = p_geomSvc->Z_KMAG_BEND();
93  Z_ABSORBER = p_geomSvc->Z_ABSORBER();
94  Z_FMAG_BEND = p_geomSvc->Z_FMAG_BEND();
95  Z_KFMAG_BEND = p_geomSvc->Z_KFMAG_BEND();
96  ELOSS_KFMAG = p_geomSvc->ELOSS_KFMAG();
97  ELOSS_ABSORBER = p_geomSvc->ELOSS_ABSORBER();
98  }
99  }
100 }
101 
102 //Signed hit definition
104 {
105 }
106 
107 SignedHit::SignedHit(int detectorID) : sign(0)
108 {
109  hit.index = -1;
110  hit.detectorID = detectorID;
111 }
112 
113 SignedHit::SignedHit(Hit hit_input, int sign_input) : hit(hit_input), sign(sign_input)
114 {
115 }
116 
117 void SignedHit::identify(std::ostream& os) const
118 {
119  if(sign > 0) os << "L - ";
120  if(sign > 0) os << "R - ";
121  if(sign == 0) os << "U - ";
122 
123  os << hit.index << " " << hit.detectorID << " " << hit.elementID << std::endl;
124 }
125 
126 //Proptube segment definition
127 //const GeomSvc* PropSegment::p_geomSvc = GeomSvc::instance();
128 
129 PropSegment::PropSegment() : a(-999.), b(-999.), err_a(100.), err_b(100.), chisq(1.E6), nHodoHits(0)
130 {
131  for(int i = 0; i < 4; ++i) hits[i].hit.index = -1;
132  for(int i = 0; i < 4; ++i) hodoHits[i].index = -1;
133  initGlobalVariables();
134 }
135 
137 {
138  a = -999.;
139  b = -999.;
140  err_a = 100;
141  err_b = 100;
142 
143  for(int i = 0; i < 4; ++i) hits[i].hit.index = -1;
144 
145  chisq = 1E6;
146 }
147 
148 void PropSegment::print(std::ostream& os) const
149 {
150  using namespace std;
151 
152  os << "nHits: " << getNHits() << ", nPlanes: " << getNPlanes() << endl;
153  os << "a = " << a << ", b = " << b << ", chisq = " << chisq << endl;
154  os << "TX_MAX = " << TX_MAX << ", X0_MAX = " << X0_MAX << ", chisq max = " << 5 << endl;
155  //os << "Absorber projection: " << getExpPosition(MUID_Z_REF) << endl;
156 
157  for(int i = 0; i < 4; ++i)
158  {
159  if(hits[i].sign > 0) os << "L: ";
160  if(hits[i].sign < 0) os << "R: ";
161  if(hits[i].sign == 0) os << "U: ";
162 
163  os << hits[i].hit.index << " " << hits[i].hit.detectorID << " " << hits[i].hit.elementID << " === ";
164  }
165  os << endl;
166 }
167 
168 double PropSegment::getClosestApproach(double z, double pos)
169 {
170  return (a*z + b - pos)/sqrt(a*a + 1.);
171 }
172 
173 double PropSegment::getPosRef(double default_val)
174 {
175  if(hits[0].hit.index < 0 && hits[1].hit.index < 0) return default_val;
176 
177  int nRefPoints = 0;
178  double pos_exp = 0.;
179  for(int i = 0; i < 2; ++i)
180  {
181  if(hits[i].hit.index < 0) continue;
182 
183  pos_exp += hits[i].hit.pos;
184  ++nRefPoints;
185  }
186 
187  return pos_exp/nRefPoints;
188 }
189 
191 {
192  int nHits = 0;
193  for(int i = 0; i < 4; ++i)
194  {
195  if(hits[i].hit.index >= 0) ++nHits;
196  }
197  return nHits;
198 }
199 
201 {
202  int nPlanes = 0;
203  for(int i = 0; i < 2; ++i)
204  {
205  if(hits[i].hit.index >= 0 && hits[i+1].hit.index >= 0) ++nPlanes;
206  }
207  return nPlanes;
208 }
209 
211 {
212  if(getNHits() < 2) return 0;
213  if(getNPlanes() != 2) return 0;
214  if(chisq > 5.) return 0;
215 
216  //May need optimization
217  if(fabs(a) > TX_MAX) return 0;
218  if(fabs(b) > X0_MAX) return 0;
219 
220  return 1;
221 }
222 
224 {
225  //Sign assignment for 1st and 2nd hits
226  if(hits[0].hit.index > 0 && hits[1].hit.index > 0)
227  {
228  if(hits[0].hit.elementID == hits[1].hit.elementID)
229  {
230  hits[0].sign = -1;
231  hits[1].sign = 1;
232  }
233  else
234  {
235  hits[0].sign = 1;
236  hits[1].sign = -1;
237  }
238  }
239  else
240  {
241  hits[0].sign = 0;
242  hits[1].sign = 0;
243  }
244 
245  //Sign assignment for 3rd and 4th hits
246  if(hits[2].hit.index > 0 && hits[3].hit.index > 0)
247  {
248  if(hits[2].hit.elementID == hits[3].hit.elementID)
249  {
250  hits[2].sign = -1;
251  hits[3].sign = 1;
252  }
253  else
254  {
255  hits[2].sign = 1;
256  hits[3].sign = -1;
257  }
258  }
259  else
260  {
261  hits[2].sign = 0;
262  hits[3].sign = 0;
263  }
264 }
265 
266 void PropSegment::resolveLR(int settings)
267 {
268  hits[0].sign = 2*(settings & 1) - 1;
269  hits[1].sign = 2*((settings & 2) >> 1) - 1;
270  hits[2].sign = 2*((settings & 4) >> 1) - 1;
271  hits[3].sign = 2*((settings & 8) >> 1) - 1;
272 }
273 
275 {
276  int nHits = getNHits();
277  if(nHits == 2)
278  {
279  fit_2hits();
280  }
281  else
282  {
283  fit_34hits();
284  }
285 
286  //remove one bad hits if possible/needed
287  while(nHits > 2 && chisq > 5.)
288  {
289  int index = -1;
290  double res_max = 0.;
291  for(int i = 0; i < 4; ++i)
292  {
293  if(hits[i].hit.index < 0) continue;
294 
295  double res = fabs(hits[i].pos() - a*p_geomSvc->getPlanePosition(hits[i].hit.detectorID) - b);
296  if(res > res_max)
297  {
298  index = i;
299  res_max = res;
300  }
301  }
302 
303 #ifdef _DEBUG_ON
304  LogInfo("Invoking prop segment re-fitting...");
305  LogInfo("Removing hit " << index << " with residual = " << res_max);
306  LogInfo("Before removing a = " << a << ", b = " << b << ", chisq = " << chisq);
307 #endif
308 
309  //remove the bad hit
310  hits[index].hit.index = -1;
311 
312  //fit again
313  --nHits;
314  if(nHits == 2)
315  {
316  fit_2hits();
317  }
318  else
319  {
320  fit_34hits();
321  }
322 
323 #ifdef _DEBUG_ON
324  LogInfo("After removing a = " << a << ", b = " << b << ", chisq = " << chisq);
325 #endif
326  }
327 }
328 
330 {
331  double z[2], pos[2];
332 
333  int idx = 0;
334  for(int i = 0; i < 4; ++i)
335  {
336  if(hits[i].hit.index < 0) continue;
337 
338  z[idx] = p_geomSvc->getPlanePosition(hits[i].hit.detectorID);
339  pos[idx] = hits[i].hit.pos;
340 
341  ++idx;
342  }
343 
344  a = (pos[1] - pos[0])/(z[1] - z[0]);
345  b = pos[0] - a*z[0];
346  err_a = 1.5;
347  err_b = 1.5;
348  chisq = 0.;
349 }
350 
351 /*
352 void PropSegment::fit_34hits()
353 {
354  int index_min = -1;
355  double chisq_min = 1E8;
356  for(int i = 0; i < 16; ++i)
357  {
358  resolveLR(i);
359 
360  linearFit_iterative();
361  if(chisq < chisq_min)
362  {
363  chisq_min = chisq;
364  index_min = i;
365  }
366  }
367 
368  resolveLR(index_min);
369  linearFit_iterative();
370 }
371 */
372 
374 {
375  resolveLR();
377 }
378 
380 {
381  double sum = 0.;
382  double sx = 0.;
383  double sy = 0.;
384  double sxx = 0.;
385  double syy = 0.;
386  double sxy = 0.;
387 
388  double x[14], y[14];
389  for(int i = 0; i < 4; ++i)
390  {
391  if(hits[i].hit.index < 0) continue;
392 
393  y[i] = hits[i].pos();
394  x[i] = p_geomSvc->getPlanePosition(hits[i].hit.detectorID);
395 
396  ++sum;
397  sx += x[i];
398  sy += y[i];
399  sxx += (x[i]*x[i]);
400  syy += (y[i]*y[i]);
401  sxy += (x[i]*y[i]);
402  }
403 
404  /*
405  for(int i = 0; i < nHodoHits; ++i)
406  {
407  int idx = i + 4;
408  y[idx] = hodoHits[i].pos;
409  x[idx] = p_geomSvc->getPlanePosition(hodoHits[i].detectorID);
410 
411  ++sum;
412  sx += x[idx];
413  sy += y[idx];
414  sxx += (x[idx]*x[idx]);
415  syy += (y[idx]*y[idx]);
416  sxy += (x[idx]*y[idx]);
417  }
418  */
419 
420  double det = sum*sxx - sx*sx;
421  if(fabs(det) < 1E-20) return;
422 
423  a = (sum*sxy - sx*sy)/det;
424  b = (sy*sxx - sxy*sx)/det;
425  err_a = sqrt(fabs(sum/det));
426  err_b = sqrt(fabs(sxx/det));
427 
428  chisq = 0.;
429  for(int i = 0; i < 4; ++i)
430  {
431  if(hits[i].hit.index < 0) continue;
432  chisq += ((y[i] - a*x[i] -b)*(y[i] - a*x[i] -b));
433  }
434 }
435 
437 {
438  //Algorithm refer to Kun's PhD thesis
439 
440  //prepare the raw data
441  int len = 0;
442  double x[4], y[4], r[4]; //note r here is signed drift distance
443  for(int i = 0; i < 4; ++i)
444  {
445  if(hits[i].hit.index < 0) continue;
446 
447  y[len] = hits[i].pos();
448  x[len] = p_geomSvc->getPlanePosition(hits[i].hit.detectorID);
449  r[len] = hits[i].sign*hits[i].hit.driftDistance;
450 
451  ++len;
452  }
453 
454  //while loop with less than 100 iterations
455  a = 0;
456  int iter = 0;
457  double a_prev = -999.; // value of a in previous iteration
458  double _x[4], _y[4]; // corrected hit pos
459  while(fabs(a_prev - a) > 1E-4 && ++iter < 100)
460  {
461  a_prev = a;
462 
463  //prepare corrected hit pos
464  double C, D, E, F, G, H;
465  C = 0.;
466  D = 0.;
467  E = 0.;
468  F = 0.;
469  G = 0.;
470  H = 0.;
471 
472  for(int i = 0; i < len; ++i)
473  {
474  _x[i] = x[i] - r[i]*a/sqrt(a*a + 1.);
475  _y[i] = y[i] + r[i]/sqrt(a*a + 1.);
476 
477  C += 1.;
478  D += _x[i];
479  E += _y[i];
480  F += _x[i]*_x[i];
481  G += _y[i]*_y[i];
482  H += _x[i]*_y[i];
483  }
484 
485  double alpha = H - D*E/C;
486  double beta = F - G -D*D/C + E*E/C;
487 
488  a = (-beta + sqrt(beta*beta + 4*alpha*alpha))/alpha/2.;
489  b = (E - a*D)/C;
490 
491  chisq = 0.;
492  for(int i = 0; i < len; ++i)
493  {
494  chisq += (a*_x[i] + b - _y[i])*(a*_x[i] + b - _y[i])/(a*a + 1.);
495  }
496  }
497 }
498 
499 
500 Tracklet::Tracklet() : stationID(-1), nXHits(0), nUHits(0), nVHits(0), chisq(9999.), chisq_vtx(9999.), tx(0.), ty(0.), x0(0.), y0(0.), invP(0.1), err_tx(-1.), err_ty(-1.), err_x0(-1.), err_y0(-1.), err_invP(-1.)
501 {
502  for(int i = 0; i < nChamberPlanes; i++) residual[i] = 999.;
503  initGlobalVariables();
504 }
505 
506 int Tracklet::isValid() const
507 {
508  if(stationID < 1 || stationID > nStations) return 0;
509  if(fabs(tx) > TX_MAX || fabs(x0) > X0_MAX) return 0;
510  if(fabs(ty) > TY_MAX || fabs(y0) > Y0_MAX) return 0;
511  if(err_tx < 0 || err_ty < 0 || err_x0 < 0 || err_y0 < 0) return 0;
512 
513  double prob = getProb();
514  if(stationID != nStations && prob < PROB_LOOSE) return 0;
515 
516  //Tracklets in each station
517  int nHits = nXHits + nUHits + nVHits;
518  if(stationID < nStations-1)
519  {
520  if(nXHits < 1 || nUHits < 1 || nVHits < 1) return 0;
521  if(nHits < 4) return 0;
522  if(chisq > 40.) return 0;
523  }
524  else
525  {
526  //Number of hits cuts, second index is X, U, V, first index is station-1, 2, 3
527  int nRealHits[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
528  for(std::list<SignedHit>::const_iterator iter = hits.begin(); iter != hits.end(); ++iter)
529  {
530  if(iter->hit.index < 0) continue;
531 
532  int idx1 = iter->hit.detectorID <= 12 ? 0 : (iter->hit.detectorID <= 18 ? 1 : 2);
533  int idx2 = p_geomSvc->getPlaneType(iter->hit.detectorID) - 1;
534 
535  ++nRealHits[idx1][idx2];
536  }
537 
538  //Number of hits cut after removing bad hits
539  for(int i = 1; i < 3; ++i)
540  {
541  if(nRealHits[i][0] < 1 || nRealHits[i][1] < 1 || nRealHits[i][2] < 1) return 0;
542  if(nRealHits[i][0] + nRealHits[i][1] + nRealHits[i][2] < 4) return 0;
543  }
544 
545  //for global tracks only -- TODO: may need to set a new station-1 cut
546  if(stationID == nStations)
547  {
548  if(nRealHits[0][0] < 1 || nRealHits[0][1] < 1 || nRealHits[0][2] < 1) return 0;
549  if(nRealHits[0][0] + nRealHits[0][1] + nRealHits[0][2] < 4) return 0;
550 
551  if(prob < PROB_TIGHT) return 0;
552  if(KMAG_ON)
553  {
554  if(invP < INVP_MIN || invP > INVP_MAX) return 0;
555  }
556  }
557  }
558 
559  return 1;
560 }
561 
563 {
564  /*
565  This function is originally included in the isValid() function, applied when stationID >= nStations-1.
566  It is moved to this separate function so that isValid can be a const function
567  TODO: Need to verify this function is not really needed, i.e. the nX/U/Vhits counter has been properly taken care of for
568  during the hit removal process.
569  */
570  nXHits = 0;
571  nUHits = 0;
572  nVHits = 0;
573  for(std::list<SignedHit>::const_iterator iter = hits.begin(); iter != hits.end(); ++iter)
574  {
575  if(iter->hit.index < 0) continue;
576 
577  int idx = p_geomSvc->getPlaneType(iter->hit.detectorID) - 1;
578  if(idx == 0)
579  {
580  ++nXHits;
581  }
582  else if(idx == 1)
583  {
584  ++nUHits;
585  }
586  else
587  {
588  ++nVHits;
589  }
590  }
591 }
592 
593 double Tracklet::getProb() const
594 {
595  int ndf;
596  if(stationID == nStations && KMAG_ON)
597  {
598  ndf = getNHits() - 5;
599  }
600  else
601  {
602  ndf = getNHits() - 4;
603  }
604 
605  return TMath::Prob(chisq, ndf);
606  //return -chisq/ndf;
607 }
608 
609 double Tracklet::getMomProb() const
610 {
611  double weights[40] = {0, 0, 3.1292e-05, 0.00203877, 0.0147764, 0.0417885, 0.08536, 0.152212, 0.250242, 0.322011, 0.327125, 0.275443, 0.220316, 0.189932, 0.162112, 0.131674, 0.100102, 0.0736696, 0.0510353, 0.0364215, 0.0233914, 0.0152907, 0.00992716, 0.00601322, 0.00382757, 0.00239005, 0.00137169, 0.000768309, 0.000413311, 0.00019659, 8.31216e-05, 2.77721e-05, 7.93826e-06, 7.45884e-07, 2.57648e-08, 0, 6.00088e-09, 0, 0, 0};
612  int index = int(1./invP/2.5);
613 
614  return (index >= 0 && index < 40) ? (weights[index] < 1.E-5 ? 1.E-5 : weights[index]) : 1.E-5;
615 }
616 
617 TVector3 Tracklet::getExpMomentum(double z)
618 {
619  return (KMAG_ON && stationID >= nStations-1 && z < Z_KMAG_BEND - 1.) ? getMomentumSt1() : getMomentumSt3();
620 }
621 
622 double Tracklet::getExpPositionX(double z) const
623 {
624  if(KMAG_ON && stationID >= nStations-1 && z < Z_KMAG_BEND - 1.)
625  {
626  double tx_st1 = tx + PT_KICK_KMAG*invP*getCharge();
627  double x0_st1 = tx*Z_KMAG_BEND + x0 - tx_st1*Z_KMAG_BEND;
628 
629  return x0_st1 + tx_st1*z;
630  }
631  else
632  {
633  return x0 + tx*z;
634  }
635 }
636 
637 double Tracklet::getExpPosErrorX(double z) const
638 {
639  double err_x;
640  if(KMAG_ON && stationID >= nStations-1 && z < Z_KMAG_BEND - 1.)
641  {
642  double err_kick = fabs(err_invP*PT_KICK_KMAG);
643  double err_tx_st1 = err_tx + err_kick;
644  double err_x0_st1 = err_x0 + err_kick*Z_KMAG_BEND;
645 
646  err_x = err_x0_st1 + fabs(err_tx_st1*z);
647  }
648  else
649  {
650  err_x = fabs(err_tx*z) + err_x0;
651  }
652 
653  if(z > Z_ABSORBER) err_x += 1.;
654  return err_x;
655 }
656 
657 double Tracklet::getExpPositionY(double z) const
658 {
659  return y0 + ty*z;
660 }
661 
662 double Tracklet::getExpPosErrorY(double z) const
663 {
664  double err_y = fabs(err_ty*z) + err_y0;
665  if(z > Z_ABSORBER) err_y += 1.;
666 
667  return err_y;
668 }
669 
670 double Tracklet::getExpPositionW(int detectorID)
671 {
672  double z = p_geomSvc->getPlanePosition(detectorID);
673 
674  double x_exp = getExpPositionX(z);
675  double y_exp = getExpPositionY(z);
676 
677  return p_geomSvc->getCostheta(detectorID)*x_exp + p_geomSvc->getSintheta(detectorID)*y_exp;
678 }
679 
680 bool Tracklet::operator<(const Tracklet& elem) const
681 {
682  //return nXHits + nUHits + nVHits - 0.4*chisq > elem.nXHits + elem.nUHits + elem.nVHits - 0.4*elem.chisq;
683  if(getNHits() == elem.getNHits())
684  {
685  return chisq < elem.chisq;
686  }
687  else
688  {
689  return getProb() > elem.getProb();
690  }
691 }
692 
693 bool Tracklet::similarity(const Tracklet& elem) const
694 {
695  int nCommonHits = 0;
696  std::list<SignedHit>::const_iterator first = hits.begin();
697  std::list<SignedHit>::const_iterator second = elem.hits.begin();
698 
699  while(first != hits.end() && second != elem.hits.end())
700  {
701  if((*first) < (*second))
702  {
703  ++first;
704  }
705  else if((*second) < (*first))
706  {
707  ++second;
708  }
709  else
710  {
711  if((*first) == (*second)) nCommonHits++;
712  ++first;
713  ++second;
714  }
715  }
716 
717  if(nCommonHits/double(elem.getNHits()) > 0.33333) return true;
718  return false;
719 }
720 
721 double Tracklet::getMomentum() const
722 {
723  //Ref. SEAQUEST-doc-453-v3 by Don. Geesaman
724  //if(KMAG_ON == 0) return 1E8;
725 
726  double p = 50.;
727  double charge = getCharge();
728 
729  double c1 = Z_FMAG_BEND*PT_KICK_FMAG*charge;
730  double c2 = Z_KMAG_BEND*PT_KICK_KMAG*charge;
731  double c3 = -x0;
732  double c4 = ELOSS_KFMAG/2.;
733  double c5 = ELOSS_KFMAG;
734 
735  double b = c1/c3 + c2/c3 - c4 - c5;
736  double c = c4*c5 - c1*c5/c3 - c2*c4/c3;
737 
738  double disc = b*b - 4*c;
739  if(disc > 0.)
740  {
741  p = (-b + sqrt(disc))/2. - ELOSS_KFMAG;
742  }
743 
744  if(p < 10. || p > 120. || disc < 0)
745  {
746  double k = fabs(getExpPositionX(Z_KFMAG_BEND)/Z_KFMAG_BEND - tx);
747  p = 1./(0.00832161 + 0.184186*k - 0.104132*k*k) + ELOSS_ABSORBER;
748  }
749 
750  return p;
751 }
752 
754 {
755  return x0*KMAGSTR > tx ? 1 : -1;
756 }
757 
758 void Tracklet::getXZInfoInSt1(double& tx_st1, double& x0_st1)
759 {
760  if(KMAG_ON)
761  {
762  tx_st1 = tx + PT_KICK_KMAG*invP*getCharge();
763  x0_st1 = tx*Z_KMAG_BEND + x0 - tx_st1*Z_KMAG_BEND;
764  }
765  else
766  {
767  tx_st1 = tx;
768  x0_st1 = x0;
769  }
770 }
771 
772 void Tracklet::getXZErrorInSt1(double& err_tx_st1, double& err_x0_st1)
773 {
774  if(KMAG_ON)
775  {
776  double err_kick = fabs(err_invP*PT_KICK_KMAG);
777  err_tx_st1 = err_tx + err_kick;
778  err_x0_st1 = err_x0 + err_kick*Z_KMAG_BEND;
779  }
780  else
781  {
782  err_tx_st1 = err_tx;
783  err_x0_st1 = err_x0;
784  }
785 }
786 
788 {
789  Tracklet tracklet;
790  tracklet.stationID = nStations - 1;
791 
792  tracklet.nXHits = nXHits + elem.nXHits;
793  tracklet.nUHits = nUHits + elem.nUHits;
794  tracklet.nVHits = nVHits + elem.nVHits;
795 
796  tracklet.hits.assign(hits.begin(), hits.end());
797  if(elem.stationID > stationID)
798  {
799  tracklet.hits.insert(tracklet.hits.end(), elem.hits.begin(), elem.hits.end());
800  }
801  else
802  {
803  tracklet.hits.insert(tracklet.hits.begin(), elem.hits.begin(), elem.hits.end());
804  }
805 
806  tracklet.err_tx = 1./sqrt(1./err_tx/err_tx + 1./elem.err_tx/elem.err_tx);
807  tracklet.err_ty = 1./sqrt(1./err_ty/err_ty + 1./elem.err_ty/elem.err_ty);
808  tracklet.err_x0 = 1./sqrt(1./err_x0/err_x0 + 1./elem.err_x0/elem.err_x0);
809  tracklet.err_y0 = 1./sqrt(1./err_y0/err_y0 + 1./elem.err_y0/elem.err_y0);
810 
811  tracklet.tx = (tx/err_tx/err_tx + elem.tx/elem.err_tx/elem.err_tx)*tracklet.err_tx*tracklet.err_tx;
812  tracklet.ty = (ty/err_ty/err_ty + elem.ty/elem.err_ty/elem.err_ty)*tracklet.err_ty*tracklet.err_ty;
813  tracklet.x0 = (x0/err_x0/err_x0 + elem.x0/elem.err_x0/elem.err_x0)*tracklet.err_x0*tracklet.err_x0;
814  tracklet.y0 = (y0/err_y0/err_y0 + elem.y0/elem.err_y0/elem.err_y0)*tracklet.err_y0*tracklet.err_y0;
815 
816  tracklet.invP = 1./tracklet.getMomentum();
817  tracklet.err_invP = 0.25*tracklet.invP;
818 
819  tracklet.calcChisq();
820  return tracklet;
821 }
822 
824 {
825  Tracklet tracklet;
826  tracklet.stationID = nStations;
827 
828  tracklet.nXHits = nXHits + elem.nXHits;
829  tracklet.nUHits = nUHits + elem.nUHits;
830  tracklet.nVHits = nVHits + elem.nVHits;
831 
832  tracklet.hits.assign(hits.begin(), hits.end());
833  if(elem.stationID > stationID)
834  {
835  tracklet.hits.insert(tracklet.hits.end(), elem.hits.begin(), elem.hits.end());
836  }
837  else
838  {
839  tracklet.hits.insert(tracklet.hits.begin(), elem.hits.begin(), elem.hits.end());
840  }
841 
842  if(elem.stationID == nStations - 1)
843  {
844  tracklet.tx = elem.tx;
845  tracklet.ty = elem.ty;
846  tracklet.x0 = elem.x0;
847  tracklet.y0 = elem.y0;
848  tracklet.invP = 1./elem.getMomentum();
849 
850  tracklet.err_tx = elem.err_tx;
851  tracklet.err_ty = elem.err_ty;
852  tracklet.err_x0 = elem.err_x0;
853  tracklet.err_y0 = elem.err_y0;
854  tracklet.err_invP = 0.25*tracklet.invP;
855  }
856  else
857  {
858  tracklet.tx = tx;
859  tracklet.ty = ty;
860  tracklet.x0 = x0;
861  tracklet.y0 = y0;
862  tracklet.invP = 1./getMomentum();
863 
864  tracklet.err_tx = err_tx;
865  tracklet.err_ty = err_ty;
866  tracklet.err_x0 = err_x0;
867  tracklet.err_y0 = err_y0;
868  tracklet.err_invP = 0.25*tracklet.invP;
869  }
870 
871  tracklet.calcChisq();
872  return tracklet;
873 }
874 
876 {
877  Tracklet tracklet;
878  tracklet.stationID = stationID;
879 
880  tracklet.tx = tx;
881  tracklet.ty = ty;
882  tracklet.x0 = x0;
883  tracklet.y0 = y0;
884  tracklet.invP = 1./getMomentum();
885 
886  tracklet.err_tx = err_tx;
887  tracklet.err_ty = err_ty;
888  tracklet.err_x0 = err_x0;
889  tracklet.err_y0 = err_y0;
890  tracklet.err_invP = 0.25*tracklet.invP;
891 
892  tracklet.chisq_vtx = chisq_vtx < 999 ? chisq_vtx : elem.chisq_vtx;
893 
894  tracklet.seg_x = seg_x;
895  tracklet.seg_y = seg_y;
896 
897  std::list<SignedHit>::iterator elemend = elem.hits.begin();
898  for(int i = 0; i < 6; ++i) ++elemend;
899  tracklet.hits.insert(tracklet.hits.begin(), hits.begin(), hits.end());
900  tracklet.hits.insert(tracklet.hits.begin(), elem.hits.begin(), elemend);
901  tracklet.hits.sort();
902 
903  tracklet.calcChisq();
904  tracklet.isValid();
905  return tracklet;
906 }
907 
909 {
910  std::vector<int> detectorIDs_all;
911  for(int i = stationID*6 - 5; i <= stationID*6; ++i) detectorIDs_all.push_back(i);
912 
913  std::vector<int> detectorIDs_now;
914  for(std::list<SignedHit>::const_iterator iter = hits.begin(); iter != hits.end(); ++iter)
915  {
916  detectorIDs_now.push_back(iter->hit.detectorID);
917  }
918 
919  std::vector<int> detectorIDs_miss(6);
920  std::vector<int>::iterator iter = std::set_difference(detectorIDs_all.begin(), detectorIDs_all.end(), detectorIDs_now.begin(), detectorIDs_now.end(), detectorIDs_miss.begin());
921  detectorIDs_miss.resize(iter - detectorIDs_miss.begin());
922 
923  for(std::vector<int>::iterator iter = detectorIDs_miss.begin(); iter != detectorIDs_miss.end(); ++iter)
924  {
925  SignedHit dummy;
926  dummy.hit.detectorID = *iter;
927 
928  hits.push_back(dummy);
929  }
930 
931  sortHits();
932 }
933 
935 {
936  chisq = 0.;
937 
938  double tx_st1, x0_st1;
939  if(stationID == nStations && KMAG_ON)
940  {
941  getXZInfoInSt1(tx_st1, x0_st1);
942  }
943 
944  for(std::list<SignedHit>::const_iterator iter = hits.begin(); iter != hits.end(); ++iter)
945  {
946  if(iter->hit.index < 0) continue;
947 
948  int detectorID = iter->hit.detectorID;
949  int index = detectorID - 1;
950 
951  double sigma;
952  if(iter->sign == 0 || COARSE_MODE)
953  sigma = p_geomSvc->getPlaneSpacing(detectorID)/sqrt(12.);
954  else
955  sigma = p_geomSvc->getPlaneResolution(detectorID);
956 
957  //double p = iter->hit.pos + iter->sign*fabs(iter->hit.driftDistance);
958  if(KMAG_ON && stationID == nStations && detectorID <= 12)
959  {
960  //residual[index] = p - p_geomSvc->getInterception(detectorID, tx_st1, ty, x0_st1, y0);
961  residual[index] = iter->sign*fabs(iter->hit.driftDistance) - p_geomSvc->getDCA(detectorID, iter->hit.elementID, tx_st1, ty, x0_st1, y0);
962  }
963  else
964  {
965  //residual[index] = p - p_geomSvc->getInterception(detectorID, tx, ty, x0, y0);
966  residual[index] = iter->sign*fabs(iter->hit.driftDistance) - p_geomSvc->getDCA(detectorID, iter->hit.elementID, tx, ty, x0, y0);
967  }
968 
969  chisq += (residual[index]*residual[index]/sigma/sigma);
970  //std::cout << iter->hit.detectorID << " " << iter->hit.elementID << " " << iter->sign << " " << iter->hit.pos << " " << iter->hit.driftDistance << " " << residual[index] << " " << sigma << " " << chisq << std::endl;
971  }
972 
973  //std::cout << chisq << std::endl;
974  return chisq;
975 }
976 
978 {
979  int id = 0;
980  for(std::list<SignedHit>::const_iterator iter = hits.begin(); iter != hits.end(); ++iter)
981  {
982  if(id == index) return *iter;
983  id++;
984  }
985 
986  SignedHit dummy;
987  return dummy;
988 }
989 
990 double Tracklet::Eval(const double* par)
991 {
992  tx = par[0];
993  ty = par[1];
994  x0 = par[2];
995  y0 = par[3];
996  if(KMAG_ON) invP = par[4];
997 
998  //std::cout << tx << " " << ty << " " << x0 << " " << y0 << " " << 1./invP << std::endl;
999  return calcChisq();
1000 }
1001 
1003 {
1004  SRecTrack strack;
1005  strack.setChisq(chisq);
1006  for(std::list<SignedHit>::iterator iter = hits.begin(); iter != hits.end(); ++iter)
1007  {
1008  if(iter->hit.index < 0) continue;
1009 
1010  double z = p_geomSvc->getPlanePosition(iter->hit.detectorID);
1011  double tx_val, tx_err, x0_val, x0_err;
1012  if(iter->hit.detectorID <= 12)
1013  {
1014  getXZInfoInSt1(tx_val, x0_val);
1015  getXZErrorInSt1(tx_err, x0_err);
1016  }
1017  else
1018  {
1019  tx_val = tx;
1020  x0_val = x0;
1021  tx_err = err_tx;
1022  x0_err = err_x0;
1023  }
1024 
1025  TMatrixD state(5, 1), covar(5, 5);
1026  state[0][0] = getCharge()*invP*sqrt((1. + tx_val*tx_val)/(1. + tx_val*tx_val + ty*ty));
1027  state[1][0] = tx_val;
1028  state[2][0] = ty;
1029  state[3][0] = getExpPositionX(z);
1030  state[4][0] = getExpPositionY(z);
1031 
1032  covar.Zero();
1033  covar[0][0] = err_invP*err_invP;
1034  covar[1][1] = tx_err*tx_err;
1035  covar[2][2] = err_ty*err_ty;
1036  covar[3][3] = getExpPosErrorX(z)*getExpPosErrorX(z);
1037  covar[4][4] = getExpPosErrorY(z)*getExpPosErrorY(z);
1038 
1039  strack.insertHitIndex(iter->hit.index*iter->sign);
1040  strack.insertStateVector(state);
1041  strack.insertCovariance(covar);
1042  strack.insertZ(z);
1043  }
1044 
1045  //Set single vertex swimming
1046  strack.swimToVertex(nullptr, nullptr, hyptest);
1047 
1048  //Set trigger road info
1049  TriggerRoad road(*this);
1050  strack.setTriggerRoad(road.getRoadID());
1051 
1052  //Set prop tube slopes
1053  strack.setNHitsInPT(seg_x.getNHits(), seg_y.getNHits());
1054  strack.setPTSlope(seg_x.a, seg_y.a);
1055 
1056  return strack;
1057 }
1058 
1060 {
1061  double tx_st1, x0_st1;
1062  getXZInfoInSt1(tx_st1, x0_st1);
1063 
1064  double pz = 1./invP/sqrt(1. + tx_st1*tx_st1);
1065  return TVector3(pz*tx_st1, pz*ty, pz);
1066 }
1067 
1069 {
1070  double pz = 1./invP/sqrt(1. + tx*tx);
1071  return TVector3(pz*tx, pz*ty, pz);
1072 }
1073 
1074 void Tracklet::print(std::ostream& os)
1075 {
1076  using namespace std;
1077 
1078  calcChisq();
1079  TVector3 mom1 = getMomentumSt1();
1080  TVector3 mom3 = getMomentumSt3();
1081 
1082  os << "Tracklet in station " << stationID << endl;
1083  os << nXHits + nUHits + nVHits << " hits in this station with chisq = " << chisq << endl;
1084  os << "Momentum in z @st1: " << mom1.Pz() << " +/- " << mom1.Pz()*err_invP/invP << endl;
1085  os << "Momentum in z @st3: " << mom3.Pz() << " +/- " << mom3.Pz()*err_invP/invP << endl;
1086  os << "Charge: " << getCharge() << endl;
1087  for(std::list<SignedHit>::iterator iter = hits.begin(); iter != hits.end(); ++iter)
1088  {
1089  if(iter->sign > 0) os << "L: ";
1090  if(iter->sign < 0) os << "R: ";
1091  if(iter->sign == 0) os << "U: ";
1092 
1093  os << iter->hit.index << " " << iter->hit.detectorID << " " << iter->hit.elementID << " " << residual[iter->hit.detectorID-1] << " === ";
1094  }
1095  os << endl;
1096 
1097  os << "X-Z: (" << tx << " +/- " << err_tx << ")*z + (" << x0 << " +/- " << err_x0 << ")" << endl;
1098  os << "Y-Z: (" << ty << " +/- " << err_ty << ")*z + (" << y0 << " +/- " << err_y0 << ")" << endl;
1099 
1100  os << "KMAG projection: X = " << getExpPositionX(Z_KMAG_BEND) << " +/- " << getExpPosErrorX(Z_KMAG_BEND) << endl;
1101  os << "KMAG projection: Y = " << getExpPositionY(Z_KMAG_BEND) << " +/- " << getExpPosErrorY(Z_KMAG_BEND) << endl;
1102  os << "KMAGSTR = " << KMAGSTR << endl;
1103 }
1104 
1106 {}
1107 
1109 {
1110  Reset();
1111 }
1112 
1113 void TrackletVector::identify(std::ostream& os) const
1114 {
1115  os << "TrackletVector with " << size() << " entries" << std::endl;
1116 }
1117 
1119 {
1120  for(auto iter = trackletVec.begin(); iter != trackletVec.end(); ++iter) delete (*iter);
1121  trackletVec.clear();
1122 }
1123 
1124 const Tracklet* TrackletVector::at(const size_t index) const
1125 {
1126  if(index >= size()) return nullptr;
1127  return trackletVec[index];
1128 }
1129 
1130 Tracklet* TrackletVector::at(const size_t index)
1131 {
1132  if(index >= size()) return nullptr;
1133  return trackletVec[index];
1134 }
1135 
1137 {
1138  trackletVec.push_back(tracklet->Clone());
1139 }
1140 
1141 size_t TrackletVector::erase(const size_t index)
1142 {
1143  if(index >= size()) return size();
1144 
1145  delete trackletVec[index];
1146  trackletVec.erase(trackletVec.begin() + index);
1147  return trackletVec.size();
1148 }
virtual bool get_BoolFlag(const std::string &name) const
Definition: PHFlag.cc:151
void insertHitIndex(Int_t index)
Definition: SRecEvent.h:154
void identify(std::ostream &os=std::cout) const
double Z_FMAG_BEND() const
Definition: GeomSvc.h:265
void identify(std::ostream &os=std::cout) const
Float_t driftDistance
Definition: SRawEvent.h:81
void linearFit_iterative()
void resolveLR()
Tracklet operator+(const Tracklet &elem) const
SignedHit hits[4]
Definition: FastTracklet.h:118
Tracklet * Clone() const
Definition: FastTracklet.h:132
SignedHit getSignedHit(int index)
double calcChisq()
double getSintheta(int detectorID) const
Definition: GeomSvc.h:202
void getXZErrorInSt1(double &err_tx_st1, double &err_x0_st1)
Short_t detectorID
Definition: SRawEvent.h:78
double getExpPosErrorX(double z) const
double Eval(const double *par)
double residual[nChamberPlanes]
Definition: FastTracklet.h:247
double ELOSS_KFMAG() const
Definition: GeomSvc.h:269
virtual double get_DoubleFlag(const std::string &name) const
Definition: PHFlag.cc:49
double getExpPositionW(int detectorID)
void fit_34hits()
virtual ~TrackletVector()
double getPlaneResolution(int detectorID) const
Definition: GeomSvc.h:209
int isValid() const
isValid returns non zero if object contains vailid data
SRecTrack getSRecTrack(bool hyptest=true)
void insertStateVector(TMatrixD state)
Definition: SRecEvent.h:155
bool operator<(const Tracklet &elem) const
double err_a
Definition: FastTracklet.h:107
void insertZ(Double_t z)
Definition: SRecEvent.h:157
double Z_ABSORBER() const
Definition: GeomSvc.h:275
double getMomentum() const
size_t erase(const size_t index)
double pos()
Definition: FastTracklet.h:44
static recoConsts * instance()
Definition: recoConsts.cc:7
TVector3 getMomentumSt1()
double getExpPositionY(double z) const
int getCharge() const
void insertCovariance(TMatrixD covar)
Definition: SRecEvent.h:156
void print(std::ostream &os=std::cout)
double err_y0
Definition: FastTracklet.h:243
const Tracklet * at(const size_t index) const
double Z_KFMAG_BEND() const
Definition: GeomSvc.h:267
Definition of hit structure.
Definition: SRawEvent.h:34
double getExpPosErrorY(double z) const
std::list< SignedHit > hits
Definition: FastTracklet.h:227
int getNHits() const
void print(std::ostream &os=std::cout) const
void setPTSlope(Double_t slopeX, Double_t slopeY)
Definition: SRecEvent.h:224
#define nStations
Definition: GlobalConsts.h:5
void fit_2hits()
double ELOSS_ABSORBER() const
Definition: GeomSvc.h:271
int isValid() const
isValid returns non zero if object contains vailid data
double getMomProb() const
double chisq
Definition: FastTracklet.h:221
void addDummyHits()
void updateNHits()
TVector3 getExpMomentum(double z)
double chisq_vtx
Definition: FastTracklet.h:224
int getNHits() const
Definition: FastTracklet.h:146
double getDCA(int detectorID, int elementID, double tx, double ty, double x0, double y0)
Definition: GeomSvc.cxx:940
PropSegment seg_x
Definition: FastTracklet.h:230
Int_t index
Definition: SRawEvent.h:77
double err_tx
Definition: FastTracklet.h:240
PropSegment seg_y
Definition: FastTracklet.h:231
double getPlaneSpacing(int detectorID) const
Definition: GeomSvc.h:198
double err_invP
Definition: FastTracklet.h:244
double getPosRef(double default_val=-9999.)
void setNHitsInPT(Int_t nHitsX, Int_t nHitsY)
Definition: SRecEvent.h:225
int getPlaneType(int detectorID) const
Definition: GeomSvc.h:223
void Reset()
Clear Event.
double getClosestApproach(double z, double pos)
TVector3 getMomentumSt3()
double err_x0
Definition: FastTracklet.h:242
double getCostheta(int detectorID) const
Definition: GeomSvc.h:201
double y0
Definition: FastTracklet.h:237
#define nChamberPlanes
Definition: GlobalConsts.h:6
ClassImp(PdbCalChan)
static GeomSvc * instance()
singlton instance
Definition: GeomSvc.cxx:211
double err_ty
Definition: FastTracklet.h:241
Short_t elementID
Definition: SRawEvent.h:79
int getNPlanes() const
Hit hodoHits[4]
Definition: FastTracklet.h:115
#define LogInfo(message)
Definition: DbSvc.cc:14
Float_t pos
Definition: SRawEvent.h:82
double ty
Definition: FastTracklet.h:235
double invP
Definition: FastTracklet.h:238
int stationID
Definition: FastTracklet.h:213
void setTriggerRoad(Int_t roadID)
Definition: SRecEvent.h:220
double Z_KMAG_BEND() const
Getter/setters for a set of fixed parameters - should not be changed unless absolutely necessary...
Definition: GeomSvc.h:263
Tracklet operator*(const Tracklet &elem) const
double getExpPositionX(double z) const
double tx
Definition: FastTracklet.h:234
void setChisq(Double_t chisq)
Sets.
Definition: SRecEvent.h:153
double getProb() const
size_t size() const
Definition: FastTracklet.h:264
double err_b
Definition: FastTracklet.h:108
void push_back(const Tracklet *tracklet)
Tracklet merge(Tracklet &elem)
double getPlanePosition(int detectorID) const
Definition: GeomSvc.h:197
void swimToVertex(TVector3 *pos=nullptr, TVector3 *mom=nullptr, bool hyptest=true)
Simple swim to vertex.
Definition: SRecEvent.cxx:402
double x0
Definition: FastTracklet.h:236
void linearFit_simple()
void sortHits()
Definition: FastTracklet.h:142
double chisq
Definition: FastTracklet.h:111
void getXZInfoInSt1(double &tx_st1, double &x0_st1)
TCanvas * c1
Definition: Fun4SimTree.C:5
bool similarity(const Tracklet &elem) const