LArSoft  v09_90_00
Liquid Argon Software toolkit - https://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 
18 
19 #include <iterator>
20 
26 
27 namespace cosmic {
28 
30  public:
31  explicit TrackPFParticleMatch(fhicl::ParameterSet const& p);
32 
33  void produce(art::Event& e) override;
34 
35  private:
37  std::string fTrackModuleLabel;
38  };
39 
41  {
42  fPFParticleModuleLabel = p.get<std::string>("PFParticleModuleLabel");
43  fTrackModuleLabel = p.get<std::string>("TrackModuleLabel", "track");
44 
45  // Call appropriate Produces<>() functions here.
46  produces<art::Assns<recob::Track, recob::PFParticle>>();
47  }
48 
50  {
51  // Instatiate the output
52  std::unique_ptr<art::Assns<recob::Track, recob::PFParticle>> trackPFParticleAssns(
54 
55  // Recover handle for PFParticles
57  evt.getByLabel(fPFParticleModuleLabel, pfParticleHandle);
58 
59  // Recover the clusters so we can do associations to the hits
60  // In theory the clusters come from the same producer as the PFParticles
62  evt.getByLabel(fPFParticleModuleLabel, clusterHandle);
63 
64  if (!(pfParticleHandle.isValid() && clusterHandle.isValid())) {
65  evt.put(std::move(trackPFParticleAssns));
66  return;
67  }
68 
69  // Recover the handle for the tracks
71  evt.getByLabel(fTrackModuleLabel, trackHandle);
72 
73  if (!trackHandle.isValid()) {
74  evt.put(std::move(trackPFParticleAssns));
75  return;
76  }
77 
78  // The strategy will be to build sets of maps which will enable us to go from hit to either Track or PFParticle
79  using HitToTrackMap =
80  std::map<int, std::vector<art::Ptr<recob::Track>>>; // Allows for hit sharing
81 
82  // Build out the track/hit map first
83  // Recover the track/hit associations
84  art::FindManyP<recob::Hit> trackHitAssns(trackHandle, evt, fTrackModuleLabel);
85 
86  // Get an empty map
87  HitToTrackMap hitToTrackMap;
88 
89  // Fill it
90  for (size_t idx = 0; idx < trackHandle->size(); idx++) {
91  art::Ptr<recob::Track> track(trackHandle, idx);
92 
93  std::vector<art::Ptr<recob::Hit>> trackHitVec = trackHitAssns.at(track.key());
94 
95  for (const auto& hitPtr : trackHitVec) {
96  hitToTrackMap[hitPtr.key()].push_back(track);
97  }
98  }
99 
100  // Now we walk up the remaining list of associations needed to go from CR tags to hits
101  // We'll need to go from tracks to PFParticles
102  // From PFParticles we go to clusters
103  art::FindManyP<recob::Cluster> clusterAssns(pfParticleHandle, evt, fPFParticleModuleLabel);
104 
105  // Likewise, recover the collection of associations to hits
106  art::FindManyP<recob::Hit> clusterHitAssns(clusterHandle, evt, fPFParticleModuleLabel);
107 
108  // We'll store this info in a rather complicated data structure...
109  using TrackToPFParticleHitMap =
110  std::map<art::Ptr<recob::Track>,
111  std::map<art::Ptr<recob::PFParticle>, std::vector<art::Ptr<recob::Hit>>>>;
112 
113  TrackToPFParticleHitMap trackToPFParticleHitMap;
114 
115  // Now we go through the PFParticles and match hits to tracks
116  for (size_t idx = 0; idx < pfParticleHandle->size(); idx++) {
117  art::Ptr<recob::PFParticle> pfParticle(pfParticleHandle, idx);
118 
119  // Recover associated clusters
120  std::vector<art::Ptr<recob::Cluster>> clusterVec = clusterAssns.at(pfParticle.key());
121 
122  // Loop through the clusters
123  for (const auto& cluster : clusterVec) {
124  // Recover associated hits
125  std::vector<art::Ptr<recob::Hit>> hitVec = clusterHitAssns.at(cluster.key());
126 
127  // Loop through hits and look for associated track
128  for (const auto& hit : hitVec) {
129  HitToTrackMap::iterator hitToTrackItr = hitToTrackMap.find(hit.key());
130 
131  if (hitToTrackItr != hitToTrackMap.end()) {
132  for (auto& track : hitToTrackItr->second)
133  trackToPFParticleHitMap[track][pfParticle].push_back(hit);
134  }
135  }
136  }
137  }
138 
139  // Ok, now we can create the associations
140  for (auto& trackMapItr : trackToPFParticleHitMap) {
141  std::vector<art::Ptr<recob::PFParticle>> pfParticleVec;
142 
143  for (auto& pfParticleMapItr : trackMapItr.second) {
144  // We need to make sure we don't associate the case where the hits are from crossing tracks
145  // which would be an illegal association.
146  // Two things to check: that more than one view is matched in the hits
147  // That some fraction of the matched hits are from the track
148  int nHitsPerView[] = {0, 0, 0};
149 
150  for (const auto& hit : pfParticleMapItr.second) {
151  nHitsPerView[hit->View()]++;
152  }
153 
154  int nViewsWithHits(0);
155 
156  for (auto& nHits : nHitsPerView)
157  if (nHits > 0) nViewsWithHits++;
158 
159  if (nViewsWithHits < 2) continue;
160 
161  // Get the hits associated to the track again
162  std::vector<art::Ptr<recob::Hit>> trackHitVec = trackHitAssns.at(trackMapItr.first.key());
163 
164  // Fraction of hits from track shared with PFParticle
165  float sharedHitFrac = float(pfParticleMapItr.second.size()) / float(trackHitVec.size());
166 
167  if (sharedHitFrac < 0.3) continue;
168 
169  // Ok, this is an association to make
170  pfParticleVec.push_back(pfParticleMapItr.first);
171  }
172 
173  util::CreateAssn(evt, trackMapItr.first, pfParticleVec, *trackPFParticleAssns);
174  }
175 
176  evt.put(std::move(trackPFParticleAssns));
177 
178  return;
179 
180  } // end of produce
182 
184 
185 }
intermediate_table::iterator iterator
TrackPFParticleMatch(fhicl::ParameterSet const &p)
Declaration of signal hit object.
EDProducer(fhicl::ParameterSet const &pset)
Definition: EDProducer.cc:6
Cluster finding and building.
bool isValid() const noexcept
Definition: Handle.h:203
PutHandle< PROD > put(std::unique_ptr< PROD > &&edp, std::string const &instance={})
Definition: Event.h:77
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:65
key_type key() const noexcept
Definition: Ptr.h:166
Provides recob::Track data product.
Declaration of cluster object.
Detector simulation of raw signals on wires.
bool CreateAssn(art::Event &evt, std::vector< T > const &a, art::Ptr< U > const &b, art::Assns< U, T > &assn, std::string a_instance, size_t index=UINT_MAX)
Creates a single one-to-one association.
bool getByLabel(std::string const &label, std::string const &instance, Handle< PROD > &result) const
Utility object to perform functions of association.
void produce(art::Event &e) override
TCEvent evt
Definition: DataStructs.cxx:8
Float_t e
Definition: plot.C:35
Float_t track
Definition: plot.C:35