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
20 #include "canvas/Persistency/Common/FindOneP.h"
22 
23 // LArSoft Includes
29 
30 namespace hit{
31 
32  class TTHitFinder : public art::EDProducer {
33 
34  public:
35 
36  explicit TTHitFinder(fhicl::ParameterSet const& pset);
37 
38  private:
39  void produce(art::Event& evt) override;
40 
41  std::string fCalDataModuleLabel; /// Input caldata module name
42  float fMinSigPeakInd; /// Induction wire signal height threshold at peak
43  float fMinSigPeakCol; /// Collection wire signal height threshold at peak
44  float fMinSigTailInd; /// Induction wire signal height threshold outside peak
45  float fMinSigTailCol; /// Collection wire signal height threshold outside peak
46  int fIndWidth; /// Induction wire hit width (in time ticks)
47  int fColWidth; /// Collection wire hit width (in time ticks)
48 
49  float getTotalCharge(const float*,int,float);
50 
51  }; // class TTHitFinder
52 
53  //-------------------------------------------------
55  : EDProducer{pset}
56  {
57  fCalDataModuleLabel = pset.get< std::string >("CalDataModuleLabel");
58  fMinSigPeakInd = pset.get< float >("MinSigPeakInd");
59  fMinSigPeakCol = pset.get< float >("MinSigPeakCol");
60  fMinSigTailInd = pset.get< float >("MinSigTailInd",-99); //defaulting to well-below zero
61  fMinSigTailCol = pset.get< float >("MinSigTailCol",-99); //defaulting to well-below zero
62  fIndWidth = pset.get< int >("IndWidth", 3); //defaulting to 3
63  fColWidth = pset.get< int >("ColWidth", 3); //defaulting to 3
64 
65  //enforce a minimum width
66  if(fIndWidth<1){
67  mf::LogWarning("TTHitFinder") << "IndWidth must be 1 at minimum. Resetting width to one time tick";
68  fIndWidth = 1;
69  }
70  if(fColWidth<1){
71  mf::LogWarning("TTHitFinder") << "ColWidth must be 1 at minimum. Resetting width to one time tick";
72  fColWidth = 1;
73  }
74 
75  // let HitCollectionCreator declare that we are going to produce
76  // hits and associations with wires and raw digits
80 
81  }
82 
83  //-------------------------------------------------
85  {
86 
87  // these objects contain the hit collections
88  // and their associations to wires and raw digits:
89  recob::HitCollectionCreator hitCollection_U(evt, "uhits");
90  recob::HitCollectionCreator hitCollection_V(evt, "vhits");
91  recob::HitCollectionCreator hitCollection_Y(evt, "yhits");
92 
93  // Read in the wire List object(s).
95  evt.getByLabel(fCalDataModuleLabel,wireVecHandle);
96  std::vector<recob::Wire> const& wireVec(*wireVecHandle);
97 
98  // also get the raw digits associated with wires
99  art::FindOneP<raw::RawDigit> WireToRawDigits
100  (wireVecHandle, evt, fCalDataModuleLabel);
101 
103 
104  //initialize some variables that will be in the loop.
105  float threshold_peak = 0;
106  float threshold_tail = -99;
107  int width = 3;
108 
109  //Loop over wires
110  for(unsigned int wireIter = 0; wireIter < wireVec.size(); wireIter++) {
111 
112  //get our wire
113  art::Ptr<recob::Wire> wire(wireVecHandle, wireIter);
114  art::Ptr<raw::RawDigit> const& rawdigits = WireToRawDigits.at(wireIter);
115 
116  std::vector<float> signal(wire->Signal());
117  std::vector<float>::iterator timeIter; // iterator for time bins
118  geo::WireID wire_id = (geom->ChannelToWire(wire->Channel())).at(0); //just grabbing the first one
119 
120 
121  //set the thresholds and widths based on wire type
122  geo::SigType_t sigType = geom->SignalType(wire->Channel());
123  if(sigType == geo::kInduction){
124  threshold_peak = fMinSigPeakInd;
125  threshold_tail = fMinSigTailInd;
126  width = fIndWidth;
127  }
128  else if(sigType == geo::kCollection){
129  threshold_peak = fMinSigPeakCol;
130  threshold_tail = fMinSigTailCol;
131  width = fColWidth;
132  }
133 
134  //make a half_width variable to be the search window around each time tick.
135  float half_width = ((float)width-1)/2.;
136 
137  //now do the loop over the time ticks on the wire
138  int time_bin = -1;
139  float peak_val = 0;
140  for(timeIter = signal.begin(); timeIter < signal.end(); timeIter++){
141  time_bin++;
142 
143  //set the peak value, taking average between ticks if desired total width is even
144  if(width%2==1) peak_val = *timeIter;
145  else if(width%2==0) peak_val = 0.5 * (*timeIter + *(timeIter+1));
146 
147  //continue immediately if we are not above the threshold
148  if(peak_val < threshold_peak) continue;
149 
150  //continue if we are too close to the edge
151  if( time_bin-half_width < 0 ) continue;
152  if( time_bin+half_width > signal.size() ) continue;
153 
154  //if necessary, do loop over hit width, and check tail thresholds
155  int begin_tail_tick = std::floor(time_bin-half_width);
156  float totalCharge = getTotalCharge(&signal[begin_tail_tick],width,threshold_tail);
157  if(totalCharge==-999) {
158  MF_LOG_DEBUG("TTHitFinder") << "Rejecting would be hit at (plane,wire,time_bin,first_bin,last_bin)=("
159  << wire_id.Plane << "," << wire_id.Wire << "," << time_bin << "," << begin_tail_tick << "," << begin_tail_tick+width-1 << "): "
160  << signal.at(time_bin-1) << " "
161  << signal.at(time_bin) << " "
162  << signal.at(time_bin+1);
163  continue;
164  }
165 
166  //OK, if we've passed all tests up to this point, we have a hit!
167 
168  float hit_time = time_bin;
169  if(width%2==0) hit_time = time_bin+0.5;
170 
171  // hit time region is 2 widths (4 RMS) wide
172  const raw::TDCtick_t start_tick = hit_time - width,
173  end_tick = hit_time + width;
174 
175  // make the hit
177  *wire, // wire
178  wire_id, // wireID
179  start_tick, // start_tick
180  end_tick, // end_tick
181  width / 2., // rms
182  hit_time, // peak_time
183  0., // sigma_peak_time
184  peak_val, // peak_amplitude
185  0., // sigma_peak_amplitude
186  totalCharge, // hit_integral
187  0., // hit_sigma_integral
188  totalCharge, // summedADC
189  1, // multiplicity (dummy value)
190  0, // local_index (dummy value)
191  1., // goodness_of_fit (dummy value)
192  0 // dof
193  );
194  if(wire_id.Plane==0)
195  hitCollection_U.emplace_back(hit.move(), wire, rawdigits);
196  else if(wire_id.Plane==1)
197  hitCollection_V.emplace_back(hit.move(), wire, rawdigits);
198  else if(wire_id.Plane==2)
199  hitCollection_Y.emplace_back(hit.move(), wire, rawdigits);
200 
201  }//End loop over time ticks on wire
202 
203  MF_LOG_DEBUG("TTHitFinder") << "Finished wire " << wire_id.Wire << " (plane " << wire_id.Plane << ")"
204  << "\tTotal hits (U,V,Y)= ("
205  << hitCollection_U.size() << ","
206  << hitCollection_V.size() << ","
207  << hitCollection_Y.size() << ")";
208 
209  }//End loop over all wires
210 
211  // put the hit collection and associations into the event
212  mf::LogInfo("TTHitFinder") << "Total TTHitFinder hits (U,V,Y)=("
213  << hitCollection_U.size() << ","
214  << hitCollection_V.size() << ","
215  << hitCollection_Y.size() << ")";
216  hitCollection_U.put_into(evt); // reminder: instance name was "uhits"
217  hitCollection_V.put_into(evt); // reminder: instance name was "vhits"
218  hitCollection_Y.put_into(evt); // reminder: instance name was "yhits"
219 
220  } // End of produce()
221 
222 
223  //-------------------------------------------------
224  float TTHitFinder::getTotalCharge(const float* signal_vector,int width=3,float threshold=-99){
225 
226  float totalCharge = 0;
227  for(int tick=0; tick<width; tick++){
228  if(signal_vector[tick] < threshold){
229  totalCharge = -999; //special value for being below threshold
230  break;
231  }
232  totalCharge += signal_vector[tick];
233  }
234  return totalCharge;
235 
236  }//end getTotalCharge method
237 
239 
240 } // end of hit namespace
intermediate_table::iterator iterator
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.
std::string string
Definition: nybbler.cc:12
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
EDProducer(fhicl::ParameterSet const &pset)
Definition: EDProducer.h:20
std::vector< geo::WireID > ChannelToWire(raw::ChannelID_t const channel) const
Returns a list of wires connected to the specified TPC channel.
WireID_t Wire
Index of the wire within its plane.
Definition: geo_types.h:580
SigType_t SignalType(geo::PlaneID const &pid) const
Returns the type of signal on the channels of specified TPC 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
art framework interface to geometry description
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.
bool getByLabel(std::string const &label, std::string const &instance, Handle< PROD > &result) const
Definition: DataViewImpl.h:633
A class handling a collection of hits and its associations.
Definition: HitCreator.h:508
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:67
Signal from induction planes.
Definition: geo_types.h:145
raw::ChannelID_t Channel() const
Returns the ID of the channel (or InvalidChannelID)
Definition: Wire.h:231
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
Detector simulation of raw signals on wires.
std::vector< float > Signal() const
Return a zero-padded full length vector filled with RoI signal.
Definition: Wire.cxx:47
ProducesCollector & producesCollector() noexcept
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.
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
#define MF_LOG_DEBUG(id)
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:7
TTHitFinder(fhicl::ParameterSet const &pset)
recob::Hit && move()
Prepares the constructed hit to be moved away.
Definition: HitCreator.h:343
float getTotalCharge(const float *, int, float)
Collection wire hit width (in time ticks)
Signal from collection planes.
Definition: geo_types.h:146