Classes | Public Types | Public Member Functions | Private Member Functions | Private Attributes | List of all members
trkf::TrackKalmanFitter Class Reference

Fit tracks using Kalman Filter fit+smooth. More...

#include <TrackKalmanFitter.h>

Classes

struct  Config
 

Public Types

using Parameters = fhicl::Table< Config >
 

Public Member Functions

 TrackKalmanFitter (const TrackStatePropagator *prop, bool useRMS, bool sortHitsByPlane, bool sortHitsByWire, bool sortOutputHitsMinLength, bool skipNegProp, bool cleanZigzag, bool rejectHighMultHits, bool rejectHitsNegativeGOF, float hitErr2ScaleFact, bool tryNoSkipWhenFails, bool tryBothDirs, bool pickBestHitOnWire, float maxResidue, float maxResidueFirstHit, float maxChi2, float maxDist, float negDistTolerance, int dumpLevel)
 Constructor from TrackStatePropagator and values of configuration parameters. More...
 
 TrackKalmanFitter (const TrackStatePropagator *prop, Parameters const &p)
 Constructor from TrackStatePropagator and Parameters table. More...
 
bool fitTrack (detinfo::DetectorPropertiesData const &detProp, const recob::TrackTrajectory &traj, int tkID, const SMatrixSym55 &covVtx, const SMatrixSym55 &covEnd, const std::vector< art::Ptr< recob::Hit >> &hits, const double pval, const int pdgid, const bool flipDirection, recob::Track &outTrack, std::vector< art::Ptr< recob::Hit >> &outHits, trkmkr::OptionalOutputs &optionals) const
 Fit track starting from TrackTrajectory. More...
 
bool fitTrack (detinfo::DetectorPropertiesData const &detProp, const Point_t &position, const Vector_t &direction, SMatrixSym55 &trackStateCov, const std::vector< art::Ptr< recob::Hit >> &hits, const std::vector< recob::TrajectoryPointFlags > &flags, const int tkID, const double pval, const int pdgid, recob::Track &outTrack, std::vector< art::Ptr< recob::Hit >> &outHits, trkmkr::OptionalOutputs &optionals) const
 Fit track starting from intial position, direction, and flags. More...
 
bool doFitWork (KFTrackState &trackState, detinfo::DetectorPropertiesData const &detProp, std::vector< HitState > &hitstatev, std::vector< recob::TrajectoryPointFlags::Mask_t > &hitflagsv, std::vector< KFTrackState > &fwdPrdTkState, std::vector< KFTrackState > &fwdUpdTkState, std::vector< unsigned int > &hitstateidx, std::vector< unsigned int > &rejectedhsidx, std::vector< unsigned int > &sortedtksidx, bool applySkipClean=true) const
 Function where the core of the fit is performed. More...
 

Private Member Functions

KFTrackState setupInitialTrackState (const Point_t &position, const Vector_t &direction, SMatrixSym55 &trackStateCov, const double pval, const int pdgid) const
 Return track state from intial position, direction, and covariance. More...
 
bool setupInputStates (detinfo::DetectorPropertiesData const &detProp, const std::vector< art::Ptr< recob::Hit >> &hits, const std::vector< recob::TrajectoryPointFlags > &flags, const KFTrackState &trackState, std::vector< HitState > &hitstatev, std::vector< recob::TrajectoryPointFlags::Mask_t > &hitflagsv) const
 Setup vectors of HitState and Masks to be used during the fit. More...
 
void sortOutput (std::vector< HitState > &hitstatev, std::vector< KFTrackState > &fwdUpdTkState, std::vector< unsigned int > &hitstateidx, std::vector< unsigned int > &rejectedhsidx, std::vector< unsigned int > &sortedtksidx, std::vector< recob::TrajectoryPointFlags::Mask_t > &hitflagsv, bool applySkipClean=true) const
 Sort the output states. More...
 
bool fillResult (const std::vector< art::Ptr< recob::Hit >> &inHits, const int tkID, const int pdgid, std::vector< HitState > &hitstatev, std::vector< recob::TrajectoryPointFlags::Mask_t > &hitflagsv, std::vector< KFTrackState > &fwdPrdTkState, std::vector< KFTrackState > &fwdUpdTkState, std::vector< unsigned int > &hitstateidx, std::vector< unsigned int > &rejectedhsidx, std::vector< unsigned int > &sortedtksidx, recob::Track &outTrack, std::vector< art::Ptr< recob::Hit >> &outHits, trkmkr::OptionalOutputs &optionals) const
 Fill the output objects. More...
 

Private Attributes

art::ServiceHandle< geo::Geometry const > geom
 
const TrackStatePropagatorpropagator
 
bool useRMS_
 
bool sortHitsByPlane_
 
bool sortHitsByWire_
 
bool sortOutputHitsMinLength_
 
bool skipNegProp_
 
bool cleanZigzag_
 
bool rejectHighMultHits_
 
bool rejectHitsNegativeGOF_
 
float hitErr2ScaleFact_
 
bool tryNoSkipWhenFails_
 
bool tryBothDirs_
 
bool pickBestHitOnWire_
 
float maxResidue_
 
float maxResidueFirstHit_
 
float maxChi2_
 
float maxDist_
 
float negDistTolerance_
 
int dumpLevel_
 

Detailed Description

Fit tracks using Kalman Filter fit+smooth.

This algorithm fits tracks using a Kalman Filter forward fit followed by a backward smoothing. The resulting track will feature covariance matrices at start and end positions. Fundamental components of the fit are trkf::KFTrackState and trkf::TrackStatePropagator.

Inputs are: recob::TrackTrajectory, initial covariance, associated hits, momentum estimate, particle id hypothesis. Alternatively, instead of a TrackTrajectory the fit can be input with initial position and direction, and vector of recob::TrajectoryPointFlags.

Outputs are: resulting recob::Track, associated hits, and trkmkr::OptionalOutputs.

For configuration options see TrackKalmanFitter::Config

Author
G. Cerati (FNAL, MicroBooNE)
Date
2017
Version
1.0

Definition at line 50 of file TrackKalmanFitter.h.

Member Typedef Documentation

Definition at line 145 of file TrackKalmanFitter.h.

Constructor & Destructor Documentation

trkf::TrackKalmanFitter::TrackKalmanFitter ( const TrackStatePropagator prop,
bool  useRMS,
bool  sortHitsByPlane,
bool  sortHitsByWire,
bool  sortOutputHitsMinLength,
bool  skipNegProp,
bool  cleanZigzag,
bool  rejectHighMultHits,
bool  rejectHitsNegativeGOF,
float  hitErr2ScaleFact,
bool  tryNoSkipWhenFails,
bool  tryBothDirs,
bool  pickBestHitOnWire,
float  maxResidue,
float  maxResidueFirstHit,
float  maxChi2,
float  maxDist,
float  negDistTolerance,
int  dumpLevel 
)
inline

Constructor from TrackStatePropagator and values of configuration parameters.

Definition at line 148 of file TrackKalmanFitter.h.

167  {
168  propagator = prop;
169  useRMS_ = useRMS;
170  sortHitsByPlane_ = sortHitsByPlane;
172  sortOutputHitsMinLength_ = sortOutputHitsMinLength;
173  skipNegProp_ = skipNegProp;
174  cleanZigzag_ = cleanZigzag;
175  rejectHighMultHits_ = rejectHighMultHits;
176  rejectHitsNegativeGOF_ = rejectHitsNegativeGOF;
177  hitErr2ScaleFact_ = hitErr2ScaleFact;
178  tryNoSkipWhenFails_ = tryNoSkipWhenFails;
179  tryBothDirs_ = tryBothDirs;
180  pickBestHitOnWire_ = pickBestHitOnWire;
181  maxResidue_ = (maxResidue > 0 ? maxResidue : std::numeric_limits<float>::max());
183  (maxResidueFirstHit > 0 ? maxResidueFirstHit : std::numeric_limits<float>::max());
184  maxChi2_ = (maxChi2 > 0 ? maxChi2 : std::numeric_limits<float>::max());
185  maxDist_ = (maxDist > 0 ? maxDist : std::numeric_limits<float>::max());
186  negDistTolerance_ = negDistTolerance;
187  dumpLevel_ = dumpLevel;
188  }
bool sortHitsByWire(art::Ptr< recob::Hit > a, art::Ptr< recob::Hit > b)
const TrackStatePropagator * propagator
static int max(int a, int b)
trkf::TrackKalmanFitter::TrackKalmanFitter ( const TrackStatePropagator prop,
Parameters const &  p 
)
inlineexplicit

Constructor from TrackStatePropagator and Parameters table.

Definition at line 191 of file TrackKalmanFitter.h.

192  : TrackKalmanFitter(prop,
193  p().useRMS(),
194  p().sortHitsByPlane(),
195  p().sortHitsByWire(),
196  p().sortOutputHitsMinLength(),
197  p().skipNegProp(),
198  p().cleanZigzag(),
199  p().rejectHighMultHits(),
200  p().rejectHitsNegativeGOF(),
201  p().hitErr2ScaleFact(),
202  p().tryNoSkipWhenFails(),
203  p().tryBothDirs(),
204  p().pickBestHitOnWire(),
205  p().maxResidue(),
206  p().maxResidueFirstHit(),
207  p().maxChi2(),
208  p().maxDist(),
209  p().negDistTolerance(),
210  p().dumpLevel())
211  {}
TrackKalmanFitter(const TrackStatePropagator *prop, bool useRMS, bool sortHitsByPlane, bool sortHitsByWire, bool sortOutputHitsMinLength, bool skipNegProp, bool cleanZigzag, bool rejectHighMultHits, bool rejectHitsNegativeGOF, float hitErr2ScaleFact, bool tryNoSkipWhenFails, bool tryBothDirs, bool pickBestHitOnWire, float maxResidue, float maxResidueFirstHit, float maxChi2, float maxDist, float negDistTolerance, int dumpLevel)
Constructor from TrackStatePropagator and values of configuration parameters.
bool sortHitsByWire(art::Ptr< recob::Hit > a, art::Ptr< recob::Hit > b)
p
Definition: test.py:223

Member Function Documentation

bool trkf::TrackKalmanFitter::doFitWork ( KFTrackState trackState,
detinfo::DetectorPropertiesData const &  detProp,
std::vector< HitState > &  hitstatev,
std::vector< recob::TrajectoryPointFlags::Mask_t > &  hitflagsv,
std::vector< KFTrackState > &  fwdPrdTkState,
std::vector< KFTrackState > &  fwdUpdTkState,
std::vector< unsigned int > &  hitstateidx,
std::vector< unsigned int > &  rejectedhsidx,
std::vector< unsigned int > &  sortedtksidx,
bool  applySkipClean = true 
) const

Function where the core of the fit is performed.

Definition at line 301 of file TrackKalmanFitter.cxx.

311 {
312  fwdPrdTkState.clear();
313  fwdUpdTkState.clear();
314  hitstateidx.clear();
315  rejectedhsidx.clear();
316  sortedtksidx.clear();
317  // these three vectors are aligned
318  fwdPrdTkState.reserve(hitstatev.size());
319  fwdUpdTkState.reserve(hitstatev.size());
320  hitstateidx.reserve(hitstatev.size());
321 
322  // keep a copy in case first propagation fails
323  KFTrackState startState = trackState;
324 
325  if (sortHitsByPlane_) {
326  //array of hit indices in planes, keeping the original sorting by plane
327  const unsigned int nplanes = geom->MaxPlanes();
328  std::vector<std::vector<unsigned int>> hitsInPlanes(nplanes);
329  for (unsigned int ihit = 0; ihit < hitstatev.size(); ihit++) {
330  hitsInPlanes[hitstatev[ihit].wireId().Plane].push_back(ihit);
331  }
332  if (sortHitsByWire_) {
333  for (unsigned int iplane = 0; iplane < nplanes; ++iplane) {
334  if (geom->Plane(iplane).GetIncreasingWireDirection<Vector_t>().Dot(trackState.momentum()) >
335  0) {
336  std::sort(hitsInPlanes[iplane].begin(),
337  hitsInPlanes[iplane].end(),
338  [hitstatev](const unsigned int& a, const unsigned int& b) -> bool {
339  return hitstatev[a].wireId().Wire < hitstatev[b].wireId().Wire;
340  });
341  }
342  else {
343  std::sort(hitsInPlanes[iplane].begin(),
344  hitsInPlanes[iplane].end(),
345  [hitstatev](const unsigned int& a, const unsigned int& b) -> bool {
346  return hitstatev[a].wireId().Wire > hitstatev[b].wireId().Wire;
347  });
348  }
349  }
350  }
351 
352  //dump hits sorted in each plane
353  if (dumpLevel_ > 1) {
354  int ch = 0;
355  for (auto p : hitsInPlanes) {
356  for (auto h : p) {
357  std::cout << "hit #/Plane/Wire/x/mask: " << ch++ << " " << hitstatev[h].wireId().Plane
358  << " " << hitstatev[h].wireId().Wire << " " << hitstatev[h].hitMeas() << " "
359  << hitflagsv[h] << std::endl;
360  }
361  }
362  }
363 
364  //array of indices, where iterHitsInPlanes[i] is the iterator over hitsInPlanes[i]
365  std::vector<unsigned int> iterHitsInPlanes(nplanes, 0);
366  for (unsigned int p = 0; p < hitstatev.size(); ++p) {
367  if (dumpLevel_ > 1) std::cout << std::endl << "processing hit #" << p << std::endl;
368  if (dumpLevel_ > 1)
369  std::cout << "hit sizes: rej=" << rejectedhsidx.size() << " good=" << hitstateidx.size()
370  << " input=" << hitstatev.size() << std::endl;
371  if (dumpLevel_ > 1) {
372  std::cout << "compute distance from state=" << std::endl;
373  trackState.dump();
374  }
375  int min_plane = -1;
376  double min_dist = DBL_MAX;
377  //find the closest hit according to the sorting in each plane
378  for (unsigned int iplane = 0; iplane < nplanes; ++iplane) {
379  //note: ih is a reference, so when 'continue' we increment iterHitsInPlanes[iplane] and the hit is effectively rejected
380  if (dumpLevel_ > 1)
381  std::cout << "iplane=" << iplane << " nplanes=" << nplanes
382  << " iterHitsInPlanes[iplane]=" << iterHitsInPlanes[iplane]
383  << " hitsInPlanes[iplane].size()=" << hitsInPlanes[iplane].size() << std::endl;
384  for (unsigned int& ih = iterHitsInPlanes[iplane]; ih < hitsInPlanes[iplane].size(); ++ih) {
385  //
386  unsigned int ihit = hitsInPlanes[iplane][ih];
387  if (dumpLevel_ > 1)
388  std::cout << "ih=" << ih << " ihit=" << ihit << " size=" << hitsInPlanes[iplane].size()
389  << std::endl;
390  const auto& hitstate = hitstatev[ihit];
391  const auto& hitflags = hitflagsv[ihit];
392  if (hitflags.isSet(recob::TrajectoryPointFlagTraits::NoPoint) ||
395  if (dumpLevel_ > 1)
396  std::cout << "rejecting hit flags="
397  << hitflags.isSet(recob::TrajectoryPointFlagTraits::NoPoint) << ", "
398  << hitflags.isSet(recob::TrajectoryPointFlagTraits::ExcludedFromFit) << ", "
399  << hitflags.isSet(recob::TrajectoryPointFlagTraits::Rejected) << " "
400  << hitflags << std::endl;
401  rejectedhsidx.push_back(ihit);
402  continue;
403  }
404  //get distance to measurement surface
405  bool success = true;
406  const double dist =
407  propagator->distanceToPlane(success, trackState.trackState(), hitstate.plane());
408  if (dumpLevel_ > 1)
409  std::cout << "distance to plane " << iplane << " wire=" << hitstate.wireId().Wire
410  << " = " << dist << ", min_dist=" << std::min(min_dist, 999.)
411  << " min_plane=" << min_plane << " success=" << success
412  << " wirepo=" << hitstate.plane().position() << std::endl;
413  if (!success) {
414  rejectedhsidx.push_back(ihit);
415  continue;
416  }
417  if (applySkipClean && skipNegProp_ && fwdUpdTkState.size() > 0 &&
418  dist < negDistTolerance_) {
419  rejectedhsidx.push_back(ihit);
420  continue;
421  }
422  if (dist < min_dist) {
423  min_plane = iplane;
424  min_dist = dist;
425  }
426  break;
427  }
428  }
429  if (dumpLevel_ > 1)
430  std::cout
431  << "pick min_dist=" << min_dist << " min_plane=" << min_plane << " wire="
432  << (min_plane < 0 ?
433  -1 :
434  hitstatev[hitsInPlanes[min_plane][iterHitsInPlanes[min_plane]]].wireId().Wire)
435  << std::endl;
436  //
437  //now we know which is the closest wire: get the hitstate and increment the iterator
438  if (min_plane < 0) {
439  if (rejectedhsidx.size() + hitstateidx.size() == hitstatev.size())
440  break;
441  else
442  continue;
443  }
444  unsigned int ihit = hitsInPlanes[min_plane][iterHitsInPlanes[min_plane]];
445  const auto* hitstate = &hitstatev[ihit];
446  iterHitsInPlanes[min_plane]++;
447  //
448  //propagate to measurement surface
449  bool propok = true;
450  trackState = propagator->propagateToPlane(propok,
451  detProp,
452  trackState.trackState(),
453  hitstate->plane(),
454  true,
455  true,
457  if (!propok && !(applySkipClean && fwdUpdTkState.size() > 0 && skipNegProp_)) {
458  if (dumpLevel_ > 1) std::cout << "attempt backward prop" << std::endl;
459  trackState = propagator->propagateToPlane(propok,
460  detProp,
461  trackState.trackState(),
462  hitstate->plane(),
463  true,
464  true,
466  }
467  if (dumpLevel_ > 1) {
468  std::cout << "hit state " << std::endl;
469  hitstate->dump();
470  std::cout << "propagation result=" << propok << std::endl;
471  std::cout << "propagated state " << std::endl;
472  trackState.dump();
473  std::cout << "propagated planarity="
474  << hitstate->plane().direction().Dot(hitstate->plane().position() -
475  trackState.position())
476  << std::endl;
477  std::cout << "residual=" << trackState.residual(*hitstate)
478  << " chi2=" << trackState.chi2(*hitstate) << std::endl;
479  }
480  if (propok) {
481 
482  //reject the first hit if its residue is too large (due to e.g. spurious hit or bad hit sorting)
483  if (applySkipClean && fwdUpdTkState.size() == 0 &&
484  std::abs(trackState.residual(*hitstate)) > maxResidueFirstHit_) {
485  if (dumpLevel_ > 1)
486  std::cout << "rejecting first hit with residual=" << trackState.residual(*hitstate)
487  << std::endl;
488  rejectedhsidx.push_back(ihit);
489  trackState = startState;
490  continue;
491  }
492 
493  //if there is >1 consecutive hit on the same wire, choose the one with best chi2 and exclude the others (should this be optional?)
494  if (pickBestHitOnWire_) {
495  auto wire = hitstate->wireId().Wire;
496  float min_chi2_wire = trackState.chi2(*hitstate);
497  for (unsigned int jh = iterHitsInPlanes[min_plane]; jh < hitsInPlanes[min_plane].size();
498  ++jh) {
499  const unsigned int jhit = hitsInPlanes[min_plane][jh];
500  const auto& jhitstate = hitstatev[jhit];
501  if (jhitstate.wireId().Wire != wire) break;
502  if (ihit != jhit) iterHitsInPlanes[min_plane]++;
503  float chi2 = trackState.chi2(jhitstate);
504  if (dumpLevel_ > 1 && ihit != jhit)
505  std::cout << "additional hit on the same wire with jhit=" << jhit << " chi2=" << chi2
506  << " ihit=" << ihit << " min_chi2_wire=" << min_chi2_wire << std::endl;
507  if (chi2 < min_chi2_wire) {
508  min_chi2_wire = chi2;
509  if (dumpLevel_ > 1 && ihit != jhit) {
510  std::cout << "\tnow using ";
511  jhitstate.dump();
512  }
513  if (ihit != jhit) rejectedhsidx.push_back(ihit);
514  ihit = jhit;
515  }
516  else {
517  rejectedhsidx.push_back(jhit);
518  }
519  }
520  }
521 
522  hitstate = &hitstatev[ihit];
523  auto& hitflags = hitflagsv[ihit];
524 
525  //reject hits failing maxResidue, maxChi2, or maxDist cuts
526  if (fwdUpdTkState.size() > 0 && applySkipClean &&
527  (std::abs(trackState.residual(*hitstate)) > maxResidue_ ||
528  trackState.chi2(*hitstate) > maxChi2_ || min_dist > maxDist_)) {
529  //
530  if (dumpLevel_ > 1)
531  std::cout << "rejecting hit with res=" << std::abs(trackState.residual(*hitstate))
532  << " chi2=" << trackState.chi2(*hitstate) << " dist=" << min_dist
533  << std::endl;
534  // reset the current state, do not update the hit, and mark as excluded from the fit
535  if (fwdUpdTkState.size() > 0)
536  trackState = fwdUpdTkState.back();
537  else
538  trackState = startState;
539  rejectedhsidx.push_back(ihit);
541  hitflags.set(
543  NoPoint); //fixme: this is only for event display, also needed by current definition of ValidPoint
544  continue;
545  }
546 
547  hitstateidx.push_back(ihit);
548  fwdPrdTkState.push_back(trackState);
549 
550  //hits with problematic flags are kept but not used for update and flagged as excluded from fit
551  if (hitflags.isSet(recob::TrajectoryPointFlagTraits::HitIgnored) ||
557  //
558  // reset the current state, do not update the hit, and mark as excluded from the fit
559  if (fwdUpdTkState.size() > 0)
560  trackState = fwdUpdTkState.back();
561  else
562  trackState = startState;
563  fwdUpdTkState.push_back(trackState);
565  hitflags.set(
567  NoPoint); //fixme: this is only for event display, also needed by current definition of ValidPoint
568  continue;
569  }
570  //now update the forward fitted track
571  bool upok = trackState.updateWithHitState(*hitstate);
572  if (upok == 0) {
573  mf::LogWarning("TrackKalmanFitter") << "Fit failure at " << __FILE__ << " " << __LINE__;
574  return false;
575  }
576  if (dumpLevel_ > 1) {
577  std::cout << "updated state " << std::endl;
578  trackState.dump();
579  }
580  fwdUpdTkState.push_back(trackState);
581  }
582  else {
583  if (dumpLevel_ > 0)
584  std::cout << "WARNING: forward propagation failed. Skip this hit..." << std::endl;
585  // restore the last successful propagation
586  if (fwdPrdTkState.size() > 0)
587  trackState = fwdPrdTkState.back();
588  else
589  trackState = startState;
590  rejectedhsidx.push_back(ihit);
591  continue;
592  }
593  if (rejectedhsidx.size() + hitstateidx.size() == hitstatev.size()) break;
594  }
595  }
596  else {
597  for (unsigned int ihit = 0; ihit < hitstatev.size(); ++ihit) {
598  const auto& hitstate = hitstatev[ihit];
599  if (dumpLevel_ > 1) {
600  std::cout << std::endl << "processing hit #" << ihit << std::endl;
601  hitstate.dump();
602  }
603  auto& hitflags = hitflagsv[ihit];
606  rejectedhsidx.push_back(ihit);
607  continue;
608  }
609  bool success = true;
610  const double dist =
611  propagator->distanceToPlane(success, trackState.trackState(), hitstate.plane());
612  if (applySkipClean && fwdUpdTkState.size() > 0 && skipNegProp_) {
613  if (dist < 0. || success == false) {
614  if (dumpLevel_ > 0)
615  std::cout << "WARNING: negative propagation distance. Skip this hit..." << std::endl;
616  ;
617  rejectedhsidx.push_back(ihit);
618  continue;
619  }
620  }
621  //propagate to measurement surface
622  bool propok = true;
623  trackState = propagator->propagateToPlane(propok,
624  detProp,
625  trackState.trackState(),
626  hitstate.plane(),
627  true,
628  true,
630  if (!propok && !(applySkipClean && skipNegProp_))
631  trackState = propagator->propagateToPlane(propok,
632  detProp,
633  trackState.trackState(),
634  hitstate.plane(),
635  true,
636  true,
638  if (propok) {
639  hitstateidx.push_back(ihit);
640  fwdPrdTkState.push_back(trackState);
641  //
642  if (hitflags.isSet(recob::TrajectoryPointFlagTraits::HitIgnored) ||
648  (fwdUpdTkState.size() > 0 && applySkipClean &&
649  (std::abs(trackState.residual(hitstate)) > maxResidue_ ||
650  trackState.chi2(hitstate) > maxChi2_ || dist > maxDist_))) {
651  if (dumpLevel_ > 1)
652  std::cout << "rejecting hit with res=" << std::abs(trackState.residual(hitstate))
653  << " chi2=" << trackState.chi2(hitstate) << " dist=" << dist << std::endl;
654  // reset the current state, do not update the hit, mark as excluded from the fit
655  if (fwdUpdTkState.size() > 0)
656  trackState = fwdUpdTkState.back();
657  else
658  trackState = startState;
659  fwdUpdTkState.push_back(trackState);
661  hitflags.set(
663  NoPoint); //fixme: this is only for event display, also needed by current definition of ValidPoint
664  continue;
665  }
666  //
667  bool upok = trackState.updateWithHitState(hitstate);
668  if (upok == 0) {
669  mf::LogWarning("TrackKalmanFitter") << "Fit failure at " << __FILE__ << " " << __LINE__;
670  return false;
671  }
672  fwdUpdTkState.push_back(trackState);
673  }
674  else {
675  if (dumpLevel_ > 0)
676  std::cout << "WARNING: forward propagation failed. Skip this hit..." << std::endl;
677  ;
678  // restore the last successful propagation
679  if (fwdPrdTkState.size() > 0)
680  trackState = fwdPrdTkState.back();
681  else
682  trackState = startState;
683  rejectedhsidx.push_back(ihit);
684  continue;
685  }
686  } //for (auto hitstate : hitstatev)
687  }
688 
689  if (dumpLevel_ > 2) assert(rejectedhsidx.size() + hitstateidx.size() == hitstatev.size());
690  if (dumpLevel_ > 0) {
691  std::cout << "TRACK AFTER FWD" << std::endl;
692  std::cout << "hit sizes=" << rejectedhsidx.size() << " " << hitstateidx.size() << " "
693  << hitstatev.size() << std::endl;
694  trackState.dump();
695  }
696 
697  //reinitialize trf for backward fit, scale the error to avoid biasing the backward fit
698  trackState.setCovariance(100. * trackState.covariance());
699 
700  startState = trackState;
701 
702  //backward loop over track states and hits in fwdUpdTracks: use hits for backward fit and fwd track states for smoothing
703  int nvalidhits = 0;
704  for (int itk = fwdPrdTkState.size() - 1; itk >= 0; itk--) {
705  auto& fwdPrdTrackState = fwdPrdTkState[itk];
706  auto& fwdUpdTrackState = fwdUpdTkState[itk];
707  const auto& hitstate = hitstatev[hitstateidx[itk]];
708  auto& hitflags = hitflagsv[hitstateidx[itk]];
709  if (dumpLevel_ > 1) {
710  std::cout << std::endl << "processing backward hit #" << itk << std::endl;
711  hitstate.dump();
712  }
713  bool propok = true;
714  trackState = propagator->propagateToPlane(propok,
715  detProp,
716  trackState.trackState(),
717  hitstate.plane(),
718  true,
719  true,
721  if (!propok)
722  trackState = propagator->propagateToPlane(propok,
723  detProp,
724  trackState.trackState(),
725  hitstate.plane(),
726  true,
727  true,
728  TrackStatePropagator::FORWARD); //do we want this?
729  //
730  if (dumpLevel_ > 1) {
731  std::cout << "propagation result=" << propok << std::endl;
732  std::cout << "propagated state " << std::endl;
733  trackState.dump();
734  std::cout << "propagated planarity="
735  << hitstate.plane().direction().Dot(hitstate.plane().position() -
736  trackState.position())
737  << std::endl;
738  }
739  if (propok) {
740  //combine forward predicted and backward predicted
741  bool pcombok = fwdPrdTrackState.combineWithTrackState(trackState.trackState());
742  if (pcombok == 0) {
743  mf::LogWarning("TrackKalmanFitter") << "Fit failure at " << __FILE__ << " " << __LINE__;
744  return false;
745  }
746  if (dumpLevel_ > 1) {
747  std::cout << "combined prd state " << std::endl;
748  fwdPrdTrackState.dump();
749  }
750  // combine forward updated and backward predicted and update backward predicted, only if the hit was not excluded
751  if (hitflags.isSet(recob::TrajectoryPointFlagTraits::ExcludedFromFit) == 0) {
752  bool ucombok = fwdUpdTrackState.combineWithTrackState(trackState.trackState());
753  if (ucombok == 0) {
754  mf::LogWarning("TrackKalmanFitter") << "Fit failure at " << __FILE__ << " " << __LINE__;
755  return false;
756  }
757  if (dumpLevel_ > 1) {
758  std::cout << "combined upd state " << std::endl;
759  fwdUpdTrackState.dump();
760  }
761  bool upok = trackState.updateWithHitState(hitstate);
762  if (upok == 0) {
763  mf::LogWarning("TrackKalmanFitter") << "Fit failure at " << __FILE__ << " " << __LINE__;
764  return false;
765  }
766  if (dumpLevel_ > 1) {
767  std::cout << "updated state " << std::endl;
768  trackState.dump();
769  }
770  // Keep a copy in case a future propagation fails
771  startState = trackState;
772  //
773  nvalidhits++;
774  }
775  else {
776  fwdUpdTrackState = fwdPrdTrackState;
777  }
778  }
779  else {
780  // ok, if the backward propagation failed we exclude this point from the rest of the fit,
781  // but we can still use its position from the forward fit, so just mark it as ExcludedFromFit
783  hitflags.set(
784  recob::TrajectoryPointFlagTraits::NoPoint); // fixme: this is only for event display, also
785  // needed by current definition of ValidPoint
786  if (dumpLevel_ > 0)
787  std::cout << "WARNING: backward propagation failed. Skip this hit... hitstateidx[itk]="
788  << hitstateidx[itk] << " itk=" << itk << std::endl;
789  ;
790  // restore the last successful propagation
791  trackState = startState;
792  continue;
793  }
794  } //for (unsigned int itk = fwdPrdTkState.size()-1; itk>=0; itk--) {
795 
796  if (nvalidhits < 4) {
797  mf::LogWarning("TrackKalmanFitter") << "Fit failure at " << __FILE__ << " " << __LINE__ << " ";
798  return false;
799  }
800 
801  if (dumpLevel_ > 1) std::cout << "sort output with nvalidhits=" << nvalidhits << std::endl;
802 
803  // sort output states
804  sortOutput(
805  hitstatev, fwdUpdTkState, hitstateidx, rejectedhsidx, sortedtksidx, hitflagsv, applySkipClean);
806  size_t nsortvalid = 0;
807  for (auto& idx : sortedtksidx) {
808  auto& hitflags = hitflagsv[hitstateidx[idx]];
809  if (hitflags.isSet(recob::TrajectoryPointFlagTraits::ExcludedFromFit) == 0) nsortvalid++;
810  }
811  if (nsortvalid < 4) {
812  mf::LogWarning("TrackKalmanFitter") << "Fit failure at " << __FILE__ << " " << __LINE__ << " ";
813  return false;
814  }
815 
816  if (dumpLevel_ > 2) assert(rejectedhsidx.size() + sortedtksidx.size() == hitstatev.size());
817  return true;
818 }
end
while True: pbar.update(maxval-len(onlies[E][S])) #print iS, "/", len(onlies[E][S]) found = False for...
static constexpr Flag_t Merged
The hit might have contribution from particles other than this.
static constexpr Flag_t Suspicious
The point reconstruction is somehow questionable.
PlaneGeo const & Plane(unsigned int const p, unsigned int const tpc=0, unsigned int const cstat=0) const
Returns the specified wire.
static constexpr Flag_t NoPoint
The trajectory point is not defined.
Namespace for the trajectory point flags.
art::ServiceHandle< geo::Geometry const > geom
Vector GetIncreasingWireDirection() const
Returns the direction of increasing wires.
Definition: PlaneGeo.h:457
TrackState propagateToPlane(bool &success, const detinfo::DetectorPropertiesData &detProp, const TrackState &origin, const Plane &target, bool dodedx, bool domcs, PropDirection dir=FORWARD) const
Main function for propagation of a TrackState to a Plane.
double distanceToPlane(bool &success, const Point_t &origpos, const Vector_t &origdir, const Plane &target) const
Distance of a TrackState (Point and Vector) to a Plane, along the TrackState direction.
void sortOutput(std::vector< HitState > &hitstatev, std::vector< KFTrackState > &fwdUpdTkState, std::vector< unsigned int > &hitstateidx, std::vector< unsigned int > &rejectedhsidx, std::vector< unsigned int > &sortedtksidx, std::vector< recob::TrajectoryPointFlags::Mask_t > &hitflagsv, bool applySkipClean=true) const
Sort the output states.
T abs(T value)
unsigned int MaxPlanes() const
Returns the largest number of planes among all TPCs in this detector.
const double a
p
Definition: test.py:223
const TrackStatePropagator * propagator
static constexpr Flag_t HitIgnored
Hit was not included for the computation of the trajectory.
static constexpr Flag_t Rejected
The hit is extraneous to this track.
static constexpr Flag_t ExcludedFromFit
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
Definition: statistics.h:55
constexpr double dist(const TReal *x, const TReal *y, const unsigned int dimension)
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
static bool * b
Definition: config.cpp:1043
static constexpr Flag_t DetectorIssue
The hit is associated to a problematic channel.
decltype(auto) constexpr begin(T &&obj)
ADL-aware version of std::begin.
Definition: StdUtils.h:72
static constexpr Flag_t DeltaRay
The hit might have contribution from a δ ray.
static constexpr Flag_t Shared
The hit is known to be associated also to another trajectory.
recob::tracking::Vector_t Vector_t
QTextStream & endl(QTextStream &s)
bool trkf::TrackKalmanFitter::fillResult ( const std::vector< art::Ptr< recob::Hit >> &  inHits,
const int  tkID,
const int  pdgid,
std::vector< HitState > &  hitstatev,
std::vector< recob::TrajectoryPointFlags::Mask_t > &  hitflagsv,
std::vector< KFTrackState > &  fwdPrdTkState,
std::vector< KFTrackState > &  fwdUpdTkState,
std::vector< unsigned int > &  hitstateidx,
std::vector< unsigned int > &  rejectedhsidx,
std::vector< unsigned int > &  sortedtksidx,
recob::Track outTrack,
std::vector< art::Ptr< recob::Hit >> &  outHits,
trkmkr::OptionalOutputs optionals 
) const
private

Fill the output objects.

Definition at line 946 of file TrackKalmanFitter.cxx.

959 {
960  // fill output trajectory objects with smoothed track and its hits
961  int nvalidhits = 0;
962  trkmkr::TrackCreationBookKeeper tcbk(outHits, optionals, tkID, pdgid, true);
963  for (unsigned int p : sortedtksidx) {
964  const auto& trackstate = fwdUpdTkState[p];
965  const auto& hitflags = hitflagsv[hitstateidx[p]];
966  const unsigned int originalPos = hitstateidx[p];
967  if (dumpLevel_ > 2) assert(originalPos >= 0 && originalPos < hitstatev.size());
968  //
969  const auto& prdtrack = fwdPrdTkState[p];
970  const auto& hitstate = hitstatev[hitstateidx[p]];
971  if (dumpLevel_ > 2) assert(hitstate.wireId().Plane == inHits[originalPos]->WireID().Plane);
972  //
973  float chi2 =
975  prdtrack.chi2(hitstate));
976  if (hitflags.isSet(recob::TrajectoryPointFlagTraits::NoPoint) == false) nvalidhits++;
977  //
979  if (optionals.isTrackFitInfosInit()) {
980  ope.setTrackFitHitInfo(recob::TrackFitHitInfo(hitstate.hitMeas(),
981  hitstate.hitMeasErr2(),
982  prdtrack.parameters(),
983  prdtrack.covariance(),
984  hitstate.wireId()));
985  }
986  tcbk.addPoint(trackstate.position(),
987  trackstate.momentum(),
988  inHits[originalPos],
989  recob::TrajectoryPointFlags(originalPos, hitflags),
990  chi2,
991  ope);
992  }
993  if (dumpLevel_ > 0) std::cout << "fillResult nvalidhits=" << nvalidhits << std::endl;
994 
995  // fill also with rejected hits information
996  SMatrixSym55 fakeCov55;
997  for (int i = 0; i < 5; i++)
998  for (int j = i; j < 5; j++)
999  fakeCov55(i, j) = util::kBogusD;
1000  for (unsigned int rejidx = 0; rejidx < rejectedhsidx.size(); ++rejidx) {
1001  const unsigned int originalPos = rejectedhsidx[rejidx];
1002  auto& mask = hitflagsv[rejectedhsidx[rejidx]];
1007  //
1008  const auto& hitstate = hitstatev[rejectedhsidx[rejidx]];
1009  if (dumpLevel_ > 2) assert(hitstate.wireId().Plane == inHits[originalPos]->WireID().Plane);
1011  if (optionals.isTrackFitInfosInit()) {
1013  hitstate.hitMeas(),
1014  hitstate.hitMeasErr2(),
1016  fakeCov55,
1017  hitstate.wireId()));
1018  }
1021  inHits[originalPos],
1022  recob::TrajectoryPointFlags(originalPos, mask),
1023  -1.,
1024  ope);
1025  }
1026 
1027  if (dumpLevel_ > 0)
1028  std::cout << "outHits.size()=" << outHits.size() << " inHits.size()=" << inHits.size()
1029  << std::endl;
1030  if (dumpLevel_ > 2) assert(outHits.size() == inHits.size());
1031 
1032  bool propok = true;
1033  KFTrackState resultF =
1034  propagator->rotateToPlane(propok,
1035  fwdUpdTkState[sortedtksidx.front()].trackState(),
1036  Plane(fwdUpdTkState[sortedtksidx.front()].position(),
1037  fwdUpdTkState[sortedtksidx.front()].momentum()));
1038  KFTrackState resultB =
1039  propagator->rotateToPlane(propok,
1040  fwdUpdTkState[sortedtksidx.back()].trackState(),
1041  Plane(fwdUpdTkState[sortedtksidx.back()].position(),
1042  fwdUpdTkState[sortedtksidx.back()].momentum()));
1043 
1044  outTrack =
1045  tcbk.finalizeTrack(SMatrixSym55(resultF.covariance()), SMatrixSym55(resultB.covariance()));
1046 
1047  //if there are points with zero momentum return false
1048  size_t point = 0;
1049  while (outTrack.HasValidPoint(point)) {
1050  if (outTrack.MomentumAtPoint(outTrack.NextValidPoint(point++)) <= 1.0e-9) {
1051  mf::LogWarning("TrackKalmanFitter") << "found point with zero momentum!" << std::endl;
1052  return false;
1053  }
1054  }
1055 
1056  if (dumpLevel_ > 0) {
1057  std::cout << "outTrack vertex=" << outTrack.Start() << "\ndir=" << outTrack.StartDirection()
1058  << "\ncov=\n"
1059  << outTrack.StartCovariance() << "\nlength=" << outTrack.Length()
1060  << "\nchi2/ndof=" << outTrack.Chi2PerNdof() << std::endl;
1061  }
1062 
1063  return true;
1064 }
static constexpr Flag_t NoPoint
The trajectory point is not defined.
recob::tracking::Point_t Point_t
Definition: TrackState.h:18
recob::tracking::Vector_t Vector_t
Definition: TrackState.h:19
const SMatrixSym55 & StartCovariance() const
Access to covariance matrices.
Definition: Track.h:153
recob::tracking::SMatrixSym55 SMatrixSym55
Definition: TrackState.h:15
bool HasValidPoint(size_t i) const
Definition: Track.h:111
double MomentumAtPoint(unsigned int p) const
Definition: Track.h:141
Vector_t StartDirection() const
Access to track direction at different points.
Definition: Track.h:131
const double e
double Length(size_t p=0) const
Access to various track properties.
Definition: Track.h:167
recob::tracking::SVector5 SVector5
Definition: TrackState.h:12
Point_t const & Start() const
Access to track position at different points.
Definition: Track.h:123
Object storing per-hit information from a track fit.
Struct holding point-by-point elements used in OptionalOutputs.
Definition: TrackMaker.h:36
float Chi2PerNdof() const
Definition: Track.h:169
TrackState rotateToPlane(bool &success, const TrackState &origin, const Plane &target) const
Rotation of a TrackState to a Plane (zero distance propagation)
p
Definition: test.py:223
const TrackStatePropagator * propagator
static constexpr Flag_t HitIgnored
Hit was not included for the computation of the trajectory.
static constexpr Flag_t Rejected
The hit is extraneous to this track.
static constexpr Flag_t ExcludedFromFit
recob::tracking::SMatrixSym55 SMatrixSym55
size_t NextValidPoint(size_t index) const
Definition: Track.h:107
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
Helper class to aid the creation of a recob::Track, keeping data vectors in sync. ...
bool isTrackFitInfosInit()
check initialization of the output vector of TrackFitHitInfos
Definition: TrackMaker.h:162
constexpr double kBogusD
obviously bogus double value
void setTrackFitHitInfo(recob::TrackFitHitInfo &&aTrackFitHitInfo)
set the recob::TrackFitHitInfo unique_ptr
Definition: TrackMaker.h:40
recob::tracking::Plane Plane
Definition: TrackState.h:17
Set of flags pertaining a point of the track.
QTextStream & endl(QTextStream &s)
bool trkf::TrackKalmanFitter::fitTrack ( detinfo::DetectorPropertiesData const &  detProp,
const recob::TrackTrajectory traj,
int  tkID,
const SMatrixSym55 covVtx,
const SMatrixSym55 covEnd,
const std::vector< art::Ptr< recob::Hit >> &  hits,
const double  pval,
const int  pdgid,
const bool  flipDirection,
recob::Track outTrack,
std::vector< art::Ptr< recob::Hit >> &  outHits,
trkmkr::OptionalOutputs optionals 
) const

Fit track starting from TrackTrajectory.

Definition at line 37 of file TrackKalmanFitter.cxx.

49 {
50  auto position = traj.Vertex();
51  auto direction = traj.VertexDirection();
52 
53  if (tryBothDirs_) {
54  recob::Track fwdTrack;
55  std::vector<art::Ptr<recob::Hit>> fwdHits;
56  trkmkr::OptionalOutputs fwdoptionals;
57  SMatrixSym55 fwdcov = covVtx;
58  bool okfwd = fitTrack(detProp,
59  position,
60  direction,
61  fwdcov,
62  hits,
63  traj.Flags(),
64  tkID,
65  pval,
66  pdgid,
67  fwdTrack,
68  fwdHits,
69  fwdoptionals);
70 
71  recob::Track bwdTrack;
72  std::vector<art::Ptr<recob::Hit>> bwdHits;
73  trkmkr::OptionalOutputs bwdoptionals;
74  SMatrixSym55 bwdcov = covEnd;
75  bool okbwd = fitTrack(detProp,
76  position,
77  -direction,
78  bwdcov,
79  hits,
80  traj.Flags(),
81  tkID,
82  pval,
83  pdgid,
84  bwdTrack,
85  bwdHits,
86  bwdoptionals);
87 
88  if (okfwd == false && okbwd == false) { return false; }
89  else if (okfwd == true && okbwd == true) {
90  if ((fwdTrack.CountValidPoints() / (fwdTrack.Length() * fwdTrack.Chi2PerNdof())) >=
91  (bwdTrack.CountValidPoints() / (bwdTrack.Length() * bwdTrack.Chi2PerNdof()))) {
92  outTrack = fwdTrack;
93  outHits = fwdHits;
94  optionals = std::move(fwdoptionals);
95  }
96  else {
97  outTrack = bwdTrack;
98  outHits = bwdHits;
99  optionals = std::move(bwdoptionals);
100  }
101  }
102  else if (okfwd == true) {
103  outTrack = fwdTrack;
104  outHits = fwdHits;
105  optionals = std::move(fwdoptionals);
106  }
107  else {
108  outTrack = bwdTrack;
109  outHits = bwdHits;
110  optionals = std::move(bwdoptionals);
111  }
112  return true;
113  }
114  else {
115  if (flipDirection) {
116  position = traj.End();
117  direction = -traj.EndDirection();
118  }
119 
120  auto trackStateCov = (flipDirection ? covEnd : covVtx);
121 
122  return fitTrack(detProp,
123  position,
124  direction,
125  trackStateCov,
126  hits,
127  traj.Flags(),
128  tkID,
129  pval,
130  pdgid,
131  outTrack,
132  outHits,
133  optionals);
134  }
135 }
Flags_t const & Flags() const
Returns all flags.
bool fitTrack(detinfo::DetectorPropertiesData const &detProp, const recob::TrackTrajectory &traj, int tkID, const SMatrixSym55 &covVtx, const SMatrixSym55 &covEnd, const std::vector< art::Ptr< recob::Hit >> &hits, const double pval, const int pdgid, const bool flipDirection, recob::Track &outTrack, std::vector< art::Ptr< recob::Hit >> &outHits, trkmkr::OptionalOutputs &optionals) const
Fit track starting from TrackTrajectory.
Vector_t VertexDirection() const
Returns the direction of the trajectory at the first point.
def move(depos, offset)
Definition: depos.py:107
Point_t const & Vertex() const
Returns the position of the first valid point of the trajectory [cm].
Vector_t EndDirection() const
Returns the direction of the trajectory at the last point.
pval
Definition: tracks.py:168
recob::tracking::SMatrixSym55 SMatrixSym55
Point_t const & End() const
Returns the position of the last valid point of the trajectory [cm].
Struct holding optional TrackMaker outputs.
Definition: TrackMaker.h:114
Track from a non-cascading particle.A recob::Track consists of a recob::TrackTrajectory, plus additional members relevant for a "fitted" track:
Definition: Track.h:49
bool trkf::TrackKalmanFitter::fitTrack ( detinfo::DetectorPropertiesData const &  detProp,
const Point_t position,
const Vector_t direction,
SMatrixSym55 trackStateCov,
const std::vector< art::Ptr< recob::Hit >> &  hits,
const std::vector< recob::TrajectoryPointFlags > &  flags,
const int  tkID,
const double  pval,
const int  pdgid,
recob::Track outTrack,
std::vector< art::Ptr< recob::Hit >> &  outHits,
trkmkr::OptionalOutputs optionals 
) const

Fit track starting from intial position, direction, and flags.

Definition at line 138 of file TrackKalmanFitter.cxx.

150 {
151  if (dumpLevel_ > 1)
152  std::cout << "Fitting track with tkID=" << tkID << " start pos=" << position
153  << " dir=" << direction << " nHits=" << hits.size() << " mom=" << pval
154  << " pdg=" << pdgid << std::endl;
155  if (hits.size() < 4) {
156  mf::LogWarning("TrackKalmanFitter") << "Fit failure at " << __FILE__ << " " << __LINE__;
157  return false;
158  }
159 
160  // setup the KFTrackState we'll use throughout the fit
161  KFTrackState trackState = setupInitialTrackState(position, direction, trackStateCov, pval, pdgid);
162 
163  // setup vector of HitStates and flags, with either same or inverse order as input hit vector
164  // this is what we'll loop over during the fit
165  std::vector<HitState> hitstatev;
166  std::vector<recob::TrajectoryPointFlags::Mask_t> hitflagsv;
167  bool inputok = setupInputStates(detProp, hits, flags, trackState, hitstatev, hitflagsv);
168  if (!inputok) return false;
169 
170  // track and index vectors we use to store the fit results
171  std::vector<KFTrackState> fwdPrdTkState;
172  std::vector<KFTrackState> fwdUpdTkState;
173  std::vector<unsigned int> hitstateidx;
174  std::vector<unsigned int> rejectedhsidx;
175  std::vector<unsigned int> sortedtksidx;
176 
177  // do the actual fit
178  bool fitok = doFitWork(trackState,
179  detProp,
180  hitstatev,
181  hitflagsv,
182  fwdPrdTkState,
183  fwdUpdTkState,
184  hitstateidx,
185  rejectedhsidx,
186  sortedtksidx);
187  if (!fitok && (skipNegProp_ || cleanZigzag_) && tryNoSkipWhenFails_) {
188  mf::LogWarning("TrackKalmanFitter")
189  << "Trying to recover with skipNegProp = false and cleanZigzag = false\n";
190  fitok = doFitWork(trackState,
191  detProp,
192  hitstatev,
193  hitflagsv,
194  fwdPrdTkState,
195  fwdUpdTkState,
196  hitstateidx,
197  rejectedhsidx,
198  sortedtksidx,
199  false);
200  }
201  if (!fitok) {
202  mf::LogWarning("TrackKalmanFitter") << "Fit failed for track with ID=" << tkID << "\n";
203  return false;
204  }
205 
206  // fill the track, the output hit vector, and the optional output products
207  bool fillok = fillResult(hits,
208  tkID,
209  pdgid,
210  hitstatev,
211  hitflagsv,
212  fwdPrdTkState,
213  fwdUpdTkState,
214  hitstateidx,
215  rejectedhsidx,
216  sortedtksidx,
217  outTrack,
218  outHits,
219  optionals);
220  return fillok;
221 }
bool doFitWork(KFTrackState &trackState, detinfo::DetectorPropertiesData const &detProp, std::vector< HitState > &hitstatev, std::vector< recob::TrajectoryPointFlags::Mask_t > &hitflagsv, std::vector< KFTrackState > &fwdPrdTkState, std::vector< KFTrackState > &fwdUpdTkState, std::vector< unsigned int > &hitstateidx, std::vector< unsigned int > &rejectedhsidx, std::vector< unsigned int > &sortedtksidx, bool applySkipClean=true) const
Function where the core of the fit is performed.
bool setupInputStates(detinfo::DetectorPropertiesData const &detProp, const std::vector< art::Ptr< recob::Hit >> &hits, const std::vector< recob::TrajectoryPointFlags > &flags, const KFTrackState &trackState, std::vector< HitState > &hitstatev, std::vector< recob::TrajectoryPointFlags::Mask_t > &hitflagsv) const
Setup vectors of HitState and Masks to be used during the fit.
bool fillResult(const std::vector< art::Ptr< recob::Hit >> &inHits, const int tkID, const int pdgid, std::vector< HitState > &hitstatev, std::vector< recob::TrajectoryPointFlags::Mask_t > &hitflagsv, std::vector< KFTrackState > &fwdPrdTkState, std::vector< KFTrackState > &fwdUpdTkState, std::vector< unsigned int > &hitstateidx, std::vector< unsigned int > &rejectedhsidx, std::vector< unsigned int > &sortedtksidx, recob::Track &outTrack, std::vector< art::Ptr< recob::Hit >> &outHits, trkmkr::OptionalOutputs &optionals) const
Fill the output objects.
KFTrackState setupInitialTrackState(const Point_t &position, const Vector_t &direction, SMatrixSym55 &trackStateCov, const double pval, const int pdgid) const
Return track state from intial position, direction, and covariance.
pval
Definition: tracks.py:168
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
QTextStream & endl(QTextStream &s)
trkf::KFTrackState trkf::TrackKalmanFitter::setupInitialTrackState ( const Point_t position,
const Vector_t direction,
SMatrixSym55 trackStateCov,
const double  pval,
const int  pdgid 
) const
private

Return track state from intial position, direction, and covariance.

Definition at line 224 of file TrackKalmanFitter.cxx.

229 {
230  //start from large enough covariance matrix so that the fit is not biased
231  if (trackStateCov == SMatrixSym55()) {
232  trackStateCov(0, 0) = 1000.;
233  trackStateCov(1, 1) = 1000.;
234  trackStateCov(2, 2) = 0.25;
235  trackStateCov(3, 3) = 0.25;
236  trackStateCov(4, 4) = 10.;
237  }
238  else
239  trackStateCov *= 100.;
240  // build vector of parameters on plane with point on the track and direction normal to the plane parallel to the track (so the first four parameters are zero by construction)
241  SVector5 trackStatePar(0., 0., 0., 0., 1. / pval);
242  return KFTrackState(trackStatePar,
243  trackStateCov,
245  true,
246  pdgid); //along direction by definition
247 }
recob::tracking::SMatrixSym55 SMatrixSym55
Definition: TrackState.h:15
recob::tracking::SVector5 SVector5
Definition: TrackState.h:12
pval
Definition: tracks.py:168
recob::tracking::Plane Plane
Definition: TrackState.h:17
bool trkf::TrackKalmanFitter::setupInputStates ( detinfo::DetectorPropertiesData const &  detProp,
const std::vector< art::Ptr< recob::Hit >> &  hits,
const std::vector< recob::TrajectoryPointFlags > &  flags,
const KFTrackState trackState,
std::vector< HitState > &  hitstatev,
std::vector< recob::TrajectoryPointFlags::Mask_t > &  hitflagsv 
) const
private

Setup vectors of HitState and Masks to be used during the fit.

Definition at line 250 of file TrackKalmanFitter.cxx.

257 {
258  if (dumpLevel_ > 1)
259  std::cout << "flags.size()=" << flags.size() << " hits.size()=" << hits.size() << std::endl;
260 
261  // setup vector of HitStates and flags, with either same or inverse order as input hit vector
262  // this is what we'll loop over during the fit
263  const size_t fsize = flags.size();
264  for (size_t ihit = 0; ihit != hits.size(); ihit++) {
265  const auto& hit = hits[ihit];
266  double t = hit->PeakTime();
267  double terr = (useRMS_ ? hit->RMS() : hit->SigmaPeakTime());
268  double x =
269  detProp.ConvertTicksToX(t, hit->WireID().Plane, hit->WireID().TPC, hit->WireID().Cryostat);
270  double xerr = terr * detProp.GetXTicksCoefficient();
271  hitstatev.emplace_back(
272  x, hitErr2ScaleFact_ * xerr * xerr, hit->WireID(), geom->WireIDToWireGeo(hit->WireID()));
273  //
274  if (fsize > 0 && ihit < fsize)
275  hitflagsv.push_back(flags[ihit].mask());
276  else
277  hitflagsv.push_back(recob::TrajectoryPointFlags::DefaultFlagsMask());
278  //
279  if (rejectHighMultHits_ && hit->Multiplicity() > 1) {
280  hitflagsv.back().set(recob::TrajectoryPointFlagTraits::Merged);
282  }
283  if (rejectHitsNegativeGOF_ && hit->GoodnessOfFit() < 0) {
284  hitflagsv.back().set(recob::TrajectoryPointFlagTraits::Suspicious);
286  }
287  //
288  if (dumpLevel_ > 2)
289  std::cout << "pushed flag mask=" << hitflagsv.back()
290  << " merged=" << hitflagsv.back().isSet(recob::TrajectoryPointFlagTraits::Merged)
291  << " suspicious="
292  << hitflagsv.back().isSet(recob::TrajectoryPointFlagTraits::Suspicious)
293  << " nopoint=" << hitflagsv.back().isSet(recob::TrajectoryPointFlagTraits::NoPoint)
294  << std::endl;
295  }
296  if (dumpLevel_ > 2) assert(hits.size() == hitstatev.size());
297  return true;
298 }
static constexpr Flag_t Merged
The hit might have contribution from particles other than this.
static constexpr Flag_t Suspicious
The point reconstruction is somehow questionable.
static constexpr Flag_t NoPoint
The trajectory point is not defined.
static constexpr Mask_t DefaultFlagsMask()
Flags used in default construction.
art::ServiceHandle< geo::Geometry const > geom
Detector simulation of raw signals on wires.
static constexpr Flag_t ExcludedFromFit
list x
Definition: train.py:276
QTextStream & endl(QTextStream &s)
WireGeo const & WireIDToWireGeo(geo::WireID const &wireid) const
void trkf::TrackKalmanFitter::sortOutput ( std::vector< HitState > &  hitstatev,
std::vector< KFTrackState > &  fwdUpdTkState,
std::vector< unsigned int > &  hitstateidx,
std::vector< unsigned int > &  rejectedhsidx,
std::vector< unsigned int > &  sortedtksidx,
std::vector< recob::TrajectoryPointFlags::Mask_t > &  hitflagsv,
bool  applySkipClean = true 
) const
private

Sort the output states.

Definition at line 821 of file TrackKalmanFitter.cxx.

828 {
829  //
831  //sort hits keeping fixed the order on planes and picking the closest next plane
832  const unsigned int nplanes = geom->MaxPlanes();
833  std::vector<std::vector<unsigned int>> tracksInPlanes(nplanes);
834  for (unsigned int p = 0; p < hitstateidx.size(); ++p) {
835  const auto& hitstate = hitstatev[hitstateidx[p]];
836  tracksInPlanes[hitstate.wireId().Plane].push_back(p);
837  }
838  if (dumpLevel_ > 2) {
839  for (auto s : fwdUpdTkState) {
840  std::cout << "state pos=" << s.position() << std::endl;
841  }
842  }
843  //find good starting point
844  std::vector<unsigned int> iterTracksInPlanes;
845  for (auto it : tracksInPlanes)
846  iterTracksInPlanes.push_back(0);
847  auto pos = fwdUpdTkState.front().position();
848  auto dir = fwdUpdTkState.front().momentum();
849  unsigned int p = 0;
850  for (; p < fwdUpdTkState.size(); ++p) {
851  if (hitflagsv[hitstateidx[p]].isSet(recob::TrajectoryPointFlagTraits::ExcludedFromFit) == 0) {
852  pos = fwdUpdTkState[p].position();
853  dir = fwdUpdTkState[p].momentum();
854  if (dumpLevel_ > 2)
855  std::cout << "sort output found point not excluded with p=" << p
856  << " hitstateidx[p]=" << hitstateidx[p] << " pos=" << pos << std::endl;
857  break;
858  }
859  else {
860  rejectedhsidx.push_back(hitstateidx[p]);
861  }
862  }
863  if (dumpLevel_ > 1)
864  std::cout << "sort output init with pos=" << pos << " dir=" << dir << std::endl;
865  //pick hits based on minimum dot product with respect to position and direction at previous hit
866  for (; p < fwdUpdTkState.size(); ++p) {
867  int min_plane = -1;
868  double min_dotp = DBL_MAX;
869  for (unsigned int iplane = 0; iplane < iterTracksInPlanes.size(); ++iplane) {
870  for (unsigned int& itk = iterTracksInPlanes[iplane]; itk < tracksInPlanes[iplane].size();
871  ++itk) {
872  auto& trackstate = fwdUpdTkState[tracksInPlanes[iplane][iterTracksInPlanes[iplane]]];
873  auto& tmppos = trackstate.position();
874  const double dotp = dir.Dot(tmppos - pos);
875  if (dumpLevel_ > 2)
876  std::cout << "iplane=" << iplane << " tmppos=" << tmppos << " tmpdir=" << tmppos - pos
877  << " dotp=" << dotp << std::endl;
878  if (dotp < min_dotp) {
879  min_plane = iplane;
880  min_dotp = dotp;
881  }
882  break;
883  }
884  }
885  if (min_plane < 0) continue;
886  const unsigned int ihit = tracksInPlanes[min_plane][iterTracksInPlanes[min_plane]];
887  if (applySkipClean && skipNegProp_ && min_dotp < negDistTolerance_ &&
888  sortedtksidx.size() > 0) {
889  if (dumpLevel_ > 2)
890  std::cout << "sort output rejecting hit #" << ihit << " plane=" << min_plane
891  << " with min_dotp=" << min_dotp << std::endl;
892  rejectedhsidx.push_back(hitstateidx[ihit]);
893  iterTracksInPlanes[min_plane]++;
894  continue;
895  }
896  if (dumpLevel_ > 2)
897  std::cout << "sort output picking hit #" << ihit << " plane=" << min_plane
898  << " with min_dotp=" << min_dotp << std::endl;
899  auto& trackstate = fwdUpdTkState[ihit];
900  pos = trackstate.position();
901  dir = trackstate.momentum();
902  //
903  sortedtksidx.push_back(ihit);
904  iterTracksInPlanes[min_plane]++;
905  }
906  }
907  else {
908  for (unsigned int p = 0; p < fwdUpdTkState.size(); ++p) {
909  sortedtksidx.push_back(p);
910  }
911  }
912  //
913  if (applySkipClean && cleanZigzag_) {
914  std::vector<unsigned int> itoerase;
915  bool clean = false;
916  while (!clean) {
917  bool broken = false;
918  auto pos0 = fwdUpdTkState[sortedtksidx[0]].position();
919  unsigned int i = 1;
920  unsigned int end = sortedtksidx.size() - 1;
921  for (; i < end; ++i) {
922  auto dir0 = fwdUpdTkState[sortedtksidx[i]].position() - pos0;
923  auto dir2 =
924  fwdUpdTkState[sortedtksidx[i + 1]].position() - fwdUpdTkState[sortedtksidx[i]].position();
925  dir0 /= dir0.R();
926  dir2 /= dir2.R();
927  if (dir2.Dot(dir0) < 0.) {
928  broken = true;
929  end--;
930  break;
931  }
932  else
933  pos0 = fwdUpdTkState[sortedtksidx[i]].position();
934  }
935  if (!broken) { clean = true; }
936  else {
937  rejectedhsidx.push_back(hitstateidx[sortedtksidx[i]]);
938  sortedtksidx.erase(sortedtksidx.begin() + i);
939  }
940  }
941  }
942  //
943 }
end
while True: pbar.update(maxval-len(onlies[E][S])) #print iS, "/", len(onlies[E][S]) found = False for...
art::ServiceHandle< geo::Geometry const > geom
string dir
unsigned int MaxPlanes() const
Returns the largest number of planes among all TPCs in this detector.
p
Definition: test.py:223
static constexpr Flag_t ExcludedFromFit
static QCString * s
Definition: config.cpp:1042
QTextStream & endl(QTextStream &s)

Member Data Documentation

bool trkf::TrackKalmanFitter::cleanZigzag_
private

Definition at line 300 of file TrackKalmanFitter.h.

int trkf::TrackKalmanFitter::dumpLevel_
private

Definition at line 312 of file TrackKalmanFitter.h.

art::ServiceHandle<geo::Geometry const> trkf::TrackKalmanFitter::geom
private

Definition at line 293 of file TrackKalmanFitter.h.

float trkf::TrackKalmanFitter::hitErr2ScaleFact_
private

Definition at line 303 of file TrackKalmanFitter.h.

float trkf::TrackKalmanFitter::maxChi2_
private

Definition at line 309 of file TrackKalmanFitter.h.

float trkf::TrackKalmanFitter::maxDist_
private

Definition at line 310 of file TrackKalmanFitter.h.

float trkf::TrackKalmanFitter::maxResidue_
private

Definition at line 307 of file TrackKalmanFitter.h.

float trkf::TrackKalmanFitter::maxResidueFirstHit_
private

Definition at line 308 of file TrackKalmanFitter.h.

float trkf::TrackKalmanFitter::negDistTolerance_
private

Definition at line 311 of file TrackKalmanFitter.h.

bool trkf::TrackKalmanFitter::pickBestHitOnWire_
private

Definition at line 306 of file TrackKalmanFitter.h.

const TrackStatePropagator* trkf::TrackKalmanFitter::propagator
private

Definition at line 294 of file TrackKalmanFitter.h.

bool trkf::TrackKalmanFitter::rejectHighMultHits_
private

Definition at line 301 of file TrackKalmanFitter.h.

bool trkf::TrackKalmanFitter::rejectHitsNegativeGOF_
private

Definition at line 302 of file TrackKalmanFitter.h.

bool trkf::TrackKalmanFitter::skipNegProp_
private

Definition at line 299 of file TrackKalmanFitter.h.

bool trkf::TrackKalmanFitter::sortHitsByPlane_
private

Definition at line 296 of file TrackKalmanFitter.h.

bool trkf::TrackKalmanFitter::sortHitsByWire_
private

Definition at line 297 of file TrackKalmanFitter.h.

bool trkf::TrackKalmanFitter::sortOutputHitsMinLength_
private

Definition at line 298 of file TrackKalmanFitter.h.

bool trkf::TrackKalmanFitter::tryBothDirs_
private

Definition at line 305 of file TrackKalmanFitter.h.

bool trkf::TrackKalmanFitter::tryNoSkipWhenFails_
private

Definition at line 304 of file TrackKalmanFitter.h.

bool trkf::TrackKalmanFitter::useRMS_
private

Definition at line 295 of file TrackKalmanFitter.h.


The documentation for this class was generated from the following files: