Belle II Software  release-08-01-10
Track.cc
1 /* Copyright 2008-2010, Technische Universitaet Muenchen,
2  Authors: Christian Hoeppner & Sebastian Neubert & Johannes Rauch
3 
4  This file is part of GENFIT.
5 
6  GENFIT is free software: you can redistribute it and/or modify
7  it under the terms of the GNU Lesser General Public License as published
8  by the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  GENFIT is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU Lesser General Public License for more details.
15 
16  You should have received a copy of the GNU Lesser General Public License
17  along with GENFIT. If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 #include "Track.h"
21 
22 #include "Exception.h"
23 #include "IO.h"
24 #include "KalmanFitterInfo.h"
25 #include "KalmanFitStatus.h"
26 #include "PlanarMeasurement.h"
27 #include "AbsMeasurement.h"
28 
29 #include "WireTrackCandHit.h"
30 
31 #include <algorithm>
32 #include <map>
33 
34 #include <TDatabasePDG.h>
35 #include <TMath.h>
36 #include <TBuffer.h>
37 
38 //#include <glog/logging.h>
39 
40 //#define DEBUG
41 
42 
43 namespace genfit {
44 
45  Track::Track() :
46  cardinalRep_(0), fitStatuses_(), mcTrackId_(-1), timeSeed_(0), stateSeed_(6), covSeed_(6)
47  {
48  ;
49  }
50 
51 
52  Track::Track(const TrackCand& trackCand, const MeasurementFactory<AbsMeasurement>& factory, AbsTrackRep* rep) :
53  cardinalRep_(0), fitStatuses_(), stateSeed_(6), covSeed_(6)
54  {
55 
56  if (rep != nullptr)
57  addTrackRep(rep);
58 
59  createMeasurements(trackCand, factory);
60 
61  // Copy seed information from candidate
62  timeSeed_ = trackCand.getTimeSeed();
63  stateSeed_ = trackCand.getStateSeed();
64  covSeed_ = trackCand.getCovSeed();
65 
66  mcTrackId_ = trackCand.getMcTrackId();
67 
68  // fill cache
69  fillPointsWithMeasurement();
70 
71  checkConsistency();
72  }
73 
74  void
75  Track::createMeasurements(const TrackCand& trackCand, const MeasurementFactory<AbsMeasurement>& factory)
76  {
77  // create the measurements using the factory.
78  std::vector <AbsMeasurement*> factoryHits = factory.createMany(trackCand);
79 
80  if (factoryHits.size() != trackCand.getNHits()) {
81  Exception exc("Track::Track ==> factoryHits.size() != trackCand->getNHits()", __LINE__, __FILE__);
82  exc.setFatal();
83  throw exc;
84  }
85 
86  // create TrackPoints
87  for (unsigned int i = 0; i < factoryHits.size(); ++i) {
88  TrackPoint* tp = new TrackPoint(factoryHits[i], this);
89  tp->setSortingParameter(trackCand.getHit(i)->getSortingParameter());
90  insertPoint(tp);
91  }
92  }
93 
94 
95  Track::Track(AbsTrackRep* trackRep, const TVectorD& stateSeed) :
96  cardinalRep_(0), fitStatuses_(), mcTrackId_(-1), timeSeed_(0), stateSeed_(stateSeed),
97  covSeed_(TMatrixDSym::kUnit, TMatrixDSym(6))
98  {
99  addTrackRep(trackRep);
100  }
101 
102 
103  Track::Track(AbsTrackRep* trackRep, const TVector3& posSeed, const TVector3& momSeed) :
104  cardinalRep_(0), fitStatuses_(), mcTrackId_(-1), timeSeed_(0), stateSeed_(6),
105  covSeed_(TMatrixDSym::kUnit, TMatrixDSym(6))
106  {
107  addTrackRep(trackRep);
108  setStateSeed(posSeed, momSeed);
109  }
110 
111 
112  Track::Track(AbsTrackRep* trackRep, const TVectorD& stateSeed, const TMatrixDSym& covSeed) :
113  cardinalRep_(0), fitStatuses_(), mcTrackId_(-1), timeSeed_(0), stateSeed_(stateSeed),
114  covSeed_(covSeed)
115  {
116  addTrackRep(trackRep);
117  }
118 
119 
120  Track::Track(const Track& rhs) :
121  TObject(rhs),
122  cardinalRep_(rhs.cardinalRep_), mcTrackId_(rhs.mcTrackId_), timeSeed_(rhs.timeSeed_),
123  stateSeed_(rhs.stateSeed_), covSeed_(rhs.covSeed_)
124  {
125  rhs.checkConsistency();
126 
127  std::map<const AbsTrackRep*, AbsTrackRep*> oldRepNewRep;
128 
129  for (std::vector<AbsTrackRep*>::const_iterator it = rhs.trackReps_.begin(); it != rhs.trackReps_.end(); ++it) {
130  AbsTrackRep* newRep = (*it)->clone();
131  addTrackRep(newRep);
132  oldRepNewRep[(*it)] = newRep;
133  }
134 
135  trackPoints_.reserve(rhs.trackPoints_.size());
136  for (std::vector<TrackPoint*>::const_iterator it = rhs.trackPoints_.begin(); it != rhs.trackPoints_.end(); ++it) {
137  trackPoints_.push_back(new TrackPoint(**it, oldRepNewRep));
138  trackPoints_.back()->setTrack(this);
139  }
140 
141  for (std::map< const AbsTrackRep*, FitStatus* >::const_iterator it = rhs.fitStatuses_.begin(); it != rhs.fitStatuses_.end(); ++it) {
142  setFitStatus(it->second->clone(), oldRepNewRep[it->first]);
143  }
144 
145  fillPointsWithMeasurement();
146 
147  checkConsistency();
148  }
149 
150  Track& Track::operator=(Track other)
151  {
152  swap(other);
153 
154  for (std::vector<TrackPoint*>::const_iterator it = trackPoints_.begin(); it != trackPoints_.end(); ++it) {
155  (*it)->setTrack(this);
156  }
157 
158  fillPointsWithMeasurement();
159 
160  checkConsistency();
161 
162  return *this;
163  }
164 
165  void Track::swap(Track& other)
166  {
167  std::swap(this->trackReps_, other.trackReps_);
168  std::swap(this->cardinalRep_, other.cardinalRep_);
169  std::swap(this->trackPoints_, other.trackPoints_);
170  std::swap(this->trackPointsWithMeasurement_, other.trackPointsWithMeasurement_);
171  std::swap(this->fitStatuses_, other.fitStatuses_);
172  std::swap(this->mcTrackId_, other.mcTrackId_);
173  std::swap(this->timeSeed_, other.timeSeed_);
174  std::swap(this->stateSeed_, other.stateSeed_);
175  std::swap(this->covSeed_, other.covSeed_);
176 
177  }
178 
179  Track::~Track()
180  {
181  this->Clear();
182  }
183 
184  void Track::Clear(Option_t*)
185  {
186  // This function is needed for TClonesArray embedding.
187  // FIXME: smarter containers or pointers needed ...
188  for (size_t i = 0; i < trackPoints_.size(); ++i)
189  delete trackPoints_[i];
190 
191  trackPoints_.clear();
192  trackPointsWithMeasurement_.clear();
193 
194  for (std::map< const AbsTrackRep*, FitStatus* >::iterator it = fitStatuses_.begin(); it != fitStatuses_.end(); ++it)
195  delete it->second;
196  fitStatuses_.clear();
197 
198  for (size_t i = 0; i < trackReps_.size(); ++i)
199  delete trackReps_[i];
200  trackReps_.clear();
201 
202  cardinalRep_ = 0;
203 
204  mcTrackId_ = -1;
205 
206  timeSeed_ = 0;
207  stateSeed_.Zero();
208  covSeed_.Zero();
209  }
210 
211 
212  TrackPoint* Track::getPoint(int id) const
213  {
214  if (id < 0)
215  id += trackPoints_.size();
216 
217  return trackPoints_.at(id);
218  }
219 
220 
221  TrackPoint* Track::getPointWithMeasurement(int id) const
222  {
223  if (id < 0)
224  id += trackPointsWithMeasurement_.size();
225 
226  return trackPointsWithMeasurement_.at(id);
227  }
228 
229 
230  TrackPoint* Track::getPointWithMeasurementAndFitterInfo(int id, const AbsTrackRep* rep) const
231  {
232  if (rep == nullptr)
233  rep = getCardinalRep();
234 
235  if (id >= 0) {
236  int i = 0;
237  for (std::vector<TrackPoint*>::const_iterator it = trackPointsWithMeasurement_.begin(); it != trackPointsWithMeasurement_.end();
238  ++it) {
239  if ((*it)->hasFitterInfo(rep)) {
240  if (id == i)
241  return (*it);
242  ++i;
243  }
244  }
245  } else {
246  // Search backwards.
247  int i = -1;
248  for (std::vector<TrackPoint*>::const_reverse_iterator it = trackPointsWithMeasurement_.rbegin();
249  it != trackPointsWithMeasurement_.rend(); ++it) {
250  if ((*it)->hasFitterInfo(rep)) {
251  if (id == i)
252  return (*it);
253  --i;
254  }
255  }
256  }
257 
258  // Not found, i.e. abs(id) > number of fitted TrackPoints
259  return 0;
260  }
261 
262 
263  TrackPoint* Track::getPointWithFitterInfo(int id, const AbsTrackRep* rep) const
264  {
265  if (rep == nullptr)
266  rep = getCardinalRep();
267 
268  if (id >= 0) {
269  int i = 0;
270  for (std::vector<TrackPoint*>::const_iterator it = trackPoints_.begin(); it != trackPoints_.end(); ++it) {
271  if ((*it)->hasFitterInfo(rep)) {
272  if (id == i)
273  return (*it);
274  ++i;
275  }
276  }
277  } else {
278  // Search backwards.
279  int i = -1;
280  for (std::vector<TrackPoint*>::const_reverse_iterator it = trackPoints_.rbegin(); it != trackPoints_.rend(); ++it) {
281  if ((*it)->hasFitterInfo(rep)) {
282  if (id == i)
283  return (*it);
284  --i;
285  }
286  }
287  }
288 
289  // Not found, i.e. abs(id) > number of fitted TrackPoints
290  return 0;
291  }
292 
293 
294  const MeasuredStateOnPlane& Track::getFittedState(int id, const AbsTrackRep* rep, bool biased) const
295  {
296  if (rep == nullptr)
297  rep = getCardinalRep();
298 
299  TrackPoint* point = getPointWithFitterInfo(id, rep);
300  if (point == nullptr) {
301  Exception exc("Track::getFittedState ==> no trackPoint with fitterInfo for rep", __LINE__, __FILE__);
302  exc.setFatal();
303  throw exc;
304  }
305  return point->getFitterInfo(rep)->getFittedState(biased);
306  }
307 
308 
309  int Track::getIdForRep(const AbsTrackRep* rep) const
310  {
311  for (size_t i = 0; i < trackReps_.size(); ++i)
312  if (trackReps_[i] == rep)
313  return i;
314 
315  Exception exc("Track::getIdForRep ==> cannot find TrackRep in Track", __LINE__, __FILE__);
316  exc.setFatal();
317  throw exc;
318  }
319 
320 
321  bool Track::hasFitStatus(const AbsTrackRep* rep) const
322  {
323  if (rep == nullptr)
324  rep = getCardinalRep();
325 
326  if (fitStatuses_.find(rep) == fitStatuses_.end())
327  return false;
328 
329  return (fitStatuses_.at(rep) != nullptr);
330  }
331 
332 
333  bool Track::hasKalmanFitStatus(const AbsTrackRep* rep) const
334  {
335  if (rep == nullptr)
336  rep = getCardinalRep();
337 
338  if (fitStatuses_.find(rep) == fitStatuses_.end())
339  return false;
340 
341  return (dynamic_cast<KalmanFitStatus*>(fitStatuses_.at(rep)) != nullptr);
342  }
343 
344 
346  {
347  return dynamic_cast<KalmanFitStatus*>(getFitStatus(rep));
348  }
349 
350 
351  void Track::setFitStatus(FitStatus* fitStatus, const AbsTrackRep* rep)
352  {
353  if (fitStatuses_.find(rep) != fitStatuses_.end())
354  delete fitStatuses_.at(rep);
355 
356  fitStatuses_[rep] = fitStatus;
357  }
358 
359 
360  void Track::setStateSeed(const TVector3& pos, const TVector3& mom)
361  {
362  stateSeed_.ResizeTo(6);
363 
364  stateSeed_(0) = pos.X();
365  stateSeed_(1) = pos.Y();
366  stateSeed_(2) = pos.Z();
367 
368  stateSeed_(3) = mom.X();
369  stateSeed_(4) = mom.Y();
370  stateSeed_(5) = mom.Z();
371  }
372 
373 
374 
375  void Track::insertPoint(TrackPoint* point, int id)
376  {
377 
378  point->setTrack(this);
379 
380 #ifdef DEBUG
381  debugOut << "Track::insertPoint at position " << id << "\n";
382 #endif
383  assert(point != nullptr);
384  trackHasChanged();
385 
386  point->setTrack(this);
387 
388  if (trackPoints_.size() == 0) {
389  trackPoints_.push_back(point);
390 
391  if (point->hasRawMeasurements())
392  trackPointsWithMeasurement_.push_back(point);
393 
394  return;
395  }
396 
397  if (id == -1 || id == (int)trackPoints_.size()) {
398  trackPoints_.push_back(point);
399 
400  if (point->hasRawMeasurements())
401  trackPointsWithMeasurement_.push_back(point);
402 
403  deleteReferenceInfo(std::max(0, (int)trackPoints_.size() - 2), (int)trackPoints_.size() - 1);
404 
405  // delete fitter infos if inserted point has a measurement
406  if (point->hasRawMeasurements()) {
407  deleteForwardInfo(-1, -1);
408  deleteBackwardInfo(0, -2);
409  }
410 
411  return;
412  }
413 
414  // [-size, size-1] is the allowed range
415  assert(id < (ssize_t)trackPoints_.size() || -id - 1 <= (ssize_t)trackPoints_.size());
416 
417  if (id < 0)
418  id += trackPoints_.size() + 1;
419 
420  // insert
421  trackPoints_.insert(trackPoints_.begin() + id, point); // insert inserts BEFORE
422 
423  // delete fitter infos if inserted point has a measurement
424  if (point->hasRawMeasurements()) {
425  deleteForwardInfo(id, -1);
426  deleteBackwardInfo(0, id);
427  }
428 
429  // delete reference info of neighbouring points
430  deleteReferenceInfo(std::max(0, id - 1), std::min((int)trackPoints_.size() - 1, id + 1));
431 
432  fillPointsWithMeasurement();
433  }
434 
435 
436  void Track::insertPoints(std::vector<TrackPoint*> points, int id)
437  {
438 
439  int nBefore = getNumPoints();
440  int n = points.size();
441 
442  if (n == 0)
443  return;
444  if (n == 1) {
445  insertPoint(points[0], id);
446  return;
447  }
448 
449  for (std::vector<TrackPoint*>::iterator p = points.begin(); p != points.end(); ++p)
450  (*p)->setTrack(this);
451 
452  if (id == -1 || id == (int)trackPoints_.size()) {
453  trackPoints_.insert(trackPoints_.end(), points.begin(), points.end());
454 
455  deleteReferenceInfo(std::max(0, nBefore - 1), nBefore);
456 
457  deleteForwardInfo(nBefore, -1);
458  deleteBackwardInfo(0, std::max(0, nBefore - 1));
459 
460  fillPointsWithMeasurement();
461 
462  return;
463  }
464 
465 
466  assert(id < (ssize_t)trackPoints_.size() || -id - 1 <= (ssize_t)trackPoints_.size());
467 
468  if (id < 0)
469  id += trackPoints_.size() + 1;
470 
471 
472  // insert
473  trackPoints_.insert(trackPoints_.begin() + id, points.begin(), points.end()); // insert inserts BEFORE
474 
475  // delete fitter infos if inserted point has a measurement
476  deleteForwardInfo(id, -1);
477  deleteBackwardInfo(0, id + n);
478 
479  // delete reference info of neighbouring points
480  deleteReferenceInfo(std::max(0, id - 1), std::min((int)trackPoints_.size() - 1, id));
481  deleteReferenceInfo(std::max(0, id + n - 1), std::min((int)trackPoints_.size() - 1, id + n));
482 
483  fillPointsWithMeasurement();
484  }
485 
486 
487  void Track::deletePoint(int id)
488  {
489 
490 #ifdef DEBUG
491  debugOut << "Track::deletePoint at position " << id << "\n";
492 #endif
493 
494  trackHasChanged();
495 
496  if (id < 0)
497  id += trackPoints_.size();
498  assert(id > 0);
499 
500 
501  // delete forwardInfo after point (backwardInfo before point) if deleted point has a measurement
502  if (trackPoints_[id]->hasRawMeasurements()) {
503  deleteForwardInfo(id, -1);
504  deleteBackwardInfo(0, id - 1);
505  }
506 
507  // delete reference info of neighbouring points
508  deleteReferenceInfo(std::max(0, id - 1), std::min((int)trackPoints_.size() - 1, id + 1));
509 
510  // delete point
511  std::vector<TrackPoint*>::iterator it = std::find(trackPointsWithMeasurement_.begin(), trackPointsWithMeasurement_.end(),
512  trackPoints_[id]);
513  if (it != trackPointsWithMeasurement_.end())
514  trackPointsWithMeasurement_.erase(it);
515 
516  delete trackPoints_[id];
517  trackPoints_.erase(trackPoints_.begin() + id);
518 
519  fillPointsWithMeasurement();
520 
521  }
522 
523 
524  void Track::insertMeasurement(AbsMeasurement* measurement, int id)
525  {
526  insertPoint(new TrackPoint(measurement, this), id);
527  }
528 
530  {
531  if (hasFitStatus(rep)) {
532  delete fitStatuses_.at(rep);
533  fitStatuses_.erase(rep);
534  }
535 
536  // delete FitterInfos related to the deleted TrackRep
537  for (const auto& trackPoint : trackPoints_) {
538  if (trackPoint->hasFitterInfo(rep)) {
539  trackPoint->deleteFitterInfo(rep);
540  }
541  }
542  }
543 
544 
545  void Track::mergeTrack(const Track* other, int id)
546  {
547 
548 #ifdef DEBUG
549  debugOut << "Track::mergeTrack\n";
550 #endif
551 
552  if (other->getNumPoints() == 0)
553  return;
554 
555  std::map<const AbsTrackRep*, AbsTrackRep*> otherRepThisRep;
556  std::vector<const AbsTrackRep*> otherRepsToRemove;
557 
558  for (std::vector<AbsTrackRep*>::const_iterator otherRep = other->trackReps_.begin(); otherRep != other->trackReps_.end();
559  ++otherRep) {
560  bool found(false);
561  for (std::vector<AbsTrackRep*>::const_iterator thisRep = trackReps_.begin(); thisRep != trackReps_.end(); ++thisRep) {
562  if ((*thisRep)->isSame(*otherRep)) {
563  otherRepThisRep[*otherRep] = *thisRep;
564 #ifdef DEBUG
565  debugOut << " map other rep " << *otherRep << " to " << (*thisRep) << "\n";
566 #endif
567  if (found) {
568  Exception exc("Track::mergeTrack ==> more than one matching rep.", __LINE__, __FILE__);
569  exc.setFatal();
570  throw exc;
571  }
572  found = true;
573  break;
574  }
575  }
576  if (!found) {
577  otherRepsToRemove.push_back(*otherRep);
578 #ifdef DEBUG
579  debugOut << " remove other rep " << *otherRep << "\n";
580 #endif
581  }
582  }
583 
584 
585  std::vector<TrackPoint*> points;
586  points.reserve(other->getNumPoints());
587 
588  for (std::vector<TrackPoint*>::const_iterator otherTp = other->trackPoints_.begin(); otherTp != other->trackPoints_.end();
589  ++otherTp) {
590  points.push_back(new TrackPoint(**otherTp, otherRepThisRep, &otherRepsToRemove));
591  }
592 
593  insertPoints(points, id);
594  }
595 
596 
597  void Track::addTrackRep(AbsTrackRep* trackRep)
598  {
599  trackReps_.push_back(trackRep);
600  fitStatuses_[trackRep] = new FitStatus();
601  }
602 
603 
605  {
606  if (id < 0)
607  id += trackReps_.size();
608 
609  AbsTrackRep* rep = trackReps_.at(id);
610 
611  // update cardinalRep_
612  if (int(cardinalRep_) == id)
613  cardinalRep_ = 0; // reset
614  else if (int(cardinalRep_) > id)
615  --cardinalRep_; // make cardinalRep_ point to the same TrackRep before and after deletion
616 
617  // delete FitterInfos related to the deleted TrackRep
618  for (std::vector<TrackPoint*>::const_iterator pointIt = trackPoints_.begin(); pointIt != trackPoints_.end(); ++pointIt) {
619  (*pointIt)->deleteFitterInfo(rep);
620  }
621 
622  // delete fitStatus
623  delete fitStatuses_.at(rep);
624  fitStatuses_.erase(rep);
625 
626  // delete rep
627  delete rep;
628  trackReps_.erase(trackReps_.begin() + id);
629  }
630 
631 
632  void Track::setCardinalRep(int id)
633  {
634 
635  if (id < 0)
636  id += trackReps_.size();
637 
638  if (id >= 0 && (unsigned int)id < trackReps_.size())
639  cardinalRep_ = id;
640  else {
641  cardinalRep_ = 0;
642  errorOut << "Track::setCardinalRep: Attempted to set cardinalRep_ to a value out of bounds. Resetting cardinalRep_ to 0." <<
643  std::endl;
644  }
645  }
646 
647 
649  {
650 
651  // Todo: test
652 
653  if (trackReps_.size() <= 1)
654  return;
655 
656  double minChi2(9.E99);
657  const AbsTrackRep* bestRep(nullptr);
658 
659  for (std::map< const AbsTrackRep*, FitStatus* >::const_iterator it = fitStatuses_.begin(); it != fitStatuses_.end(); ++it) {
660  if (it->second->isFitConverged()) {
661  if (it->second->getChi2() < minChi2) {
662  minChi2 = it->second->getChi2();
663  bestRep = it->first;
664  }
665  }
666  }
667 
668  if (bestRep != nullptr) {
669  setCardinalRep(getIdForRep(bestRep));
670  }
671  }
672 
673 
674  bool Track::sort()
675  {
676 #ifdef DEBUG
677  debugOut << "Track::sort \n";
678 #endif
679 
680  int nPoints(trackPoints_.size());
681  // original order
682  std::vector<TrackPoint*> pointsBefore(trackPoints_);
683 
684  // sort
685  std::stable_sort(trackPoints_.begin(), trackPoints_.end(), TrackPointComparator());
686 
687  // see where order changed
688  int equalUntil(-1), equalFrom(nPoints);
689  for (int i = 0; i < nPoints; ++i) {
690  if (pointsBefore[i] == trackPoints_[i])
691  equalUntil = i;
692  else
693  break;
694  }
695 
696  if (equalUntil == nPoints - 1)
697  return false; // sorting did not change anything
698 
699 
700  trackHasChanged();
701 
702  for (int i = nPoints - 1; i > equalUntil; --i) {
703  if (pointsBefore[i] == trackPoints_[i])
704  equalFrom = i;
705  else
706  break;
707  }
708 
709 #ifdef DEBUG
710  debugOut << "Track::sort. Equal up to (including) hit " << equalUntil << " and from (including) hit " << equalFrom << " \n";
711 #endif
712 
713  deleteForwardInfo(equalUntil + 1, -1);
714  deleteBackwardInfo(0, equalFrom - 1);
715 
716  deleteReferenceInfo(std::max(0, equalUntil + 1), std::min((int)trackPoints_.size() - 1, equalFrom - 1));
717 
718  fillPointsWithMeasurement();
719 
720  return true;
721  }
722 
723 
724  bool Track::udpateSeed(int id, AbsTrackRep* rep, bool biased)
725  {
726  try {
727  const MeasuredStateOnPlane& fittedState = getFittedState(id, rep, biased);
728  setTimeSeed(fittedState.getTime());
729  setStateSeed(fittedState.get6DState());
730  setCovSeed(fittedState.get6DCov());
731 
732  double fittedCharge = fittedState.getCharge();
733 
734  for (unsigned int i = 0; i < trackReps_.size(); ++i) {
735  if (trackReps_[i]->getPDGCharge() * fittedCharge < 0) {
736  trackReps_[i]->switchPDGSign();
737  }
738  }
739  } catch (Exception& e) {
740  // in this case the original track seed will be used
741  return false;
742  }
743  return true;
744  }
745 
746 
748  {
749 
750  std::reverse(trackPoints_.begin(), trackPoints_.end());
751 
752  deleteForwardInfo(0, -1);
753  deleteBackwardInfo(0, -1);
754  deleteReferenceInfo(0, -1);
755 
756  fillPointsWithMeasurement();
757  }
758 
759 
761  {
762  if (rep != nullptr) {
763  rep->switchPDGSign();
764  return;
765  }
766 
767  for (unsigned int i = 0; i < trackReps_.size(); ++i) {
768  trackReps_[i]->switchPDGSign();
769  }
770  }
771 
772 
774  {
775  udpateSeed(-1); // set fitted state of last hit as new seed
776  reverseMomSeed(); // flip momentum direction
777  switchPDGSigns();
778  reverseTrackPoints(); // also deletes all fitterInfos
779  }
780 
781 
782  void Track::deleteForwardInfo(int startId, int endId, const AbsTrackRep* rep)
783  {
784 #ifdef DEBUG
785  debugOut << "Track::deleteForwardInfo from position " << startId << " to " << endId << "\n";
786 #endif
787 
788  trackHasChanged();
789 
790  if (startId < 0)
791  startId += trackPoints_.size();
792  if (endId < 0)
793  endId += trackPoints_.size();
794  endId += 1;
795 
796  assert(endId >= startId);
797 
798  for (std::vector<TrackPoint*>::const_iterator pointIt = trackPoints_.begin() + startId; pointIt != trackPoints_.begin() + endId;
799  ++pointIt) {
800  if (rep != nullptr) {
801  if ((*pointIt)->hasFitterInfo(rep))
802  (*pointIt)->getFitterInfo(rep)->deleteForwardInfo();
803  } else {
804  const std::vector<AbsFitterInfo*> fitterInfos = (*pointIt)->getFitterInfos();
805  for (std::vector<AbsFitterInfo*>::const_iterator fitterInfoIt = fitterInfos.begin(); fitterInfoIt != fitterInfos.end();
806  ++fitterInfoIt) {
807  (*fitterInfoIt)->deleteForwardInfo();
808  }
809  }
810  }
811  }
812 
813  void Track::deleteBackwardInfo(int startId, int endId, const AbsTrackRep* rep)
814  {
815 
816 #ifdef DEBUG
817  debugOut << "Track::deleteBackwardInfo from position " << startId << " to " << endId << "\n";
818 #endif
819 
820  trackHasChanged();
821 
822  if (startId < 0)
823  startId += trackPoints_.size();
824  if (endId < 0)
825  endId += trackPoints_.size();
826  endId += 1;
827 
828  assert(endId >= startId);
829 
830 
831  for (std::vector<TrackPoint*>::const_iterator pointIt = trackPoints_.begin() + startId; pointIt != trackPoints_.begin() + endId;
832  ++pointIt) {
833  if (rep != nullptr) {
834  if ((*pointIt)->hasFitterInfo(rep))
835  (*pointIt)->getFitterInfo(rep)->deleteBackwardInfo();
836  } else {
837  const std::vector<AbsFitterInfo*> fitterInfos = (*pointIt)->getFitterInfos();
838  for (std::vector<AbsFitterInfo*>::const_iterator fitterInfoIt = fitterInfos.begin(); fitterInfoIt != fitterInfos.end();
839  ++fitterInfoIt) {
840  (*fitterInfoIt)->deleteBackwardInfo();
841  }
842  }
843  }
844  }
845 
846  void Track::deleteReferenceInfo(int startId, int endId, const AbsTrackRep* rep)
847  {
848 
849 #ifdef DEBUG
850  debugOut << "Track::deleteReferenceInfo from position " << startId << " to " << endId << "\n";
851 #endif
852 
853  trackHasChanged();
854 
855  if (startId < 0)
856  startId += trackPoints_.size();
857  if (endId < 0)
858  endId += trackPoints_.size();
859  endId += 1;
860 
861  assert(endId >= startId);
862 
863  for (std::vector<TrackPoint*>::const_iterator pointIt = trackPoints_.begin() + startId; pointIt != trackPoints_.begin() + endId;
864  ++pointIt) {
865  if (rep != nullptr) {
866  if ((*pointIt)->hasFitterInfo(rep))
867  (*pointIt)->getFitterInfo(rep)->deleteReferenceInfo();
868  } else {
869  std::vector<AbsFitterInfo*> fitterInfos = (*pointIt)->getFitterInfos();
870  for (std::vector<AbsFitterInfo*>::const_iterator fitterInfoIt = fitterInfos.begin(); fitterInfoIt != fitterInfos.end();
871  ++fitterInfoIt) {
872  (*fitterInfoIt)->deleteReferenceInfo();
873  }
874  }
875  }
876  }
877 
878  void Track::deleteMeasurementInfo(int startId, int endId, const AbsTrackRep* rep)
879  {
880 
881 #ifdef DEBUG
882  debugOut << "Track::deleteMeasurementInfo from position " << startId << " to " << endId << "\n";
883 #endif
884 
885  trackHasChanged();
886 
887  if (startId < 0)
888  startId += trackPoints_.size();
889  if (endId < 0)
890  endId += trackPoints_.size();
891  endId += 1;
892 
893  assert(endId >= startId);
894 
895  for (std::vector<TrackPoint*>::const_iterator pointIt = trackPoints_.begin() + startId; pointIt != trackPoints_.begin() + endId;
896  ++pointIt) {
897  if (rep != nullptr) {
898  if ((*pointIt)->hasFitterInfo(rep))
899  (*pointIt)->getFitterInfo(rep)->deleteMeasurementInfo();
900  } else {
901  std::vector<AbsFitterInfo*> fitterInfos = (*pointIt)->getFitterInfos();
902  for (std::vector<AbsFitterInfo*>::const_iterator fitterInfoIt = fitterInfos.begin(); fitterInfoIt != fitterInfos.end();
903  ++fitterInfoIt) {
904  (*fitterInfoIt)->deleteMeasurementInfo();
905  }
906  }
907  }
908  }
909 
910  void Track::deleteFitterInfo(int startId, int endId, const AbsTrackRep* rep)
911  {
912 
913 #ifdef DEBUG
914  debugOut << "Track::deleteFitterInfo from position " << startId << " to " << endId << "\n";
915 #endif
916 
917  trackHasChanged();
918 
919  if (startId < 0)
920  startId += trackPoints_.size();
921  if (endId < 0)
922  endId += trackPoints_.size();
923  endId += 1;
924 
925  assert(endId >= startId);
926 
927  for (std::vector<TrackPoint*>::const_iterator pointIt = trackPoints_.begin() + startId; pointIt != trackPoints_.begin() + endId;
928  ++pointIt) {
929  if (rep != nullptr) {
930  if ((*pointIt)->hasFitterInfo(rep))
931  (*pointIt)->deleteFitterInfo(rep);
932  } else {
933  for (std::vector<AbsTrackRep*>::const_iterator repIt = trackReps_.begin(); repIt != trackReps_.end(); ++repIt) {
934  if ((*pointIt)->hasFitterInfo(*repIt))
935  (*pointIt)->deleteFitterInfo(*repIt);
936  }
937  }
938  }
939  }
940 
941 
942  double Track::getTrackLen(AbsTrackRep* rep, int startId, int endId) const
943  {
944 
945  if (startId < 0)
946  startId += trackPoints_.size();
947  if (endId < 0)
948  endId += trackPoints_.size();
949 
950  bool backwards(false);
951  if (startId > endId) {
952  double temp = startId;
953  startId = endId;
954  endId = temp;
955  backwards = true;
956  }
957 
958  endId += 1;
959 
960  if (rep == nullptr)
961  rep = getCardinalRep();
962 
963  double trackLen(0);
964  StateOnPlane state;
965 
966  for (std::vector<TrackPoint*>::const_iterator pointIt = trackPoints_.begin() + startId; pointIt != trackPoints_.begin() + endId;
967  ++pointIt) {
968  if (!(*pointIt)->hasFitterInfo(rep)) {
969  Exception e("Track::getTracklength: trackPoint has no fitterInfo", __LINE__, __FILE__);
970  throw e;
971  }
972 
973  if (pointIt != trackPoints_.begin() + startId) {
974  trackLen += rep->extrapolateToPlane(state, (*pointIt)->getFitterInfo(rep)->getPlane());
975  }
976 
977  state = (*pointIt)->getFitterInfo(rep)->getFittedState();
978  }
979 
980  if (backwards)
981  trackLen *= -1.;
982 
983  return trackLen;
984  }
985 
986 
988  {
989  TrackCand* cand = new TrackCand();
990 
991  cand->setTime6DSeedAndPdgCode(timeSeed_, stateSeed_, getCardinalRep()->getPDG());
992  cand->setCovSeed(covSeed_);
993  cand->setMcTrackId(mcTrackId_);
994 
995  for (unsigned int i = 0; i < trackPointsWithMeasurement_.size(); ++i) {
996  const TrackPoint* tp = trackPointsWithMeasurement_[i];
997  const std::vector< AbsMeasurement* >& measurements = tp->getRawMeasurements();
998 
999  for (unsigned int j = 0; j < measurements.size(); ++j) {
1000  const AbsMeasurement* m = measurements[j];
1001  TrackCandHit* tch;
1002 
1003  int planeId = -1;
1004  if (dynamic_cast<const PlanarMeasurement*>(m)) {
1005  planeId = static_cast<const PlanarMeasurement*>(m)->getPlaneId();
1006  }
1007 
1008  if (m->isLeftRightMeasurement()) {
1009  tch = new WireTrackCandHit(m->getDetId(), m->getHitId(), planeId,
1010  tp->getSortingParameter(), m->getLeftRightResolution());
1011  } else {
1012  tch = new TrackCandHit(m->getDetId(), m->getHitId(), planeId,
1013  tp->getSortingParameter());
1014  }
1015  cand->addHit(tch);
1016  }
1017  }
1018 
1019  return cand;
1020  }
1021 
1022 
1023  double Track::getTOF(AbsTrackRep* rep, int startId, int endId) const
1024  {
1025 
1026  if (startId < 0)
1027  startId += trackPoints_.size();
1028  if (endId < 0)
1029  endId += trackPoints_.size();
1030 
1031  if (startId > endId) {
1032  std::swap(startId, endId);
1033  }
1034 
1035  endId += 1;
1036 
1037  if (rep == nullptr)
1038  rep = getCardinalRep();
1039 
1040  StateOnPlane state;
1041 
1042  const TrackPoint* startPoint(trackPoints_[startId]);
1043  const TrackPoint* endPoint(trackPoints_[endId]);
1044 
1045  if (!startPoint->hasFitterInfo(rep)
1046  || !endPoint->hasFitterInfo(rep)) {
1047  Exception e("Track::getTOF: trackPoint has no fitterInfo", __LINE__, __FILE__);
1048  throw e;
1049  }
1050 
1051  double tof = (rep->getTime(endPoint->getFitterInfo(rep)->getFittedState())
1052  - rep->getTime(startPoint->getFitterInfo(rep)->getFittedState()));
1053  return tof;
1054  }
1055 
1056 
1057  void Track::fixWeights(AbsTrackRep* rep, int startId, int endId)
1058  {
1059 
1060  if (startId < 0)
1061  startId += trackPoints_.size();
1062  if (endId < 0)
1063  endId += trackPoints_.size();
1064 
1065  assert(startId >= 0);
1066  assert(startId <= endId);
1067  assert(endId <= (int)trackPoints_.size());
1068 
1069  std::vector< AbsFitterInfo* > fis;
1070 
1071  for (std::vector<TrackPoint*>::iterator tp = trackPoints_.begin() + startId; tp != trackPoints_.begin() + endId; ++tp) {
1072  fis.clear();
1073  if (rep == nullptr) {
1074  fis = (*tp)->getFitterInfos();
1075  } else if ((*tp)->hasFitterInfo(rep)) {
1076  fis.push_back((*tp)->getFitterInfo(rep));
1077  }
1078 
1079  for (std::vector< AbsFitterInfo* >::iterator fi = fis.begin(); fi != fis.end(); ++fi) {
1080  KalmanFitterInfo* kfi = dynamic_cast<KalmanFitterInfo*>(*fi);
1081  if (kfi == nullptr)
1082  continue;
1083 
1084  kfi->fixWeights();
1085  }
1086  }
1087  }
1088 
1089 
1090  void Track::prune(const Option_t* option)
1091  {
1092 
1093  PruneFlags f;
1094  f.setFlags(option);
1095 
1096  for (std::map< const AbsTrackRep*, FitStatus* >::const_iterator it = fitStatuses_.begin(); it != fitStatuses_.end(); ++it) {
1097  it->second->getPruneFlags().setFlags(option);
1098  }
1099 
1100  // prune trackPoints
1101  if (f.hasFlags("F") || f.hasFlags("L")) {
1102  TrackPoint* firstPoint = getPointWithFitterInfo(0);
1103  TrackPoint* lastPoint = getPointWithFitterInfo(-1);
1104  for (unsigned int i = 0; i < trackPoints_.size(); ++i) {
1105  if (trackPoints_[i] == firstPoint && f.hasFlags("F"))
1106  continue;
1107 
1108  if (trackPoints_[i] == lastPoint && f.hasFlags("L"))
1109  continue;
1110 
1111  delete trackPoints_[i];
1112  trackPoints_.erase(trackPoints_.begin() + i);
1113  --i;
1114  }
1115  }
1116 
1117  // prune TrackReps
1118  if (f.hasFlags("C")) {
1119  for (unsigned int i = 0; i < trackReps_.size(); ++i) {
1120  if (i != cardinalRep_) {
1121  deleteTrackRep(i);
1122  --i;
1123  }
1124  }
1125  }
1126 
1127 
1128  // from remaining trackPoints: prune measurementsOnPlane, unneeded fitterInfoStuff
1129  for (unsigned int i = 0; i < trackPoints_.size(); ++i) {
1130  if (f.hasFlags("W"))
1131  trackPoints_[i]->deleteRawMeasurements();
1132 
1133  std::vector< AbsFitterInfo* > fis = trackPoints_[i]->getFitterInfos();
1134  for (unsigned int j = 0; j < fis.size(); ++j) {
1135 
1136  if (i == 0 && f.hasFlags("FLI"))
1137  fis[j]->deleteForwardInfo();
1138  else if (i == trackPoints_.size() - 1 && f.hasFlags("FLI"))
1139  fis[j]->deleteBackwardInfo();
1140  else if (f.hasFlags("FI"))
1141  fis[j]->deleteForwardInfo();
1142  else if (f.hasFlags("LI"))
1143  fis[j]->deleteBackwardInfo();
1144 
1145  if (f.hasFlags("U") && dynamic_cast<KalmanFitterInfo*>(fis[j]) != nullptr) {
1146  static_cast<KalmanFitterInfo*>(fis[j])->deletePredictions();
1147  }
1148 
1149  // also delete reference info if points have been removed since it is invalid then!
1150  if (f.hasFlags("R") or f.hasFlags("F") or f.hasFlags("L"))
1151  fis[j]->deleteReferenceInfo();
1152  if (f.hasFlags("M"))
1153  fis[j]->deleteMeasurementInfo();
1154  }
1155  }
1156 
1157  fillPointsWithMeasurement();
1158 
1159 #ifdef DEBUG
1160  debugOut << "pruned Track: "; Print();
1161 #endif
1162 
1163  }
1164 
1165 
1166  void Track::Print(const Option_t* option) const
1167  {
1168  TString opt = option;
1169  opt.ToUpper();
1170  if (opt.Contains("C")) { // compact
1171 
1172  printOut << "\n ";
1173  for (unsigned int i = 0; i < trackPoints_.size(); ++i) {
1174 
1175  int color = 32 * (size_t)(trackPoints_[i]) % 15;
1176  switch (color) {
1177  case 0:
1178  printOut << "\033[1;30m";
1179  break;
1180  case 1:
1181  printOut << "\033[0;34m";
1182  break;
1183  case 2:
1184  printOut << "\033[1;34m";
1185  break;
1186  case 3:
1187  printOut << "\033[0;32m";
1188  break;
1189  case 4:
1190  printOut << "\033[1;32m";
1191  break;
1192  case 5:
1193  printOut << "\033[0;36m";
1194  break;
1195  case 6:
1196  printOut << "\033[1;36m";
1197  break;
1198  case 7:
1199  printOut << "\033[0;31m";
1200  break;
1201  case 8:
1202  printOut << "\033[1;31m";
1203  break;
1204  case 9:
1205  printOut << "\033[0;35m";
1206  break;
1207  case 10:
1208  printOut << "\033[1;35m";
1209  break;
1210  case 11:
1211  printOut << "\033[0;33m";
1212  break;
1213  case 12:
1214  printOut << "\033[1;33m";
1215  break;
1216  case 13:
1217  printOut << "\033[0;37m";
1218  break;
1219  default:
1220  ;
1221  }
1222  printOut << trackPoints_[i] << "\033[00m ";
1223  }
1224  printOut << "\n";
1225 
1226  printOut << " ";
1227  for (unsigned int i = 0; i < trackPoints_.size(); ++i) {
1228  printf("% -9.3g ", trackPoints_[i]->getSortingParameter());
1229  }
1230 
1231  for (std::vector<AbsTrackRep*>::const_iterator rep = trackReps_.begin(); rep != trackReps_.end(); ++rep) {
1232  printOut << "\n" << getIdForRep(*rep) << " ";
1233  for (unsigned int i = 0; i < trackPoints_.size(); ++i) {
1234  if (! trackPoints_[i]->hasFitterInfo(*rep)) {
1235  printOut << " ";
1236  continue;
1237  }
1238  AbsFitterInfo* fi = trackPoints_[i]->getFitterInfo(*rep);
1239  if (fi->hasMeasurements())
1240  printOut << "M";
1241  else
1242  printOut << " ";
1243 
1244  if (fi->hasReferenceState())
1245  printOut << "R";
1246  else
1247  printOut << " ";
1248 
1249  printOut << " ";
1250  }
1251  printOut << "\n";
1252 
1253  printOut << " -> ";
1254  for (unsigned int i = 0; i < trackPoints_.size(); ++i) {
1255  if (! trackPoints_[i]->hasFitterInfo(*rep)) {
1256  printOut << " ";
1257  continue;
1258  }
1259  AbsFitterInfo* fi = trackPoints_[i]->getFitterInfo(*rep);
1260  if (fi->hasForwardPrediction())
1261  printOut << "P";
1262  else
1263  printOut << " ";
1264 
1265  if (fi->hasForwardUpdate())
1266  printOut << "U";
1267  else
1268  printOut << " ";
1269 
1270  printOut << " ";
1271  }
1272  printOut << "\n";
1273 
1274  printOut << " <- ";
1275  for (unsigned int i = 0; i < trackPoints_.size(); ++i) {
1276  if (! trackPoints_[i]->hasFitterInfo(*rep)) {
1277  printOut << " ";
1278  continue;
1279  }
1280  AbsFitterInfo* fi = trackPoints_[i]->getFitterInfo(*rep);
1281  if (fi->hasBackwardPrediction())
1282  printOut << "P";
1283  else
1284  printOut << " ";
1285 
1286  if (fi->hasBackwardUpdate())
1287  printOut << "U";
1288  else
1289  printOut << " ";
1290 
1291  printOut << " ";
1292  }
1293 
1294  printOut << "\n";
1295 
1296  } //end loop over reps
1297 
1298  printOut << "\n";
1299  return;
1300  }
1301 
1302 
1303 
1304  printOut << "=======================================================================================\n";
1305  printOut << "genfit::Track, containing " << trackPoints_.size() << " TrackPoints and " << trackReps_.size() << " TrackReps.\n";
1306  printOut << " Seed state: "; stateSeed_.Print();
1307 
1308  for (unsigned int i = 0; i < trackReps_.size(); ++i) {
1309  printOut << " TrackRep Nr. " << i;
1310  if (i == cardinalRep_)
1311  printOut << " (This is the cardinal rep)";
1312  printOut << "\n";
1313  trackReps_[i]->Print();
1314  }
1315 
1316  printOut << "---------------------------------------------------------------------------------------\n";
1317 
1318  for (unsigned int i = 0; i < trackPoints_.size(); ++i) {
1319  printOut << "TrackPoint Nr. " << i << "\n";
1320  trackPoints_[i]->Print();
1321  printOut << "..........................................................................\n";
1322  }
1323 
1324  for (std::map< const AbsTrackRep*, FitStatus* >::const_iterator it = fitStatuses_.begin(); it != fitStatuses_.end(); ++it) {
1325  it->second->Print();
1326  }
1327 
1328  printOut << "=======================================================================================\n";
1329 
1330  }
1331 
1332 
1333  void Track::checkConsistency() const
1334  {
1335 
1336  // cppcheck-suppress unreadVariable
1337  bool consistent = true;
1338  std::stringstream failures;
1339 
1340  std::map<const AbsTrackRep*, const KalmanFitterInfo*> prevFis;
1341 
1342  // check if seed is 6D
1343  if (stateSeed_.GetNrows() != 6) {
1344  failures << "Track::checkConsistency(): stateSeed_ dimension != 6" << std::endl;
1345  // cppcheck-suppress unreadVariable
1346  consistent = false;
1347  }
1348 
1349  if (covSeed_.GetNrows() != 6) {
1350  failures << "Track::checkConsistency(): covSeed_ dimension != 6" << std::endl;
1351  // cppcheck-suppress unreadVariable
1352  consistent = false;
1353  }
1354 
1355  if (covSeed_.Max() == 0.) {
1356  // Nota bene: The consistency is not set to false when this occurs, because it does not break the consistency of
1357  // the track. However, when something else fails we keep this as additional error information.
1358  failures << "Track::checkConsistency(): Warning: covSeed_ is zero" << std::endl;
1359  }
1360 
1361  // check if correct number of fitStatuses
1362  if (fitStatuses_.size() != trackReps_.size()) {
1363  failures << "Track::checkConsistency(): Number of fitStatuses is != number of TrackReps " << std::endl;
1364  // cppcheck-suppress unreadVariable
1365  consistent = false;
1366  }
1367 
1368  // check if cardinalRep_ is in range of trackReps_
1369  if (trackReps_.size() && cardinalRep_ >= trackReps_.size()) {
1370  failures << "Track::checkConsistency(): cardinalRep id " << cardinalRep_ << " out of bounds" << std::endl;
1371  // cppcheck-suppress unreadVariable
1372  consistent = false;
1373  }
1374 
1375  for (std::vector<AbsTrackRep*>::const_iterator rep = trackReps_.begin(); rep != trackReps_.end(); ++rep) {
1376  // check for nullptr
1377  if ((*rep) == nullptr) {
1378  failures << "Track::checkConsistency(): TrackRep is nullptr" << std::endl;
1379  // cppcheck-suppress unreadVariable
1380  consistent = false;
1381  }
1382 
1383  // check for valid pdg code
1384  TParticlePDG* particle = TDatabasePDG::Instance()->GetParticle((*rep)->getPDG());
1385  if (particle == nullptr) {
1386  failures << "Track::checkConsistency(): TrackRep pdg ID " << (*rep)->getPDG() << " is not valid" << std::endl;
1387  // cppcheck-suppress unreadVariable
1388  consistent = false;
1389  }
1390 
1391  // check if corresponding FitStatus is there
1392  if (fitStatuses_.find(*rep) == fitStatuses_.end() and fitStatuses_.find(*rep)->second != nullptr) {
1393  failures << "Track::checkConsistency(): No FitStatus for Rep or FitStatus is nullptr" << std::endl;
1394  // cppcheck-suppress unreadVariable
1395  consistent = false;
1396  }
1397  }
1398 
1399  // check TrackPoints
1400  for (std::vector<TrackPoint*>::const_iterator tp = trackPoints_.begin(); tp != trackPoints_.end(); ++tp) {
1401  // check for nullptr
1402  if ((*tp) == nullptr) {
1403  failures << "Track::checkConsistency(): TrackPoint is nullptr" << std::endl;
1404  // cppcheck-suppress unreadVariable
1405  consistent = false;
1406  }
1407  // check if trackPoint points back to this track
1408  if ((*tp)->getTrack() != this) {
1409  failures << "Track::checkConsistency(): TrackPoint does not point back to this track" << std::endl;
1410  // cppcheck-suppress unreadVariable
1411  consistent = false;
1412  }
1413 
1414  // check rawMeasurements
1415  const std::vector<AbsMeasurement*>& rawMeasurements = (*tp)->getRawMeasurements();
1416  for (std::vector<AbsMeasurement*>::const_iterator m = rawMeasurements.begin(); m != rawMeasurements.end(); ++m) {
1417  // check for nullptr
1418  if ((*m) == nullptr) {
1419  failures << "Track::checkConsistency(): Measurement is nullptr" << std::endl;
1420  // cppcheck-suppress unreadVariable
1421  consistent = false;
1422  }
1423  // check if measurement points back to TrackPoint
1424  if ((*m)->getTrackPoint() != *tp) {
1425  failures << "Track::checkConsistency(): Measurement does not point back to correct TrackPoint" << std::endl;
1426  // cppcheck-suppress unreadVariable
1427  consistent = false;
1428  }
1429  }
1430 
1431  // check fitterInfos
1432  std::vector<AbsFitterInfo*> fitterInfos = (*tp)->getFitterInfos();
1433  for (std::vector<AbsFitterInfo*>::const_iterator fi = fitterInfos.begin(); fi != fitterInfos.end(); ++fi) {
1434  // check for nullptr
1435  if ((*fi) == nullptr) {
1436  failures << "Track::checkConsistency(): FitterInfo is nullptr. TrackPoint: " << *tp << std::endl;
1437  // cppcheck-suppress unreadVariable
1438  consistent = false;
1439  }
1440 
1441  // check if fitterInfos point to valid TrackReps in trackReps_
1442  int mycount(0);
1443  for (std::vector<AbsTrackRep*>::const_iterator rep = trackReps_.begin(); rep != trackReps_.end(); ++rep) {
1444  if ((*rep) == (*fi)->getRep()) {
1445  ++mycount;
1446  }
1447  }
1448  if (mycount == 0) {
1449  failures << "Track::checkConsistency(): fitterInfo points to TrackRep which is not in Track" << std::endl;
1450  // cppcheck-suppress unreadVariable
1451  consistent = false;
1452  }
1453 
1454  if (!((*fi)->checkConsistency(&(this->getFitStatus((*fi)->getRep())->getPruneFlags())))) {
1455  failures << "Track::checkConsistency(): FitterInfo not consistent. TrackPoint: " << *tp << std::endl;
1456  // cppcheck-suppress unreadVariable
1457  consistent = false;
1458  }
1459 
1460  if (dynamic_cast<KalmanFitterInfo*>(*fi) != nullptr) {
1461  if (prevFis[(*fi)->getRep()] != nullptr &&
1462  static_cast<KalmanFitterInfo*>(*fi)->hasReferenceState() &&
1463  prevFis[(*fi)->getRep()]->hasReferenceState()) {
1464  double len = static_cast<KalmanFitterInfo*>(*fi)->getReferenceState()->getForwardSegmentLength();
1465  double prevLen = prevFis[(*fi)->getRep()]->getReferenceState()->getBackwardSegmentLength();
1466  if (fabs(prevLen + len) > 1E-10) {
1467  failures << "Track::checkConsistency(): segment lengths of reference states for rep " << (*fi)->getRep() << " (id " << getIdForRep((
1468  *fi)->getRep()) << ") at TrackPoint " << (*tp) << " don't match" << std::endl;
1469  failures << prevLen << " + " << len << " = " << prevLen + len << std::endl;
1470  failures << "TrackPoint " << *tp << ", FitterInfo " << *fi << ", rep " << getIdForRep((*fi)->getRep()) << std::endl;
1471  // cppcheck-suppress unreadVariable
1472  consistent = false;
1473  }
1474  }
1475 
1476  prevFis[(*fi)->getRep()] = static_cast<KalmanFitterInfo*>(*fi);
1477  } else
1478  prevFis[(*fi)->getRep()] = nullptr;
1479 
1480  } // end loop over FitterInfos
1481 
1482  } // end loop over TrackPoints
1483 
1484 
1485  // check trackPointsWithMeasurement_
1486  std::vector<TrackPoint*> trackPointsWithMeasurement;
1487 
1488  for (std::vector<TrackPoint*>::const_iterator it = trackPoints_.begin(); it != trackPoints_.end(); ++it) {
1489  if ((*it)->hasRawMeasurements()) {
1490  trackPointsWithMeasurement.push_back(*it);
1491  }
1492  }
1493 
1494  if (trackPointsWithMeasurement.size() != trackPointsWithMeasurement_.size()) {
1495  failures << "Track::checkConsistency(): trackPointsWithMeasurement_ has incorrect size" << std::endl;
1496  // cppcheck-suppress unreadVariable
1497  consistent = false;
1498  }
1499 
1500  for (unsigned int i = 0; i < trackPointsWithMeasurement.size(); ++i) {
1501  if (trackPointsWithMeasurement[i] != trackPointsWithMeasurement_[i]) {
1502  failures << "Track::checkConsistency(): trackPointsWithMeasurement_ is not correct" << std::endl;
1503  failures << "has id " << i << ", address " << trackPointsWithMeasurement_[i] << std::endl;
1504  failures << "should have id " << i << ", address " << trackPointsWithMeasurement[i] << std::endl;
1505  // cppcheck-suppress unreadVariable
1506  consistent = false;
1507  }
1508  }
1509 
1510  if (not consistent) {
1511  throw genfit::Exception(failures.str(), __LINE__, __FILE__);
1512  }
1513  }
1514 
1515 
1516  void Track::trackHasChanged()
1517  {
1518 
1519 #ifdef DEBUG
1520  debugOut << "Track::trackHasChanged \n";
1521 #endif
1522 
1523  if (fitStatuses_.empty())
1524  return;
1525 
1526  for (std::map< const AbsTrackRep*, FitStatus* >::const_iterator it = fitStatuses_.begin(); it != fitStatuses_.end(); ++it) {
1527  it->second->setHasTrackChanged();
1528  }
1529  }
1530 
1531 
1532  void Track::fillPointsWithMeasurement()
1533  {
1534  trackPointsWithMeasurement_.clear();
1535  trackPointsWithMeasurement_.reserve(trackPoints_.size());
1536 
1537  for (std::vector<TrackPoint*>::const_iterator it = trackPoints_.begin(); it != trackPoints_.end(); ++it) {
1538  if ((*it)->hasRawMeasurements()) {
1539  trackPointsWithMeasurement_.push_back(*it);
1540  }
1541  }
1542  }
1543 
1544 
1545  void Track::Streamer(TBuffer& R__b)
1546  {
1547  // Stream an object of class genfit::Track.
1548  const bool streamTrackPoints = true; // debugging option
1549  //This works around a msvc bug and should be harmless on other platforms
1550  typedef ::genfit::Track thisClass;
1551  UInt_t R__s, R__c;
1552  if (R__b.IsReading()) {
1553  this->Clear();
1554  Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
1555  if (R__v) { }
1556  TObject::Streamer(R__b);
1557  {
1558  std::vector<AbsTrackRep*>& R__stl = trackReps_;
1559  R__stl.clear();
1560  TClass* R__tcl1 = TBuffer::GetClass(typeid(genfit::AbsTrackRep));
1561  if (R__tcl1 == 0) {
1562  Error("trackReps_ streamer", "Missing the TClass object for genfit::AbsTrackRep!");
1563  return;
1564  }
1565  int R__i, R__n;
1566  R__b >> R__n;
1567  R__stl.reserve(R__n);
1568  for (R__i = 0; R__i < R__n; R__i++) {
1569  genfit::AbsTrackRep* R__t;
1570  R__b >> R__t;
1571  R__stl.push_back(R__t);
1572  }
1573  }
1574  R__b >> cardinalRep_;
1575  if (streamTrackPoints) {
1576  std::vector<TrackPoint*>& R__stl = trackPoints_;
1577  R__stl.clear();
1578  TClass* R__tcl1 = TBuffer::GetClass(typeid(genfit::TrackPoint));
1579  if (R__tcl1 == 0) {
1580  Error("trackPoints_ streamer", "Missing the TClass object for genfit::TrackPoint!");
1581  return;
1582  }
1583  int R__i, R__n;
1584  R__b >> R__n;
1585  R__stl.reserve(R__n);
1586  for (R__i = 0; R__i < R__n; R__i++) {
1587  genfit::TrackPoint* R__t;
1588  R__t = (genfit::TrackPoint*)R__b.ReadObjectAny(R__tcl1);
1589  R__t->setTrack(this);
1590  R__t->fixupRepsForReading();
1591  R__stl.push_back(R__t);
1592  }
1593  }
1594  {
1595  std::map<const AbsTrackRep*, FitStatus*>& R__stl = fitStatuses_;
1596  R__stl.clear();
1597  TClass* R__tcl1 = TBuffer::GetClass(typeid(genfit::AbsTrackRep));
1598  if (R__tcl1 == 0) {
1599  Error("fitStatuses_ streamer", "Missing the TClass object for genfit::AbsTrackRep!");
1600  return;
1601  }
1602  TClass* R__tcl2 = TBuffer::GetClass(typeid(genfit::FitStatus));
1603  if (R__tcl2 == 0) {
1604  Error("fitStatuses_ streamer", "Missing the TClass object for genfit::FitStatus!");
1605  return;
1606  }
1607  int R__i, R__n;
1608  R__b >> R__n;
1609  for (R__i = 0; R__i < R__n; R__i++) {
1610  int id;
1611  R__b >> id;
1612  genfit::FitStatus* R__t2;
1613  R__t2 = (genfit::FitStatus*)R__b.ReadObjectAny(R__tcl2);
1614 
1615  R__stl[this->getTrackRep(id)] = R__t2;
1616  }
1617  }
1618  // timeSeed_ was introduced in version 3. If reading an earlier
1619  // version, default to zero.
1620  if (R__v >= 3) {
1621  R__b >> timeSeed_;
1622  } else {
1623  timeSeed_ = 0;
1624  }
1625  stateSeed_.Streamer(R__b);
1626  covSeed_.Streamer(R__b);
1627  R__b.CheckByteCount(R__s, R__c, thisClass::IsA());
1628 
1629  fillPointsWithMeasurement();
1630  } else {
1631  R__c = R__b.WriteVersion(thisClass::IsA(), kTRUE);
1632  TObject::Streamer(R__b);
1633  {
1634  std::vector<AbsTrackRep*>& R__stl = trackReps_;
1635  int R__n = int(R__stl.size());
1636  R__b << R__n;
1637  if (R__n) {
1638  TClass* R__tcl1 = TBuffer::GetClass(typeid(genfit::AbsTrackRep));
1639  if (R__tcl1 == 0) {
1640  Error("trackReps_ streamer", "Missing the TClass object for genfit::AbsTrackRep!");
1641  return;
1642  }
1643  std::vector<AbsTrackRep*>::iterator R__k;
1644  for (R__k = R__stl.begin(); R__k != R__stl.end(); ++R__k) {
1645  R__b << *R__k;
1646  }
1647  }
1648  }
1649  R__b << cardinalRep_;
1650  if (streamTrackPoints) {
1651  std::vector<TrackPoint*>& R__stl = trackPoints_;
1652  int R__n = int(R__stl.size());
1653  R__b << R__n;
1654  if (R__n) {
1655  std::vector<TrackPoint*>::iterator R__k;
1656  for (R__k = R__stl.begin(); R__k != R__stl.end(); ++R__k) {
1657  R__b << (*R__k);
1658  }
1659  }
1660  }
1661  {
1662  std::map<const AbsTrackRep*, FitStatus*>& R__stl = fitStatuses_;
1663  int R__n = int(R__stl.size());
1664  R__b << R__n;
1665  if (R__n) {
1666  TClass* R__tcl1 = TBuffer::GetClass(typeid(genfit::AbsTrackRep));
1667  if (R__tcl1 == 0) {
1668  Error("fitStatuses_ streamer", "Missing the TClass object for genfit::AbsTrackRep!");
1669  return;
1670  }
1671  TClass* R__tcl2 = TBuffer::GetClass(typeid(genfit::FitStatus));
1672  if (R__tcl2 == 0) {
1673  Error("fitStatuses_ streamer", "Missing the TClass object for genfit::FitStatus!");
1674  return;
1675  }
1676  std::map<const AbsTrackRep*, FitStatus*>::iterator R__k;
1677  for (R__k = R__stl.begin(); R__k != R__stl.end(); ++R__k) {
1678  int id = this->getIdForRep((*R__k).first);
1679  R__b << id;
1680  R__b << ((*R__k).second);
1681  }
1682  }
1683  }
1684  R__b << timeSeed_;
1685  stateSeed_.Streamer(R__b);
1686  covSeed_.Streamer(R__b);
1687  R__b.SetByteCount(R__c, kTRUE);
1688  }
1689  }
1690 
1692  {
1693  for (size_t i = 0; i < trackPoints_.size(); ++i)
1694  delete trackPoints_[i];
1695 
1696  trackPoints_.clear();
1697  trackPointsWithMeasurement_.clear();
1698 
1699  for (std::map< const AbsTrackRep*, FitStatus* >::iterator it = fitStatuses_.begin(); it != fitStatuses_.end(); ++it)
1700  delete it->second;
1701  fitStatuses_.clear();
1702  }
1703 
1704 } /* End of namespace genfit */
R E
internal precision of FFTW codelets
Contains the measurement and covariance in raw detector coordinates.
Abstract base class for a track representation.
Definition: AbsTrackRep.h:66
virtual double getTime(const StateOnPlane &) const =0
Get the time corresponding to the StateOnPlane. Extrapolation.
bool switchPDGSign()
try to multiply pdg code with -1. (Switch from particle to anti-particle and vice versa).
Definition: AbsTrackRep.cc:183
virtual double extrapolateToPlane(StateOnPlane &state, const genfit::SharedPlanePtr &plane, bool stopAtBoundary=false, bool calcJacobianNoise=false) const =0
Extrapolates the state to plane, and returns the extrapolation length and, via reference,...
Exception class for error handling in GENFIT (provides storage for diagnostic information)
Definition: Exception.h:48
void setFatal(bool b=true)
Set fatal flag.
Definition: Exception.h:61
Class where important numbers and properties of a fit can be stored.
Definition: FitStatus.h:80
FitStatus for use with AbsKalmanFitter implementations.
Collects information needed and produced by a AbsKalmanFitter implementations and is specific to one ...
#StateOnPlane with additional covariance matrix.
Factory object to create AbsMeasurement objects from digitized and clustered data.
std::vector< measurement_T * > createMany(const TrackCand &cand) const
Create a collection of Measurements.
Measurement class implementing a planar hit geometry (1 or 2D).
A state with arbitrary dimension defined in a DetPlane.
Definition: StateOnPlane.h:47
Hit object for use in TrackCand.
Definition: TrackCandHit.h:34
Track candidate – seed values and indices.
Definition: TrackCand.h:69
int getMcTrackId() const
Get the MCT track id, for MC simulations - default value = -1.
Definition: TrackCand.h:119
void setCovSeed(const TMatrixDSym &cov6D)
set the covariance matrix seed (6D).
Definition: TrackCand.h:175
void setMcTrackId(int i)
Set the MCT track id, for MC simulations.
Definition: TrackCand.h:151
const TMatrixDSym & getCovSeed() const
get the covariance matrix seed (6D).
Definition: TrackCand.h:131
const TVectorD & getStateSeed() const
Returns the 6D seed state; should be in global coordinates.
Definition: TrackCand.h:134
void setTime6DSeedAndPdgCode(double time, const TVectorD &state6D, const int pdgCode)
This function works the same as set6DSeed but instead of a charge hypothesis you can set a pdg code w...
Definition: TrackCand.cc:279
double getTimeSeed() const
Get the time at which the seed state is defined.
Definition: TrackCand.h:122
Helper class for TrackPoint sorting, used in Track::sort().
Definition: Track.h:45
Object containing AbsMeasurement and AbsFitterInfo objects.
Definition: TrackPoint.h:46
AbsFitterInfo * getFitterInfo(const AbsTrackRep *rep=nullptr) const
Get fitterInfo for rep. Per default, use cardinal rep.
Definition: TrackPoint.cc:170
void fixupRepsForReading()
This function is used when reading the TrackPoint and is called by the owner in order to build fitter...
Definition: TrackPoint.cc:319
Collection of TrackPoint objects, AbsTrackRep objects and FitStatus objects.
Definition: Track.h:71
void determineCardinalRep()
See with which AbsTrackRep the track was fitted best (converged fit w/ smallest chi2) and set the car...
Definition: Track.cc:648
bool sort()
Sort TrackPoint and according to their sorting parameters.
Definition: Track.cc:674
KalmanFitStatus * getKalmanFitStatus(const AbsTrackRep *rep=nullptr) const
If FitStatus is a KalmanFitStatus, return it. Otherwise return nullptr.
Definition: Track.cc:345
void deleteFittedState(const genfit::AbsTrackRep *rep)
Delete the fit status and all the FitStates of the TrackPoints for the given hypothesis.
Definition: Track.cc:529
double getTOF(AbsTrackRep *rep=nullptr, int startId=0, int endId=-1) const
get time of flight in ns between to trackPoints (if nullptr, for cardinal rep)
Definition: Track.cc:1023
void insertPoints(std::vector< genfit::TrackPoint * > points, int id=-1)
Insert TrackPoints BEFORE TrackPoint with position id, if id >= 0.
Definition: Track.cc:436
TrackCand * constructTrackCand() const
Construct a new TrackCand containing the hit IDs of the measurements.
Definition: Track.cc:987
void insertPoint(TrackPoint *point, int id=-1)
Insert TrackPoint BEFORE TrackPoint with position id, if id >= 0.
Definition: Track.cc:375
bool udpateSeed(int id=0, AbsTrackRep *rep=nullptr, bool biased=true)
Try to set the fitted state as seed.
Definition: Track.cc:724
int mcTrackId_
if MC simulation, store the mc track id here
Definition: Track.h:318
void fixWeights(AbsTrackRep *rep=nullptr, int startId=0, int endId=-1)
Helper function: For all KalmanFitterInfos belonging to rep (if nullptr, for all reps),...
Definition: Track.cc:1057
bool hasFitStatus(const AbsTrackRep *rep=nullptr) const
Check if track has a FitStatus for given AbsTrackRep. Per default, check for cardinal rep.
Definition: Track.cc:321
double getTrackLen(AbsTrackRep *rep=nullptr, int startId=0, int endId=-1) const
get TrackLength between to trackPoints (if nullptr, for cardinal rep)
Definition: Track.cc:942
void reverseMomSeed()
Flip direction of momentum seed.
Definition: Track.h:235
FitStatus * getFitStatus(const AbsTrackRep *rep=nullptr) const
Get FitStatus for a AbsTrackRep. Per default, return FitStatus for cardinalRep.
Definition: Track.h:154
void insertMeasurement(AbsMeasurement *measurement, int id=-1)
Creates a new TrackPoint containing the measurement, and adds it to the track.
Definition: Track.cc:524
const MeasuredStateOnPlane & getFittedState(int id=0, const AbsTrackRep *rep=nullptr, bool biased=true) const
Shortcut to get FittedStates.
Definition: Track.cc:294
bool hasKalmanFitStatus(const AbsTrackRep *rep=nullptr) const
Check if track has a KalmanFitStatus for given AbsTrackRep. Per default, check for cardinal rep.
Definition: Track.cc:333
std::map< const AbsTrackRep *, FitStatus * > fitStatuses_
helper
Definition: Track.h:316
void reverseTrackPoints()
Flip the ordering of the TrackPoints.
Definition: Track.cc:747
void prune(const Option_t *="CFLWRMIU")
Delete unneeded information from the Track.
Definition: Track.cc:1090
void mergeTrack(const Track *other, int id=-1)
Merge two tracks.
Definition: Track.cc:545
void switchPDGSigns(AbsTrackRep *rep=nullptr)
Switch the pdg signs of specified rep (of all reps if rep == nullptr).
Definition: Track.cc:760
void deleteTrackPointsAndFitStatus()
Delete all measurement information and the track points of the track. Does not delete track represent...
Definition: Track.cc:1691
void reverseTrack()
Make track ready to be fitted in reverse direction.
Definition: Track.cc:773
AbsTrackRep * getCardinalRep() const
Get cardinal track representation.
Definition: Track.h:145
void deleteTrackRep(int id)
Delete a AbsTrackRep and all corresponding AbsFitterInfo objects in every TrackPoint.
Definition: Track.cc:604
int getIdForRep(const AbsTrackRep *rep) const
This is used when streaming TrackPoints.
Definition: Track.cc:309
Hit object for use in TrackCand.
Defines for I/O streams used for error and debug printing.
std::ostream debugOut
Default stream for debug output.
std::ostream printOut
Default stream for output of Print calls.
std::ostream errorOut
Default stream for error output.
Info which information has been pruned from the Track.
Definition: FitStatus.h:47