KalmanFilterFitTrackMaker_tool.cc
Go to the documentation of this file.
3 #include "fhiclcpp/types/Atom.h"
5 
7 
11 
14 
19 
20 namespace trkmkr {
21 
22  /**
23  * @file larreco/TrackFinder/KalmanFilterFitTrackMaker_tool.cc
24  * @class trkmkr::KalmanFilterFitTrackMaker
25  *
26  * @brief Concrete implementation of a tool to fit tracks with
27  * TrackKalmanFitter.
28  *
29  * Concrete implementation of a tool to fit tracks with
30  * trkf::TrackKalmanFitter; inherits from abstract class TrackMaker. It
31  * prepares the input needed by the fitter (momentum, particleId, direction),
32  * and returns a track with all outputs filled. If the flag
33  * keepInputTrajectoryPoints is set to true, the tracjetory points from the
34  * input track are copied into the output, so that only the covariance
35  * matrices, the chi2 and the ndof in the output track are resulting from the
36  * fit.
37  *
38  * For configuration options see KalmanFilterFitTrackMaker#Options and
39  * KalmanFilterFitTrackMaker#Config.
40  *
41  * @author G. Cerati (FNAL, MicroBooNE)
42  * @date 2017
43  * @version 1.0
44  */
45 
47 
48  public:
49  struct Options {
50  using Name = fhicl::Name;
52  //
54  Name("defaultMomInGeV"),
55  Comment("Default momentum estimate value (all other options are set to "
56  "false, or if the estimate is not available)."),
57  1.0};
59  Name("momFromMCSCollection"),
60  Comment("Flag used to get initial momentum estimate from MCSFitResult "
61  "collection specified by mcsInputTag."),
62  false};
64  Comment("InputTag of MCSFitResult collection.")};
66  Name("momFromCombAndPid"),
67  Comment("Flag used to get initial momentum estimate from either range "
68  "or mcs fit, based on particle id and containement (from "
69  "contInputTag collection)."),
70  false};
72  Name("contInputTag"),
73  Comment("InputTag of CosmicTag collection for containement.")};
75  Name("pidFromCollection"),
76  Comment("Flag used to get initial particle id estimate from ParticleID "
77  "collection specified by pidInputTag."),
78  false};
80  Comment("InputTag of ParticleID collection.")};
82  Name("pidFromLengthCut"),
83  Comment("Particle ID based on length: if shorted than cut is assumed "
84  "to be a proton, if longer a muon; disabled if negative."),
85  -1.};
87  Name("defaultPdgId"),
88  Comment("Default particle id hypothesis (all other options are set to "
89  "false, or if the estimate is not available)."),
90  13};
92  Name("dirFromVec"),
93  Comment("Assume track direction as the one giving positive dot product "
94  "with vector specified by dirVec."),
95  false};
97  Name("dirVec"),
98  Comment("Fhicl sequence defining the vector used when dirFromVec=true. "
99  "It must have 3 elements.")};
101  Name("alwaysInvertDir"),
102  Comment("If true, fit all tracks from end to vertex assuming inverted "
103  "direction."),
104  false};
106  Name("keepInputTrajectoryPoints"),
107  Comment("Option to keep positions and directions from input "
108  "trajectory/track. The fit will provide only covariance matrices, "
109  "chi2, ndof, particle Id and absolute momentum. It may also modify "
110  "the trajectory point flags. In order to avoid inconsistencies, it "
111  "has to be used with the following fitter options all set to false: "
112  "sortHitsByPlane, sortOutputHitsMinLength, skipNegProp."),
113  false};
114  //
115  };
116 
117  struct Config {
118  using Name = fhicl::Name;
123  };
125 
126  /// Constructor from Parameters
128  : p_(p)
129  , prop{p_().propagator}
130  , kalmanFitter{&prop, p_().fitter}
131  , mcsfitter{p_().mcsfit}
132  , mom_def_{p_().options().defaultMomInGeV()}
133  , momFromMCSColl_{p_().options().momFromMCSCollection()}
134  , momFromCombAndPid_{p_().options().momFromCombAndPid()}
135  , pidFromColl_{p_().options().pidFromCollection()}
136  , mom_len_cut_{p_().options().pidFromLengthCut()}
137  , pid_def_{p_().options().defaultPdgId()}
138  , alwaysFlip_{p_().options().alwaysInvertDir()}
139  , dirFromVec_{p_().options().dirFromVec()}
140  {
141  if (momFromMCSColl_) { mcsInputTag_ = p_().options().mcsInputTag(); }
142  if (momFromCombAndPid_) { contInputTag_ = p_().options().contInputTag(); }
143  if (pidFromColl_) { pidInputTag_ = p_().options().pidInputTag(); }
144  if (dirFromVec_) {
145  auto d = p_().options().dirVec();
146  dirVec = recob::tracking::Vector_t{d[0], d[1], d[2]};
147  }
148  //
150  (p_().fitter().sortHitsByPlane() || p_().fitter().sortOutputHitsMinLength() ||
151  p_().fitter().skipNegProp())) {
152  throw cet::exception("KalmanFilterFitTrackMaker")
153  << "Incompatible configuration parameters: keepInputTrajectoryPoints "
154  "needs the following fitter options all set to false: "
155  "sortHitsByPlane, sortOutputHitsMinLength, skipNegProp."
156  << "\n";
157  }
159  throw cet::exception("KalmanFilterFitTrackMaker")
160  << "Incompatible configuration parameters: momFromMCSCollection and "
161  "momFromCombAndPid cannot be both true at the same time."
162  << "\n";
163  }
164  if (pidFromColl_ && mom_len_cut_ > 0) {
165  throw cet::exception("KalmanFilterFitTrackMaker")
166  << "Incompatible configuration parameters: pidFromCollection and "
167  "pidFromLengthCut cannot be respectively true and >0. at the same "
168  "time."
169  << "\n";
170  }
171  if (alwaysFlip_ && dirFromVec_) {
172  throw cet::exception("KalmanFilterFitTrackMaker")
173  << "Incompatible configuration parameters: alwaysInvertDir and "
174  "dirFromVec cannot be both true at the same time."
175  << "\n";
176  }
177  //
178  }
179 
180  /// initialize event: get collection of recob::MCSFitResult
181  void
182  initEvent(const art::Event& e) override
183  {
184  if (momFromMCSColl_)
185  mcs = e.getValidHandle<std::vector<recob::MCSFitResult>>(mcsInputTag_).product();
186  if (momFromCombAndPid_) {
187  cont = e.getValidHandle<std::vector<anab::CosmicTag>>(contInputTag_).product();
188  }
189  if (pidFromColl_) {
190  pid = e.getValidHandle<std::vector<anab::ParticleID>>(pidInputTag_).product();
191  }
192  }
193 
194  /// function that actually calls the fitter
196  const recob::TrackTrajectory& traj,
197  const int tkID,
198  const std::vector<art::Ptr<recob::Hit>>& inHits,
199  const SMatrixSym55& covVtx,
200  const SMatrixSym55& covEnd,
201  recob::Track& outTrack,
203  OptionalOutputs& optionals) const;
204 
205  /// override of TrackMaker purely virtual function with
206  /// recob::TrackTrajectory as argument
207  bool
209  const recob::TrackTrajectory& traj,
210  const int tkID,
211  const std::vector<art::Ptr<recob::Hit>>& inHits,
212  recob::Track& outTrack,
214  OptionalOutputs& optionals) const override
215  {
216  return makeTrackImpl(detProp,
217  traj,
218  tkID,
219  inHits,
222  outTrack,
223  outHits,
224  optionals);
225  }
226 
227  /// override of TrackMaker virtual function with recob::Track as argument
228  bool
230  const recob::Track& track,
231  const std::vector<art::Ptr<recob::Hit>>& inHits,
232  recob::Track& outTrack,
234  OptionalOutputs& optionals) const override
235  {
236  auto covs = track.Covariances();
237  return makeTrackImpl(detProp,
238  track.Trajectory(),
239  track.ID(),
240  inHits,
241  covs.first,
242  covs.second,
243  outTrack,
244  outHits,
245  optionals);
246  }
247 
248  /// set the particle ID hypothesis
249  int getParticleID(const recob::TrackTrajectory& traj, const int tkID) const;
250  /// set the initial momentum estimate
251  double getMomentum(const recob::TrackTrajectory& traj,
252  const int pid,
253  const bool isFlip,
254  const int tkID) const;
255  /// decide whether to flip the direction or not
256  bool isFlipDirection(const recob::TrackTrajectory& traj, const int tkID) const;
257 
258  /// restore the TrajectoryPoints in the Track to be the same as those in the
259  /// input TrackTrajectory (but keep covariance matrices and chi2 from fit).
261  const std::vector<art::Ptr<recob::Hit>>& inHits,
262  recob::Track& outTrack,
264  OptionalOutputs& optionals) const;
265 
266  private:
271  double mom_def_;
278  double mom_len_cut_;
279  int pid_def_;
283  const std::vector<recob::MCSFitResult>* mcs = nullptr;
284  const std::vector<anab::CosmicTag>* cont = nullptr;
285  const std::vector<anab::ParticleID>* pid = nullptr;
287  };
288 }
289 
290 bool
292  const recob::TrackTrajectory& traj,
293  const int tkID,
294  const std::vector<art::Ptr<recob::Hit>>& inHits,
295  const SMatrixSym55& covVtx,
296  const SMatrixSym55& covEnd,
297  recob::Track& outTrack,
299  OptionalOutputs& optionals) const
300 {
301  const int pid = getParticleID(traj, tkID);
302  const bool flipDirection = isFlipDirection(traj, tkID);
303  const double mom = getMomentum(traj, pid, flipDirection, tkID); // what about mom uncertainty?
304  bool fitok = kalmanFitter.fitTrack(detProp,
305  traj,
306  tkID,
307  covVtx,
308  covEnd,
309  inHits,
310  mom,
311  pid,
312  flipDirection,
313  outTrack,
314  outHits,
315  optionals);
316  if (!fitok) return false;
318  restoreInputPoints(traj, inHits, outTrack, outHits, optionals);
319  }
320  return true;
321 }
322 
323 double
325  const int pid,
326  const bool isFlip,
327  const int tkID) const
328 {
329  double mom = (mom_def_ > 0 ? mom_def_ : traj.StartMomentum());
330  if (momFromMCSColl_) {
331  double mcsmom = (isFlip ? mcs->at(tkID).bwdMomentum() : mcs->at(tkID).fwdMomentum());
332  // make sure the mcs fit converged
333  if (mcsmom > 0.01 && mcsmom < 7.) mom = mcsmom;
334  }
335  if (momFromCombAndPid_) {
336  bool isContained = cont->at(tkID).CosmicType() == anab::kNotTagged;
337  // for now momentum from range implemented only for muons and protons
338  // so treat pions as muons (~MIPs) and kaons as protons
339  int pidtmp = pid;
340  if (pidtmp == 211 || pidtmp == 13)
341  pidtmp = 13;
342  else
343  pidtmp = 2212;
344  mom = tmc.GetTrackMomentum(traj.Length(), pidtmp);
345  if (isContained == false) {
346  auto mcsresult = mcsfitter.fitMcs(traj, pid);
347  double mcsmom = (isFlip ? mcsresult.bwdMomentum() : mcsresult.fwdMomentum());
348  // make sure the mcs fit converged, also the mcsmom should not be less
349  // than the range!
350  if (mcsmom > 0.01 && mcsmom < 7. && mcsmom > mom) mom = mcsmom;
351  }
352  }
353  return mom;
354 }
355 
356 int
358  const int tkID) const
359 {
360  if (pidFromColl_) {
361  return -1; //pid->at(tkID).Pdg();
362  }
363  if (mom_len_cut_ > 0.) { return (traj.Length() < mom_len_cut_ ? 2212 : 13); }
364  return pid_def_;
365 }
366 
367 bool
369  const int tkID) const
370 {
371  if (alwaysFlip_) { return true; }
372  else if (dirFromVec_) {
373  auto tdir = traj.VertexDirection();
374  if (tdir.Dot(dirVec) < 0.) return true;
375  }
376  return false;
377 }
378 
379 void
381  const recob::TrackTrajectory& traj,
382  const std::vector<art::Ptr<recob::Hit>>& inHits,
383  recob::Track& outTrack,
385  OptionalOutputs& optionals) const
386 {
387  if (optionals.isTrackFitInfosInit()) {
388  throw cet::exception("KalmanFilterFitTrackMaker")
389  << "Option keepInputTrajectoryPoints not compatible with "
390  "doTrackFitHitInfo, please set doTrackFitHitInfo to false in the "
391  "track producer.\n";
392  }
393  const auto np = outTrack.NumberTrajectoryPoints();
395  outHits, optionals, outTrack.ID(), outTrack.ParticleId(), traj.HasMomentum());
396  //
397  std::vector<unsigned int> flagsmap(np, -1);
398  for (unsigned int i = 0; i < np; ++i)
399  flagsmap[outTrack.FlagsAtPoint(i).fromHit()] = i;
400  //
401  for (unsigned int p = 0; p < np; ++p) {
402  auto mask = outTrack.FlagsAtPoint(flagsmap[p]).mask();
405  tcbk.addPoint(traj.LocationAtPoint(p),
406  traj.MomentumVectorAtPoint(p),
407  inHits[p],
409  0);
410  }
411  auto covs = outTrack.Covariances();
412  tcbk.setTotChi2(outTrack.Chi2());
413  outTrack = tcbk.finalizeTrack(std::move(covs.first), std::move(covs.second));
414  //
415 }
416 
int getParticleID(const recob::TrackTrajectory &traj, const int tkID) const
set the particle ID hypothesis
bool makeTrackImpl(const detinfo::DetectorPropertiesData &detProp, const recob::TrackTrajectory &traj, const int tkID, const std::vector< art::Ptr< recob::Hit >> &inHits, const SMatrixSym55 &covVtx, const SMatrixSym55 &covEnd, recob::Track &outTrack, std::vector< art::Ptr< recob::Hit >> &outHits, OptionalOutputs &optionals) const
function that actually calls the fitter
#define DEFINE_ART_CLASS_TOOL(tool)
Definition: ToolMacros.h:42
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.
int ParticleId() const
Definition: Track.h:171
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
const recob::TrackTrajectory & Trajectory() const
Access to the stored recob::TrackTrajectory.
Definition: Track.h:98
KalmanFilterFitTrackMaker(Parameters const &p)
Constructor from Parameters.
recob::tracking::SMatrixSym55 SMatrixSym55
Definition: TrackState.h:15
struct vector vector
ChannelGroupService::Name Name
float Chi2() const
Definition: Track.h:168
size_t NumberTrajectoryPoints() const
Various functions related to the presence and the number of (valid) points.
Definition: Track.h:102
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.
constexpr Mask_t const & mask() const
Returns the entire set of bits as a bit mask.
std::pair< SMatrixSym55, SMatrixSym55 > Covariances() const
Definition: Track.h:162
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
recob::MCSFitResult fitMcs(const recob::TrackTrajectory &traj) const
Base abstract class for tools used to fit tracks.
Definition: TrackMaker.h:223
constexpr HitIndex_t fromHit() const
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.
const double e
tracking::SMatrixSym55 SMatrixSym55
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:
def move(depos, offset)
Definition: depos.py:107
ValidHandle< PROD > getValidHandle(InputTag const &tag) const
Definition: DataViewImpl.h:441
p
Definition: test.py:223
double StartMomentum() const
Concrete implementation of a tool to fit tracks with TrackKalmanFitter.
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
int ID() const
Definition: Track.h:198
#define Comment
bool HasMomentum() const
Returns whether information about the momentum is available.
Definition: Trajectory.h:425
Helper class to aid the creation of a recob::Track, keeping data vectors in sync. ...
Class for Maximum Likelihood fit of Multiple Coulomb Scattering angles between segments within a Trac...
PointFlags_t const & FlagsAtPoint(size_t i) const
Definition: Track.h:118
bool isTrackFitInfosInit()
check initialization of the output vector of TrackFitHitInfos
Definition: TrackMaker.h:162
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:114
Set of flags pertaining a point of the track.
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
double GetTrackMomentum(double trkrange, int pdg) const
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33