LArSoft  v06_85_00
Liquid Argon Software toolkit - http://larsoft.org/
TrackPFParticleMatch_module.cc
Go to the documentation of this file.
1 // Class: TrackPFParticleMatch
3 // Module Type: producer
4 // File: TrackPFParticleMatch_module.cc
5 // This module aims to enhance cosmic ray rejection by
6 // matching tracks which were fit from "other" producers
7 // to PFParticles by comparing hits
8 // The output will be a set of associations relating the two
9 //
10 // Generated at Mon Mar 28 19:17:00 2016 by Tracy Usher by cloning CosmicTrackTagger
11 // from art v1_02_02.
12 // artmod -e beginJob -e reconfigure -e endJob producer trkf::TrackPFParticleMatch
14 
21 
22 #include <vector>
23 #include <iostream>
24 #include <cmath>
25 #include <algorithm>
26 #include <numeric>
27 #include <iterator>
28 
31 
37 
44 
45 #include "TVector3.h"
46 
47 namespace cosmic
48 {
49 
51 {
52 public:
53  explicit TrackPFParticleMatch(fhicl::ParameterSet const & p);
54  virtual ~TrackPFParticleMatch();
55 
56  void produce(art::Event & e) override;
57 
58  void beginJob() override;
59  void reconfigure(fhicl::ParameterSet const & p) ;
60  void endJob() override;
61 
62 private:
64  std::string fTrackModuleLabel;
65 };
66 
67 
69 // :
70 // Initialize member data here.
71 {
72  this->reconfigure(p);
73 
74  // Call appropriate Produces<>() functions here.
75  produces< art::Assns<recob::Track, recob::PFParticle>>();
76 }
77 
79 {
80  // Clean up dynamic memory and other resources here.
81 }
82 
84 {
85  // Instatiate the output
86  std::unique_ptr< art::Assns<recob::Track, recob::PFParticle > > trackPFParticleAssns( new art::Assns<recob::Track, recob::PFParticle>);
87 
88  // Recover handle for PFParticles
90  evt.getByLabel( fPFParticleModuleLabel, pfParticleHandle);
91 
92  // Recover the clusters so we can do associations to the hits
93  // In theory the clusters come from the same producer as the PFParticles
95  evt.getByLabel(fPFParticleModuleLabel, clusterHandle);
96 
97  if (!(pfParticleHandle.isValid() && clusterHandle.isValid()))
98  {
99  evt.put( std::move(trackPFParticleAssns) );
100  return;
101  }
102 
103  // Recover the handle for the tracks
105  evt.getByLabel( fTrackModuleLabel, trackHandle);
106 
107  if (!trackHandle.isValid())
108  {
109  evt.put( std::move(trackPFParticleAssns) );
110  return;
111  }
112 
113  // The strategy will be to build sets of maps which will enable us to go from hit to either Track or PFParticle
114  using HitToTrackMap = std::map<int, std::vector<art::Ptr<recob::Track>>>; // Allows for hit sharing
115 
116  // Build out the track/hit map first
117  // Recover the track/hit associations
118  art::FindManyP<recob::Hit> trackHitAssns(trackHandle, evt, fTrackModuleLabel);
119 
120  // Get an empty map
121  HitToTrackMap hitToTrackMap;
122 
123  // Fill it
124  for(size_t idx = 0; idx < trackHandle->size(); idx++)
125  {
126  art::Ptr<recob::Track> track(trackHandle, idx);
127 
128  std::vector<art::Ptr<recob::Hit>> trackHitVec = trackHitAssns.at(track.key());
129 
130  for (const auto& hitPtr : trackHitVec)
131  {
132  hitToTrackMap[hitPtr.key()].push_back(track);
133  }
134  }
135 
136  // Now we walk up the remaining list of associations needed to go from CR tags to hits
137  // We'll need to go from tracks to PFParticles
138  // From PFParticles we go to clusters
139  art::FindManyP<recob::Cluster> clusterAssns(pfParticleHandle, evt, fPFParticleModuleLabel);
140 
141  // Likewise, recover the collection of associations to hits
142  art::FindManyP<recob::Hit> clusterHitAssns(clusterHandle, evt, fPFParticleModuleLabel);
143 
144  // We'll store this info in a rather complicated data structure...
145  using TrackToPFParticleHitMap = std::map<art::Ptr<recob::Track>, std::map<art::Ptr<recob::PFParticle>,std::vector<art::Ptr<recob::Hit>>>>;
146 
147  TrackToPFParticleHitMap trackToPFParticleHitMap;
148 
149  // Now we go through the PFParticles and match hits to tracks
150  for(size_t idx = 0; idx < pfParticleHandle->size(); idx++)
151  {
152  art::Ptr<recob::PFParticle> pfParticle(pfParticleHandle, idx);
153 
154  // Recover associated clusters
155  std::vector<art::Ptr<recob::Cluster>> clusterVec = clusterAssns.at(pfParticle.key());
156 
157  // Loop through the clusters
158  for(const auto& cluster : clusterVec)
159  {
160  // Recover associated hits
161  std::vector<art::Ptr<recob::Hit>> hitVec = clusterHitAssns.at(cluster.key());
162 
163  // Loop through hits and look for associated track
164  for(const auto& hit : hitVec)
165  {
166  HitToTrackMap::iterator hitToTrackItr = hitToTrackMap.find(hit.key());
167 
168  if (hitToTrackItr != hitToTrackMap.end())
169  {
170  for(auto& track : hitToTrackItr->second)
171  trackToPFParticleHitMap[track][pfParticle].push_back(hit);
172  }
173  }
174  }
175  }
176 
177  // Ok, now we can create the associations
178  for (auto& trackMapItr : trackToPFParticleHitMap)
179  {
180  std::vector<art::Ptr<recob::PFParticle>> pfParticleVec;
181 
182  for(auto& pfParticleMapItr : trackMapItr.second)
183  {
184  // We need to make sure we don't associate the case where the hits are from crossing tracks
185  // which would be an illegal association.
186  // Two things to check: that more than one view is matched in the hits
187  // That some fraction of the matched hits are from the track
188  int nHitsPerView[] = {0,0,0};
189 
190  for(const auto& hit : pfParticleMapItr.second)
191  {
192  nHitsPerView[hit->View()]++;
193  }
194 
195  int nViewsWithHits(0);
196 
197  for(auto& nHits : nHitsPerView) if (nHits > 0) nViewsWithHits++;
198 
199  if (nViewsWithHits < 2) continue;
200 
201  // Get the hits associated to the track again
202  std::vector<art::Ptr<recob::Hit>> trackHitVec = trackHitAssns.at(trackMapItr.first.key());
203 
204  // Fraction of hits from track shared with PFParticle
205  float sharedHitFrac = float(pfParticleMapItr.second.size()) / float(trackHitVec.size());
206 
207  if (sharedHitFrac < 0.3) continue;
208 
209  // Ok, this is an association to make
210  pfParticleVec.push_back(pfParticleMapItr.first);
211  }
212 
213  util::CreateAssn(*this, evt, trackMapItr.first, pfParticleVec, *trackPFParticleAssns);
214  }
215 
216  evt.put( std::move(trackPFParticleAssns));
217 
218  return;
219 
220 } // end of produce
222 
224 {
225 }
226 
228 {
229  fPFParticleModuleLabel = p.get< std::string >("PFParticleModuleLabel");
230  fTrackModuleLabel = p.get< std::string >("TrackModuleLabel", "track");
231 }
232 
234  // Implementation of optional member function here.
235 }
236 
238 
239 }
key_type key() const
Definition: Ptr.h:356
Collect all the geometry header files together.
TrackPFParticleMatch(fhicl::ParameterSet const &p)
intermediate_table::iterator iterator
Declaration of signal hit object.
Cluster finding and building.
ProductID put(std::unique_ptr< PROD > &&product)
Definition: Event.h:102
bool isValid() const
Definition: Handle.h:190
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:42
T get(std::string const &key) const
Definition: ParameterSet.h:231
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.
Declaration of cluster object.
Provides recob::Track data product.
Detector simulation of raw signals on wires.
Utility object to perform functions of association.
bool getByLabel(std::string const &label, std::string const &productInstanceName, Handle< PROD > &result) const
Definition: DataViewImpl.h:344
void produce(art::Event &e) override
void reconfigure(fhicl::ParameterSet const &p)
Float_t e
Definition: plot.C:34
Algorithm for generating space points from hits.
Float_t track
Definition: plot.C:34
art framework interface to geometry description