All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
HitSelector_module.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // Class: HitSelector
4 // Module Type: producer
5 // File: HitSelector_module.cc
6 //
7 // This module tries to remove spurious hits which might have been
8 // created during the deconvolution process
9 //
10 // Configuration parameters:
11 //
12 // HitProducerLabel - the producer of the recob::Hit objects
13 //
14 // Created by Tracy Usher (usher@slac.stanford.edu) on July 17, 2018
15 //
16 ////////////////////////////////////////////////////////////////////////
17 
18 #include <cmath>
19 #include <algorithm>
20 #include <vector>
21 
22 #include "art/Framework/Core/ModuleMacros.h"
23 #include "art/Framework/Core/EDProducer.h"
24 #include "art/Framework/Principal/Event.h"
25 #include "art/Framework/Services/Registry/ServiceHandle.h"
26 #include "canvas/Utilities/InputTag.h"
27 #include "messagefacility/MessageLogger/MessageLogger.h"
28 
30 #include "larcore/CoreUtils/ServiceUtil.h" // lar::providerFrom()
37 
38 class HitSelector : public art::EDProducer
39 {
40 public:
41 
42  // Copnstructors, destructor.
43  explicit HitSelector(fhicl::ParameterSet const & pset);
44  virtual ~HitSelector();
45 
46  // Overrides.
47  virtual void reconfigure(fhicl::ParameterSet const & pset);
48  virtual void produce(art::Event & e);
49  virtual void beginJob();
50  virtual void endJob();
51 
52 private:
53  // define vector for hits to make sure of uniform use
54  using HitPtrVector = std::vector<art::Ptr<recob::Hit>>;
55 
56  // Fcl parameters.
57  art::InputTag fHitProducerLabel; ///< The full collection of hits
58  std::vector<float> fMinMaxPulseHeighMulti; ///< Max pulse height of a pulse train must be this large
59  std::vector<float> fMinPulseHeightMulti; ///< Multi hit snippets, minimum pulse height per plane
60  std::vector<float> fMinPulseWidthMulti; ///< Multi hit snippets, minimum pulse width per plane
61  std::vector<float> fMinPulseHeightSingle; ///< Single hit snippets, minimum pulse height per plane
62  std::vector<float> fMinPulseWidthSingle; ///< Single hit snippets, minimum pulse width per plane
63 
64  // Statistics.
65  int fNumEvent; ///< Number of events seen.
66 };
67 
68 DEFINE_ART_MODULE(HitSelector)
69 
70 //----------------------------------------------------------------------------
71 /// Constructor.
72 ///
73 /// Arguments:
74 ///
75 /// pset - Fcl parameters.
76 ///
77 HitSelector::HitSelector(fhicl::ParameterSet const & pset) : EDProducer{pset},
78 fNumEvent(0)
79 {
80  reconfigure(pset);
81 
82  // let HitCollectionCreator declare that we are going to produce
83  // hits and associations with wires and raw digits
84  // (with no particular product label)
86 
87  // Report.
88  mf::LogInfo("HitSelector") << "HitSelector configured\n";
89 }
90 
91 //----------------------------------------------------------------------------
92 /// Destructor.
94 {}
95 
96 //----------------------------------------------------------------------------
97 /// Reconfigure method.
98 ///
99 /// Arguments:
100 ///
101 /// pset - Fcl parameter set.
102 ///
103 void HitSelector::reconfigure(fhicl::ParameterSet const & pset)
104 {
105  fHitProducerLabel = pset.get<art::InputTag>("HitProducerLabel");
106  fMinMaxPulseHeighMulti = pset.get<std::vector<float>>("MinMaxPulseHeightMulti");
107  fMinPulseHeightMulti = pset.get<std::vector<float>>("MinPulseHeightMulti");
108  fMinPulseWidthMulti = pset.get<std::vector<float>>("MinPulseWidthMulti");
109  fMinPulseHeightSingle = pset.get<std::vector<float>>("MinPulseHeightSingle");
110  fMinPulseWidthSingle = pset.get<std::vector<float>>("MinPulseWidthSingle");
111 }
112 
113 //----------------------------------------------------------------------------
114 /// Begin job method.
116 {
117 // auto const* detp = lar::providerFrom<detinfo::DetectorPropertiesService>();
118 // auto const* geo = lar::providerFrom<geo::Geometry>();
119 // auto const* ts = lar::providerFrom<detinfo::DetectorClocksService>();
120 }
121 
122 //----------------------------------------------------------------------------
123 /// Produce method.
124 ///
125 /// Arguments:
126 ///
127 /// evt - Art event.
128 ///
129 /// This is the primary method. The goal is to produce a list of recob::Hit
130 /// objects which are a "clean" subset of all hits and which are believed to
131 /// be due to a neutrino interaction. It does this by considering input CosmicTag
132 /// objects, relating them to PFParticles/Tracks and removing the hits
133 /// associated to those objects which are believed to be Cosmic Rays.
134 ///
135 void HitSelector::produce(art::Event & evt)
136 {
137  ++fNumEvent;
138 
139  // Start by looking up the original hits
140  art::Handle< std::vector<recob::Hit> > hitHandle;
141  evt.getByLabel(fHitProducerLabel, hitHandle);
142 
143  // also get the associated wires and raw digits;
144  // we assume they have been created by the same module as the hits
145  art::FindOneP<raw::RawDigit> hitToRawDigitAssns(hitHandle, evt, fHitProducerLabel);
146  art::FindOneP<recob::Wire> hitToWireAssns( hitHandle, evt, fHitProducerLabel);
147 
148  // this object contains the hit collection
149  // and its associations to wires and raw digits:
151  hitToWireAssns.isValid(),
152  hitToRawDigitAssns.isValid()
153  );
154 
155  // If there are no hits then there should be no output
156  if (hitHandle.isValid())
157  {
158  HitPtrVector hitPtrVec;
159  HitPtrVector hitSnippetVec;
160 
161  art::fill_ptr_vector(hitPtrVec, hitHandle);
162 
163  int lastHitIndex = 0;
164 
165  // Loop the hits and make some plots
166  for(const auto& curHitPtr : hitPtrVec)
167  {
168  // Have we collected all of the hits on the same snippet?
169  if (!hitSnippetVec.empty() && lastHitIndex >= curHitPtr->LocalIndex())
170  {
171  // Recover plane
172  int plane = hitSnippetVec.front()->WireID().Plane;
173 
174  // Only worried about multi hit snippets
175  if (hitSnippetVec.size() > 1)
176  {
177  // Sort in order of largest to smallest pulse height
178  std::sort(hitSnippetVec.begin(),hitSnippetVec.end(),[](const auto& left, const auto& right){return left->PeakAmplitude() > right->PeakAmplitude();});
179 
180  float maxPulseHeight = hitSnippetVec.front()->PeakAmplitude();
181 
182  // Require the largest pulse in the train to be above threshold
183  if (maxPulseHeight > fMinMaxPulseHeighMulti[plane])
184  {
185  // Loop over all hits...
186  for(size_t idx = 0; idx < hitSnippetVec.size(); idx++)
187  {
188  art::Ptr<recob::Hit> hitPtr = hitSnippetVec[idx];
189 
190  float pulseHeight = hitPtr->PeakAmplitude();
191  float pulseWid = hitPtr->RMS();
192  int numDOF = hitPtr->DegreesOfFreedom();
193 
194  // Watch for case of long pulse trains (numDOF == 1) and keep all of these no matter
195  // Also always keep the largest (first) pulse
196  // Otherwise, select on minimum pulse height and width
197  if (idx == 0 || numDOF == 1 || (pulseHeight > fMinPulseHeightMulti[plane] && pulseWid > fMinPulseWidthMulti[plane]))
198  {
199  art::Ptr<recob::Wire> wire = hitToWireAssns.at(hitPtr.key());
200  art::Ptr<raw::RawDigit> rawdigits = hitToRawDigitAssns.at(hitPtr.key());
201 
202  hcol.emplace_back(*hitPtr, wire, rawdigits);
203  }
204  }
205  }
206  }
207  // Here we handle the case of single hits
208  else
209  {
210  art::Ptr<recob::Hit> hitPtr = hitSnippetVec.front();
211 
212  float pulseHeight = hitPtr->PeakAmplitude();
213  float pulseWid = hitPtr->RMS();
214 
215  if (pulseHeight > fMinPulseHeightSingle[plane] && pulseWid > fMinPulseWidthSingle[plane])
216  {
217  art::Ptr<recob::Wire> wire = hitToWireAssns.at(hitPtr.key());
218  art::Ptr<raw::RawDigit> rawdigits = hitToRawDigitAssns.at(hitPtr.key());
219 
220  hcol.emplace_back(*hitPtr, wire, rawdigits);
221  }
222  }
223 
224  hitSnippetVec.clear();
225  }
226 
227  lastHitIndex = curHitPtr->LocalIndex();
228  hitSnippetVec.push_back(curHitPtr);
229  }
230  }
231 
232  // put the hit collection and associations into the event
233  hcol.put_into(evt);
234 
235  return;
236 }
237 
238 //----------------------------------------------------------------------------
239 /// End job method.
241 {
242  mf::LogInfo("HitSelector")
243  << "HitSelector statistics:\n"
244  << " Number of events = " << fNumEvent;
245 }
std::vector< float > fMinPulseHeightMulti
Multi hit snippets, minimum pulse height per plane.
Utilities related to art service access.
virtual void beginJob()
Begin job method.
int fNumEvent
Number of events seen.
Declaration of signal hit object.
walls no right
Definition: selectors.fcl:105
for pfile in ack l reconfigure(.*) override"` do echo "checking $
art::InputTag fHitProducerLabel
The full collection of hits.
std::vector< float > fMinPulseWidthMulti
Multi hit snippets, minimum pulse width per plane.
static void declare_products(art::ProducesCollector &collector, std::string instance_name="", bool doWireAssns=true, bool doRawDigitAssns=true)
Declares the hit products we are going to fill.
Definition: HitCreator.cxx:248
virtual ~HitSelector()
Destructor.
Helper functions to create a hit.
virtual void reconfigure(fhicl::ParameterSet const &pset)
A class handling a collection of hits and its associations.
Definition: HitCreator.h:508
std::vector< art::Ptr< recob::Hit >> HitPtrVector
std::vector< float > fMinPulseHeightSingle
Single hit snippets, minimum pulse height per plane.
std::vector< float > fMinPulseWidthSingle
Single hit snippets, minimum pulse width per plane.
walls no left
Definition: selectors.fcl:105
std::vector< float > fMinMaxPulseHeighMulti
Max pulse height of a pulse train must be this large.
do i e
HitSelector(fhicl::ParameterSet const &pset)
TCEvent evt
Definition: DataStructs.cxx:8
virtual void produce(art::Event &e)
virtual void endJob()
End job method.
art framework interface to geometry description