StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
FwdTracker.h
1 #ifndef FWD_TRACKER_H
2 #define FWD_TRACKER_H
3 
4 #include "Fit/Fitter.h"
5 #include "TFile.h"
6 #include "TGraph2D.h"
7 #include "TH1.h"
8 #include "TH1F.h"
9 #include "TH2F.h"
10 #include "TRandom3.h"
11 #include "TTree.h"
12 #include "TVector3.h"
13 
14 #include <algorithm>
15 #include <memory>
16 #include <string>
17 #include <vector>
18 #include <unordered_map>
19 
20 #include "StFwdTrackMaker/include/Tracker/FwdHit.h"
21 #include "StFwdTrackMaker/include/Tracker/FwdDataSource.h"
22 #include "StFwdTrackMaker/include/Tracker/QualityPlotter.h"
23 #include "StFwdTrackMaker/include/Tracker/TrackFitter.h"
24 #include "StFwdTrackMaker/include/Tracker/BDTCriteria.h"
25 
26 #include "Criteria/Criteria.h"
27 #include "Criteria/ICriterion.h"
28 #include "KiTrack/Automaton.h"
29 #include "KiTrack/SegmentBuilder.h"
30 #include "KiTrack/SubsetHopfieldNN.h"
31 
32 #include "StFwdTrackMaker/include/Tracker/CriteriaKeeper.h"
33 
34 #include "GenFit/FitStatus.h"
35 #include "GenFit/GFRaveVertexFactory.h"
36 
37 #include "StFwdTrackMaker/FwdTrackerConfig.h"
38 #include "StFwdTrackMaker/Common.h"
39 
40 // Utility class for evaluating ID and QA truth
41 struct MCTruthUtils {
42 
43  static int dominantContribution(Seed_t hits, double &qa) {
44 
45  // track_id, hits on track
46  std::unordered_map<int,int> truth;
47  for ( auto hit : hits ) {
48  FwdHit* fhit = dynamic_cast<FwdHit*>(hit);
49  truth[ fhit->_tid ]++;
50  }
51 
52  using namespace std;
53  using P = decltype(truth)::value_type;
54  auto dom = max_element(begin(truth), end(truth), [](P a, P b){ return a.second < b.second; });
55 
56  // QA represents the percentage of hits which
57  // vote the same way on the track
58  if ( hits.size() > 0 )
59  qa = double(dom->second) / double(hits.size()) ;
60  else
61  qa = 0;
62 
63  return dom->first;
64  };
65 };
66 
68 public:
69  GenfitTrackResult( size_t nFTT, size_t nFST,
70  Seed_t &seedTrack, genfit::Track *track ) {
71  this->nFST = nFST;
72  this->nFTT = nFTT;
73  this->trackSeed = seedTrack;
74 
75  try {
76  this->track = track;
77  this->status = *(this->track->getFitStatus());
78  this->trackRep = this->track->getCardinalRep();
79 
80  this->isFitConverged = this->status.isFitConverged();
81  this->isFitConvergedFully = this->status.isFitConvergedFully();
82  this->isFitConvergedPartially = this->status.isFitConvergedPartially();
83  this->nFailedPoints = this->status.getNFailedPoints();
84  this->charge = this->status.getCharge();
85 
86  this->nPV = this->track->getNumPoints() - (nFTT + nFST);
87 
88  this->momentum = this->trackRep->getMom( this->track->getFittedState(0, this->trackRep) );
89  LOG_DEBUG << "GenfitTrackResult::set Track successful" << endm;
90 
91  } catch ( genfit::Exception &e ) {
92  LOG_ERROR << "GenfitTrackResult cannot get track" << endm;
93  this->track = nullptr;
94  this->trackRep = nullptr;
95 
96  this->isFitConverged = false;
97  this->isFitConvergedFully = false;
98  this->isFitConvergedPartially = false;
99  this->nFailedPoints = nFST + nFTT;
100  this->charge = 0;
101  }
102  }
103 
104  ~GenfitTrackResult() {
105  // MEMORY LEAK
106  // LOG_INFO << "~GenfitTrackResult" << endm;
107  // if (this->track)
108  // delete this->track;
109  // this->track = nullptr;
110  }
111 
112  void setFst( Seed_t &seedFst, genfit::Track *track ){
113  LOG_DEBUG << "GenfitTrackResult::setFSt" << endm;
114  nFST = seedFst.size();
115  fstSeed = seedFst;
116 
117  try {
118  this->fstTrack = new genfit::Track(*track);
119  // make sure the McTrackId is set correctly
120  this->fstTrack->setMcTrackId( this->track->getMcTrackId() );
121  this->fstStatus = *(this->fstTrack->getFitStatus());
122  this->fstTrackRep = this->fstTrack->getCardinalRep();
123 
124  this->isFitConverged = this->fstStatus.isFitConverged();
125  this->isFitConvergedFully = this->fstStatus.isFitConvergedFully();
126  this->isFitConvergedPartially = this->fstStatus.isFitConvergedPartially();
127  this->nFailedPoints = this->fstStatus.getNFailedPoints();
128  this->charge = this->fstStatus.getCharge();
129  this->fstMomentum = this->fstTrackRep->getMom( this->fstTrack->getFittedState(0, this->fstTrackRep) );
130 
131  } catch ( genfit::Exception &e ) {
132  LOG_ERROR << "CANNOT GET FST TRACK" << endm;
133  this->fstTrack = nullptr;
134  this->fstTrackRep = nullptr;
135 
136  this->fstIsFitConverged = false;
137  this->fstIsFitConvergedFully = false;
138  this->fstIsFitConvergedPartially = false;
139  this->fstNFailedPoints = nFST + nFTT;
140  this->fstCharge = 0;
141  }
142  }
143 
144  Seed_t trackSeed;
145  Seed_t fstSeed;
146  TVector3 momentum;
147  double charge;
148  size_t nFST = 0;
149  size_t nFTT = 0;
150  size_t nPV = 0;
151  genfit::FitStatus status;
152  genfit::AbsTrackRep *trackRep = nullptr;
153  genfit::Track *track = nullptr;
154  bool isFitConverged = false;
155  bool isFitConvergedFully = false;
156  bool isFitConvergedPartially = false;
157  size_t nFailedPoints = 0;
158 
159  // Result after FST refit
160  genfit::Track *fstTrack = nullptr;
161  genfit::AbsTrackRep *fstTrackRep = nullptr;
162  genfit::FitStatus fstStatus;
163  bool fstIsFitConverged = false;
164  bool fstIsFitConvergedFully = false;
165  bool fstIsFitConvergedPartially = false;
166  size_t fstNFailedPoints = 0;
167  double fstCharge = 0;
168  TVector3 fstMomentum;
169 
170  void summary() {
171  LOG_INFO << TString::Format( "TrackResult[p=(%f, %f, %f)/(%f, %f, %f), q=%f, nFTT=%lu, nFST=%lu, nPV=%lu, isFitConvergedFully=%d]", momentum.X(), momentum.Y(), momentum.Z(), momentum.Pt(), momentum.Eta(), momentum.Phi(), charge, nFTT, nFST, nPV, isFitConvergedFully ).Data() << endm;
172  }
173 };
174 
176  public:
177  ForwardTrackMaker() : mConfigFile("config.xml"), mEventVertex(-999, -999, -999) {
178  // noop
179  }
180 
181  const std::vector<GenfitTrackResult> &getTrackResults() const { return mTrackResults; }
182  const std::vector<Seed_t> &getRecoTracks() const { return mRecoTracks; }
183  const std::vector<TVector3> &getFitMomenta() const { return mFitMoms; }
184  const std::vector<unsigned short> &getNumFstHits() const { return mNumFstHits; }
185  const std::vector<genfit::FitStatus> &getFitStatus() const { return mFitStatus; }
186  const std::vector<genfit::AbsTrackRep *> &globalTrackReps() const { return mGlobalTrackReps; }
187  const std::vector<genfit::Track *> &globalTracks() const { return mGlobalTracks; }
188 
189  void setConfigFile(std::string cf) {
190  mConfigFile = cf;
191  }
192 
193  void setSaveCriteriaValues(bool save) {
194  mSaveCriteriaValues = save;
195  }
196 
197  // Adopt external configuration file
198  void setConfig(FwdTrackerConfig cfg) { mConfig = cfg; }
199  // Adopt external hit loader
200  void setData(std::shared_ptr<FwdDataSource>data) { mDataSource = data; }
201 
202  virtual void initialize( TString geoCache, bool genHistograms) {
203  mGenHistograms = genHistograms;
204  if (mGenHistograms) setupHistograms();
205 
206  mGeoCache = geoCache;
207  mDoTrackFitting = !(mConfig.get<bool>("TrackFitter:off", false));
208 
209  if (!mConfig.exists("TrackFitter"))
210  mDoTrackFitting = false;
211  }
212 
213 
214  void writeEventHistograms() {
215 
216  // no file, dont write anything
217  if ( !gDirectory )
218  return;
219 
220  gDirectory->cd();
221  // write out the config we use (do before histos):
222  TNamed n("mConfig", mConfig.dump());
223  n.Write();
224 
225  writeHistograms();
226 
227  gDirectory->mkdir("Fit/");
228  gDirectory->cd("Fit/");
229  mTrackFitter->writeHistograms();
230  gDirectory->cd("");
231  mQualityPlotter->writeHistograms();
232  }
233 
240  std::vector<KiTrack::ICriterion *> loadCriteria(string path) {
241 
242  std::vector<KiTrack::ICriterion *> crits;
243  auto paths = mConfig.childrenOf(path);
244 
245  for (string p : paths) {
246  string name = mConfig.get<string>(p + ":name", "");
247  bool active = mConfig.get<bool>(p + ":active", true);
248 
249  if (false == active) {
250  continue;
251  }
252 
253  float vmin = mConfig.get<float>(p + ":min", 0);
254  float vmax = mConfig.get<float>(p + ":max", 1);
255 
256  KiTrack::ICriterion * crit = nullptr;
257  if ( name == "Crit2_BDT" ){
258  crit = new BDTCrit2( vmin, vmax );
259  } else {
260  crit = KiTrack::Criteria::createCriterion(name, vmin, vmax);
261  }
262 
263  crit->setSaveValues(mSaveCriteriaValues);
264 
265  if (mSaveCriteriaValues)
266  crits.push_back(new CriteriaKeeper(crit)); // CriteriaKeeper intercepts values and saves them
267  else
268  crits.push_back(crit);
269 
270  }
271 
272  return crits;
273  }
274 
275  std::vector<float> getCriteriaValues(std::string crit_name) {
276  std::vector<float> em;
277  if (mSaveCriteriaValues != true) {
278  return em;
279  }
280 
281  for (auto crit : mTwoHitCrit) {
282  if (crit_name == crit->getName()) {
283  auto critKeeper = static_cast<CriteriaKeeper *>(crit);
284  return critKeeper->getValues();
285  }
286  }
287 
288  for (auto crit : mThreeHitCrit) {
289  if (crit_name == crit->getName()) {
290  auto critKeeper = static_cast<CriteriaKeeper *>(crit);
291  return critKeeper->getValues();
292  }
293  }
294 
295  return em;
296  };
297 
298  std::vector<std::map < std::string , float >> getCriteriaAllValues(std::string crit_name) {
299  std::vector<std::map < std::string , float >> em;
300  if (mSaveCriteriaValues != true) {
301  return em;
302  }
303 
304  for (auto crit : mTwoHitCrit) {
305  if (crit_name == crit->getName()) {
306  auto critKeeper = static_cast<CriteriaKeeper *>(crit);
307  return critKeeper->getAllValues();
308  }
309  }
310 
311  for (auto crit : mThreeHitCrit) {
312  if (crit_name == crit->getName()) {
313  auto critKeeper = static_cast<CriteriaKeeper *>(crit);
314  return critKeeper->getAllValues();
315  }
316  }
317 
318  return em;
319  };
320 
321  std::vector<int> getCriteriaTrackIds(std::string crit_name) {
322  std::vector<int> em;
323  if (mSaveCriteriaValues != true) {
324  return em;
325  }
326 
327  for (auto crit : mTwoHitCrit) {
328  if (crit_name == crit->getName()) {
329  auto critKeeper = static_cast<CriteriaKeeper *>(crit);
330  return critKeeper->getTrackIds();
331  }
332  }
333 
334  for (auto crit : mThreeHitCrit) {
335  if (crit_name == crit->getName()) {
336  auto critKeeper = static_cast<CriteriaKeeper *>(crit);
337  return critKeeper->getTrackIds();
338  }
339  }
340 
341  return em;
342  };
343 
344  void clearSavedCriteriaValues() {
345  if (mSaveCriteriaValues != true) {
346  return;
347  }
348 
349  for (auto crit : mTwoHitCrit) {
350  auto critKeeper = static_cast<CriteriaKeeper *>(crit);
351  critKeeper->clear();
352  }
353 
354  for (auto crit : mThreeHitCrit) {
355  auto critKeeper = static_cast<CriteriaKeeper *>(crit);
356  critKeeper->clear();
357  }
358  }
359 
360  size_t nHitsInHitMap(FwdDataSource::HitMap_t &hitmap) {
361  size_t n = 0;
362 
363  for (auto kv : hitmap) {
364  n += kv.second.size();
365  }
366 
367  return n;
368  }
369 
370  size_t countRecoTracks(size_t nHits) {
371  size_t n = 0;
372 
373  for (auto t : mRecoTracks) {
374  if (t.size() == nHits)
375  n++;
376  }
377 
378  return n;
379  }
380 
381  void setupHistograms() {
382 
383  mHist["input_nhits"] = new TH1I("input_nhits", ";# hits", 1000, 0, 1000);
384  mHist["nAttemptedFits"] = new TH1I("nAttemptedFits", ";;# attempted fits", 10, 0, 10);
385  mHist["nPossibleFits"] = new TH1I("nPossibleFits", ";;# possible fits", 10, 0, 10);
386  // refit with silicon
387  mHist["nPossibleReFits"] = new TH1I("nPossibleReFits", ";;# possible REfits", 10, 0, 10);
388  mHist["nAttemptedReFits"] = new TH1I("nAttemptedReFits", ";;#attempted REfits", 10, 0, 10);
389  mHist["nFailedReFits"] = new TH1I("nFailedReFits", ";;# failed REfits", 10, 0, 10);
390 
391  mHist["FitStatus"] = new TH1I("FitStatus", ";;# failed REfits", 15, 0, 15);
392  FwdTrackerUtils::labelAxis(mHist["FitStatus"]->GetXaxis(), {"Seeds", "AttemptFit", "GoodFit", "BadFit", "GoodCardinal", "PossibleReFit", "AttemptReFit", "GoodReFit", "BadReFit", "w3Si","w2Si", "w1Si", "w0Si" });
393 
394  mHist["FitDuration"] = new TH1I("FitDuration", ";Duration (ms)", 5000, 0, 50000);
395  mHist["nSiHitsFound"] = new TH2I( "nSiHitsFound", ";Si Disk; n Hits", 5, 0, 5, 10, 0, 10 );
396 
397  mHist["Step1Duration"] = new TH1I("Step1Duration", ";Duration (ms)", 500, 0, 500);
398  mHist["Step2Duration"] = new TH1I("Step2Duration", ";Duration (ms)", 500, 0, 500);
399  mHist["Step3Duration"] = new TH1I("Step3Duration", ";Duration (ms)", 500, 0, 500);
400  mHist["Step4Duration"] = new TH1I("Step4Duration", ";Duration (ms)", 500, 0, 500);
401  }
402 
403  void fillHistograms() {
404 
405  if (mGenHistograms && mDataSource != nullptr) {
406  auto hm = mDataSource->getFttHits();
407  for (auto hp : hm)
408  mHist["input_nhits"]->Fill(hp.second.size());
409  }
410  }
411 
412  void writeHistograms() {
413  if ( !mGenHistograms ){
414  return;
415  }
416 
417  for (auto nh : mHist) {
418  nh.second->SetDirectory(gDirectory);
419  nh.second->Write();
420  }
421  }
422 
423  // this is the main event loop. doEvent processes a single event iEvent...
424  void make() {
425 
426  int single_event = mConfig.get<int>("Input:event", -1);
427 
428  if (single_event >= 0) {
429  doEvent(single_event);
430  return;
431  }
432 
433  unsigned long long firstEvent = mConfig.get<unsigned long long>("Input:first-event", 0);
434 
435  if (mConfig.exists("Input:max-events")) {
436  unsigned long long maxEvents = mConfig.get<unsigned long long>("Input:max-events", 0);
437 
438  if (nEvents > maxEvents)
439  nEvents = maxEvents;
440 
441  }
442 
443  // loop over events
444 
445  for (unsigned long long iEvent = firstEvent; iEvent < firstEvent + nEvents; iEvent++) {
446  doEvent(iEvent);
447  }
448 
449  if (mGenHistograms){
450  mQualityPlotter->finish();
451  writeEventHistograms();
452  }
453  }
454 
455  void removeHits(FwdDataSource::HitMap_t &hitmap, std::vector<Seed_t> &tracks) {
456 
457  for (auto track : tracks) {
458  for (auto hit : track) {
459  int sector = hit->getSector();
460 
461  auto hitit = std::find(hitmap[sector].begin(), hitmap[sector].end(), hit);
462 
463  if (hitit != hitmap[sector].end()) {
464  hitmap[sector].erase(hitit);
465  mTotalHitsRemoved++;
466  }
467 
468  } // loop on hits in track
469  } // loop on track
470  } // removeHits
471 
472  void doEvent(unsigned long long int iEvent = 0) {
473  /************** Cleanup ****************************************/
474  // Moved cleanup to the start of doEvent, so that the fit results
475  // persist after the call
476  mRecoTracks.clear();
477  mRecoTrackQuality.clear();
478  mRecoTrackIdTruth.clear();
479  mFitMoms.clear();
480  mNumFstHits.clear();
481  mFitStatus.clear();
482 
483 
484  // Clear pointers to the track reps from previous event
485  for (auto p : mGlobalTrackReps)
486  delete p;
487 
488  mGlobalTrackReps.clear();
489 
490  // Clear pointers to global tracks
491  for (auto p : mGlobalTracks)
492  delete p;
493 
494  mGlobalTracks.clear();
495 
496  mTrackResults.clear();
497  /************** Cleanup **************************/
498 
499  if (mGenHistograms ){
500  mQualityPlotter->startEvent(); // starts the timer for this event
501  }
502 
503  mTotalHitsRemoved = 0;
504 
505  /*************************************************************/
506  // Step 1
507  // Load and sort the hits
508  /*************************************************************/
509  long long itStart = FwdTrackerUtils::nowNanoSecond();
510  FwdDataSource::HitMap_t &hitmap = mDataSource->getFttHits();;
511  FwdDataSource::McTrackMap_t &mcTrackMap = mDataSource->getMcTracks();
512 
513  fillHistograms();
514  long long duration = (FwdTrackerUtils::nowNanoSecond() - itStart) * 1e-6; // milliseconds
515  if (mGenHistograms)
516  mHist["Step1Duration"]->Fill( duration );
517 
518 
519  bool mcTrackFinding = true;
520 
521  if (mConfig.exists("TrackFinder"))
522  mcTrackFinding = false;
523 
524  /***********************************************/
525  // MC Track Finding
526  if (mcTrackFinding) {
527  LOG_DEBUG << "MC TRACK FINDING " << endm;
528  doMcTrackFinding(mcTrackMap);
529 
530  /***********************************************/
531  // REFIT with Silicon hits
532  if (mConfig.get<bool>("TrackFitter:refitSi", true)) {
533  addSiHitsMc();
534  } else {
535  LOG_DEBUG << "Skipping FST Hits" << endm;
536  // skip Si refit
537  }
538  /***********************************************/
539 
540  if (mConfig.get<bool>("TrackFitter:refitGBL", true)) {
541  for (size_t i = 0; i < mGlobalTracks.size(); i++) {
542  mTrackFitter->refitTrackWithGBL(mGlobalTracks[i]);
543  }
544  }
545 
546  if (mGenHistograms ){
547  mQualityPlotter->summarizeEvent(mRecoTracks, mcTrackMap, mFitMoms, mFitStatus);
548  }
549  return;
550  }
551  /***********************************************/
552 
553  /***********************************************/
554  // Standard Track Finding
555  // plus initial fit
556  size_t nIterations = mConfig.get<size_t>("TrackFinder:nIterations", 0);
557  for (size_t iIteration = 0; iIteration < nIterations; iIteration++) {
558  doTrackIteration(iIteration, hitmap);
559  }
560  /***********************************************/
561 
562  /***********************************************/
563  // REFIT with Silicon hits
564  if (mConfig.get<bool>("TrackFitter:refitSi", true)) {
565  addSiHits();
566  } else {
567  // Skipping Si Refit
568  }
569  /***********************************************/
570 
571  if ( mGenHistograms ){
572  mQualityPlotter->summarizeEvent(mRecoTracks, mcTrackMap, mFitMoms, mFitStatus);
573  }
574  } // doEvent
575 
576  void fitTrack(Seed_t &track) {
577 
578  if ( mGenHistograms ){
579  mHist["FitStatus"]->Fill("Seeds", 1);
580  }
581 
582  // Calculate the MC info first and check filters
583  int idt = 0;
584  double qual = 0;
585  idt = MCTruthUtils::dominantContribution(track, qual);
586 
587 
588 
589 
590  TVector3 mcSeedMom;
591 
592  auto mctm = mDataSource->getMcTracks();
593  // get the MC track momentum if we can
594  if (mctm.count(idt)) {
595  auto mct = mctm[idt];
596  mcSeedMom.SetPtEtaPhi(mct->mPt, mct->mEta, mct->mPhi);
597  }
598 
599 
600  // Mc Filter
601  bool bailout = false;
602  if (qual < mConfig.get<float>("TrackFitter.McFilter:quality-min", 0.0)) {
603  bailout = true;
604  // LOG_INFO << "BAIL OUT on Fit bc quality = " << qual << endm;
605  }
606  if (mctm.count(idt)) {
607  auto mct = mctm[idt];
608  mcSeedMom.SetPtEtaPhi(mct->mPt, mct->mEta, mct->mPhi);
609  if (mct->mPt < mConfig.get<float>("TrackFitter.McFilter:pt-min", 0.0) ||
610  mct->mPt > mConfig.get<float>("TrackFitter.McFilter:pt-max", 1e10)) {
611  bailout = true;
612  // LOG_INFO << "BAIL OUT on Fit bc Pt = " << mct->mPt << endm;
613  }
614  if (mct->mEta < mConfig.get<float>("TrackFitter.McFilter:eta-min", 0) ||
615  mct->mEta > mConfig.get<float>("TrackFitter.McFilter:eta-max", 1e10)) {
616  bailout = true;
617  // LOG_INFO << "BAIL OUT on Fit bc eta = " << mct->mEta << endm;
618  }
619 
620  } else {
621  // cannot find the track
622  }
623 
624  bailout = false;
625 
626  TVector3 p;
627  p.SetPtEtaPhi( 0, -999, 0 );
628  genfit::FitStatus fitStatus;
629 
630  genfit::AbsTrackRep *trackRep = nullptr;//new genfit::RKTrackRep(211); // pdg for pi+
631  genfit::Track *genTrack = nullptr;//new genfit::Track( trackRep, TVector3(0, 0, 0), TVector3(0, 0, 0) );
632 
633 
634  if (mDoTrackFitting && !bailout) {
635  if ( mGenHistograms ){
636  mHist["FitStatus"]->Fill("AttemptFit", 1);
637  }
638 
639  double vertex[3] = { mEventVertex.X(), mEventVertex.Y(), mEventVertex.Z() };
640 
641  double * pVertex = 0;
642  if ( fabs(mEventVertex.X()) < 100 ){
643  pVertex = vertex; // only use it if it has been set from default
644  }
645 
646 
647  if (true == mConfig.get<bool>("TrackFitter:mcSeed", false)) {
648  // use the MC pt, eta, phi as the seed for fitting
649  p = mTrackFitter->fitTrack(track, pVertex, &mcSeedMom);
650  } else {
651  // Normal case, real data
652  p = mTrackFitter->fitTrack(track, pVertex);
653  }
654 
655  if ( mGenHistograms ){
656  if (p.Perp() > 1e-3) {
657  mHist["FitStatus"]->Fill("GoodFit", 1);
658  } else {
659  mHist["FitStatus"]->Fill("BadFit", 1);
660  }
661  }
662 
663 
664  genTrack = new genfit::Track(*mTrackFitter->getTrack());
665  genTrack->setMcTrackId(idt);
666  GenfitTrackResult gtr( track.size(), 0, track, genTrack );
667 
668  // assign the fit results to be saved
669  fitStatus = mTrackFitter->getStatus();
670  trackRep = mTrackFitter->getTrackRep()->clone(); // Clone the track rep
671 
672  if ( mGenHistograms && genTrack->getFitStatus(genTrack->getCardinalRep())->isFitConverged() && p.Perp() > 1e-3) {
673  mHist["FitStatus"]->Fill("GoodCardinal", 1);
674  }
675 
676  // Save everything (now use GenfitTrackResult)
677  mFitMoms.push_back(p);
678  mGlobalTracks.push_back(genTrack);
679  mGlobalTrackReps.push_back(trackRep);
680  mFitStatus.push_back(fitStatus);
681  mRecoTrackQuality.push_back(qual);
682  mRecoTrackIdTruth.push_back(idt);
683  mNumFstHits.push_back(0);
684 
685  mTrackResults.push_back( gtr );
686 
687  LOG_DEBUG << "FwdTracker::fitTrack complete" << endm;
688  } // if (mDoTrackFitting && !bailout)
689  }
690 
691  void doTrackFitting( std::vector<Seed_t> &tracks) {
692  long long itStart = FwdTrackerUtils::nowNanoSecond();
693  // Fit each accepted track seed
694  for (auto t : tracks) {
695  fitTrack(t);
696  }
697  long long itEnd = FwdTrackerUtils::nowNanoSecond();
698  long long duration = (itEnd - itStart) * 1e-6; // milliseconds
699  if ( mGenHistograms ){
700  this->mHist["FitDuration"]->Fill(duration);
701  }
702  // TODO: After tracking vertex finding...
703 
704  }
705 
706  void doMcTrackFinding(FwdDataSource::McTrackMap_t &mcTrackMap) {
707 
708  mQualityPlotter->startIteration();
709 
710  // we will build reco tracks from each McTrack
711  for (auto kv : mcTrackMap) {
712 
713  auto mc_track = kv.second;
714  if (mc_track->mHits.size() < 4){ // require min 4 hits on track
715  continue;
716  }
717 
718  std::set<size_t> uvid;
719  Seed_t track;
720 
721  for (auto h : mc_track->mHits) {
722  track.push_back(h);
723  uvid.insert(static_cast<FwdHit *>(h)->_vid);
724  }
725 
726  if (uvid.size() == track.size()) { // only add tracks that have one hit per volume
727  mRecoTracks.push_back(track);
728  int idt = 0;
729  double qual = 0;
730  idt = MCTruthUtils::dominantContribution(track, qual);
731  mRecoTrackQuality.push_back(qual);
732  mRecoTrackIdTruth.push_back(idt);
733  } else {
734  //Skipping track that doesnt have hits on all layers
735  }
736  }
737 
738  LOG_DEBUG << "McTrackFinding Found: " << mRecoTracks.size() << " tracks" << endm;
739 
740  doTrackFitting(mRecoTracks);
741 
742  if ( mGenHistograms ){
743  mQualityPlotter->afterIteration(0, mRecoTracks);
744  }
745  }
746 
747 
758  size_t sliceHitMapInPhi( FwdDataSource::HitMap_t &inputMap, FwdDataSource::HitMap_t &outputMap, float phi_min, float phi_max ){
759  size_t n_hits_kept = 0;
760 
761  outputMap.clear(); // child STL containers will get cleared too
762  for ( auto kv : inputMap ){
763  for ( KiTrack::IHit* hit : kv.second ){
764  TVector3 vec(hit->getX(), hit->getY(), hit->getZ() );
765  if ( vec.Phi() < phi_min || vec.Phi() > phi_max ) continue;
766 
767  // now add the hits to the sliced map
768  outputMap[kv.first].push_back( hit );
769  n_hits_kept ++;
770  } // loop on hits
771  } // loop on map
772  return n_hits_kept;
773  }
774 
781  vector<Seed_t> doTrackingOnHitmapSubset( size_t iIteration, FwdDataSource::HitMap_t &hitmap ) {
782  long long itStart = FwdTrackerUtils::nowNanoSecond();
783 
784  std::vector<Seed_t> acceptedTracks;
785  std::vector<Seed_t> rejectedTracks;
786  /*************************************************************/
787  // Step 2
788  // build 2-hit segments (setup parent child relationships)
789  /*************************************************************/
790  // Initialize the segment builder with sorted hits
791  KiTrack::SegmentBuilder builder(hitmap);
792 
793  // Load the criteria used for 2-hit segments
794  // This loads from XML config if available
795  std::string criteriaPath = "TrackFinder.Iteration[" + std::to_string(iIteration) + "].SegmentBuilder";
796 
797  if (false == mConfig.exists(criteriaPath)) {
798  // Use the default for all iterations if it is given.
799  // If not then no criteria will be applied
800  criteriaPath = "TrackFinder.SegmentBuilder";
801  }
802 
803  mTwoHitCrit.clear();
804  mTwoHitCrit = loadCriteria(criteriaPath);
805  builder.addCriteria(mTwoHitCrit);
806 
807  // Setup the connector (this tells it how to connect hits together into segments)
808  std::string connPath = "TrackFinder.Iteration[" + std::to_string(iIteration) + "].Connector";
809 
810  if (false == mConfig.exists(connPath))
811  connPath = "TrackFinder.Connector";
812 
813  unsigned int distance = mConfig.get<unsigned int>(connPath + ":distance", 1);
814 
815  FwdConnector connector(distance);
816  builder.addSectorConnector(&connector);
817 
818  // Get the segments and return an automaton object for further work
819 
820  KiTrack::Automaton automaton = builder.get1SegAutomaton();
821  LOG_DEBUG << TString::Format( "nSegments=%lu", automaton.getSegments().size() ).Data() << endm;
822  LOG_DEBUG << TString::Format( "nConnections=%u", automaton.getNumberOfConnections() ).Data() << endm;
823 
824  if (automaton.getNumberOfConnections() > 900 ){
825  LOG_ERROR << "Got too many connections, bailing out of tracking" << endm;
826  return acceptedTracks;
827  }
828 
829  // at any point we can get a list of tracks out like this:
830  // std::vector < std::vector< KiTrack::IHit* > > tracks = automaton.getTracks();
831  // we can apply an optional parameter <nHits> to only get tracks with >=nHits in them
832 
833  long long duration = (FwdTrackerUtils::nowNanoSecond() - itStart) * 1e-6; // milliseconds
834  if (mGenHistograms)
835  mHist["Step2Duration"]->Fill( duration );
836  itStart = FwdTrackerUtils::nowNanoSecond();
837 
838  /*************************************************************/
839  // Step 3
840  // build 3-hit segments from the 2-hit segments
841  /*************************************************************/
842  automaton.clearCriteria();
843  automaton.resetStates();
844  criteriaPath = "TrackFinder.Iteration[" + std::to_string(iIteration) + "].ThreeHitSegments";
845 
846  if (false == mConfig.exists(criteriaPath))
847  criteriaPath = "TrackFinder.ThreeHitSegments";
848 
849  mThreeHitCrit.clear();
850  mThreeHitCrit = loadCriteria(criteriaPath);
851  automaton.addCriteria(mThreeHitCrit);
852  automaton.lengthenSegments();
853 
854  bool doAutomation = mConfig.get<bool>(criteriaPath + ":doAutomation", true);
855  bool doCleanBadStates = mConfig.get<bool>(criteriaPath + ":cleanBadStates", true);
856 
857  if (doAutomation) {
858  automaton.doAutomaton();
859  } else {
860  //Not running Automation Step
861  }
862 
863  if (doAutomation && doCleanBadStates) {
864  automaton.cleanBadStates();
865  }
866 
867  duration = (FwdTrackerUtils::nowNanoSecond() - itStart) * 1e-6; // milliseconds
868  if (mGenHistograms)
869  mHist["Step3Duration"]->Fill( duration );
870  if (duration > 200 || automaton.getNumberOfConnections() > 900){
871  LOG_WARN << "The Three Hit Criteria took more than 200ms to process, duration: " << duration << " ms" << endm;
872  LOG_WARN << "bailing out (skipping subset HNN)" << endm;
873  std::vector<Seed_t> acceptedTracks;
874  std::string subsetPath = "TrackFinder.Iteration[" + std::to_string(iIteration) + "].SubsetNN";
875  size_t minHitsOnTrack = mConfig.get<size_t>(subsetPath + ":min-hits-on-track", FwdSystem::sNFttLayers);
876  acceptedTracks = automaton.getTracks(minHitsOnTrack);
877  return acceptedTracks;
878  }
879  itStart = FwdTrackerUtils::nowNanoSecond();
880 
881  LOG_DEBUG << TString::Format( "nSegments=%lu", automaton.getSegments().size() ).Data() << endm;
882  LOG_DEBUG << TString::Format( "nConnections=%u", automaton.getNumberOfConnections() ).Data() << endm;
883 
884  /*************************************************************/
885  // Step 4
886  // Get the tracks from the possible tracks that are the best subset
887  /*************************************************************/
888  std::string subsetPath = "TrackFinder.Iteration[" + std::to_string(iIteration) + "].SubsetNN";
889 
890  if (false == mConfig.exists(subsetPath))
891  subsetPath = "TrackFinder.SubsetNN";
892 
893  // only for debug really
894  bool findSubsets = mConfig.get<bool>(subsetPath + ":active", true);
895 
896  if (findSubsets) {
897  size_t minHitsOnTrack = mConfig.get<size_t>(subsetPath + ":min-hits-on-track", 7);
898  // Getting all tracks with at least minHitsOnTrack hits on them
899  std::vector<Seed_t> tracks = automaton.getTracks(minHitsOnTrack);
900 
901  float omega = mConfig.get<float>(subsetPath + ".Omega", 0.75);
902  float stableThreshold = mConfig.get<float>(subsetPath + ".StableThreshold", 0.1);
903  float Ti = mConfig.get<float>(subsetPath + ".InitialTemp", 2.1);
904  float Tf = mConfig.get<float>(subsetPath + ".InfTemp", 0.1);
905 
906  KiTrack::SubsetHopfieldNN<Seed_t> subset;
907  subset.add(tracks);
908  subset.setOmega(omega);
909  subset.setLimitForStable(stableThreshold);
910  subset.setTStart(Ti);
911  subset.setTInf(Tf);
912 
913  SeedCompare comparer;
914  SeedQual quality;
915 
916  subset.calculateBestSet(comparer, quality);
917 
918  acceptedTracks = subset.getAccepted();
919 
920  // this call takes a long time due to possible huge combinatorics.
921  // rejectedTracks = subset.getRejected();
922  // LOG_DEBUG << "We had " << tracks.size() << " tracks. Accepted = " << acceptedTracks.size() << ", Rejected = " << rejectedTracks.size() << endm;
923 
924  } else { // the subset and hit removal
925  size_t minHitsOnTrack = mConfig.get<size_t>(subsetPath + ":min-hits-on-track", FwdSystem::sNFttLayers);
926  acceptedTracks = automaton.getTracks(minHitsOnTrack);
927  }// subset off
928 
929  duration = (FwdTrackerUtils::nowNanoSecond() - itStart) * 1e-6; // milliseconds
930  if (mGenHistograms)
931  mHist["Step4Duration"]->Fill( duration );
932  if (duration > 500){
933  LOG_WARN << "The took more than 500ms to process, duration: " << duration << " ms" << endm;
934  LOG_WARN << "We got " << acceptedTracks.size() << " tracks this round" << endm;
935  }
936  LOG_DEBUG << "We got " << acceptedTracks.size() << " tracks this round" << endm;
937  return acceptedTracks;
938  } // doTrackingOnHitmapSubset
939 
940  void doTrackIteration(size_t iIteration, FwdDataSource::HitMap_t &hitmap) {
941 
942  // empty the list of reco tracks for the iteration
943  mRecoTracksThisItertion.clear();
944 
945  // check to see if we have hits!
946  size_t nHitsThisIteration = nHitsInHitMap(hitmap);
947 
948  if (nHitsThisIteration < 4) {
949  // No hits left in the hitmap! Skipping this iteration
950  return;
951  }
952 
953  // this starts the timer for the iteration
954  if ( mGenHistograms ){
955  mQualityPlotter->startIteration();
956  }
957 
958  std::string pslPath = "TrackFinder.Iteration["+ std::to_string(iIteration) + "]:nPhiSlices";
959  if ( false == mConfig.exists( pslPath ) ) pslPath = "TrackFinder:nPhiSlices";
960  size_t phi_slice_count = mConfig.get<size_t>( pslPath, 1 );
961 
962  if ( phi_slice_count <= 1 || phi_slice_count > 100 ) { // no phi slicing!
963  LOG_DEBUG << "Tracking without phi slices" << endm;
964  /*************************************************************/
965  // Steps 2 - 4 here
966  /*************************************************************/
967  auto acceptedTracks = doTrackingOnHitmapSubset( iIteration, hitmap );
968  mRecoTracksThisItertion.insert( mRecoTracksThisItertion.end(), acceptedTracks.begin(), acceptedTracks.end() );
969  } else {
970 
971  FwdDataSource::HitMap_t slicedHitMap;
972 
973  if ( phi_slice_count == 0 || phi_slice_count > 100 ){
974  LOG_WARN << "Invalid phi_slice_count = " << phi_slice_count << ", resetting to 1" << endm;
975  phi_slice_count= 1;
976  }
977  float phi_slice = 2 * TMath::Pi() / (float) phi_slice_count;
978  for ( size_t phi_slice_index = 0; phi_slice_index < phi_slice_count; phi_slice_index++ ){
979 
980  float phi_min = phi_slice_index * phi_slice - TMath::Pi();
981  float phi_max = (phi_slice_index + 1) * phi_slice - TMath::Pi();
982 
983  /*************************************************************/
984  // Step 1A
985  // Slice the hitmap into a phi section if needed
986  // If we do that, check again that we arent wasting time on empty sections
987  /*************************************************************/
988  size_t nHitsThisSlice = 0;
989  if ( phi_slice_count > 1 ){
990  nHitsThisSlice = sliceHitMapInPhi( hitmap, slicedHitMap, phi_min, phi_max );
991  if ( nHitsThisSlice < 4 ) {
992  continue;
993  }
994  } else { // no need to slice
995  // I think this incurs a copy, maybe we can find a way to avoid.
996  slicedHitMap = hitmap;
997  }
998 
999  /*************************************************************/
1000  // Steps 2 - 4 here
1001  /*************************************************************/
1002  auto acceptedTracks = doTrackingOnHitmapSubset( iIteration, slicedHitMap );
1003  mRecoTracksThisItertion.insert( mRecoTracksThisItertion.end(), acceptedTracks.begin(), acceptedTracks.end() );
1004  } //loop on phi slices
1005  }// if loop on phi slices
1006  LOG_INFO << ".";
1007  /*************************************************************/
1008  // Step 5
1009  // Remove the hits from any track that was found
1010  /*************************************************************/
1011  std::string hrmPath = "TrackFinder.Iteration["+ std::to_string(iIteration) + "].HitRemover";
1012  if ( false == mConfig.exists( hrmPath ) ) hrmPath = "TrackFinder.HitRemover";
1013 
1014  if ( true == mConfig.get<bool>( hrmPath + ":active", true ) ){
1015  removeHits( hitmap, mRecoTracksThisItertion );
1016  }
1017 
1018  LOG_DEBUG << " FITTING " << mRecoTracksThisItertion.size() << " now" << endm;
1019 
1020  if ( mRecoTracksThisItertion.size() < 201 ){
1021  doTrackFitting( mRecoTracksThisItertion );
1022  } else {
1023  LOG_ERROR << "BAILING OUT of fit, too many track candidates" << endm;
1024  }
1025 
1026  if ( mGenHistograms ){
1027  mQualityPlotter->afterIteration( iIteration, mRecoTracksThisItertion );
1028  }
1029 
1030  // Add the set of all accepted tracks (this iteration) to our collection of found tracks from all iterations
1031  mRecoTracks.insert( mRecoTracks.end(), mRecoTracksThisItertion.begin(), mRecoTracksThisItertion.end() );
1032 
1033  } // doTrackIteration
1034 
1035  void addSiHitsMc() {
1036  FwdDataSource::HitMap_t hitmap = mDataSource->getFstHits();
1037 
1038  for (size_t i = 0; i < mTrackResults.size(); i++) {
1039  GenfitTrackResult &gtr = mTrackResults[i];
1040 
1041  if ( gtr.status.isFitConverged() == false || gtr.momentum.Perp() < 1e-3) {
1042  LOG_DEBUG << "Skipping addSiHitsMc, fit failed" << endm;
1043  return;
1044  }
1045 
1046  if ( mGenHistograms){
1047  mHist["FitStatus"]->Fill("PossibleReFit", 1);
1048  }
1049 
1050  Seed_t si_hits_for_this_track(3, nullptr);
1051 
1052  for (size_t j = 0; j < 3; j++) {
1053  for (auto h0 : hitmap[j]) {
1054  if (dynamic_cast<FwdHit *>(h0)->_tid == gtr.track->getMcTrackId()) {
1055  si_hits_for_this_track[j] = h0;
1056  break;
1057  }
1058  } // loop on hits in this layer of hitmap
1059  } // loop on hitmap layers
1060 
1061  size_t nSiHitsFound = 0;
1062  if ( si_hits_for_this_track[0] != nullptr ) nSiHitsFound++;
1063  if ( si_hits_for_this_track[1] != nullptr ) nSiHitsFound++;
1064  if ( si_hits_for_this_track[2] != nullptr ) nSiHitsFound++;
1065  LOG_DEBUG << "Found " << nSiHitsFound << " FST Hits on this track (MC lookup)" << endm;
1066 
1067  if ( mGenHistograms ){
1068  this->mHist[ "nSiHitsFound" ]->Fill( 1, ( si_hits_for_this_track[0] != nullptr ? 1 : 0 ) );
1069  this->mHist[ "nSiHitsFound" ]->Fill( 2, ( si_hits_for_this_track[1] != nullptr ? 1 : 0 ) );
1070  this->mHist[ "nSiHitsFound" ]->Fill( 3, ( si_hits_for_this_track[2] != nullptr ? 1 : 0 ) );
1071  }
1072 
1073  if (nSiHitsFound >= 1) {
1074  if ( mGenHistograms ){
1075  mHist["FitStatus"]->Fill("AttemptReFit", 1);
1076  }
1077  TVector3 p = mTrackFitter->refitTrackWithSiHits(gtr.track, si_hits_for_this_track);
1078 
1079  if ( mGenHistograms ){
1080  if (p.Perp() == mFitMoms[i].Perp()) {
1081  mHist["FitStatus"]->Fill("BadReFit", 1);
1082  LOG_DEBUG << "refitTrackWithSiHits failed refit" << endm;
1083  } else {
1084  mHist["FitStatus"]->Fill("GoodReFit", 1);
1085  gtr.setFst( si_hits_for_this_track, mTrackFitter->getTrack() );
1086  }
1087  }
1088 
1089  mNumFstHits[i] = nSiHitsFound;
1090  mFitMoms[i] = p;
1091  } // we have 3 Si hits to refit with
1092 
1093  if ( mGenHistograms ){
1094  mHist["FitStatus"]->Fill( TString::Format( "w%luSi", nSiHitsFound ).Data(), 1 );
1095  }
1096 
1097  } // loop on the global tracks
1098  } // ad Si hits via MC associations
1099 
1100  void addSiHits() {
1101  FwdDataSource::HitMap_t hitmap = mDataSource->getFstHits();
1102 
1103  // loop on global tracks
1104  for (size_t i = 0; i < mGlobalTracks.size(); i++) {
1105  if (mGlobalTracks[i]->getFitStatus(mGlobalTracks[i]->getCardinalRep())->isFitConverged() == false) {
1106  // Original Track fit did not converge, skipping
1107  return;
1108  }
1109 
1110  if ( mGenHistograms ){
1111  mHist["FitStatus"]->Fill("PossibleReFit", 1);
1112  }
1113 
1114  Seed_t hits_near_disk0;
1115  Seed_t hits_near_disk1;
1116  Seed_t hits_near_disk2;
1117  try {
1118  auto msp2 = mTrackFitter->projectToFst(2, mGlobalTracks[i]);
1119  auto msp1 = mTrackFitter->projectToFst(1, mGlobalTracks[i]);
1120  auto msp0 = mTrackFitter->projectToFst(0, mGlobalTracks[i]);
1121 
1122  // now look for Si hits near these
1123  hits_near_disk2 = findSiHitsNearMe(hitmap[2], msp2);
1124  hits_near_disk1 = findSiHitsNearMe(hitmap[1], msp1);
1125  hits_near_disk0 = findSiHitsNearMe(hitmap[0], msp0);
1126  } catch (genfit::Exception &e) {
1127  // Failed to project to Si disk: ", e.what()
1128  }
1129 
1130  vector<KiTrack::IHit *> hits_to_add;
1131 
1132  size_t nSiHitsFound = 0; // this is really # of disks on which a hit is found
1133 
1134  if ( mGenHistograms ){
1135  this->mHist[ "nSiHitsFound" ]->Fill( 1, hits_near_disk0.size() );
1136  this->mHist[ "nSiHitsFound" ]->Fill( 2, hits_near_disk1.size() );
1137  this->mHist[ "nSiHitsFound" ]->Fill( 3, hits_near_disk2.size() );
1138  }
1139 
1140  // TODO: HANDLE multiple points found?
1141  if ( hits_near_disk0.size() == 1 ) {
1142  hits_to_add.push_back( hits_near_disk0[0] );
1143  nSiHitsFound++;
1144  } else {
1145  hits_to_add.push_back( nullptr );
1146  }
1147  if ( hits_near_disk1.size() == 1 ) {
1148  hits_to_add.push_back( hits_near_disk1[0] );
1149  nSiHitsFound++;
1150  } else {
1151  hits_to_add.push_back( nullptr );
1152  }
1153  if ( hits_near_disk2.size() == 1 ) {
1154  hits_to_add.push_back( hits_near_disk2[0] );
1155  nSiHitsFound++;
1156  } else {
1157  hits_to_add.push_back( nullptr );
1158  }
1159 
1160  if (nSiHitsFound >= 1) {
1161  if ( mGenHistograms ){
1162  mHist["FitStatus"]->Fill("AttemptReFit", 1);
1163  }
1164  // LOG_INFO << "Fitting on GlobalTrack : " << mGlobalTracks[i] << " with " << nSiHitsFound << " si hits" << endm;
1165  TVector3 p = mTrackFitter->refitTrackWithSiHits(mGlobalTracks[i], hits_to_add);
1166  size_t lengthGTR = mTrackResults.size();
1167  if ( lengthGTR >= 1 ){
1168  mTrackResults[ lengthGTR - 1 ].setFst( hits_to_add, mTrackFitter->getTrack() );
1169  } else {
1170  LOG_ERROR << "Fit Results not found" << endm;
1171  }
1172 
1173  if ( mGenHistograms ){
1174  if (p.Perp() == mFitMoms[i].Perp()) {
1175  mHist["FitStatus"]->Fill("BadReFit", 1);
1176  } else {
1177  mHist["FitStatus"]->Fill("GoodReFit", 1);
1178  }
1179  }
1180 
1181  // mGlobalTracks[i] = mTrackFitter->getTrack();
1182  mNumFstHits[i] = nSiHitsFound;
1183  mFitMoms[i] = p;
1184 
1185  } else {
1186  // unable to refit
1187  }
1188 
1189  if ( mGenHistograms ){
1190  mHist["FitStatus"]->Fill( TString::Format( "w%luSi", nSiHitsFound ).Data(), 1 );
1191  }
1192 
1193  } // loop on globals
1194  } // addSiHits
1195 
1196  Seed_t findSiHitsNearMe(Seed_t &available_hits, genfit::MeasuredStateOnPlane &msp, double dphi = 0.004 * 9.5, double dr = 2.75) {
1197  double probe_phi = TMath::ATan2(msp.getPos().Y(), msp.getPos().X());
1198  double probe_r = sqrt(pow(msp.getPos().X(), 2) + pow(msp.getPos().Y(), 2));
1199 
1200  Seed_t found_hits;
1201 
1202  for (auto h : available_hits) {
1203  double h_phi = TMath::ATan2(h->getY(), h->getX());
1204  double h_r = sqrt(pow(h->getX(), 2) + pow(h->getY(), 2));
1205  double mdphi = fabs(h_phi - probe_phi);
1206 
1207  if ( mdphi < dphi && fabs( h_r - probe_r ) < dr) { // handle 2pi edge
1208  found_hits.push_back(h);
1209  }
1210  }
1211 
1212  return found_hits;
1213  }
1214 
1215  bool getSaveCriteriaValues() { return mSaveCriteriaValues; }
1216  std::vector<KiTrack::ICriterion *> getTwoHitCriteria() { return mTwoHitCrit; }
1217  std::vector<KiTrack::ICriterion *> getThreeHitCriteria() { return mThreeHitCrit; }
1218 
1219  TrackFitter *getTrackFitter() { return mTrackFitter; }
1220  void setEventVertex( TVector3 v ) { mEventVertex = v; }
1221 
1222  protected:
1223  unsigned long long int nEvents;
1224 
1225  bool mDoTrackFitting = true;
1226  bool mSaveCriteriaValues = true;
1227 
1228  FwdTrackerConfig mConfig;
1229  std::string mConfigFile;
1230  size_t mTotalHitsRemoved;
1231 
1232  std::vector<GenfitTrackResult> mTrackResults;
1233 
1234  std::vector<Seed_t> mRecoTracks; // the tracks recod from all iterations
1235  std::vector<Seed_t> mRecoTracksThisItertion;
1236 
1237  // Set to the Primary vertex for the event
1238  TVector3 mEventVertex;
1239 
1240  // These are vectors with info about each track / fit
1241  // they should all have the same length
1242  std::vector<float> mRecoTrackQuality;
1243  std::vector<int> mRecoTrackIdTruth;
1244  std::vector<TVector3> mFitMoms;
1245  std::vector<unsigned short> mNumFstHits;
1246  std::vector<genfit::FitStatus> mFitStatus;
1247  std::vector<genfit::AbsTrackRep *> mGlobalTrackReps;
1248  std::vector<genfit::Track *> mGlobalTracks;
1249 
1250  QualityPlotter *mQualityPlotter;
1251  std::shared_ptr<FwdDataSource> mDataSource;
1252 
1253  TrackFitter *mTrackFitter = nullptr;
1254 
1255  std::vector<KiTrack::ICriterion *> mTwoHitCrit;
1256  std::vector<KiTrack::ICriterion *> mThreeHitCrit;
1257 
1258  // histograms of the raw input data
1259  bool mGenHistograms = false; // controls these histograms and use of QualityPlotter
1260  TString mGeoCache;
1261  std::map<std::string, TH1 *> mHist;
1262 
1263 
1264 
1265 };
1266 
1267 #endif
std::vector< KiTrack::ICriterion * > loadCriteria(string path)
Definition: FwdTracker.h:240
Definition: FwdHit.h:68
vector< Seed_t > doTrackingOnHitmapSubset(size_t iIteration, FwdDataSource::HitMap_t &hitmap)
Does track finding steps on a subset of hits (phi slice)
Definition: FwdTracker.h:781
size_t sliceHitMapInPhi(FwdDataSource::HitMap_t &inputMap, FwdDataSource::HitMap_t &outputMap, float phi_min, float phi_max)
Slices a hitmap into a phi section.
Definition: FwdTracker.h:758