Class Reference for E1039 Core & Analysis Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
VertexFit.cxx
Go to the documentation of this file.
1 /*
2 VertexFit.cxx
3 
4 Implementation of the VertexFit, in the beginning only a old-fashioned primary vertex finder
5 is implemented
6 
7 Author: Kun Liu, liuk@fnal.gov
8 Created: 2-8-2012
9 */
10 
11 #include "VertexFit.h"
12 #include "KalmanTrack.h"
13 #include "KalmanFilter.h"
14 #include "GenFitExtrapolator.h"
15 
17 #include <fun4all/PHTFileServer.h>
18 #include <phool/PHNodeIterator.h>
19 #include <phool/PHIODataNode.h>
20 #include <phool/getClass.h>
21 #include <phool/recoConsts.h>
22 #include <phfield/PHFieldConfig_v3.h>
23 #include <phfield/PHFieldUtility.h>
24 #include <phgeom/PHGeomUtility.h>
25 
26 #include <TMatrixD.h>
27 
28 #include <iostream>
29 #include <cmath>
30 #include <memory>
31 #include <fstream>
32 
33 using namespace std;
34 
35 namespace
36 {
37  //static flag to indicate the initialized has been done
38  static bool inited = false;
39 
40  //static flag of kmag strength
41  static double FMAGSTR;
42  static double KMAGSTR;
43 
44  //Beam position and shape
45  static double X_BEAM;
46  static double Y_BEAM;
47  static double SIGX_BEAM;
48  static double SIGY_BEAM;
49 
50  //Simple swimming settings
51  static int NSTEPS_TARGET;
52  static int NSTEPS_SHIELDING;
53  static int NSTEPS_FMAG;
54 
55  //Geometric constants
56  static double Z_TARGET;
57  static double Z_DUMP;
58  static double Z_UPSTREAM;
59  static double Z_DOWNSTREAM;
60 
61  //initialize global variables
62  void initGlobalVariables()
63  {
64  if(!inited)
65  {
66  inited = true;
67 
69  FMAGSTR = rc->get_DoubleFlag("FMAGSTR");
70  KMAGSTR = rc->get_DoubleFlag("KMAGSTR");
71 
72  X_BEAM = rc->get_DoubleFlag("X_BEAM");
73  Y_BEAM = rc->get_DoubleFlag("Y_BEAM");
74  SIGX_BEAM = rc->get_DoubleFlag("SIGX_BEAM");
75  SIGY_BEAM = rc->get_DoubleFlag("SIGY_BEAM");
76 
77  NSTEPS_TARGET = rc->get_IntFlag("NSTEPS_TARGET");
78  NSTEPS_SHIELDING = rc->get_IntFlag("NSTEPS_SHIELDING");
79  NSTEPS_FMAG = rc->get_IntFlag("NSTEPS_FMAG");
80 
81  Z_TARGET = rc->get_DoubleFlag("Z_TARGET");
82  Z_DUMP = rc->get_DoubleFlag("Z_DUMP");
83  Z_UPSTREAM = rc->get_DoubleFlag("Z_UPSTREAM");
84  Z_DOWNSTREAM = rc->get_DoubleFlag("Z_DOWNSTREAM");
85  }
86  }
87 }
88 
89 VertexFit::VertexFit(const std::string& name) :
90  SubsysReco(name)
91 {
92  initGlobalVariables();
93 
95  TMatrixD m(2, 1), cov(2, 2), proj(2, 5);
96  m[0][0] = X_BEAM;
97  m[1][0] = Y_BEAM;
98 
99  cov.Zero();
100  cov[0][0] = SIGX_BEAM*SIGX_BEAM;
101  cov[1][1] = SIGY_BEAM*SIGY_BEAM;
102 
103  proj.Zero();
104  proj[0][3] = 1.;
105  proj[1][4] = 1.;
106 
107  _node_vertex.getMeasurement().ResizeTo(2, 1);
108  _node_vertex.getMeasurementCov().ResizeTo(2, 2);
109  _node_vertex.getProjector().ResizeTo(2, 5);
110 
111  _node_vertex.getMeasurement() = m;
112  _node_vertex.getMeasurementCov() = cov;
113  _node_vertex.getProjector() = proj;
114 
115  _max_iteration = 200;
116  _tolerance = .05;
117 
119  optimize = false;
120 
122  evalFileName = "vertex_eval.root";
123  evalFile = nullptr;
124  evalTree = nullptr;
125 
126 }
127 
129 {
130  if(evalFile != nullptr)
131  {
132  evalFile->cd();
133  evalTree->Write();
134  evalFile->Close();
135  }
136 }
137 
139 
140  this->bookEvaluation(evalFileName.c_str());
141 
143 }
144 
146 
147  FMAGSTR = recoConsts::instance()->get_DoubleFlag("FMAGSTR");
148  KMAGSTR = recoConsts::instance()->get_DoubleFlag("KMAGSTR");
149 
150  int ret = MakeNodes(topNode);
151  if(ret != Fun4AllReturnCodes::EVENT_OK) return ret;
152 
153  ret = GetNodes(topNode);
154  if(ret != Fun4AllReturnCodes::EVENT_OK) return ret;
155 
156  ret = InitField(topNode);
157  if(ret != Fun4AllReturnCodes::EVENT_OK) return ret;
158 
159  ret = InitGeom(topNode);
160  if(ret != Fun4AllReturnCodes::EVENT_OK) return ret;
161 
162  PHField* field = PHFieldUtility::GetFieldMapNode(nullptr, topNode);
163  assert(field);
164 
165  if(verbosity > 2) {
166  cout << "PHField check: " << "-------" << endl;
167  std::ofstream field_scan("field_scan.csv");
168  field->identify(field_scan);
169  field_scan.close();
170  }
171 
172  _kmfit = KalmanFilter::instance();
173  _kmfit->enableDumpCorrection();
174  _extrapolator.init(field, _t_geo_manager);
175 
177  _extrapolator.setPropCalc(false);
178  _extrapolator.setLengthCalc(false);
179 
181 }
182 
184 
185  _recEvent->identify();
186 
187  int ret = -99;
188  try {
189  ret = setRecEvent(_recEvent);
190  _recEvent->setRecStatus(ret);
192  LogInfo("Vertexing Returned: " << ret);
193  }
194  } catch (...) {
195  LogInfo("VertexFitting failed");
196  }
197 
199 }
200 
203 }
204 
205 int VertexFit::MakeNodes(PHCompositeNode* topNode) {
207 }
208 
209 int VertexFit::GetNodes(PHCompositeNode* topNode) {
210 
211  _recEvent = findNode::getClass<SRecEvent>(topNode, "SRecEvent");
212  if (!_recEvent) {
213  if(Verbosity() > 2) LogInfo("!_recEvent");
215  }
216 
218 }
219 
220 
221 int VertexFit::InitField(PHCompositeNode *topNode)
222 {
223  if (verbosity > 1) cout << "VertexFit::InitField" << endl;
224  PHField * phfield = PHFieldUtility::GetFieldMapNode(nullptr, topNode);
225 
226  if(phfield && verbosity > 1)
227  cout << "VertexFit::InitField - use filed from NodeTree." << endl;
228 
229  if(!phfield) {
230  if (verbosity > 1) cout << "VertexFit::InitField - create magnetic field setup" << endl;
231  unique_ptr<PHFieldConfig> default_field_cfg(nullptr);
232  default_field_cfg.reset(new PHFieldConfig_v3(recoConsts::instance()->get_CharFlag("fMagFile"), recoConsts::instance()->get_CharFlag("kMagFile"), recoConsts::instance()->get_DoubleFlag("FMAGSTR"), recoConsts::instance()->get_DoubleFlag("KMAGSTR"), 5.));
233  phfield = PHFieldUtility::GetFieldMapNode(default_field_cfg.get(), topNode, 0);
234  }
235 
236  assert(phfield);
237 
239 }
240 
241 int VertexFit::InitGeom(PHCompositeNode *topNode)
242 {
243  if (verbosity > 1) cout << "VertexFit::InitGeom" << endl;
244 
245  _t_geo_manager = PHGeomUtility::GetTGeoManager(topNode);
246 
247  if(_t_geo_manager && verbosity > 1)
248  cout << "VertexFit::InitGeom - use geom from NodeTree." << endl;
249 
250  assert(_t_geo_manager);
251 
253 }
254 
255 int VertexFit::setRecEvent(SRecEvent* recEvent, int sign1, int sign2)
256 {
257  std::vector<int> idx_pos = recEvent->getChargedTrackIDs(sign1);
258  std::vector<int> idx_neg = recEvent->getChargedTrackIDs(sign2);
259 
260  nPos = idx_pos.size();
261  nNeg = idx_neg.size();
262  if(nPos*nNeg == 0) return VFEXIT_FAIL_DIMUONPAIR;
263 
264  //Prepare evaluation output
265  if(evalTree != nullptr)
266  {
267  runID = recEvent->getRunID();
268  eventID = recEvent->getEventID();
269  targetPos = recEvent->getTargetPos();
270  }
271 
272  //Loop over all possible combinations
273  for(int i = 0; i < nPos; ++i)
274  {
275  if(!recEvent->getTrack(idx_pos[i]).isValid()) continue;
277  LogInfo("pos track OK");
278  }
279 
280  int j = sign1 + sign2 == 0 ? 0 : i + 1; // this is to avoid using same track twice in like-sign mode
281  for(; j < nNeg; ++j)
282  {
283  //Only needed for like-sign muons
284  if(idx_pos[i] == idx_neg[j]) continue;
286  LogInfo("two track OK");
287  }
288 
289  SRecTrack track_neg = recEvent->getTrack(idx_neg[j]);
290  if(!track_neg.isValid()) continue;
292  LogInfo("neg track OK");
293  }
294  SRecTrack track_pos = recEvent->getTrack(idx_pos[i]);
295 
296  SRecDimuon dimuon;
297  dimuon.trackID_pos = idx_pos[i];
298  dimuon.trackID_neg = idx_neg[j];
299 
300  dimuon.p_pos_single = track_pos.getMomentumVertex();
301  dimuon.p_neg_single = track_neg.getMomentumVertex();
302  dimuon.vtx_pos = track_pos.getVertex();
303  dimuon.vtx_neg = track_neg.getVertex();
304  dimuon.chisq_single = track_pos.getChisqVertex() + track_neg.getChisqVertex();
305 
306  //Start prepare the vertex fit
307  init();
308  if(KMAGSTR > 0)
309  {
310  addTrack(0, track_pos);
311  addTrack(1, track_neg);
312  }
313  else
314  {
315  addTrack(0, track_neg);
316  addTrack(1, track_pos);
317  }
318  addHypothesis(0.5*(dimuon.vtx_pos[2] + dimuon.vtx_neg[2]), 50.);
319  addHypothesis(findDimuonVertexFast(track_pos, track_neg), 50.);
320  choice_eval = processOnePair();
321 
322  //Fill the dimuon info which are not related to track refitting first
323  dimuon.chisq_vx = getVXChisq();
324  dimuon.vtx.SetXYZ(_vtxpar_curr._r[0][0], _vtxpar_curr._r[1][0], _vtxpar_curr._r[2][0]);
325 
326  dimuon.proj_target_pos = track_pos.getTargetPos();
327  dimuon.proj_dump_pos = track_pos.getDumpPos();
328  dimuon.proj_target_neg = track_neg.getTargetPos();
329  dimuon.proj_dump_neg = track_neg.getDumpPos();
330 
331  //Retrieve the results
332  double z_vertex_opt = getVertexZ0();
333  if(optimize)
334  {
335  //if(z_vertex_opt < -80. && getKFChisq() < 10.) z_vertex_opt = Z_TARGET;
336  if(dimuon.proj_target_pos.Perp() < dimuon.proj_dump_pos.Perp() && dimuon.proj_target_neg.Perp() < dimuon.proj_dump_neg.Perp())
337  {
338  int nTry = 0;
339  double z_curr = 9999.;
340  while(fabs(z_curr - z_vertex_opt) > 0.5 && nTry < 100)
341  {
342  z_curr = z_vertex_opt;
343  ++nTry;
344 
345  track_pos.setZVertex(z_vertex_opt);
346  track_neg.setZVertex(z_vertex_opt);
347 
348  double m = (track_pos.getMomentumVertex() + track_neg.getMomentumVertex()).M();
349  //z_vertex_opt = -189.6 + 17.71*m - 1.159*m*m; //parameterization of r1.4.0
350  z_vertex_opt = -305.465 + 104.731*m - 24.3589*m*m + 2.5564*m*m*m - 0.0978876*m*m*m*m;
351 
352  //std::cout << nTry << " " << z_curr << " " << z_vertex_opt << " " << (track_pos.getMomentumVertex() + track_neg.getMomentumVertex()).M() << std::endl;
353  }
354  }
355  }
356 
357  track_pos.setZVertex(z_vertex_opt);
358  track_neg.setZVertex(z_vertex_opt);
359  dimuon.p_pos = track_pos.getMomentumVertex();
360  dimuon.p_neg = track_neg.getMomentumVertex();
361  dimuon.chisq_kf = track_pos.getChisqVertex() + track_neg.getChisqVertex();
362 
363  /*
364  //If we are running in the like-sign mode, reverse one sign of px
365  if(sign1 + sign2 != 0)
366  {
367  if(dimuon.p_pos.Px() < 0)
368  {
369  dimuon.p_pos.SetPx(-dimuon.p_pos.Px());
370  dimuon.p_pos_single.SetPx(-dimuon.p_pos_single.Px());
371  }
372  if(dimuon.p_neg.Px() > 0)
373  {
374  dimuon.p_neg.SetPx(-dimuon.p_neg.Px());
375  dimuon.p_neg_single.SetPx(-dimuon.p_neg_single.Px());
376  }
377  if(dimuon.p_pos.Py()*dimuon.p_neg.Py() > 0)
378  {
379  dimuon.p_pos.SetPy(-dimuon.p_pos.Py());
380  dimuon.p_pos_single.SetPy(-dimuon.p_pos_single.Py());
381  }
382  }
383  */
384  dimuon.calcVariables();
385 
386  //Test three fixed hypothesis
387  dimuon.chisq_dump = track_pos.getChisqDump() + track_neg.getChisqDump();
388  dimuon.chisq_target = track_pos.getChisqTarget() + track_neg.getChisqTarget();
389  dimuon.chisq_upstream = track_pos.getChisqUpstream() + track_neg.getChisqUpstream();
390 
391  //Fill the final data
392  recEvent->insertDimuon(dimuon);
393 
394  //Fill the evaluation data
395  p_idx_eval = dimuon.trackID_pos;
396  m_idx_eval = dimuon.trackID_neg;
397  fillEvaluation();
398  }
399  }
400 
401  if(recEvent->getNDimuons() > 0) return VFEXIT_SUCCESS;
402  return VFEXIT_FAIL_ITERATION;
403 }
404 
406 {
407  //Swim both tracks all the way down, and store the numbers
408  TVector3 pos1[NSTEPS_FMAG + NSTEPS_TARGET + 1];
409  TVector3 pos2[NSTEPS_FMAG + NSTEPS_TARGET + 1];
410  TVector3 mom1[NSTEPS_FMAG + NSTEPS_TARGET + 1];
411  TVector3 mom2[NSTEPS_FMAG + NSTEPS_TARGET + 1];
412  track1.swimToVertex(pos1, mom1);
413  track2.swimToVertex(pos2, mom2);
414 
415  int iStep_min = -1;
416  double dist_min = 1E6;
417  int charge1 = track1.getCharge();
418  int charge2 = track2.getCharge();
419  for(int iStep = 0; iStep < NSTEPS_FMAG + NSTEPS_TARGET + 1; ++iStep)
420  {
421  double dist = (pos1[iStep] - pos2[iStep]).Perp();
422  if(dist < dist_min && FMAGSTR*charge1*mom1[iStep].Px() > 0 && FMAGSTR*charge2*mom2[iStep].Px() > 0)
423  {
424  iStep_min = iStep;
425  dist_min = dist;
426  }
427  }
428 
429  if(iStep_min == -1) return Z_DUMP;
430  return pos1[iStep_min].Z();
431 }
432 
434 {
435  _trkpar_curr.clear();
436 
437  z_vertex.clear();
438  r_vertex.clear();
439  chisq_km.clear();
440  chisq_vx.clear();
441 
442  z_start.clear();
443  sig_z_start.clear();
444 
446  //addHypothesis(Z_DUMP, 50.);
447  //addHypothesis(Z_TARGET, 50.);
448 }
449 
450 void VertexFit::setStartingVertex(double z_start, double sigz_start)
451 {
453  _vtxpar_curr._r[0][0] = X_BEAM;
454  _vtxpar_curr._r[1][0] = Y_BEAM;
455  _vtxpar_curr._r[2][0] = z_start;
456 
457  _vtxpar_curr._cov.Zero();
458  _vtxpar_curr._cov[0][0] = SIGX_BEAM*SIGX_BEAM;
459  _vtxpar_curr._cov[1][1] = SIGY_BEAM*SIGY_BEAM;
460  _vtxpar_curr._cov[2][2] = sigz_start*sigz_start;
461 
462  _chisq_vertex = 0.;
463  _chisq_kalman = 0.;
464 }
465 
467 {
468  double chisq_min = 1E6;
469  int index_min = -1;
470 
471  nStart = z_start.size();
472  for(int i = 0; i < nStart; ++i)
473  {
474 #ifdef _DEBUG_ON
475  LogInfo("Testing starting point: " << z_start[i]);
476 #endif
477 
478  setStartingVertex(z_start[i], sig_z_start[i]);
479  nIter_eval[i] = findVertex();
480 
481  chisq_km.push_back(_chisq_kalman);
482  chisq_vx.push_back(_chisq_vertex);
483  z_vertex.push_back(_vtxpar_curr._r[2][0]);
484  r_vertex.push_back(sqrt(_vtxpar_curr._r[0][0]*_vtxpar_curr._r[0][0] + _vtxpar_curr._r[1][0]*_vtxpar_curr._r[1][0]));
485 
486  if(_chisq_kalman < chisq_min)
487  {
488  index_min = i;
489  chisq_min = _chisq_kalman;
490  }
491  }
492 
493  if(index_min < 0) return 0;
494 
495  _chisq_kalman = chisq_km[index_min];
496  _chisq_vertex = chisq_vx[index_min];
497  _vtxpar_curr._r[2][0] = z_vertex[index_min];
498  if(z_vertex[index_min] > 1E4)
499  {
500  index_min = z_start.size();
501  _vtxpar_curr._r[2][0] = z_start.back();
502  }
503 
504  return index_min;
505 }
506 
507 void VertexFit::addTrack(int index, KalmanTrack& _track)
508 {
509  if(_track.getNodeList().front().isSmoothDone())
510  {
511  _trkpar_curr.push_back(_track.getNodeList().front().getSmoothed());
512  }
513  else if(_track.getNodeList().front().isFilterDone())
514  {
515  _trkpar_curr.push_back(_track.getNodeList().front().getFiltered());
516  }
517  else
518  {
519  _trkpar_curr.push_back(_track.getNodeList().front().getPredicted());
520  }
521 }
522 
523 void VertexFit::addTrack(int index, SRecTrack& _track)
524 {
525  TrkPar _trkpar;
526  _trkpar._state_kf = _track.getStateVector(0);
527  _trkpar._covar_kf = _track.getCovariance(0);
528  _trkpar._z = _track.getZ(0);
529 
530  _trkpar_curr.push_back(_trkpar);
531 }
532 
533 void VertexFit::addTrack(int index, TrkPar& _trkpar)
534 {
535  _trkpar_curr.push_back(_trkpar);
536 }
537 
539 {
540  int nIter = 0;
541  double _chisq_kalman_prev = 1E6;
542  for(; nIter < _max_iteration; ++nIter)
543  {
544 #ifdef _DEBUG_ON
545  LogInfo("Iteration: " << nIter);
546 #endif
547 
548  _chisq_vertex = 0.;
549  _chisq_kalman = 0.;
550  for(unsigned int j = 0; j < _trkpar_curr.size(); j++)
551  {
552  _node_vertex.resetFlags();
553  //_node_vertex.getMeasurement() = _vtxpar_curr._r.GetSub(0, 1, 0, 0);
554  //_node_vertex.getMeasurementCov() = _vtxpar_curr._cov.GetSub(0, 1, 0, 1);
555  _node_vertex.setZ(_vtxpar_curr._r[2][0]);
556 
557  _kmfit->setCurrTrkpar(_trkpar_curr[j]);
558  if(!_kmfit->fit_node(_node_vertex))
559  {
560 #ifdef _DEBUG_ON
561  LogInfo("Vertex fit for this track failed!");
562 #endif
563  _chisq_kalman = 1E5;
564  break;
565  }
566  else
567  {
568  _chisq_kalman += _node_vertex.getChisq();
569  }
570 
571  updateVertex();
572  }
573 
575 #ifdef _DEBUG_ON
576  LogInfo("At this iteration: ");
577  LogInfo(_vtxpar_curr._r[2][0] << " === " << _node_vertex.getZ() << " : " << _chisq_kalman << " === " << _chisq_vertex << " : " << _vtxpar_curr._r[0][0] << " === " << _vtxpar_curr._r[1][0]);
578 #endif
579  if(_vtxpar_curr._r[2][0] < Z_UPSTREAM || _vtxpar_curr._r[2][0] > Z_DOWNSTREAM)
580  {
581  _chisq_kalman = 1E5;
582  _chisq_vertex = 1E5;
583  break;
584  }
585 
586  if(nIter > 0 && (fabs(_vtxpar_curr._r[2][0] - _node_vertex.getZ()) < _tolerance || _chisq_kalman > _chisq_kalman_prev)) break;
587  _chisq_kalman_prev = _chisq_kalman;
588  }
589 
590  return nIter+1;
591 }
592 
594 {
595  double p = fabs(1./_node_vertex.getFiltered()._state_kf[0][0]);
596  double px = _node_vertex.getFiltered()._state_kf[1][0];
597  double py = _node_vertex.getFiltered()._state_kf[2][0];
598  double pz = sqrt(p*p - px*px - py*py);
599 
601  TMatrixD H(2, 3);
602  H.Zero();
603 
604  H[0][0] = 1.;
605  H[1][1] = 1.;
606  H[0][2] = -px/pz;
607  H[1][2] = -py/pz;
608 
609  TMatrixD vertex_dummy(3, 1);
610  vertex_dummy.Zero();
611  vertex_dummy[2][0] = _vtxpar_curr._r[2][0];
612 
613  TMatrixD mxy = _node_vertex.getFiltered()._state_kf.GetSub(3, 4, 0, 0);
614  TMatrixD Vxy = _node_vertex.getFiltered()._covar_kf.GetSub(3, 4, 3, 4);
615  TMatrixD S = SMatrix::invertMatrix(Vxy + SMatrix::getABCt(H, _vtxpar_curr._cov, H));
616  TMatrixD K = SMatrix::getABtC(_vtxpar_curr._cov, H, S);
617  TMatrixD zeta = mxy - H*(_vtxpar_curr._r - vertex_dummy);
618  TMatrixD _r_filtered = _vtxpar_curr._r + K*zeta;
619  TMatrixD _cov_filtered = _vtxpar_curr._cov - K*H*(_vtxpar_curr._cov);
620 
621  _chisq_vertex += SMatrix::getAtBC(zeta, S, zeta)[0][0];
622 
623  _vtxpar_curr._r = _r_filtered;
624  _vtxpar_curr._cov = _cov_filtered;
625 }
626 
628 {
629  TrkPar _trkpar_start;
630  _trkpar_start._state_kf = _track.getStateVector(0);
631  _trkpar_start._covar_kf = _track.getCovariance(0);
632  _trkpar_start._z = _track.getZ(0);
633 
634  return findSingleMuonVertex(_trkpar_start);
635 }
636 
638 {
639  TrkPar _trkpar_start;
640  if(_node_start.isSmoothDone())
641  {
642  _trkpar_start = _node_start.getSmoothed();
643  }
644  else if(_node_start.isFilterDone())
645  {
646  _trkpar_start = _node_start.getFiltered();
647  }
648  else
649  {
650  _trkpar_start = _node_start.getPredicted();
651  }
652 
653  return findSingleMuonVertex(_trkpar_start);
654 }
655 
657 {
658  _extrapolator.setInitialStateWithCov(_trkpar_start._z, _trkpar_start._state_kf, _trkpar_start._covar_kf);
659  double z_vertex_single = _extrapolator.extrapolateToIP();
660 
661  return z_vertex_single;
662 }
663 
664 void VertexFit::bookEvaluation(std::string evalFileName)
665 {
666  evalFile = new TFile(evalFileName.c_str(), "recreate");
667  evalTree = new TTree("T", "VertexFit eval");
668 
669  evalTree->Branch("runID", &runID, "runID/I");
670  evalTree->Branch("eventID", &eventID, "eventID/I");
671  evalTree->Branch("targetPos", &targetPos, "targetPos/I");
672  evalTree->Branch("choice_eval", &choice_eval, "choice_eval/I");
673  evalTree->Branch("choice_by_kf_eval", &choice_by_kf_eval, "choice_by_kf_eval/I");
674  evalTree->Branch("choice_by_vx_eval", &choice_by_vx_eval, "choice_by_vx_eval/I");
675 
676  evalTree->Branch("nStart", &nStart, "nStart/I");
677  evalTree->Branch("nIter_eval", nIter_eval, "nIter_eval[nStart]/I");
678  evalTree->Branch("chisq_kf_eval", chisq_kf_eval, "chisq_kf_eval[nStart]/D");
679  evalTree->Branch("chisq_vx_eval", chisq_vx_eval, "chisq_vx_eval[nStart]/D");
680  evalTree->Branch("z_vertex_eval", z_vertex_eval, "z_vertex_eval[nStart]/D");
681  evalTree->Branch("r_vertex_eval", r_vertex_eval, "r_vertex_eval[nStart]/D");
682  evalTree->Branch("z_start_eval", z_start_eval, "z_start_eval[nStart]/D");
683 
684  evalTree->Branch("m_chisq_kf_eval", &m_chisq_kf_eval, "m_chisq_kf_eval/D");
685  evalTree->Branch("m_z_vertex_eval", &m_z_vertex_eval, "m_z_vertex_eval/D");
686  evalTree->Branch("s_chisq_kf_eval", &s_chisq_kf_eval, "s_chisq_kf_eval/D");
687  evalTree->Branch("s_z_vertex_eval", &s_z_vertex_eval, "s_z_vertex_eval/D");
688 }
689 
691 {
692  if(evalTree == nullptr) return;
693 
694  choice_by_kf_eval = -1;
695  choice_by_vx_eval = -1;
696  double chisq_kf_min = 1E6;
697  double chisq_vx_min = 1E6;
698 
699  m_chisq_kf_eval = 0.;
700  m_z_vertex_eval = 0.;
701  for(int i = 0; i < nStart; ++i)
702  {
703  chisq_kf_eval[i] = chisq_km[i];
704  chisq_vx_eval[i] = chisq_vx[i];
705  z_vertex_eval[i] = z_vertex[i];
706  r_vertex_eval[i] = r_vertex[i];
707  z_start_eval[i] = z_start[i];
708 
709  m_chisq_kf_eval += chisq_kf_eval[i];
710  m_z_vertex_eval += z_vertex_eval[i];
711 
712  if(chisq_kf_min > chisq_km[i])
713  {
714  choice_by_kf_eval = i;
715  chisq_kf_min = chisq_km[i];
716  }
717 
718  if(chisq_vx_min > chisq_vx[i])
719  {
720  choice_by_vx_eval = i;
721  chisq_vx_min = chisq_vx[i];
722  }
723  }
724  m_chisq_kf_eval /= nStart;
725  m_z_vertex_eval /= nStart;
726 
727  s_chisq_kf_eval = 0.;
728  s_z_vertex_eval = 0.;
729  if(nStart == 1)
730  {
731  evalTree->Fill();
732  return;
733  }
734 
735  for(int i = 0; i < nStart; ++i)
736  {
737  s_chisq_kf_eval += ((m_chisq_kf_eval - chisq_kf_eval[i])*(m_chisq_kf_eval - chisq_kf_eval[i]));
738  s_z_vertex_eval += ((m_z_vertex_eval - z_vertex_eval[i])*(m_z_vertex_eval - z_vertex_eval[i]));
739  }
740  s_chisq_kf_eval = sqrt(s_chisq_kf_eval/(nStart-1));
741  s_z_vertex_eval = sqrt(s_z_vertex_eval/(nStart-1));
742 
743  evalTree->Fill();
744 }
745 
747 {
748  using namespace std;
749 
750  for(unsigned int i = 0; i < z_start.size(); i++)
751  {
752  cout << "============= Hypothesis " << i << " ============" << endl;
753  cout << "z_start = " << z_start[i] << ", sigz_start = " << sig_z_start[i] << endl;
754  cout << "Found z_vertex = " << z_vertex[i] << endl;
755  cout << "With chisq_km = " << chisq_km[i] << " and chisq_vx = " << chisq_vx[i] << endl;
756  }
757 }
bool isFilterDone()
Definition: KalmanUtil.h:132
TrkPar & getFiltered()
Definition: KalmanUtil.h:107
Double_t chisq_target
Definition: SRecEvent.h:397
#define VFEXIT_FAIL_ITERATION
Definition: GlobalConsts.h:27
Int_t getNDimuons()
Get dimuons.
Definition: SRecEvent.h:454
int verbosity
The verbosity level. 0 means not verbose at all.
Definition: Fun4AllBase.h:75
TrkPar & getPredicted()
Gets.
Definition: KalmanUtil.h:106
double getVXChisq()
Definition: VertexFit.h:108
TVector3 getDumpPos()
Definition: SRecEvent.h:185
VertexFit(const std::string &name="VertexFit")
Definition: VertexFit.cxx:89
int setRecEvent(SRecEvent *recEvent, int sign1=1, int sign2=-1)
Set the SRecEvent, main external call the use vertex fit.
Definition: VertexFit.cxx:255
void addTrack(int index, SRecTrack &_track)
Add one track parameter set into the fit.
Definition: VertexFit.cxx:523
Int_t trackID_pos
Definition: SRecEvent.h:359
Double_t getChisqVertex()
Definition: SRecEvent.h:182
TVector3 getVertex()
Definition: SRecEvent.h:180
void setRecStatus(int status)
Definition: SRecEvent.h:424
Double_t getZ(Int_t i)
Definition: SRecEvent.h:110
void setStartingVertex(double z_start, double sigz_start)
Definition: VertexFit.cxx:450
TVector3 vtx_pos
Definition: SRecEvent.h:372
TVector3 proj_target_neg
Definition: SRecEvent.h:378
TLorentzVector p_neg
Definition: SRecEvent.h:364
Double_t chisq_upstream
Definition: SRecEvent.h:399
void addHypothesis(double z, double sigz=50.)
Definition: VertexFit.h:88
TVector3 proj_dump_pos
Definition: SRecEvent.h:377
virtual double get_DoubleFlag(const std::string &name) const
Definition: PHFlag.cc:49
Double_t getChisqDump()
Definition: SRecEvent.h:197
TMatrixD & getMeasurement()
Definition: KalmanUtil.h:110
int processOnePair()
After setting both tracks and hypothesis, start the iteration.
Definition: VertexFit.cxx:466
Double_t getChisqTarget()
Definition: SRecEvent.h:198
Int_t getTargetPos()
Definition: SRecEvent.h:435
PHFieldConfig_v3 implements field configuration information for input a field map file...
static TMatrixD getAtBC(const TMatrixD &A, const TMatrixD &B, const TMatrixD &C)
Definition: KalmanUtil.cxx:133
void setZVertex(Double_t z, bool update=true)
Definition: SRecEvent.cxx:168
transient DST object for field storage and access
Definition: PHField.h:13
int isValid() const
isValid returns non zero if object contains vailid data
Definition: SRecEvent.cxx:371
bool isSmoothDone()
Definition: KalmanUtil.h:133
static recoConsts * instance()
Definition: recoConsts.cc:7
double findDimuonVertexFast(SRecTrack &track1, SRecTrack &track2)
Definition: VertexFit.cxx:405
void setLengthCalc(bool option)
void fillEvaluation()
Definition: VertexFit.cxx:690
static TMatrixD invertMatrix(const TMatrixD &m)
Definition: KalmanUtil.cxx:52
void insertDimuon(SRecDimuon dimuon)
Insert dimuon.
Definition: SRecEvent.h:462
TMatrixD & getProjector()
Definition: KalmanUtil.h:122
TVector3 proj_dump_neg
Definition: SRecEvent.h:379
bool init(const PHField *field, const TGeoManager *geom)
Initialize geometry and physics.
void setInitialStateWithCov(double z_in, TMatrixD &state_in, TMatrixD &cov_in)
Set input initial state parameters.
Int_t getRunID()
Definition: SRecEvent.h:432
void setCurrTrkpar(Node &_node)
set the current track parameter using the current node
Definition: KalmanFilter.h:45
double getVertexZ0()
Gets.
Definition: VertexFit.h:107
Double_t chisq_kf
Definition: SRecEvent.h:393
std::vector< Int_t > getChargedTrackIDs(Int_t charge)
Get track IDs.
Definition: SRecEvent.cxx:712
Double_t chisq_single
Definition: SRecEvent.h:390
double findSingleMuonVertex(SRecTrack &_track)
Definition: VertexFit.cxx:627
TVector3 getTargetPos()
Definition: SRecEvent.h:187
void init()
Initialize and reset.
Definition: VertexFit.cxx:433
double _z
Definition: KalmanUtil.h:87
static PHField * GetFieldMapNode(const PHFieldConfig *default_config=nullptr, PHCompositeNode *topNode=nullptr, const int verbosity=0)
Get transient PHField from DST nodes. If not found, make a new one based on default_config.
double getZ()
Definition: KalmanUtil.h:126
void setZ(double z)
Definition: KalmanUtil.h:137
bool fit_node(Node &_node)
Fit one node.
#define VFEXIT_FAIL_DIMUONPAIR
Definition: GlobalConsts.h:26
int findVertex()
Find the primary vertex.
Definition: VertexFit.cxx:538
TMatrixD & getMeasurementCov()
Definition: KalmanUtil.h:111
virtual int Verbosity() const
Gets the verbosity of this module.
Definition: Fun4AllBase.h:64
TLorentzVector getMomentumVertex()
Get the vertex info.
Definition: SRecEvent.cxx:340
Output a lot of messages.
Definition: Fun4AllBase.h:48
std::list< Node > & getNodeList()
Definition: KalmanTrack.h:84
int End(PHCompositeNode *topNode)
Called at the end of all processing.
Definition: VertexFit.cxx:201
#define VFEXIT_SUCCESS
Definition: GlobalConsts.h:18
static KalmanFilter * instance()
singlton instance
TLorentzVector p_neg_single
Definition: SRecEvent.h:368
TMatrixD _state_kf
State vectors and its covariance.
Definition: KalmanUtil.h:85
static TMatrixD getABCt(const TMatrixD &A, const TMatrixD &B, const TMatrixD &C)
Definition: KalmanUtil.cxx:125
SRecTrack & getTrack(Int_t i)
Definition: SRecEvent.h:448
Double_t getChisqUpstream()
Definition: SRecEvent.h:199
static TGeoManager * GetTGeoManager(PHCompositeNode *topNode)
Main user interface: DST node -&gt; TGeoManager for downstream use.
TLorentzVector p_pos
Definition: SRecEvent.h:363
TMatrixD _r
Definition: VertexFit.h:58
int InitRun(PHCompositeNode *topNode)
Definition: VertexFit.cxx:145
TVector3 proj_target_pos
Definition: SRecEvent.h:376
TMatrixD getCovariance(Int_t i)
Definition: SRecEvent.h:109
void bookEvaluation(std::string evalFileName="vtx_eval.root")
Evaluation.
Definition: VertexFit.cxx:664
int process_event(PHCompositeNode *topNode)
Definition: VertexFit.cxx:183
void identify(std::ostream &os=std::cout) const
PHObject virtual overloads.
Definition: SRecEvent.h:410
void resetFlags()
Definition: KalmanUtil.cxx:381
TVector3 vtx_neg
Definition: SRecEvent.h:373
Double_t chisq_dump
Definition: SRecEvent.h:398
TMatrixD _covar_kf
Definition: KalmanUtil.h:86
TVector3 vtx
Definition: SRecEvent.h:371
int Init(PHCompositeNode *topNode)
Definition: VertexFit.cxx:138
#define LogInfo(message)
Definition: DbSvc.cc:14
Int_t trackID_neg
Definition: SRecEvent.h:360
void enableDumpCorrection()
Enable the dump mode: stop calc prop matrix, start calc travel length.
Definition: KalmanFilter.h:52
TMatrixD getStateVector(Int_t i)
Definition: SRecEvent.h:108
void print()
Debugging output.
Definition: VertexFit.cxx:746
void updateVertex()
Core function, update the vertex prediction according to the track info.
Definition: VertexFit.cxx:593
Int_t getCharge() const
Gets.
Definition: SRecEvent.h:100
Double_t chisq_vx
Definition: SRecEvent.h:394
TLorentzVector p_pos_single
Definition: SRecEvent.h:367
void setPropCalc(bool option)
External control of modes.
static TMatrixD getABtC(const TMatrixD &A, const TMatrixD &B, const TMatrixD &C)
Definition: KalmanUtil.cxx:141
void calcVariables()
Definition: SRecEvent.cxx:593
TFile clean handling.
double getChisq()
Definition: KalmanUtil.h:127
TrkPar & getSmoothed()
Definition: KalmanUtil.h:108
TMatrixD _cov
Definition: VertexFit.h:59
virtual int get_IntFlag(const std::string &name) const
Definition: PHFlag.cc:117
double extrapolateToIP()
Extrapolate to the primary vertex.
void swimToVertex(TVector3 *pos=nullptr, TVector3 *mom=nullptr, bool hyptest=true)
Simple swim to vertex.
Definition: SRecEvent.cxx:402
Int_t getEventID()
Definition: SRecEvent.h:434
virtual void identify(std::ostream &os=std::cout) const
Definition: PHField.h:30