All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TTHitFinder_module.cc
Go to the documentation of this file.
1 /*!
2  * Title: TTHitFinder class
3  * Author: wketchum@lanl.gov
4  * Inputs: recob::Wire (calibrated)
5  * Outputs: recob::Hit
6  *
7  * Description:
8  * This module, TimeTickHitFinder (or TTHitFinder for short) is designed to
9  * produce a minimal hit object, that is simple a time tick above threshold.
10  * There is intention to allow for overlap of hits, with a downstream app
11  * that will need to clean it up.
12  */
13 #include <string>
14 #include <math.h>
15 
16 // Framework includes
17 #include "art/Framework/Core/ModuleMacros.h"
18 #include "art/Framework/Principal/Event.h"
19 #include "art/Framework/Core/EDProducer.h"
20 #include "art/Framework/Services/Registry/ServiceHandle.h"
21 #include "canvas/Persistency/Common/FindOneP.h"
22 #include "messagefacility/MessageLogger/MessageLogger.h"
23 
24 // LArSoft Includes
30 
31 namespace hit{
32 
33  class TTHitFinder : public art::EDProducer {
34 
35  public:
36 
37  explicit TTHitFinder(fhicl::ParameterSet const& pset);
38 
39  private:
40  void produce(art::Event& evt) override;
41 
42  std::string fCalDataModuleLabel; /// Input caldata module name
43  float fMinSigPeakInd; /// Induction wire signal height threshold at peak
44  float fMinSigPeakCol; /// Collection wire signal height threshold at peak
45  float fMinSigTailInd; /// Induction wire signal height threshold outside peak
46  float fMinSigTailCol; /// Collection wire signal height threshold outside peak
47  int fIndWidth; /// Induction wire hit width (in time ticks)
48  int fColWidth; /// Collection wire hit width (in time ticks)
49 
50  float getTotalCharge(const float*,int,float);
51 
52  }; // class TTHitFinder
53 
54  //-------------------------------------------------
55  TTHitFinder::TTHitFinder(fhicl::ParameterSet const& pset)
56  : EDProducer{pset}
57  {
58  fCalDataModuleLabel = pset.get< std::string >("CalDataModuleLabel");
59  fMinSigPeakInd = pset.get< float >("MinSigPeakInd");
60  fMinSigPeakCol = pset.get< float >("MinSigPeakCol");
61  fMinSigTailInd = pset.get< float >("MinSigTailInd",-99); //defaulting to well-below zero
62  fMinSigTailCol = pset.get< float >("MinSigTailCol",-99); //defaulting to well-below zero
63  fIndWidth = pset.get< int >("IndWidth", 3); //defaulting to 3
64  fColWidth = pset.get< int >("ColWidth", 3); //defaulting to 3
65 
66  //enforce a minimum width
67  if(fIndWidth<1){
68  mf::LogWarning("TTHitFinder") << "IndWidth must be 1 at minimum. Resetting width to one time tick";
69  fIndWidth = 1;
70  }
71  if(fColWidth<1){
72  mf::LogWarning("TTHitFinder") << "ColWidth must be 1 at minimum. Resetting width to one time tick";
73  fColWidth = 1;
74  }
75 
76  // let HitCollectionCreator declare that we are going to produce
77  // hits and associations with wires and raw digits
78  recob::HitCollectionCreator::declare_products(producesCollector(), "uhits");
79  recob::HitCollectionCreator::declare_products(producesCollector(), "vhits");
80  recob::HitCollectionCreator::declare_products(producesCollector(), "yhits");
81 
82  }
83 
84  //-------------------------------------------------
85  void TTHitFinder::produce(art::Event& evt)
86  {
87 
88  // these objects contain the hit collections
89  // and their associations to wires and raw digits:
90  recob::HitCollectionCreator hitCollection_U(evt, "uhits");
91  recob::HitCollectionCreator hitCollection_V(evt, "vhits");
92  recob::HitCollectionCreator hitCollection_Y(evt, "yhits");
93 
94  // Read in the wire List object(s).
95  art::Handle< std::vector<recob::Wire> > wireVecHandle;
96  evt.getByLabel(fCalDataModuleLabel,wireVecHandle);
97  std::vector<recob::Wire> const& wireVec(*wireVecHandle);
98 
99  // also get the raw digits associated with wires
100  art::FindOneP<raw::RawDigit> WireToRawDigits
101  (wireVecHandle, evt, fCalDataModuleLabel);
102 
103  art::ServiceHandle<geo::Geometry const> geom;
104 
105  //initialize some variables that will be in the loop.
106  float threshold_peak = 0;
107  float threshold_tail = -99;
108  int width = 3;
109 
110  //Loop over wires
111  for(unsigned int wireIter = 0; wireIter < wireVec.size(); wireIter++) {
112 
113  //get our wire
114  art::Ptr<recob::Wire> wire(wireVecHandle, wireIter);
115  art::Ptr<raw::RawDigit> const& rawdigits = WireToRawDigits.at(wireIter);
116 
117  std::vector<float> signal(wire->Signal());
118  std::vector<float>::iterator timeIter; // iterator for time bins
119  geo::WireID wire_id = (geom->ChannelToWire(wire->Channel())).at(0); //just grabbing the first one
120 
121 
122  //set the thresholds and widths based on wire type
123  geo::SigType_t sigType = geom->SignalType(wire->Channel());
124  if(sigType == geo::kInduction){
125  threshold_peak = fMinSigPeakInd;
126  threshold_tail = fMinSigTailInd;
127  width = fIndWidth;
128  }
129  else if(sigType == geo::kCollection){
130  threshold_peak = fMinSigPeakCol;
131  threshold_tail = fMinSigTailCol;
132  width = fColWidth;
133  }
134 
135  //make a half_width variable to be the search window around each time tick.
136  float half_width = ((float)width-1)/2.;
137 
138  //now do the loop over the time ticks on the wire
139  int time_bin = -1;
140  float peak_val = 0;
141  for(timeIter = signal.begin(); timeIter < signal.end(); timeIter++){
142  time_bin++;
143 
144  //set the peak value, taking average between ticks if desired total width is even
145  if(width%2==1) peak_val = *timeIter;
146  else if(width%2==0) peak_val = 0.5 * (*timeIter + *(timeIter+1));
147 
148  //continue immediately if we are not above the threshold
149  if(peak_val < threshold_peak) continue;
150 
151  //continue if we are too close to the edge
152  if( time_bin-half_width < 0 ) continue;
153  if( time_bin+half_width > signal.size() ) continue;
154 
155  //if necessary, do loop over hit width, and check tail thresholds
156  int begin_tail_tick = std::floor(time_bin-half_width);
157  float totalCharge = getTotalCharge(&signal[begin_tail_tick],width,threshold_tail);
158  if(totalCharge==-999) {
159  MF_LOG_DEBUG("TTHitFinder") << "Rejecting would be hit at (plane,wire,time_bin,first_bin,last_bin)=("
160  << wire_id.Plane << "," << wire_id.Wire << "," << time_bin << "," << begin_tail_tick << "," << begin_tail_tick+width-1 << "): "
161  << signal.at(time_bin-1) << " "
162  << signal.at(time_bin) << " "
163  << signal.at(time_bin+1);
164  continue;
165  }
166 
167  //OK, if we've passed all tests up to this point, we have a hit!
168 
169  float hit_time = time_bin;
170  if(width%2==0) hit_time = time_bin+0.5;
171 
172  // hit time region is 2 widths (4 RMS) wide
173  const raw::TDCtick_t start_tick = hit_time - width,
174  end_tick = hit_time + width;
175 
176  // make the hit
178  *wire, // wire
179  wire_id, // wireID
180  start_tick, // start_tick
181  end_tick, // end_tick
182  width / 2., // rms
183  hit_time, // peak_time
184  0., // sigma_peak_time
185  peak_val, // peak_amplitude
186  0., // sigma_peak_amplitude
187  totalCharge, // hit_integral
188  0., // hit_sigma_integral
189  totalCharge, // summedADC
190  1, // multiplicity (dummy value)
191  0, // local_index (dummy value)
192  1., // goodness_of_fit (dummy value)
193  0 // dof
194  );
195  if(wire_id.Plane==0)
196  hitCollection_U.emplace_back(hit.move(), wire, rawdigits);
197  else if(wire_id.Plane==1)
198  hitCollection_V.emplace_back(hit.move(), wire, rawdigits);
199  else if(wire_id.Plane==2)
200  hitCollection_Y.emplace_back(hit.move(), wire, rawdigits);
201 
202  }//End loop over time ticks on wire
203 
204  MF_LOG_DEBUG("TTHitFinder") << "Finished wire " << wire_id.Wire << " (plane " << wire_id.Plane << ")"
205  << "\tTotal hits (U,V,Y)= ("
206  << hitCollection_U.size() << ","
207  << hitCollection_V.size() << ","
208  << hitCollection_Y.size() << ")";
209 
210  }//End loop over all wires
211 
212  // put the hit collection and associations into the event
213  mf::LogInfo("TTHitFinder") << "Total TTHitFinder hits (U,V,Y)=("
214  << hitCollection_U.size() << ","
215  << hitCollection_V.size() << ","
216  << hitCollection_Y.size() << ")";
217  hitCollection_U.put_into(evt); // reminder: instance name was "uhits"
218  hitCollection_V.put_into(evt); // reminder: instance name was "vhits"
219  hitCollection_Y.put_into(evt); // reminder: instance name was "yhits"
220 
221  } // End of produce()
222 
223 
224  //-------------------------------------------------
225  float TTHitFinder::getTotalCharge(const float* signal_vector,int width=3,float threshold=-99){
226 
227  float totalCharge = 0;
228  for(int tick=0; tick<width; tick++){
229  if(signal_vector[tick] < threshold){
230  totalCharge = -999; //special value for being below threshold
231  break;
232  }
233  totalCharge += signal_vector[tick];
234  }
235  return totalCharge;
236 
237  }//end getTotalCharge method
238 
239  DEFINE_ART_MODULE(TTHitFinder)
240 
241 } // end of hit namespace
int fColWidth
Induction wire hit width (in time ticks)
float fMinSigTailInd
Collection wire signal height threshold at peak.
float fMinSigPeakCol
Induction wire signal height threshold at peak.
Definition of basic raw digits.
WireID_t Wire
Index of the wire within its plane.
Definition: geo_types.h:580
process_name hit
Definition: cheaterreco.fcl:51
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
int TDCtick_t
Type representing a TDC tick.
Definition: RawTypes.h:25
Class managing the creation of a new recob::Hit object.
Definition: HitCreator.h:83
Helper functions to create a hit.
A class handling a collection of hits and its associations.
Definition: HitCreator.h:508
Signal from induction planes.
Definition: geo_types.h:145
enum geo::_plane_sigtype SigType_t
tick_as<> tick
Tick number, represented by std::ptrdiff_t.
Definition: electronics.h:75
void emplace_back(recob::Hit &&hit, art::Ptr< recob::Wire > const &wire=art::Ptr< recob::Wire >(), art::Ptr< raw::RawDigit > const &digits=art::Ptr< raw::RawDigit >())
Adds the specified hit to the data collection.
Definition: HitCreator.cxx:290
PlaneID_t Plane
Index of the plane within its TPC.
Definition: geo_types.h:493
float fMinSigTailCol
Induction wire signal height threshold outside peak.
Definition of data types for geometry description.
void put_into(art::Event &)
Moves the data into an event.
Definition: HitCreator.h:652
std::string fCalDataModuleLabel
size_t size() const
Returns the number of hits currently in the collection.
Definition: HitCreator.h:636
float fMinSigPeakInd
Input caldata module name.
Declaration of basic channel signal object.
void produce(art::Event &evt) override
int fIndWidth
Collection wire signal height threshold outside peak.
TCEvent evt
Definition: DataStructs.cxx:8
TTHitFinder(fhicl::ParameterSet const &pset)
recob::Hit && move()
Prepares the constructed hit to be moved away.
Definition: HitCreator.h:343
art framework interface to geometry description
float getTotalCharge(const float *, int, float)
Collection wire hit width (in time ticks)
Signal from collection planes.
Definition: geo_types.h:146