LArSoft  v06_85_00
Liquid Argon Software toolkit - http://larsoft.org/
TrackKalmanCheater_module.cc
Go to the documentation of this file.
1 // Class: TrackKalmanCheater
3 // Module Type: producer
4 // File: TrackKalmanCheater.h
5 //
6 // This class produces RecoBase/Track objects using KalmanFilterService.
7 // MC truth information is used to associate Hits used as input to
8 // the Kalman filter.
9 //
10 // Configuration parameters:
11 //
12 // Hist - Histogram flag (generate histograms if true).
13 // UseClusterHits - Use clustered hits if true, use all hits if false.
14 // HitModuleLabel - Module label for unclustered Hits.
15 // ClusterModuleLabel - Module label for Clusters.
16 // MaxTcut - Maximum delta ray energy in Mev for dE/dx.
17 // KalmanFilterAlg - Parameter set for KalmanFilterAlg.
18 // SpacePointAlg - Parmaeter set for space points.
19 //
21 
22 #include <vector>
23 #include <deque>
24 
30 #include "cetlib_except/exception.h"
31 
47 
48 #include "TH1F.h"
49 
50 namespace trkf {
51 
52  class Propagator;
53 
55  public:
56 
57  // Copnstructors, destructor.
58 
59  explicit TrackKalmanCheater(fhicl::ParameterSet const & pset);
60  virtual ~TrackKalmanCheater();
61 
62  // Overrides.
63 
64  virtual void reconfigure(fhicl::ParameterSet const & pset);
65  virtual void produce(art::Event & e);
66  virtual void beginJob();
67  virtual void endJob();
68 
69  private:
70 
71  // Fcl parameters.
72 
73  bool fHist;
77  std::string fHitModuleLabel;
78  std::string fClusterModuleLabel;
79  double fMaxTcut;
80 
82  const Propagator* fProp;
83 
84  // Histograms.
85 
86  TH1F* fHIncChisq;
87  TH1F* fHPull;
88 
89  // Statistics.
90 
91  int fNumEvent;
92  int fNumTrack;
93 
94  };
95 
97 
98 } // namespace trkf
99 
100 //------------------------------------------------------------------------------
108  : fHist(false)
109  , fKFAlg(pset.get<fhicl::ParameterSet>("KalmanFilterAlg"))
110  , fSpacePointAlg(pset.get<fhicl::ParameterSet>("SpacePointAlg"))
111  , fUseClusterHits(false)
112  , fMaxTcut(0.)
113  , fProp(0)
114  , fHIncChisq(0)
115  , fHPull(0)
116  , fNumEvent(0)
117  , fNumTrack(0)
118 {
119  reconfigure(pset);
120  produces<std::vector<recob::Track> >();
121  produces<std::vector<recob::SpacePoint> >();
122  produces<art::Assns<recob::Track, recob::Hit> >();
123  produces<art::Assns<recob::Track, recob::SpacePoint> >();
124  produces<art::Assns<recob::SpacePoint, recob::Hit> >();
125 
126  // Report.
127 
128  mf::LogInfo("TrackKalmanCheater")
129  << "TrackKalmanCheater configured with the following parameters:\n"
130  << " UseClusterHits = " << fUseClusterHits << "\n"
131  << " HitModuleLabel = " << fHitModuleLabel << "\n"
132  << " ClusterModuleLabel = " << fClusterModuleLabel;
133 }
134 
135 //------------------------------------------------------------------------------
138 {}
139 
140 //------------------------------------------------------------------------------
148 {
149  fHist = pset.get<bool>("Hist");
150  fKFAlg.reconfigure(pset.get<fhicl::ParameterSet>("KalmanFilterAlg"));
151  fSpacePointAlg.reconfigure(pset.get<fhicl::ParameterSet>("SpacePointAlg"));
152  fUseClusterHits = pset.get<bool>("UseClusterHits");
153  fHitModuleLabel = pset.get<std::string>("HitModuleLabel");
154  fClusterModuleLabel = pset.get<std::string>("ClusterModuleLabel");
155  fMaxTcut = pset.get<double>("MaxTcut");
156  if(fProp != 0)
157  delete fProp;
158  fProp = new PropYZPlane(fMaxTcut, true);
159 }
160 
161 //------------------------------------------------------------------------------
164 {
165  if(fHist) {
166 
167  // Book histograms.
168 
170  art::TFileDirectory dir = tfs->mkdir("hitkalman", "TrackKalmanCheater histograms");
171 
172  fHIncChisq = dir.make<TH1F>("IncChisq", "Incremental Chisquare", 100, 0., 20.);
173  fHPull = dir.make<TH1F>("Pull", "Hit Pull", 100, -10., 10.);
174  }
175 }
176 
177 //------------------------------------------------------------------------------
188 {
189  ++fNumEvent;
190 
191  // Make a collection of tracks, plus associations, that will
192  // eventually be inserted into the event.
193 
194  std::unique_ptr<std::vector<recob::Track> > tracks(new std::vector<recob::Track>);
195  std::unique_ptr< art::Assns<recob::Track, recob::Hit> > th_assn(new art::Assns<recob::Track, recob::Hit>);
196  std::unique_ptr< art::Assns<recob::Track, recob::SpacePoint> > tsp_assn(new art::Assns<recob::Track, recob::SpacePoint>);
197 
198  // Make a collection of space points, plus associations, that will
199  // be inserted into the event.
200 
201  std::unique_ptr<std::vector<recob::SpacePoint> > spts(new std::vector<recob::SpacePoint>);
202  std::unique_ptr< art::Assns<recob::SpacePoint, recob::Hit> > sph_assn(new art::Assns<recob::SpacePoint, recob::Hit>);
203 
204  // Make a collection of KGTracks where we will save our results.
205 
206  std::deque<KGTrack> kalman_tracks;
207 
208  // Get Services.
209 
213 
214  // Reset space point algorithm.
215 
217 
218 
219  // Get Hits.
220 
222 
223  if(fUseClusterHits) {
224 
225  // Get clusters.
226 
228  evt.getByLabel(fClusterModuleLabel, clusterh);
229 
230  // Get hits from all clusters.
232 
233  if(clusterh.isValid()) {
234  int nclus = clusterh->size();
235 
236  for(int i = 0; i < nclus; ++i) {
237  art::Ptr<recob::Cluster> pclus(clusterh, i);
238  std::vector< art::Ptr<recob::Hit> > clushits = fm.at(i);
239  int nhits = clushits.size();
240  hits.reserve(hits.size() + nhits);
241 
242  for(std::vector< art::Ptr<recob::Hit> >::const_iterator ihit = clushits.begin();
243  ihit != clushits.end(); ++ihit) {
244  hits.push_back(*ihit);
245  }
246  }
247  }
248  }
249  else {
250 
251  // Get unclustered hits.
252 
254  evt.getByLabel(fHitModuleLabel, hith);
255  if(hith.isValid()) {
256  int nhits = hith->size();
257  hits.reserve(nhits);
258 
259  for(int i = 0; i < nhits; ++i)
260  hits.push_back(art::Ptr<recob::Hit>(hith, i));
261  }
262  }
263 
264  // Sort hits into separate PtrVectors based on track id.
265 
266  std::map<int, art::PtrVector<recob::Hit> > hitmap;
267 
268  // Loop over hits.
269 
271  ihit != hits.end(); ++ihit) {
272  //const recob::Hit& hit = **ihit;
273 
274  // Get track ids for this hit.
275 
276  std::vector<sim::TrackIDE> tids = bt_serv->HitToTrackIDEs(*ihit);
277 
278  // Loop over track ids.
279 
280  for(std::vector<sim::TrackIDE>::const_iterator itid = tids.begin();
281  itid != tids.end(); ++itid) {
282  int trackID = itid->trackID;
283 
284  // Add hit to PtrVector corresponding to this track id.
285 
286  hitmap[trackID].push_back(*ihit);
287  }
288  }
289 
290  // Extract geant mc particles.
291 
292  sim::ParticleList const& plist = pi_serv->ParticleList();
293 
294  // Loop over geant particles.
295 
296  {
297  // use mf::LogDebug instead of LOG_DEBUG because we reuse it in many lines;
298  // insertions are protected by mf::isDebugEnabled()
299  mf::LogDebug log("TrackKalmanCheater");
301  ipart != plist.end(); ++ipart) {
302  const simb::MCParticle* part = (*ipart).second;
303  if (!part) throw cet::exception("TrackKalmanCheater") << "no particle!\n";
304  int pdg = part->PdgCode();
305 
306  // Ignore everything except stable charged nonshowering particles.
307 
308  int apdg = std::abs(pdg);
309  if(apdg == 13 || // Muon
310  apdg == 211 || // Charged pion
311  apdg == 321 || // Charged kaon
312  apdg == 2212) { // (Anti)proton
313 
314  int trackid = part->TrackId();
315  int stat = part->StatusCode();
316  int nhit = 0;
317  if(hitmap.count(trackid) != 0)
318  nhit = hitmap[trackid].size();
319  const TLorentzVector& pos = part->Position();
320  const TLorentzVector& mom = part->Momentum();
321 
322  if (mf::isDebugEnabled()) {
323  log << "Trackid=" << trackid
324  << ", pdgid=" << pdg
325  << ", status=" << stat
326  << ", NHit=" << nhit << "\n"
327  << " x = " << pos.X()
328  << ", y = " << pos.Y()
329  << ", z = " << pos.Z() << "\n"
330  << " px= " << mom.Px()
331  << ", py= " << mom.Py()
332  << ", pz= " << mom.Pz() << "\n";
333  } // if debugging
334 
335  double x = pos.X();
336  double y = pos.Y();
337  double z = pos.Z();
338  double px = mom.Px();
339  double py = mom.Py();
340  double pz = mom.Pz();
341  double p = std::sqrt(px*px + py*py + pz*pz);
342 
343  if(nhit > 0 && pz != 0.) {
344  const art::PtrVector<recob::Hit>& trackhits = hitmap[trackid];
345  if (trackhits.empty())
346  throw cet::exception("TrackKalmanCheater") << "No hits in track\n";
347 
348  // Make a seed track (KTrack).
349 
350  std::shared_ptr<const Surface> psurf(new SurfYZPlane(0., y, z, 0.));
351  TrackVector vec(5);
352  vec(0) = x;
353  vec(1) = 0.;
354  vec(2) = px / pz;
355  vec(3) = py / pz;
356  vec(4) = 1. / p;
358  KTrack trk(psurf, vec, dir, pdg);
359 
360  // Fill KHitContainer with hits.
361 
362  KHitContainerWireX cont;
363  cont.fill(trackhits, -1);
364 
365  // Count hits in each plane. Set the preferred plane to be
366  // the one with the most hits.
367 
368  std::vector<unsigned int> planehits(3, 0);
370  ih != trackhits.end(); ++ih) {
371  const recob::Hit& hit = **ih;
372  unsigned int plane = hit.WireID().Plane;
373 
374  if (plane >= planehits.size()) {
375  throw cet::exception("TrackKalmanCheater") << "plane " << plane << "...\n"; }
376  ++planehits[plane];
377  }
378  unsigned int prefplane = 0;
379  for(unsigned int i=0; i<planehits.size(); ++i) {
380  if(planehits[i] > planehits[prefplane])
381  prefplane = i;
382  }
383  if (mf::isDebugEnabled())
384  log << "Preferred plane = " << prefplane << "\n";
385 
386  // Build and smooth track.
387 
388  KGTrack trg(prefplane);
389  fKFAlg.setPlane(prefplane);
390  bool ok = fKFAlg.buildTrack(trk, trg, fProp, Propagator::FORWARD, cont, false);
391  if(ok) {
392  ok = fKFAlg.smoothTrackIter(5, trg, fProp);
393  if(ok) {
394  KETrack tremom;
395  bool pok = fKFAlg.fitMomentum(trg, fProp, tremom);
396  if(pok)
397  fKFAlg.updateMomentum(tremom, fProp, trg);
398  ++fNumTrack;
399  kalman_tracks.push_back(trg);
400  }
401  }
402  if (mf::isDebugEnabled())
403  log << (ok? "Build track succeeded.": "Build track failed.") << "\n";
404 
405  }
406  }
407  }
408  }
409 
410  // Fill histograms.
411 
412  if(fHist) {
413 
414  // First loop over tracks.
415 
416  for(std::deque<KGTrack>::const_iterator k = kalman_tracks.begin();
417  k != kalman_tracks.end(); ++k) {
418  const KGTrack& trg = *k;
419 
420  // Loop over measurements in this track.
421 
422  const std::multimap<double, KHitTrack>& trackmap = trg.getTrackMap();
423  for(std::multimap<double, KHitTrack>::const_iterator ih = trackmap.begin();
424  ih != trackmap.end(); ++ih) {
425  const KHitTrack& trh = (*ih).second;
426  const std::shared_ptr<const KHitBase>& hit = trh.getHit();
427  double chisq = hit->getChisq();
428  fHIncChisq->Fill(chisq);
429  const KHit<1>* ph1 = dynamic_cast<const KHit<1>*>(&*hit);
430  if(ph1 != 0) {
431  double pull = ph1->getResVector()(0) / std::sqrt(ph1->getResError()(0, 0));
432  fHPull->Fill(pull);
433  }
434  }
435  }
436  }
437 
438  // Process Kalman filter tracks into persistent objects.
439 
440  tracks->reserve(kalman_tracks.size());
441  for(std::deque<KGTrack>::const_iterator k = kalman_tracks.begin();
442  k != kalman_tracks.end(); ++k) {
443  const KGTrack& kalman_track = *k;
444 
445  // Add Track object to collection.
446 
447  tracks->push_back(recob::Track());
448  kalman_track.fillTrack(tracks->back(), tracks->size() - 1);
449 
450  // Make Track to Hit associations.
451 
453  std::vector<unsigned int> hittpindex;
454  kalman_track.fillHits(hits, hittpindex);
455  util::CreateAssn(*this, evt, *tracks, trhits, *th_assn, tracks->size()-1);
456 
457  // Make space points from this track.
458 
459  int nspt = spts->size();
460  fSpacePointAlg.fillSpacePoints(*spts, kalman_track.TrackMap());
461 
462  // Associate newly created space points with hits.
463  // Also associate track with newly created space points.
464 
466 
467  // Loop over newly created space points.
468 
469  for(unsigned int ispt = nspt; ispt < spts->size(); ++ispt) {
470  const recob::SpacePoint& spt = (*spts)[ispt];
471  art::ProductID sptid = getProductID<std::vector<recob::SpacePoint> >();
472  art::Ptr<recob::SpacePoint> sptptr(sptid, ispt, evt.productGetter(sptid));
473  sptvec.push_back(sptptr);
474 
475  // Make space point to hit associations.
476 
477  const art::PtrVector<recob::Hit>& sphits =
479  util::CreateAssn(*this, evt, *spts, sphits, *sph_assn, ispt);
480  }
481 
482  // Make track to space point associations.
483 
484  util::CreateAssn(*this, evt, *tracks, sptvec, *tsp_assn, tracks->size()-1);
485  }
486 
487  // Add tracks and associations to event.
488 
489  evt.put(std::move(tracks));
490  evt.put(std::move(spts));
491  evt.put(std::move(th_assn));
492  evt.put(std::move(tsp_assn));
493  evt.put(std::move(sph_assn));
494 }
495 
496 //------------------------------------------------------------------------------
499 {
500  mf::LogInfo("TrackKalmanCheater")
501  << "TrackKalmanCheater statistics:\n"
502  << " Number of events = " << fNumEvent << "\n"
503  << " Number of tracks created = " << fNumTrack;
504 }
Float_t x
Definition: compare.C:6
void reserve(size_type n)
Definition: PtrVector.h:343
TrackDirection
Track direction enum.
Definition: Surface.h:56
const std::shared_ptr< const KHitBase > & getHit() const
Measurement.
Definition: KHitTrack.h:53
const TLorentzVector & Position(const int i=0) const
Definition: MCParticle.h:223
int PdgCode() const
Definition: MCParticle.h:216
Propagate to PropYZPlane surface.
void fillTrack(recob::Track &track, int id) const
Fill a recob::Track.
Definition: KGTrack.cxx:128
void fillHits(art::PtrVector< recob::Hit > &hits, std::vector< unsigned int > &hittpindex) const
Fill a PtrVector of Hits.
Definition: KGTrack.cxx:219
A KHitContainer for KHitWireX type measurements.
const std::vector< sim::TrackIDE > HitToTrackIDEs(recob::Hit const &hit)
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
std::string fClusterModuleLabel
Clustered Hits.
geo::WireID WireID() const
Initial tdc tick for hit.
Definition: Hit.h:234
iterator begin()
Definition: PtrVector.h:223
Planar surface parallel to x-axis.
Declaration of signal hit object.
Float_t y
Definition: compare.C:6
list_type::const_iterator const_iterator
Definition: ParticleList.h:132
Double_t z
Definition: plot.C:279
int StatusCode() const
Definition: MCParticle.h:215
bool fitMomentum(const KGTrack &trg, const Propagator *prop, KETrack &tremom) const
Estimate track momentum using either range or multiple scattering.
EDProductGetter const * productGetter(ProductID const) const
Definition: Event.cc:64
KalmanFilterAlg fKFAlg
Kalman filter algorithm.
Particle class.
const KVector< N >::type & getResVector() const
Residual vector.
Definition: KHit.h:114
const art::PtrVector< recob::Hit > & getAssociatedHits(const recob::SpacePoint &spt) const
const std::multimap< double, KHitTrack > & getTrackMap() const
KHitTrack collection, indexed by path distance.
Definition: KGTrack.h:54
int fNumEvent
Number of events seen.
TFileDirectory mkdir(std::string const &dir, std::string const &descr="")
virtual void beginJob()
Begin job method.
int TrackId() const
Definition: MCParticle.h:214
std::string fHitModuleLabel
Unclustered Hits.
virtual ~TrackKalmanCheater()
Destructor.
ProductID put(std::unique_ptr< PROD > &&product)
Definition: Event.h:102
bool fUseClusterHits
Use cluster hits or all hits?
bool isValid() const
Definition: Handle.h:190
void fillSpacePoints(std::vector< recob::SpacePoint > &spts, std::multimap< double, KHitTrack > const &trackMap) const
Fill a collection of space points.
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:265
TrackKalmanCheater(fhicl::ParameterSet const &pset)
const KSymMatrix< N >::type & getResError() const
Residual error matrix.
Definition: KHit.h:117
void hits()
Definition: readHits.C:15
intermediate_table::const_iterator const_iterator
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:42
void push_back(Ptr< U > const &p)
Definition: PtrVector.h:441
Kalman filter measurement class template.
parameter set interface
T get(std::string const &key) const
Definition: ParameterSet.h:231
TString part[npart]
Definition: Style.C:32
void reconfigure(const fhicl::ParameterSet &pset)
Reconfigure method.
virtual void produce(art::Event &e)
iterator end()
Definition: PtrVector.h:237
iterator begin()
Definition: ParticleList.h:305
bool updateMomentum(const KETrack &tremom, const Propagator *prop, KGTrack &trg) const
Set track momentum at each track surface.
void fill(const art::PtrVector< recob::Hit > &hits, int only_plane) override
Fill container.
bool CreateAssn(PRODUCER const &prod, art::Event &evt, std::vector< T > const &a, art::Ptr< U > const &b, art::Assns< U, T > &assn, std::string a_instance, size_t indx=UINT_MAX)
Creates a single one-to-one association.
bool isDebugEnabled()
bool smoothTrackIter(int niter, KGTrack &trg, const Propagator *prop) const
Iteratively smooth a track.
KVector< 5 >::type TrackVector
Track state vector, dimension 5.
PlaneID_t Plane
Index of the plane within its TPC.
Definition: geo_types.h:258
Declaration of cluster object.
Provides recob::Track data product.
bool empty() const
Definition: PtrVector.h:336
Kalman Filter.
size_type size() const
Definition: PtrVector.h:308
Detector simulation of raw signals on wires.
void reconfigure(const fhicl::ParameterSet &pset)
data_t::const_iterator const_iterator
Definition: PtrVector.h:61
void clearHitMap() const
T * make(ARGS...args) const
int fNumTrack
Number of tracks produced.
Utility object to perform functions of association.
TDirectory * dir
Definition: macro.C:5
bool getByLabel(std::string const &label, std::string const &productInstanceName, Handle< PROD > &result) const
Definition: DataViewImpl.h:344
virtual void reconfigure(fhicl::ParameterSet const &pset)
void setPlane(int plane)
Set preferred view plane.
const TLorentzVector & Momentum(const int i=0) const
Definition: MCParticle.h:224
Int_t ipart
Definition: Style.C:10
SpacePointAlg fSpacePointAlg
Space point algorithm.
bool buildTrack(const KTrack &trk, KGTrack &trg, const Propagator *prop, const Propagator::PropDirection dir, KHitContainer &hits, bool linear) const
Make a new track.
TH1F * fHIncChisq
Incremental chisquare.
virtual void endJob()
End job method.
2D representation of charge deposited in the TDC/wire plane
Definition: Hit.h:49
const std::multimap< double, KHitTrack > TrackMap() const
Definition: KGTrack.h:98
double fMaxTcut
Maximum delta ray energy in MeV for restricted dE/dx.
Float_t e
Definition: plot.C:34
Algorithm for generating space points from hits.
art framework interface to geometry description
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:51
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
const Propagator * fProp
Propagator.