All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
KalmanFilterFitTrackMaker_tool.cc
Go to the documentation of this file.
1 #include "art/Utilities/ToolConfigTable.h"
2 #include "art/Utilities/ToolMacros.h"
3 #include "fhiclcpp/types/Atom.h"
4 #include "fhiclcpp/types/Sequence.h"
5 
6 #include "art/Framework/Principal/Handle.h"
7 #include "art/Framework/Principal/Event.h"
8 
12 
15 
20 
21 namespace trkmkr {
22 
23  /**
24  * @file larreco/TrackFinder/KalmanFilterFitTrackMaker_tool.cc
25  * @class trkmkr::KalmanFilterFitTrackMaker
26  *
27  * @brief Concrete implementation of a tool to fit tracks with
28  * TrackKalmanFitter.
29  *
30  * Concrete implementation of a tool to fit tracks with
31  * trkf::TrackKalmanFitter; inherits from abstract class TrackMaker. It
32  * prepares the input needed by the fitter (momentum, particleId, direction),
33  * and returns a track with all outputs filled. If the flag
34  * keepInputTrajectoryPoints is set to true, the tracjetory points from the
35  * input track are copied into the output, so that only the covariance
36  * matrices, the chi2 and the ndof in the output track are resulting from the
37  * fit.
38  *
39  * For configuration options see KalmanFilterFitTrackMaker#Options and
40  * KalmanFilterFitTrackMaker#Config.
41  *
42  * @author G. Cerati (FNAL, MicroBooNE)
43  * @date 2017
44  * @version 1.0
45  */
46 
48 
49  public:
50  struct Options {
51  using Name = fhicl::Name;
52  using Comment = fhicl::Comment;
53  //
54  fhicl::Atom<double> defaultMomInGeV{
55  Name("defaultMomInGeV"),
56  Comment("Default momentum estimate value (all other options are set to "
57  "false, or if the estimate is not available)."),
58  1.0};
59  fhicl::Atom<bool> momFromMCSCollection{
60  Name("momFromMCSCollection"),
61  Comment("Flag used to get initial momentum estimate from MCSFitResult "
62  "collection specified by mcsInputTag."),
63  false};
64  fhicl::Atom<art::InputTag> mcsInputTag{Name("mcsInputTag"),
65  Comment("InputTag of MCSFitResult collection.")};
66  fhicl::Atom<bool> momFromCombAndPid{
67  Name("momFromCombAndPid"),
68  Comment("Flag used to get initial momentum estimate from either range "
69  "or mcs fit, based on particle id and containement (from "
70  "contInputTag collection)."),
71  false};
72  fhicl::Atom<art::InputTag> contInputTag{
73  Name("contInputTag"),
74  Comment("InputTag of CosmicTag collection for containement.")};
75  fhicl::Atom<bool> pidFromCollection{
76  Name("pidFromCollection"),
77  Comment("Flag used to get initial particle id estimate from ParticleID "
78  "collection specified by pidInputTag."),
79  false};
80  fhicl::Atom<art::InputTag> pidInputTag{Name("pidInputTag"),
81  Comment("InputTag of ParticleID collection.")};
82  fhicl::Atom<double> pidFromLengthCut{
83  Name("pidFromLengthCut"),
84  Comment("Particle ID based on length: if shorted than cut is assumed "
85  "to be a proton, if longer a muon; disabled if negative."),
86  -1.};
87  fhicl::Atom<int> defaultPdgId{
88  Name("defaultPdgId"),
89  Comment("Default particle id hypothesis (all other options are set to "
90  "false, or if the estimate is not available)."),
91  13};
92  fhicl::Atom<bool> dirFromVec{
93  Name("dirFromVec"),
94  Comment("Assume track direction as the one giving positive dot product "
95  "with vector specified by dirVec."),
96  false};
97  fhicl::Sequence<float, 3u> dirVec{
98  Name("dirVec"),
99  Comment("Fhicl sequence defining the vector used when dirFromVec=true. "
100  "It must have 3 elements.")};
101  fhicl::Atom<bool> alwaysInvertDir{
102  Name("alwaysInvertDir"),
103  Comment("If true, fit all tracks from end to vertex assuming inverted "
104  "direction."),
105  false};
106  fhicl::Atom<bool> keepInputTrajectoryPoints{
107  Name("keepInputTrajectoryPoints"),
108  Comment("Option to keep positions and directions from input "
109  "trajectory/track. The fit will provide only covariance matrices, "
110  "chi2, ndof, particle Id and absolute momentum. It may also modify "
111  "the trajectory point flags. In order to avoid inconsistencies, it "
112  "has to be used with the following fitter options all set to false: "
113  "sortHitsByPlane, sortOutputHitsMinLength, skipNegProp."),
114  false};
115  //
116  };
117 
118  struct Config {
119  using Name = fhicl::Name;
120  fhicl::Table<KalmanFilterFitTrackMaker::Options> options{Name("options")};
121  fhicl::Table<trkf::TrackStatePropagator::Config> propagator{Name("propagator")};
122  fhicl::Table<trkf::TrackKalmanFitter::Config> fitter{Name("fitter")};
123  fhicl::Table<trkf::TrajectoryMCSFitter::Config> mcsfit{Name("mcsfit")};
124  };
125  using Parameters = art::ToolConfigTable<Config>;
126 
127  /// Constructor from Parameters
129  : p_(p)
130  , prop{p_().propagator}
131  , kalmanFitter{&prop, p_().fitter}
132  , mcsfitter{p_().mcsfit}
133  , mom_def_{p_().options().defaultMomInGeV()}
134  , momFromMCSColl_{p_().options().momFromMCSCollection()}
135  , momFromCombAndPid_{p_().options().momFromCombAndPid()}
136  , pidFromColl_{p_().options().pidFromCollection()}
137  , mom_len_cut_{p_().options().pidFromLengthCut()}
138  , pid_def_{p_().options().defaultPdgId()}
139  , alwaysFlip_{p_().options().alwaysInvertDir()}
140  , dirFromVec_{p_().options().dirFromVec()}
141  {
142  if (momFromMCSColl_) { mcsInputTag_ = p_().options().mcsInputTag(); }
143  if (momFromCombAndPid_) { contInputTag_ = p_().options().contInputTag(); }
144  if (pidFromColl_) { pidInputTag_ = p_().options().pidInputTag(); }
145  if (dirFromVec_) {
146  auto d = p_().options().dirVec();
147  dirVec = recob::tracking::Vector_t{d[0], d[1], d[2]};
148  }
149  //
150  if (p_().options().keepInputTrajectoryPoints() &&
151  (p_().fitter().sortHitsByPlane() || p_().fitter().sortOutputHitsMinLength() ||
152  p_().fitter().skipNegProp())) {
153  throw cet::exception("KalmanFilterFitTrackMaker")
154  << "Incompatible configuration parameters: keepInputTrajectoryPoints "
155  "needs the following fitter options all set to false: "
156  "sortHitsByPlane, sortOutputHitsMinLength, skipNegProp."
157  << "\n";
158  }
160  throw cet::exception("KalmanFilterFitTrackMaker")
161  << "Incompatible configuration parameters: momFromMCSCollection and "
162  "momFromCombAndPid cannot be both true at the same time."
163  << "\n";
164  }
165  if (pidFromColl_ && mom_len_cut_ > 0) {
166  throw cet::exception("KalmanFilterFitTrackMaker")
167  << "Incompatible configuration parameters: pidFromCollection and "
168  "pidFromLengthCut cannot be respectively true and >0. at the same "
169  "time."
170  << "\n";
171  }
172  if (alwaysFlip_ && dirFromVec_) {
173  throw cet::exception("KalmanFilterFitTrackMaker")
174  << "Incompatible configuration parameters: alwaysInvertDir and "
175  "dirFromVec cannot be both true at the same time."
176  << "\n";
177  }
178  //
179  }
180 
181  /// initialize event: get collection of recob::MCSFitResult
182  void
183  initEvent(const art::Event& e) override
184  {
185  if (momFromMCSColl_)
186  mcs = e.getValidHandle<std::vector<recob::MCSFitResult>>(mcsInputTag_).product();
187  if (momFromCombAndPid_) {
188  cont = e.getValidHandle<std::vector<anab::CosmicTag>>(contInputTag_).product();
189  }
190  if (pidFromColl_) {
191  pid = e.getValidHandle<std::vector<anab::ParticleID>>(pidInputTag_).product();
192  }
193  }
194 
195  /// function that actually calls the fitter
197  const recob::TrackTrajectory& traj,
198  const int tkID,
199  const std::vector<art::Ptr<recob::Hit>>& inHits,
200  const recob::tracking::SMatrixSym55& covVtx,
201  const recob::tracking::SMatrixSym55& covEnd,
202  recob::Track& outTrack,
203  std::vector<art::Ptr<recob::Hit>>& outHits,
204  OptionalOutputs& optionals) const;
205 
206  /// override of TrackMaker purely virtual function with
207  /// recob::TrackTrajectory as argument
208  bool
210  const recob::TrackTrajectory& traj,
211  const int tkID,
212  const std::vector<art::Ptr<recob::Hit>>& inHits,
213  recob::Track& outTrack,
214  std::vector<art::Ptr<recob::Hit>>& outHits,
215  OptionalOutputs& optionals) const override
216  {
217  return makeTrackImpl(detProp,
218  traj,
219  tkID,
220  inHits,
223  outTrack,
224  outHits,
225  optionals);
226  }
227 
228  /// override of TrackMaker virtual function with recob::Track as argument
229  bool
231  const recob::Track& track,
232  const std::vector<art::Ptr<recob::Hit>>& inHits,
233  recob::Track& outTrack,
234  std::vector<art::Ptr<recob::Hit>>& outHits,
235  OptionalOutputs& optionals) const override
236  {
237  auto covs = track.Covariances();
238  return makeTrackImpl(detProp,
239  track.Trajectory(),
240  track.ID(),
241  inHits,
242  covs.first,
243  covs.second,
244  outTrack,
245  outHits,
246  optionals);
247  }
248 
249  /// set the particle ID hypothesis
250  int getParticleID(const recob::TrackTrajectory& traj, const int tkID) const;
251  /// set the initial momentum estimate
252  double getMomentum(const recob::TrackTrajectory& traj,
253  const int pid,
254  const bool isFlip,
255  const int tkID) const;
256  /// decide whether to flip the direction or not
257  bool isFlipDirection(const recob::TrackTrajectory& traj, const int tkID) const;
258 
259  /// restore the TrajectoryPoints in the Track to be the same as those in the
260  /// input TrackTrajectory (but keep covariance matrices and chi2 from fit).
262  const std::vector<art::Ptr<recob::Hit>>& inHits,
263  recob::Track& outTrack,
264  std::vector<art::Ptr<recob::Hit>>& outHits,
265  OptionalOutputs& optionals) const;
266 
267  private:
272  double mom_def_;
274  art::InputTag mcsInputTag_;
276  art::InputTag contInputTag_;
278  art::InputTag pidInputTag_;
279  double mom_len_cut_;
280  int pid_def_;
284  const std::vector<recob::MCSFitResult>* mcs = nullptr;
285  const std::vector<anab::CosmicTag>* cont = nullptr;
286  const std::vector<anab::ParticleID>* pid = nullptr;
288  };
289 }
290 
291 bool
293  const recob::TrackTrajectory& traj,
294  const int tkID,
295  const std::vector<art::Ptr<recob::Hit>>& inHits,
296  const recob::tracking::SMatrixSym55& covVtx,
297  const recob::tracking::SMatrixSym55& covEnd,
298  recob::Track& outTrack,
299  std::vector<art::Ptr<recob::Hit>>& outHits,
300  OptionalOutputs& optionals) const
301 {
302  const int pid = getParticleID(traj, tkID);
303  const bool flipDirection = isFlipDirection(traj, tkID);
304  const double mom = getMomentum(traj, pid, flipDirection, tkID); // what about mom uncertainty?
305  bool fitok = kalmanFitter.fitTrack(detProp,
306  traj,
307  tkID,
308  covVtx,
309  covEnd,
310  inHits,
311  mom,
312  pid,
313  flipDirection,
314  outTrack,
315  outHits,
316  optionals);
317  if (!fitok) return false;
318  if (p_().options().keepInputTrajectoryPoints()) {
319  restoreInputPoints(traj, inHits, outTrack, outHits, optionals);
320  }
321  return true;
322 }
323 
324 double
326  const int pid,
327  const bool isFlip,
328  const int tkID) const
329 {
330  double mom = (mom_def_ > 0 ? mom_def_ : traj.StartMomentum());
331  if (momFromMCSColl_) {
332  double mcsmom = (isFlip ? mcs->at(tkID).bwdMomentum() : mcs->at(tkID).fwdMomentum());
333  // make sure the mcs fit converged
334  if (mcsmom > 0.01 && mcsmom < 7.) mom = mcsmom;
335  }
336  if (momFromCombAndPid_) {
337  bool isContained = cont->at(tkID).CosmicType() == anab::kNotTagged;
338  // for now momentum from range implemented only for muons and protons
339  // so treat pions as muons (~MIPs) and kaons as protons
340  int pidtmp = pid;
341  if (pidtmp == 211 || pidtmp == 13)
342  pidtmp = 13;
343  else
344  pidtmp = 2212;
345  mom = tmc.GetTrackMomentum(traj.Length(), pidtmp);
346  if (isContained == false) {
347  auto mcsresult = mcsfitter.fitMcs(traj, pid);
348  double mcsmom = (isFlip ? mcsresult.bwdMomentum() : mcsresult.fwdMomentum());
349  // make sure the mcs fit converged, also the mcsmom should not be less
350  // than the range!
351  if (mcsmom > 0.01 && mcsmom < 7. && mcsmom > mom) mom = mcsmom;
352  }
353  }
354  return mom;
355 }
356 
357 int
359  const int tkID) const
360 {
361  if (pidFromColl_) {
362  return -1; //pid->at(tkID).Pdg();
363  }
364  if (mom_len_cut_ > 0.) { return (traj.Length() < mom_len_cut_ ? 2212 : 13); }
365  return pid_def_;
366 }
367 
368 bool
370  const int tkID) const
371 {
372  if (alwaysFlip_) { return true; }
373  else if (dirFromVec_) {
374  auto tdir = traj.VertexDirection();
375  if (tdir.Dot(dirVec) < 0.) return true;
376  }
377  return false;
378 }
379 
380 void
382  const recob::TrackTrajectory& traj,
383  const std::vector<art::Ptr<recob::Hit>>& inHits,
384  recob::Track& outTrack,
385  std::vector<art::Ptr<recob::Hit>>& outHits,
386  OptionalOutputs& optionals) const
387 {
388  if (optionals.isTrackFitInfosInit()) {
389  throw cet::exception("KalmanFilterFitTrackMaker")
390  << "Option keepInputTrajectoryPoints not compatible with "
391  "doTrackFitHitInfo, please set doTrackFitHitInfo to false in the "
392  "track producer.\n";
393  }
394  const auto np = outTrack.NumberTrajectoryPoints();
396  outHits, optionals, outTrack.ID(), outTrack.ParticleId(), traj.HasMomentum());
397  //
398  std::vector<unsigned int> flagsmap(np, -1);
399  for (unsigned int i = 0; i < np; ++i)
400  flagsmap[outTrack.FlagsAtPoint(i).fromHit()] = i;
401  //
402  for (unsigned int p = 0; p < np; ++p) {
403  auto mask = outTrack.FlagsAtPoint(flagsmap[p]).mask();
406  tcbk.addPoint(traj.LocationAtPoint(p),
407  traj.MomentumVectorAtPoint(p),
408  inHits[p],
410  0);
411  }
412  auto covs = outTrack.Covariances();
413  tcbk.setTotChi2(outTrack.Chi2());
414  outTrack = tcbk.finalizeTrack(std::move(covs.first), std::move(covs.second));
415  //
416 }
417 
418 DEFINE_ART_CLASS_TOOL(trkmkr::KalmanFilterFitTrackMaker)
int getParticleID(const recob::TrackTrajectory &traj, const int tkID) const
set the particle ID hypothesis
Fit tracks using Kalman Filter fit+smooth.
bool makeTrack(const detinfo::DetectorPropertiesData &detProp, const recob::TrackTrajectory &traj, const int tkID, const std::vector< art::Ptr< recob::Hit >> &inHits, recob::Track &outTrack, std::vector< art::Ptr< recob::Hit >> &outHits, OptionalOutputs &optionals) const override
static constexpr Flag_t NoPoint
The trajectory point is not defined.
ROOT::Math::SMatrix< Double32_t, 5, 5, ROOT::Math::MatRepSym< Double32_t, 5 > > SMatrixSym55
Definition: TrackingTypes.h:85
const recob::TrackTrajectory & Trajectory() const
Access to the stored recob::TrackTrajectory.
KalmanFilterFitTrackMaker(Parameters const &p)
Constructor from Parameters.
pdgs p
Definition: selectors.fcl:22
recob::tracking::SMatrixSym55 SMatrixSym55
Definition: TrackState.h:15
size_t NumberTrajectoryPoints() const
Various functions related to the presence and the number of (valid) points.
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.
Class for propagation of a trkf::TrackState to a recob::tracking::Plane.
fhicl::Table< KalmanFilterFitTrackMaker::Options > options
constexpr Mask_t const & mask() const
Returns the entire set of bits as a bit mask.
process_name use argoneut_mc_hitfinder track
std::pair< SMatrixSym55, SMatrixSym55 > Covariances() const
void restoreInputPoints(const recob::TrackTrajectory &traj, const std::vector< art::Ptr< recob::Hit >> &inHits, recob::Track &outTrack, std::vector< art::Ptr< recob::Hit >> &outHits, OptionalOutputs &optionals) const
Base abstract class for tools used to fit tracks.
Definition: TrackMaker.h:234
fhicl::Table< trkf::TrajectoryMCSFitter::Config > mcsfit
constexpr HitIndex_t fromHit() const
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:265
Vector_t VertexDirection() const
Returns the direction of the trajectory at the first point.
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< Coord_t >, ROOT::Math::GlobalCoordinateSystemTag > Vector_t
Type for representation of momenta in 3D space. See recob::tracking::Coord_t for more details on the ...
Definition: TrackingTypes.h:29
const std::vector< anab::CosmicTag > * cont
const std::vector< recob::MCSFitResult > * mcs
double Length(size_t startAt=0) const
Returns the approximate length of the trajectory.
bool makeTrackImpl(const detinfo::DetectorPropertiesData &detProp, const recob::TrackTrajectory &traj, const int tkID, const std::vector< art::Ptr< recob::Hit >> &inHits, const recob::tracking::SMatrixSym55 &covVtx, const recob::tracking::SMatrixSym55 &covEnd, recob::Track &outTrack, std::vector< art::Ptr< recob::Hit >> &outHits, OptionalOutputs &optionals) const
function that actually calls the fitter
constexpr mask_t< EnumType > mask(EnumType bit, OtherBits...otherBits)
Returns a mask with all specified bits set.
const std::vector< anab::ParticleID > * pid
A trajectory in space reconstructed from hits.
T LocationAtPoint(unsigned int p) const
Position at point p. Use e.g. as:
double StartMomentum() const
Concrete implementation of a tool to fit tracks with TrackKalmanFitter.
BEGIN_PROLOG vertical distance to the surface Name
bool makeTrack(const detinfo::DetectorPropertiesData &detProp, const recob::Track &track, const std::vector< art::Ptr< recob::Hit >> &inHits, recob::Track &outTrack, std::vector< art::Ptr< recob::Hit >> &outHits, OptionalOutputs &optionals) const override
override of TrackMaker virtual function with recob::Track as argument
double getMomentum(const recob::TrackTrajectory &traj, const int pid, const bool isFlip, const int tkID) const
set the initial momentum estimate
void initEvent(const art::Event &e) override
initialize event: get collection of recob::MCSFitResult
bool HasMomentum() const
Returns whether information about the momentum is available.
Definition: Trajectory.h:425
fhicl::Table< trkf::TrackKalmanFitter::Config > fitter
fhicl::Table< trkf::TrackStatePropagator::Config > propagator
Helper class to aid the creation of a recob::Track, keeping data vectors in sync. ...
then echo echo For and will not be changed by echo further linking echo echo B echo The symbol is in the uninitialized data multiple common symbols may appear with the echo same name If the symbol is defined the common echo symbols are treated as undefined references For more echo details on common see the discussion of warn common echo in *Note Linker options
do i e
Class for Maximum Likelihood fit of Multiple Coulomb Scattering angles between segments within a Trac...
PointFlags_t const & FlagsAtPoint(size_t i) const
bool isTrackFitInfosInit()
check initialization of the output vector of TrackFitHitInfos
Definition: TrackMaker.h:173
bool isFlipDirection(const recob::TrackTrajectory &traj, const int tkID) const
decide whether to flip the direction or not
T MomentumVectorAtPoint(unsigned int p) const
Momentum vector at point p. Use e.g. as:
Struct holding optional TrackMaker outputs.
Definition: TrackMaker.h:125
Set of flags pertaining a point of the track.
auto const detProp
Track from a non-cascading particle.A recob::Track consists of a recob::TrackTrajectory, plus additional members relevant for a &quot;fitted&quot; track: