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