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