CandHitStandard_tool.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 /// \file CandHitStandard.cc
3 /// \author T. Usher
4 ////////////////////////////////////////////////////////////////////////
5 
7 
10 
11 #include <algorithm>
12 
13 namespace reco_tool {
14 
16  public:
17  explicit CandHitStandard(const fhicl::ParameterSet& pset);
18 
19  void findHitCandidates(const recob::Wire::RegionsOfInterest_t::datarange_t&,
20  const size_t,
21  const size_t,
22  const size_t,
23  HitCandidateVec&) const override;
24 
25  void MergeHitCandidates(const recob::Wire::RegionsOfInterest_t::datarange_t&,
26  const HitCandidateVec&,
27  MergeHitCandidateVec&) const override;
28 
29  private:
32  const size_t,
33  const size_t,
34  HitCandidateVec&) const;
35 
36  // Member variables from the fhicl file
37  const float fRoiThreshold; ///< minimum maximum to minimum peak distance
38 
39  const geo::GeometryCore* fGeometry = lar::providerFrom<geo::Geometry>();
40  };
41 
42  //----------------------------------------------------------------------
43  // Constructor.
45  : fRoiThreshold(pset.get<float>("RoiThreshold", 5.))
46  {}
47 
48  void
49  CandHitStandard::findHitCandidates(const recob::Wire::RegionsOfInterest_t::datarange_t& dataRange,
50  const size_t roiStartTick,
51  const size_t channel,
52  const size_t eventCount,
53  HitCandidateVec& hitCandidateVec) const
54  {
55  // Recover the actual waveform
56  const Waveform& waveform = dataRange.data();
57 
58  // Recover the plane index for this method
59  std::vector<geo::WireID> wids = fGeometry->ChannelToWire(channel);
60  const size_t plane = wids[0].Plane;
61 
62  // Use the recursive version to find the candidate hits
63  findHitCandidates(waveform.begin(), waveform.end(), roiStartTick, plane, hitCandidateVec);
64 
65  return;
66  }
67 
68  void
71  const size_t roiStartTick,
72  const size_t planeIdx,
73  HitCandidateVec& hitCandidateVec) const
74  {
75  // Need a minimum number of ticks to do any work here
76  if (std::distance(startItr, stopItr) > 4) {
77  // Find the highest peak in the range given
78  auto maxItr = std::max_element(startItr, stopItr);
79 
80  float maxValue = *maxItr;
81  int maxTime = std::distance(startItr, maxItr);
82 
83  if (maxValue > fRoiThreshold) {
84  // backwards to find first bin for this candidate hit
85  auto firstItr = std::distance(startItr, maxItr) > 2 ? maxItr - 1 : startItr;
86 
87  while (firstItr != startItr) {
88  // Check for pathology where waveform goes too negative
89  if (*firstItr < -fRoiThreshold) break;
90 
91  // Check both sides of firstItr and look for min/inflection point
92  if (*firstItr < *(firstItr + 1) && *firstItr <= *(firstItr - 1)) break;
93 
94  firstItr--;
95  }
96 
97  int firstTime = std::distance(startItr, firstItr);
98 
99  // Recursive call to find all candidate hits earlier than this peak
100  findHitCandidates(startItr, firstItr + 1, roiStartTick, planeIdx, hitCandidateVec);
101 
102  // forwards to find last bin for this candidate hit
103  auto lastItr = std::distance(maxItr, stopItr) > 2 ? maxItr + 1 : stopItr - 1;
104 
105  while (lastItr != stopItr - 1) {
106  // Check for pathology where waveform goes too negative
107  if (*lastItr < -fRoiThreshold) break;
108 
109  // Check both sides of firstItr and look for min/inflection point
110  if (*lastItr <= *(lastItr + 1) && *lastItr < *(lastItr - 1)) break;
111 
112  lastItr++;
113  }
114 
115  int lastTime = std::distance(startItr, lastItr);
116 
117  // Now save this candidate's start and max time info
118  HitCandidate hitCandidate;
119  hitCandidate.startTick = roiStartTick + firstTime;
120  hitCandidate.stopTick = roiStartTick + lastTime;
121  hitCandidate.maxTick = roiStartTick + firstTime;
122  hitCandidate.minTick = roiStartTick + lastTime;
123  hitCandidate.maxDerivative = *(startItr + firstTime);
124  hitCandidate.minDerivative = *(startItr + lastTime);
125  hitCandidate.hitCenter = roiStartTick + maxTime;
126  hitCandidate.hitSigma = std::max(2., float(lastTime - firstTime) / 6.);
127  hitCandidate.hitHeight = maxValue;
128 
129  hitCandidateVec.push_back(hitCandidate);
130 
131  // Recursive call to find all candidate hits later than this peak
132  findHitCandidates(lastItr + 1,
133  stopItr,
134  roiStartTick + std::distance(startItr, lastItr + 1),
135  planeIdx,
136  hitCandidateVec);
137  }
138  }
139 
140  return;
141  }
142 
143  void
145  const recob::Wire::RegionsOfInterest_t::datarange_t& rangeData,
146  const HitCandidateVec& hitCandidateVec,
147  MergeHitCandidateVec& mergedHitsVec) const
148  {
149  // If no hits then nothing to do here
150  if (hitCandidateVec.empty()) return;
151 
152  // The idea is to group hits that "touch" so they can be part of common fit, those that
153  // don't "touch" are fit independently. So here we build the output vector to achieve that
154  HitCandidateVec groupedHitVec;
155  int lastTick = hitCandidateVec.front().stopTick;
156 
157  // Step through the input hit candidates and group them by proximity
158  for (const auto& hitCandidate : hitCandidateVec) {
159  // Check condition that we have a new grouping
160  if (int(hitCandidate.startTick) - lastTick > 1) {
161  mergedHitsVec.emplace_back(groupedHitVec);
162 
163  groupedHitVec.clear();
164  }
165 
166  // Add the current hit to the current group
167  groupedHitVec.emplace_back(hitCandidate);
168 
169  lastTick = hitCandidate.stopTick;
170  }
171 
172  // Check end condition
173  if (!groupedHitVec.empty()) mergedHitsVec.emplace_back(groupedHitVec);
174 
175  return;
176  }
177 
179 }
CandHitStandard(const fhicl::ParameterSet &pset)
#define DEFINE_ART_CLASS_TOOL(tool)
Definition: ToolMacros.h:42
void findHitCandidates(const recob::Wire::RegionsOfInterest_t::datarange_t &, const size_t, const size_t, const size_t, HitCandidateVec &) const override
std::vector< geo::WireID > ChannelToWire(raw::ChannelID_t const channel) const
Returns a list of wires connected to the specified TPC channel.
intermediate_table::const_iterator const_iterator
uint8_t channel
Definition: CRTFragment.hh:201
art framework interface to geometry description
const float fRoiThreshold
minimum maximum to minimum peak distance
void MergeHitCandidates(const recob::Wire::RegionsOfInterest_t::datarange_t &, const HitCandidateVec &, MergeHitCandidateVec &) const override
double distance(double x1, double y1, double z1, double x2, double y2, double z2)
static int max(int a, int b)
Description of geometry of one entire detector.
const geo::GeometryCore * fGeometry
This provides an interface for tools which are tasked with finding candidate hits on input waveforms...
auto const & get(AssnsNode< L, R, D > const &r)
Definition: AssnsNode.h:115
std::vector< HitCandidateVec > MergeHitCandidateVec
std::vector< HitCandidate > HitCandidateVec