DrawGausHits_tool.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 /// \file DrawGausHits_tool.cc
3 /// \author T. Usher
4 ////////////////////////////////////////////////////////////////////////
5 
10 #include "nuevdb/EventDisplayBase/EventHolder.h"
11 
13 #include "canvas/Persistency/Common/FindManyP.h"
14 #include "cetlib_except/exception.h"
16 
17 #include "TF1.h"
18 #include "TPolyLine.h"
19 
20 #include <fstream>
21 
22 namespace evdb_tool {
23 
24  class DrawGausHits : public IWFHitDrawer {
25  public:
26  explicit DrawGausHits(const fhicl::ParameterSet& pset);
27 
28  ~DrawGausHits();
29 
30  void configure(const fhicl::ParameterSet& pset) override;
31  void Draw(evdb::View2D&, raw::ChannelID_t&) const override;
32 
33  private:
34  using HitParams_t = struct HitParams_t {
35  float hitCenter;
36  float hitSigma;
37  float hitHeight;
38  float hitStart;
39  float hitEnd;
40  };
41 
42  using ROIHitParamsVec = std::vector<HitParams_t>;
43  using HitParamsVec = std::vector<ROIHitParamsVec>;
44 
47  std::vector<int> fColorVec;
48  mutable std::vector<std::unique_ptr<TF1>> fHitFunctionVec;
49  };
50 
51  //----------------------------------------------------------------------
52  // Constructor.
54 
56 
57  void
59  {
60  fNumPoints = pset.get<int>("NumPoints", 1000);
61  fFloatBaseline = pset.get<bool>("FloatBaseline", false);
62 
63  fColorVec.clear();
64  fColorVec.push_back(kRed);
65  fColorVec.push_back(kGreen);
66  fColorVec.push_back(kMagenta);
67  fColorVec.push_back(kCyan);
68 
69  fHitFunctionVec.clear();
70 
71  return;
72  }
73 
74  void
75  DrawGausHits::Draw(evdb::View2D& view2D, raw::ChannelID_t& channel) const
76  {
78 
79  //grab the singleton with the event
80  const art::Event* event = evdb::EventHolder::Instance()->GetEvent();
81  if (!event) return;
82 
83  fHitFunctionVec.clear();
84 
85  for (size_t imod = 0; imod < recoOpt->fHitLabels.size(); ++imod) {
86  // Step one is to recover the hits for this label that match the input channel
87  art::InputTag const which = recoOpt->fHitLabels[imod];
88 
90  event->getByLabel(which, hitVecHandle);
91 
92  // Get a container for the subset of hits we are drawing
94 
95  try {
96  for (size_t hitIdx = 0; hitIdx < hitVecHandle->size(); hitIdx++) {
97  art::Ptr<recob::Hit> hit(hitVecHandle, hitIdx);
98 
99  if (hit->Channel() == channel) hitPtrVec.push_back(hit);
100  }
101  }
102  catch (cet::exception& e) {
103  mf::LogWarning("DrawGausHits") << "DrawGausHits"
104  << " failed with message:\n"
105  << e;
106  }
107 
108  if (hitPtrVec.empty()) continue;
109 
110  // Apparently you cannot trust some hit producers to put the hits in the correct order!
111  std::sort(hitPtrVec.begin(), hitPtrVec.end(), [](const auto& left, const auto& right) {
112  return left->PeakTime() < right->PeakTime();
113  });
114 
115  // Get associations to wires
116  art::FindManyP<recob::Wire> wireAssnsVec(hitPtrVec, *event, which);
117  std::vector<float> wireDataVec;
118 
119  // Recover the full (zero-padded outside ROI's) deconvolved waveform for this wire
120  if (wireAssnsVec.isValid() && wireAssnsVec.size() > 0) {
121  auto hwafp = wireAssnsVec.at(0).front();
122  if (!hwafp.isNull() && hwafp.isAvailable()) { wireDataVec = hwafp->Signal(); }
123  }
124 
125  // Now go through and process the hits back into the hit parameters
126  using ROIHitParamsVec = std::vector<HitParams_t>;
127  using HitParamsVec = std::vector<ROIHitParamsVec>;
128 
129  // Get an initial container for common hits on ROI
130  HitParamsVec hitParamsVec;
131  ROIHitParamsVec roiHitParamsVec;
132  raw::TDCtick_t lastEndTick(10000);
133 
134  for (const auto& hit : hitPtrVec) {
135  // check roi end condition
136  if (hit->PeakTime() - 3. * hit->RMS() > lastEndTick) {
137  if (!roiHitParamsVec.empty()) hitParamsVec.push_back(roiHitParamsVec);
138  roiHitParamsVec.clear();
139  }
140 
141  HitParams_t hitParams;
142 
143  hitParams.hitCenter = hit->PeakTime();
144  hitParams.hitSigma = hit->RMS();
145  hitParams.hitHeight = hit->PeakAmplitude();
146  hitParams.hitStart = hit->StartTick(); //PeakTime() - 3. * hit->RMS();
147  hitParams.hitEnd = hit->EndTick(); //PeakTime() + 3. * hit->RMS();
148 
149  lastEndTick = hitParams.hitEnd;
150 
151  roiHitParamsVec.emplace_back(hitParams);
152 
153  } //end loop over reco hits
154 
155  // Just in case (probably never called...)
156  if (!roiHitParamsVec.empty()) hitParamsVec.push_back(roiHitParamsVec);
157 
158  size_t roiCount(0);
159 
160  for (const auto& roiHitParamsVec : hitParamsVec) {
161  // Create a histogram here...
162  double roiStart = roiHitParamsVec.front().hitStart;
163  double roiStop = roiHitParamsVec.back().hitEnd;
164 
165  std::string funcString = "gaus(0)";
166  std::string funcName = Form("hitshape_%05zu_c%02zu", size_t(channel), roiCount++);
167 
168  for (size_t idx = 1; idx < roiHitParamsVec.size(); idx++)
169  funcString += "+gaus(" + std::to_string(3 * idx) + ")";
170 
171  // Include a baseline
172  float baseline(0.);
173 
174  if (fFloatBaseline && !wireDataVec.empty()) baseline = wireDataVec.at(roiStart);
175 
176  funcString += "+" + std::to_string(baseline);
177 
178  fHitFunctionVec.emplace_back(
179  std::make_unique<TF1>(funcName.c_str(), funcString.c_str(), roiStart, roiStop));
180  TF1& hitFunc = *fHitFunctionVec.back().get();
181 
182  hitFunc.SetLineColor(fColorVec[imod % fColorVec.size()]);
183 
184  size_t idx(0);
185  for (const auto& hitParams : roiHitParamsVec) {
186  hitFunc.SetParameter(idx + 0, hitParams.hitHeight);
187  hitFunc.SetParameter(idx + 1, hitParams.hitCenter);
188  hitFunc.SetParameter(idx + 2, hitParams.hitSigma);
189 
190  TPolyLine& hitHeight = view2D.AddPolyLine(2, kBlack, 1, 1);
191 
192  hitHeight.SetPoint(0, hitParams.hitCenter, baseline);
193  hitHeight.SetPoint(1, hitParams.hitCenter, hitParams.hitHeight + baseline);
194 
195  hitHeight.Draw("same");
196 
197  TPolyLine& hitSigma = view2D.AddPolyLine(2, kGray, 1, 1);
198 
199  hitSigma.SetPoint(
200  0, hitParams.hitCenter - hitParams.hitSigma, 0.6 * hitParams.hitHeight + baseline);
201  hitSigma.SetPoint(
202  1, hitParams.hitCenter + hitParams.hitSigma, 0.6 * hitParams.hitHeight + baseline);
203 
204  hitSigma.Draw("same");
205 
206  idx += 3;
207  }
208 
209  hitFunc.Draw("same");
210  }
211  } //end loop over HitFinding modules
212 
213  return;
214  }
215 
217 }
std::vector< HitParams_t > ROIHitParamsVec
void configure(const fhicl::ParameterSet &pset) override
#define DEFINE_ART_CLASS_TOOL(tool)
Definition: ToolMacros.h:42
std::string string
Definition: nybbler.cc:12
iterator begin()
Definition: PtrVector.h:217
std::vector< ROIHitParamsVec > HitParamsVec
uint8_t channel
Definition: CRTFragment.hh:201
int TDCtick_t
Type representing a TDC tick.
Definition: RawTypes.h:25
const double e
void push_back(Ptr< U > const &p)
Definition: PtrVector.h:435
T get(std::string const &key) const
Definition: ParameterSet.h:271
iterator end()
Definition: PtrVector.h:231
bool empty() const
Definition: PtrVector.h:330
Detector simulation of raw signals on wires.
std::vector< int > fColorVec
Declaration of signal hit object.
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
Declaration of basic channel signal object.
void Draw(evdb::View2D &, raw::ChannelID_t &) const override
std::vector< art::InputTag > fHitLabels
module labels that produced hits
unsigned int ChannelID_t
Type representing the ID of a readout channel.
Definition: RawTypes.h:28
std::vector< std::unique_ptr< TF1 > > fHitFunctionVec
raw::ChannelID_t Channel() const
ID of the readout channel the hit was extracted from.
Definition: Hit.h:230
std::string to_string(ModuleType const mt)
Definition: ModuleType.h:34
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
Event finding and building.
DrawGausHits(const fhicl::ParameterSet &pset)
struct HitParams_t{float hitCenter HitParams_t