Class Reference for E1039 Core & Analysis Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
GFTrack.cxx
Go to the documentation of this file.
1 #include "GFTrack.h"
2 
3 #include <iostream>
4 #include <algorithm>
5 
6 #include <TVectorD.h>
7 #include <TMatrixDSym.h>
8 
9 #include <GenFit/MeasuredStateOnPlane.h>
10 #include <GenFit/MeasurementOnPlane.h>
11 #include <GenFit/WireMeasurement.h>
12 #include <GenFit/PlanarMeasurement.h>
13 #include <GenFit/RKTrackRep.h>
14 #include <GenFit/AbsFitterInfo.h>
15 #include <GenFit/KalmanFitterInfo.h>
16 #include <GenFit/StateOnPlane.h>
17 
18 #include <phool/recoConsts.h>
19 
20 #include "SRawEvent.h"
21 
22 namespace
23 {
24  //static flag to indicate the initialized has been done
25  static bool inited = false;
26 
27  static double Z_TARGET;
28  static double Z_DUMP;
29  static double Z_UPSTREAM;
30 
31  static double X_BEAM;
32  static double Y_BEAM;
33  static double SIGX_BEAM;
34  static double SIGY_BEAM;
35 
36  //initialize global variables
37  void initGlobalVariables()
38  {
39  if(!inited)
40  {
41  inited = true;
42 
44  Z_TARGET = rc->get_DoubleFlag("Z_TARGET");
45  Z_DUMP = rc->get_DoubleFlag("Z_DUMP");
46  Z_UPSTREAM = rc->get_DoubleFlag("Z_UPSTREAM");
47 
48  X_BEAM = rc->get_DoubleFlag("X_BEAM");
49  Y_BEAM = rc->get_DoubleFlag("Y_BEAM");
50  SIGX_BEAM = rc->get_DoubleFlag("SIGX_BEAM");
51  SIGY_BEAM = rc->get_DoubleFlag("SIGY_BEAM");
52  }
53  }
54 };
55 
56 namespace SQGenFit
57 {
58 
59 GFTrack::GFTrack(): _track(nullptr), _trkrep(nullptr), _propState(nullptr), _virtMeas(nullptr), _trkcand(nullptr), _pdg(0)
60 {
61  initGlobalVariables();
62 }
63 
64 GFTrack::GFTrack(SRecTrack& recTrack): _track(nullptr), _trkrep(nullptr), _propState(nullptr), _virtMeas(nullptr), _trkcand(nullptr), _pdg(0)
65 {
66  _pdg = recTrack.getCharge() > 0 ? -13 : 13;
67  _trkrep = new genfit::RKTrackRep(_pdg);
68 
69  TVector3 seed_mom = recTrack.getMomentumVecSt1();
70  TVector3 seed_pos = recTrack.getPositionVecSt1();
71 
72  TVectorD seed_state(6);
73  seed_state[0] = seed_pos.X();
74  seed_state[1] = seed_pos.Y();
75  seed_state[2] = seed_pos.Z();
76  seed_state[3] = seed_mom.Px();
77  seed_state[4] = seed_mom.Py();
78  seed_state[5] = seed_mom.Pz();
79 
80  TMatrixDSym seed_cov(6);
81  double uncertainty[6] = {10., 10., 10., 3., 3., 10.};
82  for(int i = 0; i < 6; i++)
83  {
84  for(int j = 0; j < 6; j++)
85  {
86  seed_cov[i][j] = uncertainty[i]*uncertainty[j];
87  }
88  }
89  _track = new genfit::Track(_trkrep, seed_state, seed_cov);
90 
91  _fitstates.clear();
92  int nHits = recTrack.getNHits();
93  for(int i = 0; i < nHits; ++i)
94  {
95  genfit::SharedPlanePtr detPlane(new genfit::DetPlane(recTrack.getGFPlaneO(i), recTrack.getGFPlaneU(i), recTrack.getGFPlaneV(i)));
96 
97  _fitstates.push_back(genfit::MeasuredStateOnPlane(recTrack.getGFState(i), recTrack.getGFCov(i), detPlane, _trkrep, recTrack.getGFAuxInfo(i)));
98  }
99 }
100 
101 GFTrack::GFTrack(Tracklet& tracklet): _track(nullptr), _trkrep(nullptr), _propState(nullptr), _virtMeas(nullptr), _trkcand(nullptr), _pdg(0)
102 {
103  setTracklet(tracklet, 590., false);
104 }
105 
107 {
108  if(_track != nullptr) delete _track;
109 }
110 
111 void GFTrack::setVerbosity(unsigned int v)
112 {
113  if(_trkrep != nullptr) _trkrep->setDebugLvl(v);
114 }
115 
116 void GFTrack::addMeasurements(std::vector<GFMeasurement*>& measurements)
117 {
118  for(auto iter = measurements.begin(); iter != measurements.end(); ++iter)
119  {
120  if(!(*iter)->isEnabled()) continue;
121  addMeasurement(*iter);
122  }
123 }
124 
126 {
127  measurement->setTrackPtr(this);
128 
129  genfit::TrackPoint* tp = new genfit::TrackPoint(measurement, _track);
130  tp->setSortingParameter(measurement->getZ());
131  _track->insertPoint(tp);
132 }
133 
135 {
136  genfit::AbsTrackRep* rep = _track->getCardinalRep();
137  if(rep)
138  {
139  genfit::FitStatus* fs = _track->getFitStatus(rep);
140  if(fs) return fs->getChi2();
141  }
142 
143  return -1.;
144 }
145 
147 {
148  genfit::AbsTrackRep* rep = _track->getCardinalRep();
149  if(rep)
150  {
151  genfit::FitStatus* fs = _track->getFitStatus(rep);
152  if(fs) return fs->getNdf();
153  }
154 
155  return -1.;
156 }
157 
159 {
160  double z = meas->getZ();
161  if(z < _measurements.front()->getZ())
162  {
163  return 0;
164  }
165  else if(z > _measurements.back()->getZ())
166  {
167  return _measurements.size() - 1;
168  }
169  else
170  {
171  auto iter = std::lower_bound(_measurements.begin(), _measurements.end(), meas, [](GFMeasurement* a, GFMeasurement* b) { return (a->getZ() < b->getZ()); });
172  int idx = std::distance(_measurements.begin(), iter);
173  return fabs(z - _measurements[idx]->getZ()) < fabs(z - _measurements[idx-1]->getZ()) ? idx : idx-1;
174  }
175 }
176 
177 double GFTrack::extrapolateToLine(TVector3& endPoint1, TVector3& endPoint2, const int startPtID)
178 {
179  TVector3 linePoint = (endPoint2 + endPoint1);
180  TVector3 lineDir = endPoint2 - endPoint1;
181 
182  if(!setInitialStateForExtrap(startPtID)) return -9999.;
183 
184  genfit::AbsTrackRep* rep = _track->getCardinalRep();
185  double len = rep->extrapolateToLine(*_propState, linePoint, lineDir);
186 
187  TVectorD hitcoord(7);
188  hitcoord[0] = endPoint1.X();
189  hitcoord[1] = endPoint1.Y();
190  hitcoord[2] = endPoint1.Z();
191  hitcoord[3] = endPoint2.X();
192  hitcoord[4] = endPoint2.Y();
193  hitcoord[5] = endPoint2.Z();
194  hitcoord[6] = 0.;
195  TMatrixDSym tempcov(7);
196  tempcov.Zero();
197  _virtMeas.reset(new genfit::WireMeasurement(hitcoord, tempcov, 999, 999, nullptr));
198 
199  return len;
200 }
201 
202 double GFTrack::extrapolateToPlane(TVector3& pO, TVector3& pU, TVector3& pV, const int startPtID)
203 {
204  genfit::SharedPlanePtr destPlane(new genfit::DetPlane(pO, pU, pV));
205 
206  if(!setInitialStateForExtrap(startPtID)) return -9999.;
207 
208  genfit::AbsTrackRep* rep = _track->getCardinalRep();
209  double len = rep->extrapolateToPlane(*_propState, destPlane);
210 
211  TVectorD hitcoord(2);
212  hitcoord[0] = pO.X();
213  hitcoord[1] = pO.Y();
214  TMatrixDSym tempcov(2);
215  tempcov.UnitMatrix();
216 
217  genfit::PlanarMeasurement* pMeas = new genfit::PlanarMeasurement(hitcoord, tempcov, 998, 998, nullptr);
218  pMeas->setPlane(destPlane);
219  _virtMeas.reset(pMeas);
220 
221  return len;
222 }
223 
224 double GFTrack::extrapolateToPoint(TVector3& point, bool update, const int startPtID)
225 {
226  if(!setInitialStateForExtrap(startPtID)) return -9999.;
227 
228  genfit::AbsTrackRep* rep = _track->getCardinalRep();
229  double len = rep->extrapolateToPoint(*_propState, point);
230 
231  //TODO: implement the virtual spacepoint measurement here
232 
233  return len;
234 }
235 
236 double GFTrack::updatePropState(const TVectorD& meas, const TMatrixDSym& V)
237 {
238  //get the H matrix from measurement
239  std::unique_ptr<const genfit::AbsHMatrix> H(_virtMeas->constructHMatrix(_propState->getRep()));
240 
241  //Handcrafted KF
242  TVectorD stateVec(_propState->getState());
243  TMatrixDSym cov(_propState->getCov());
244  double chi2 = 9999.;
245  double ndf = meas.GetNrows();
246 
247  TVectorD res(meas - H->Hv(stateVec));
248  TMatrixDSym covSumInv(cov);
249  H->HMHt(covSumInv);
250  covSumInv += V;
251  genfit::tools::invertMatrix(covSumInv);
252 
253  TMatrixD CHt(H->MHt(cov));
254  TVectorD update(TMatrixD(CHt, TMatrixD::kMult, covSumInv)*res);
255 
256  stateVec += update;
257  covSumInv.Similarity(CHt);
258  cov -= covSumInv;
259  _propState->setStateCov(stateVec, cov);
260 
261  //calc chi2
262  TVectorD resNew(meas - H->Hv(stateVec));
263  TMatrixDSym HCHt(cov);
264  H->HMHt(HCHt);
265  HCHt -= V;
266  HCHt *= -1;
267  genfit::tools::invertMatrix(HCHt);
268  chi2 = HCHt.Similarity(resNew);
269 
270  return chi2/ndf;
271 }
272 
273 bool GFTrack::setInitialStateForExtrap(const int startPtID)
274 {
275  genfit::AbsTrackRep* rep = _track->getCardinalRep();
276  if(_track->getNumPoints() > 0)
277  {
278  genfit::TrackPoint* tp = _track->getPointWithMeasurementAndFitterInfo(startPtID, rep);
279  if(tp == nullptr) return false;
280 
281  genfit::KalmanFitterInfo* info = static_cast<genfit::KalmanFitterInfo*>(tp->getFitterInfo(rep));
282  _propState.reset(new genfit::MeasuredStateOnPlane(info->getFittedState()));
283  }
284  else
285  {
286  _propState.reset(new genfit::MeasuredStateOnPlane(_fitstates[startPtID]));
287  }
288 
289  return true;
290 }
291 
292 double GFTrack::swimToVertex(double z, TVector3* pos, TVector3* mom, TMatrixDSym* cov)
293 {
294  //Basic constants
295  TVector3 pU(1., 0., 0.);
296  TVector3 pV(0., 1., 0.);
297  TVector3 pO(0., 0., z );
298 
299  TVectorD beamCenter(2);
300  beamCenter[0] = X_BEAM; beamCenter[1] = Y_BEAM;
301  TMatrixDSym beamCov(2);
302  beamCov.Zero();
303  beamCov(0, 0) = SIGX_BEAM*SIGX_BEAM; beamCov(1, 1) = SIGY_BEAM*SIGY_BEAM;
304 
305  double chi2 = -1.;
306  try
307  {
308  double len = extrapolateToPlane(pO, pU, pV);
309  if(fabs(len) > 6000.) throw len;
310 
311  chi2 = updatePropState(beamCenter, beamCov);
312  if(cov != nullptr)
313  {
314  getExtrapPosMomCov(*pos, *mom, *cov);
315  }
316  else if(mom != nullptr)
317  {
318  getExtrapPosMom(*pos, *mom);
319  }
320  }
321  catch(genfit::Exception& e)
322  {
323  std::cerr << __FILE__ << " " << __LINE__ << ": hypo test failed vertex @Z=" << z << ": " << e.what() << std::endl;
324  return -1.;
325  }
326  catch(double len)
327  {
328  std::cerr << __FILE__ << " " << __LINE__ << ": hypo test failed vertex @Z=" << z << ": " << len << std::endl;
329  return -1.;
330  }
331 
332  return chi2;
333 }
334 
335 void GFTrack::setTracklet(Tracklet& tracklet, double z_reference, bool wildseedcov)
336 {
337  _trkcand = &tracklet;
338  _pdg = tracklet.getCharge() > 0 ? -13 : 13;
339  _trkrep = new genfit::RKTrackRep(_pdg);
340 
341  TVectorD seed_state(6);
342 
343  TVector3 seed_mom = tracklet.getExpMomentum(z_reference);
344  TVector3 seed_pos(tracklet.getExpPositionX(z_reference), tracklet.getExpPositionY(z_reference), z_reference);
345  seed_state[0] = seed_pos.X();
346  seed_state[1] = seed_pos.Y();
347  seed_state[2] = seed_pos.Z();
348  seed_state[3] = seed_mom.Px();
349  seed_state[4] = seed_mom.Py();
350  seed_state[5] = seed_mom.Pz();
351 
352  TMatrixDSym seed_cov(6);
353  double uncertainty[6] = {10., 10., 10., 3., 3., 10.};
354  for(int i = 0; i < 6; i++)
355  {
356  for(int j = 0; j < 6; j++)
357  {
358  seed_cov[i][j] = uncertainty[i]*uncertainty[j];
359  }
360  }
361 
362  if(!wildseedcov)
363  {
364  //Implement a smaller cov based on the chi^2 fit?
365  }
366  _track = new genfit::Track(_trkrep, seed_state, seed_cov);
367 
368  _measurements.clear();
369  for(auto iter = tracklet.hits.begin(); iter != tracklet.hits.end(); ++iter)
370  {
371  if(iter->hit.index < 0) continue;
372 
373  GFMeasurement* meas = new GFMeasurement(*iter);
374  _measurements.push_back(meas);
375  }
376  std::sort(_measurements.begin(), _measurements.end(), [](GFMeasurement* a, GFMeasurement* b) { return (a->getZ() < b->getZ()); });
377 
378  addMeasurements(_measurements);
380 }
381 
382 void GFTrack::postFitUpdate(bool updateMeasurements)
383 {
384  if(!updateMeasurements) return;
385  for(auto iter = _measurements.begin(); iter != _measurements.end(); ++iter)
386  {
387  (*iter)->postFitUpdate();
388  }
389 }
390 
392 {
393  //postFitUpdate();
394  //The following steps are pretty hacky and should be considered as only a temporary solution
395  SRecTrack strack;
396  strack.setChisq(getChi2());
397  for(auto iter = _measurements.begin(); iter != _measurements.end(); ++iter)
398  {
399  strack.insertHitIndex((*iter)->getBeforeFitHit().hit.index);
400 
401  const genfit::MeasuredStateOnPlane& fitstate = (*iter)->getTrackPoint()->getKalmanFitterInfo()->getFittedState(true);
402  strack.insertGFState(fitstate);
403 
404  TVector3 pos, mom;
405  fitstate.getPosMom(pos, mom);
406  TMatrixD stateVec(5, 1);
407  stateVec[0][0] = getCharge()/mom.Mag();
408  stateVec[1][0] = mom.Px()/mom.Pz();
409  stateVec[2][0] = mom.Py()/mom.Pz();
410  stateVec[3][0] = pos.X();
411  stateVec[4][0] = pos.Y();
412  strack.insertStateVector(stateVec);
413  strack.insertZ(pos.Z());
414 
415  TMatrixD cov(fitstate.getCov());
416  strack.insertCovariance(cov);
417 
418  strack.insertChisq((*iter)->getTrackPoint()->getKalmanFitterInfo()->getSmoothedChi2());
419  }
420 
421  //Swim to various places and save info
422  strack.swimToVertex(nullptr, nullptr, false);
423 
424  //Hypothesis test should be implemented here
425  TVector3 pO(0., 0., Z_UPSTREAM);
426  TVector3 pU(1., 0., 0.);
427  TVector3 pV(0., 1., 0.);
428  TVectorD beamCenter(2);
429  beamCenter[0] = X_BEAM; beamCenter[1] = Y_BEAM;
430  TMatrixDSym beamCov(2);
431  beamCov.Zero();
432  beamCov(0, 0) = SIGX_BEAM*SIGX_BEAM; beamCov(1, 1) = SIGY_BEAM*SIGY_BEAM;
433 
434  //test Z_UPSTREAM
435  strack.setChisqUpstream(swimToVertex(Z_UPSTREAM));
436 
437  //test Z_TARGET
438  strack.setChisqTarget(swimToVertex(Z_TARGET));
439 
440  //test Z_DUMP
441  strack.setChisqDump(swimToVertex(Z_DUMP));
442 
443  /*
444  //Find POCA to beamline -- it seems to be funky and mostly found some place way upstream or downstream
445  // most likely because the cross product of the track direction and beam line direction is way too small
446  // z axis to provide reasonable calculation of the POCA location. It's disabled for now.
447  TVector3 ep1(0., 0., -499.);
448  TVector3 ep2(0., 0., 0.);
449  try
450  {
451  extrapolateToLine(ep1, ep2);
452  TVectorD beamR(1); beamR(0) = 0.;
453  TMatrixDSym beamC(1); beamC(0, 0) = 1000.;
454  strack.setChisqVertex(updatePropState(beamR, beamC));
455  }
456  catch(genfit::Exception& e)
457  {
458  std::cerr << "Hypothesis test failed at beamline: " << e.what() << std::endl;
459  print(0);
460  }
461  */
462 
463  //test Z_VERTEX
464  strack.setChisqVertex(swimToVertex(strack.getVertexPos().Z()));
465 
466  strack.setKalmanStatus(1);
467  return strack;
468 }
469 
470 void GFTrack::print(unsigned int debugLvl)
471 {
472  std::cout << "=============== SGTrack ===============" << std::endl;
473  std::cout << "------------ Track candidate ----------" << std::endl;
474  _trkcand->print();
475 
476  std::cout << "------------ Fit status ---------------" << std::endl;
477  _track->getFitStatus(_trkrep)->Print();
478 
479  std::cout << "------------ Fit Result ---------------" << std::endl;
480  _track->getFittedState().Print(); //default to the first hit
481 
482  if(debugLvl < 1) return;
483  for(auto iter = _measurements.begin(); iter != _measurements.end(); ++iter)
484  {
485  (*iter)->print(debugLvl-1);
486  }
487 
488  if(debugLvl < 20) return;
489  std::cout << "------------ GenFit Track ---------------" << std::endl;
490  _track->Print();
491 }
492 
493 }
void insertHitIndex(Int_t index)
Definition: SRecEvent.h:154
SRecTrack getSRecTrack()
Definition: GFTrack.cxx:391
void insertChisq(Double_t chisq)
Definition: SRecEvent.h:158
void setTrackPtr(GFTrack *trackPtr)
void checkConsistency()
Definition: GFTrack.h:50
double updatePropState(const TVectorD &meas, const TMatrixDSym &V)
Definition: GFTrack.cxx:236
double swimToVertex(double z, TVector3 *pos=nullptr, TVector3 *mom=nullptr, TMatrixDSym *cov=nullptr)
Definition: GFTrack.cxx:292
double extrapolateToPoint(TVector3 &point, bool update=false, const int startPtID=0)
Definition: GFTrack.cxx:224
void setTracklet(Tracklet &tracklet, double z_reference=590., bool wildseedcov=false)
Definition: GFTrack.cxx:335
void setChisqUpstream(Double_t chisq)
Definition: SRecEvent.h:216
void setChisqDump(Double_t chisq)
Definition: SRecEvent.h:214
virtual double get_DoubleFlag(const std::string &name) const
Definition: PHFlag.cc:49
void insertStateVector(TMatrixD state)
Definition: SRecEvent.h:155
TVector3 getGFPlaneO(Int_t i)
Definition: SRecEvent.h:113
TVector3 getVertexPos()
Definition: SRecEvent.h:195
void setChisqVertex(Double_t chisq)
Definition: SRecEvent.h:217
void insertZ(Double_t z)
Definition: SRecEvent.h:157
TMatrixDSym getGFCov(Int_t i)
Definition: SRecEvent.h:118
void setKalmanStatus(Int_t status)
Definition: SRecEvent.h:147
void postFitUpdate(bool updateMeasurements=true)
Definition: GFTrack.cxx:382
static recoConsts * instance()
Definition: recoConsts.cc:7
int getNearestMeasurementID(GFMeasurement *meas)
Definition: GFTrack.cxx:158
double getExpPositionY(double z) const
int getCharge() const
void print(unsigned int debugLvl=0)
Definition: GFTrack.cxx:470
void insertCovariance(TMatrixD covar)
Definition: SRecEvent.h:156
void print(std::ostream &os=std::cout)
Int_t getNHits() const
Definition: SRecEvent.h:101
double extrapolateToPlane(TVector3 &pO, TVector3 &pU, TVector3 &pV, const int startPtID=0)
Definition: GFTrack.cxx:202
void getExtrapPosMomCov(TVector3 &pos, TVector3 &mom, TMatrixDSym &cov)
Definition: GFTrack.h:45
void addMeasurement(GFMeasurement *measurement)
Definition: GFTrack.cxx:125
void setVerbosity(unsigned int v)
Definition: GFTrack.cxx:111
std::list< SignedHit > hits
Definition: FastTracklet.h:227
void getExtrapPosMom(TVector3 &pos, TVector3 &mom)
Definition: GFTrack.h:46
void addMeasurements(std::vector< GFMeasurement * > &measurements)
Definition: GFTrack.cxx:116
TVectorD getGFState(Int_t i)
Definition: SRecEvent.h:117
TVector3 getPositionVecSt1() const
Definition: SRecEvent.h:136
TVector3 getMomentumVecSt1() const
Definition: SRecEvent.h:128
int getCharge()
Definition: GFTrack.h:36
TVectorD getGFAuxInfo(Int_t i)
Definition: SRecEvent.h:116
TVector3 getExpMomentum(double z)
void insertGFState(const genfit::MeasuredStateOnPlane &msop)
Definition: SRecEvent.cxx:351
TVector3 getGFPlaneV(Int_t i)
Definition: SRecEvent.h:115
void setChisqTarget(Double_t chisq)
Definition: SRecEvent.h:215
double extrapolateToLine(TVector3 &endPoint1, TVector3 &endPoint2, const int startPtID=0)
Definition: GFTrack.cxx:177
Int_t getCharge() const
Gets.
Definition: SRecEvent.h:100
double getChi2()
Definition: GFTrack.cxx:134
double getExpPositionX(double z) const
TVector3 getGFPlaneU(Int_t i)
Definition: SRecEvent.h:114
void setChisq(Double_t chisq)
Sets.
Definition: SRecEvent.h:153
void swimToVertex(TVector3 *pos=nullptr, TVector3 *mom=nullptr, bool hyptest=true)
Simple swim to vertex.
Definition: SRecEvent.cxx:402
double getNDF()
Definition: GFTrack.cxx:146