All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
DataProviderAlg.cxx
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////////////////////////
2 // Class: PointIdAlg
3 // Author: P.Plonski, R.Sulej (Robert.Sulej@cern.ch), D.Stefan, May 2016
4 ////////////////////////////////////////////////////////////////////////////////////////////////////
5 
7 
8 #include "art/Framework/Services/Registry/ServiceHandle.h"
9 #include "messagefacility/MessageLogger/MessageLogger.h"
10 #include "cetlib_except/exception.h"
11 
16 namespace detinfo {
17  class DetectorClocksData;
18 }
20 
21 namespace geo {
22  class GeometryCore;
23 }
24 
25 #include "CLHEP/Random/RandGauss.h"
26 
27 #include <algorithm>
28 #include <string>
29 #include <optional>
30 #include <vector>
31 
32 img::DataProviderAlg::DataProviderAlg(const Config& config)
33  : fAlgView{}
34  , fDownscaleMode(img::DataProviderAlg::kMax)
35  , fDriftWindow(10)
36  , fCalorimetryAlg(config.CalorimetryAlg())
37  , fGeometry(art::ServiceHandle<geo::Geometry const>().get())
38  , fAdcSumOverThr(0)
39  , fAdcSumThr(10)
40  , // set fixed threshold of 10 ADC counts for counting the sum
41  fAdcAreaOverThr(0)
42  , fNoiseSigma(0)
43  , fCoherentSigma(0)
44 {
45  fCalibrateLifetime = config.CalibrateLifetime();
46  fCalibrateAmpl = config.CalibrateAmpl();
47 
48  fAmplCalibConst.resize(fGeometry->MaxPlanes());
49  if (fCalibrateAmpl) {
50  mf::LogInfo("DataProviderAlg") << "Using calibration constants:";
51  for (size_t p = 0; p < fAmplCalibConst.size(); ++p) {
52  try {
53  fAmplCalibConst[p] = 1.2e-3 * fCalorimetryAlg.ElectronsFromADCPeak(1.0, p);
54  mf::LogInfo("DataProviderAlg") << " plane:" << p << " const:" << 1.0 / fAmplCalibConst[p];
55  }
56  catch (...) {
57  fAmplCalibConst[p] = 1.0;
58  }
59  }
60  }
61  else {
62  mf::LogInfo("DataProviderAlg") << "No plane-to-plane calibration.";
63  for (size_t p = 0; p < fAmplCalibConst.size(); ++p) {
64  fAmplCalibConst[p] = 1.0;
65  }
66  }
67 
68  fDriftWindow = config.DriftWindow();
69  fDownscaleFullView = config.DownscaleFullView();
70  fDriftWindowInv = 1.0 / fDriftWindow;
71 
72  std::string mode_str = config.DownscaleFn();
73  mf::LogVerbatim("DataProviderAlg") << "Downscale mode is: " << mode_str;
74  if (mode_str == "maxpool") {
75  //fnDownscale = [this](std::vector<float> & dst, std::vector<float> const & adc, size_t tick0) { downscaleMax(dst, adc, tick0); };
76  fDownscaleMode = img::DataProviderAlg::kMax;
77  }
78  else if (mode_str == "maxmean") {
79  //fnDownscale = [this](std::vector<float> & dst, std::vector<float> const & adc, size_t tick0) { downscaleMaxMean(dst, adc, tick0); };
80  fDownscaleMode = img::DataProviderAlg::kMaxMean;
81  }
82  else if (mode_str == "mean") {
83  //fnDownscale = [this](std::vector<float> & dst, std::vector<float> const & adc, size_t tick0) { downscaleMean(dst, adc, tick0); };
84  fDownscaleMode = img::DataProviderAlg::kMean;
85  }
86  else {
87  mf::LogError("DataProviderAlg") << "Downscale mode string not recognized, set to max pooling.";
88  //fnDownscale = [this](std::vector<float> & dst, std::vector<float> const & adc, size_t tick0) { downscaleMax(dst, adc, tick0); };
89  fDownscaleMode = img::DataProviderAlg::kMax;
90  }
91 
92  fAdcMax = config.AdcMax();
93  fAdcMin = config.AdcMin();
94  fAdcOffset = config.OutMin();
95  fAdcScale = (config.OutMax() - fAdcOffset) / (fAdcMax - fAdcMin);
96  fAdcZero = fAdcOffset + fAdcScale * (0 - fAdcMin); // level of zero ADC after scaling
97 
98  if (fAdcMax <= fAdcMin) {
99  throw cet::exception("img::DataProviderAlg") << "Misconfigured: AdcMax <= AdcMin" << std::endl;
100  }
101  if (fAdcScale == 0) {
102  throw cet::exception("img::DataProviderAlg") << "Misconfigured: OutMax == OutMin" << std::endl;
103  }
104 
105  fBlurKernel = config.BlurKernel();
106  fNoiseSigma = config.NoiseSigma();
107  fCoherentSigma = config.CoherentSigma();
108 }
109 // ------------------------------------------------------
110 
112 // ------------------------------------------------------
113 
116  detinfo::DetectorPropertiesData const& det_prop,
117  size_t wires,
118  size_t drifts)
119 {
121  result.fNWires = wires;
122  result.fNDrifts = drifts;
123  result.fNScaledDrifts = drifts / fDriftWindow;
124  result.fNCachedDrifts = fDownscaleFullView ? result.fNScaledDrifts : drifts;
125 
126  result.fWireChannels.resize(wires, raw::InvalidChannelID);
127 
128  result.fWireDriftData.resize(wires, std::vector<float>(result.fNCachedDrifts, fAdcZero));
129 
130  result.fLifetimeCorrFactors.resize(drifts);
131  if (fCalibrateLifetime) {
132  for (size_t t = 0; t < drifts; ++t) {
133  result.fLifetimeCorrFactors[t] = fCalorimetryAlg.LifetimeCorrection(clock_data, det_prop, t);
134  }
135  }
136  else {
137  for (size_t t = 0; t < drifts; ++t) {
138  result.fLifetimeCorrFactors[t] = 1.0;
139  }
140  }
141  return result;
142 }
143 // ------------------------------------------------------
144 
145 float
146 img::DataProviderAlg::poolMax(int wire, int drift, size_t r) const
147 {
148  size_t rw = r, rd = r;
149  if (!fDownscaleFullView) { rd *= fDriftWindow; }
150 
151  size_t didx = getDriftIndex(drift);
152  int d0 = didx - rd;
153  if (d0 < 0) { d0 = 0; }
154  int d1 = didx + rd;
155  if (d1 >= (int)fAlgView.fNCachedDrifts) { d1 = fAlgView.fNCachedDrifts - 1; }
156 
157  int w0 = wire - rw;
158  if (w0 < 0) { w0 = 0; }
159  int w1 = wire + rw;
160  if (w1 >= (int)fAlgView.fNWires) { w1 = fAlgView.fNWires - 1; }
161 
162  float adc, max_adc = 0;
163  for (int w = w0; w <= w1; ++w) {
164  auto const* col = fAlgView.fWireDriftData[w].data();
165  for (int d = d0; d <= d1; ++d) {
166  adc = col[d];
167  if (adc > max_adc) { max_adc = adc; }
168  }
169  }
170 
171  return max_adc;
172 }
173 // ------------------------------------------------------
174 
175 //float img::DataProviderAlg::poolSum(int wire, int drift, size_t r) const
176 //{
177 // size_t rw = r, rd = r;
178 // if (!fDownscaleFullView) { rd *= fDriftWindow; }
179 //
180 // size_t didx = getDriftIndex(drift);
181 // int d0 = didx - rd; if (d0 < 0) { d0 = 0; }
182 // int d1 = didx + rd; if (d1 >= (int)fNCachedDrifts) { d1 = fNCachedDrifts - 1; }
183 //
184 // int w0 = wire - rw; if (w0 < 0) { w0 = 0; }
185 // int w1 = wire + rw; if (w1 >= (int)fNWires) { w1 = fNWires - 1; }
186 //
187 // float sum = 0;
188 // for (int w = w0; w <= w1; ++w)
189 // {
190 // auto const * col = fWireDriftData[w].data();
191 // for (int d = d0; d <= d1; ++d) { sum += col[d]; }
192 // }
193 //
194 // return sum;
195 //}
196 // ------------------------------------------------------
197 std::vector<float>
199  std::vector<float> const& adc,
200  size_t tick0) const
201 {
202  size_t kStop = dst_size;
203  std::vector<float> result(dst_size);
204  if (adc.size() < kStop) { kStop = adc.size(); }
205  for (size_t i = 0, k0 = 0; i < kStop; ++i, k0 += fDriftWindow) {
206  size_t k1 = k0 + fDriftWindow;
207 
208  float max_adc = adc[k0] * fAlgView.fLifetimeCorrFactors[k0 + tick0];
209  for (size_t k = k0 + 1; k < k1; ++k) {
210  float ak = adc[k] * fAlgView.fLifetimeCorrFactors[k + tick0];
211  if (ak > max_adc) max_adc = ak;
212  }
213  result[i] = max_adc;
214  }
215  scaleAdcSamples(result);
216  return result;
217 }
218 
219 std::vector<float>
221  std::vector<float> const& adc,
222  size_t tick0) const
223 {
224  size_t kStop = dst_size;
225  std::vector<float> result(dst_size);
226  if (adc.size() < kStop) { kStop = adc.size(); }
227  for (size_t i = 0, k0 = 0; i < kStop; ++i, k0 += fDriftWindow) {
228  size_t k1 = k0 + fDriftWindow;
229  size_t max_idx = k0;
230  float max_adc = adc[k0] * fAlgView.fLifetimeCorrFactors[k0 + tick0];
231  for (size_t k = k0 + 1; k < k1; ++k) {
232  float ak = adc[k] * fAlgView.fLifetimeCorrFactors[k + tick0];
233  if (ak > max_adc) {
234  max_adc = ak;
235  max_idx = k;
236  }
237  }
238 
239  size_t n = 1;
240  if (max_idx > 0) {
241  max_adc += adc[max_idx - 1] * fAlgView.fLifetimeCorrFactors[max_idx - 1 + tick0];
242  n++;
243  }
244  if (max_idx + 1 < adc.size()) {
245  max_adc += adc[max_idx + 1] * fAlgView.fLifetimeCorrFactors[max_idx + 1 + tick0];
246  n++;
247  }
248 
249  result[i] = max_adc / n;
250  }
251  scaleAdcSamples(result);
252  return result;
253 }
254 
255 std::vector<float>
257  std::vector<float> const& adc,
258  size_t tick0) const
259 {
260  size_t kStop = dst_size;
261  std::vector<float> result(dst_size);
262  if (adc.size() < kStop) { kStop = adc.size(); }
263  for (size_t i = 0, k0 = 0; i < kStop; ++i, k0 += fDriftWindow) {
264  size_t k1 = k0 + fDriftWindow;
265 
266  float sum_adc = 0;
267  for (size_t k = k0; k < k1; ++k) {
268  if (k + tick0 < fAlgView.fLifetimeCorrFactors.size())
269  sum_adc += adc[k] * fAlgView.fLifetimeCorrFactors[k + tick0];
270  }
271  result[i] = sum_adc * fDriftWindowInv;
272  }
273  scaleAdcSamples(result);
274  return result;
275 }
276 
277 std::optional<std::vector<float>>
278 img::DataProviderAlg::setWireData(std::vector<float> const& adc, size_t wireIdx) const
279 {
280  if (wireIdx >= fAlgView.fWireDriftData.size()) return std::nullopt;
281  auto& wData = fAlgView.fWireDriftData[wireIdx];
282 
283  if (fDownscaleFullView) {
284  if (!adc.empty()) { return downscale(wData.size(), adc, 0); }
285  else {
286  return std::nullopt;
287  }
288  }
289  else {
290  if (adc.empty()) { return std::nullopt; }
291  else if (adc.size() <= wData.size())
292  return adc;
293  else {
294  return std::vector<float>(adc.begin(), adc.begin() + wData.size());
295  }
296  }
297  return std::make_optional(wData);
298 }
299 // ------------------------------------------------------
300 
301 bool
303  detinfo::DetectorPropertiesData const& det_prop,
304  const std::vector<recob::Wire>& wires,
305  unsigned int plane,
306  unsigned int tpc,
307  unsigned int cryo)
308 {
309  mf::LogInfo("DataProviderAlg") << "Create image for cryo:" << cryo << " tpc:" << tpc
310  << " plane:" << plane;
311 
312  fCryo = cryo;
313  fTPC = tpc;
314  fPlane = plane;
315 
316  fAdcSumOverThr = 0;
317  fAdcAreaOverThr = 0;
318 
319  size_t nwires = fGeometry->Nwires(plane, tpc, cryo);
320  size_t ndrifts = det_prop.NumberTimeSamples();
321 
322  fAlgView = resizeView(clock_data, det_prop, nwires, ndrifts);
323 
324  auto const& channelStatus =
325  art::ServiceHandle<lariov::ChannelStatusService const>()->GetProvider();
326 
327  bool allWrong = true;
328  for (auto const& wire : wires) {
329  auto wireChannelNumber = wire.Channel();
330  if (!channelStatus.IsGood(wireChannelNumber)) { continue; }
331 
332  size_t w_idx = 0;
333  for (auto const& id : fGeometry->ChannelToWire(wireChannelNumber)) {
334  if ((id.Plane == plane) && (id.TPC == tpc) && (id.Cryostat == cryo)) {
335  w_idx = id.Wire;
336 
337  auto adc = wire.Signal();
338  if (adc.size() < ndrifts) {
339  mf::LogWarning("DataProviderAlg") << "Wire ADC vector size lower than NumberTimeSamples.";
340  continue; // not critical, maybe other wires are OK, so continue
341  }
342  auto wire_data = setWireData(adc, w_idx);
343  if (!wire_data) {
344  mf::LogWarning("DataProviderAlg") << "Wire data not set.";
345  continue; // also not critical, try to set other wires
346  }
347  fAlgView.fWireDriftData[w_idx] = *wire_data;
348  for (auto v : adc) {
349  if (v >= fAdcSumThr) {
350  fAdcSumOverThr += v;
351  fAdcAreaOverThr++;
352  }
353  }
354 
355  fAlgView.fWireChannels[w_idx] = wireChannelNumber;
356  allWrong = false;
357  }
358  }
359  }
360  if (allWrong) {
361  mf::LogError("DataProviderAlg")
362  << "Wires data not set in the cryo:" << cryo << " tpc:" << tpc << " plane:" << plane;
363  return false;
364  }
365 
366  applyBlur();
367  addWhiteNoise();
368  addCoherentNoise();
369 
370  return true;
371 }
372 // ------------------------------------------------------
373 
374 float
376 {
377  val *= fAmplCalibConst[fPlane]; // prescale by plane-to-plane calibration factors
378 
379  if (val < fAdcMin) { val = fAdcMin; } // saturate
380  else if (val > fAdcMax) {
381  val = fAdcMax;
382  }
383 
384  return fAdcOffset +
385  fAdcScale *
386  (val - fAdcMin); // shift and scale to the output range, shift to the output min
387 }
388 // ------------------------------------------------------
389 void
391 {
392  float calib = fAmplCalibConst[fPlane];
393  auto* data = values.data();
394 
395  size_t k = 0, size4 = values.size() >> 2, size = values.size();
396  for (size_t i = 0; i < size4; ++i) // vectorize if you can
397  {
398  data[k] *= calib; // prescale by plane-to-plane calibration factors
399  data[k + 1] *= calib;
400  data[k + 2] *= calib;
401  data[k + 3] *= calib;
402 
403  if (data[k] < fAdcMin) { data[k] = fAdcMin; } // saturate min
404  if (data[k + 1] < fAdcMin) { data[k + 1] = fAdcMin; }
405  if (data[k + 2] < fAdcMin) { data[k + 2] = fAdcMin; }
406  if (data[k + 3] < fAdcMin) { data[k + 3] = fAdcMin; }
407 
408  if (data[k] > fAdcMax) { data[k] = fAdcMax; } // saturate max
409  if (data[k + 1] > fAdcMax) { data[k + 1] = fAdcMax; }
410  if (data[k + 2] > fAdcMax) { data[k + 2] = fAdcMax; }
411  if (data[k + 3] > fAdcMax) { data[k + 3] = fAdcMax; }
412 
413  data[k] = fAdcOffset +
414  fAdcScale *
415  (data[k] - fAdcMin); // shift and scale to the output range, shift to the output min
416  data[k + 1] = fAdcOffset + fAdcScale * (data[k + 1] - fAdcMin);
417  data[k + 2] = fAdcOffset + fAdcScale * (data[k + 2] - fAdcMin);
418  data[k + 3] = fAdcOffset + fAdcScale * (data[k + 3] - fAdcMin);
419 
420  k += 4;
421  }
422  while (k < size) {
423  data[k] = scaleAdcSample(data[k]);
424  ++k;
425  } // do the tail
426 }
427 // ------------------------------------------------------
428 
429 void
431 {
432  if (fBlurKernel.size() < 2) return;
433 
434  size_t margin_left = (fBlurKernel.size() - 1) >> 1,
435  margin_right = fBlurKernel.size() - margin_left - 1;
436 
437  std::vector<std::vector<float>> src(fAlgView.fWireDriftData.size());
438  for (size_t w = 0; w < fAlgView.fWireDriftData.size(); ++w) {
439  src[w] = fAlgView.fWireDriftData[w];
440  }
441 
442  for (size_t w = margin_left; w < fAlgView.fWireDriftData.size() - margin_right; ++w) {
443  for (size_t d = 0; d < fAlgView.fWireDriftData[w].size(); ++d) {
444  float sum = 0;
445  for (size_t i = 0; i < fBlurKernel.size(); ++i) {
446  sum += fBlurKernel[i] * src[w + i - margin_left][d];
447  }
448  fAlgView.fWireDriftData[w][d] = sum;
449  }
450  }
451 }
452 // ------------------------------------------------------
453 
454 // MUST give the same result as get_patch() in scripts/utils.py
455 bool
457  float drift,
458  size_t size_w,
459  size_t size_d,
460  std::vector<std::vector<float>>& patch) const
461 {
462  int halfSizeW = size_w / 2;
463  int halfSizeD = size_d / 2;
464 
465  int w0 = wire - halfSizeW;
466  int w1 = wire + halfSizeW;
467 
468  size_t sd = (size_t)(drift / fDriftWindow);
469  int d0 = sd - halfSizeD;
470  int d1 = sd + halfSizeD;
471 
472  int wsize = fAlgView.fWireDriftData.size();
473  for (int w = w0, wpatch = 0; w < w1; ++w, ++wpatch) {
474  auto& dst = patch[wpatch];
475  if ((w >= 0) && (w < wsize)) {
476  auto& src = fAlgView.fWireDriftData[w];
477  int dsize = src.size();
478  for (int d = d0, dpatch = 0; d < d1; ++d, ++dpatch) {
479  if ((d >= 0) && (d < dsize)) { dst[dpatch] = src[d]; }
480  else {
481  dst[dpatch] = fAdcZero;
482  }
483  }
484  }
485  else {
486  std::fill(dst.begin(), dst.end(), fAdcZero);
487  }
488  }
489 
490  return true;
491 }
492 
493 bool
495  float drift,
496  size_t size_w,
497  size_t size_d,
498  std::vector<std::vector<float>>& patch) const
499 {
500  int dsize = fDriftWindow * size_d;
501  int halfSizeW = size_w / 2;
502  int halfSizeD = dsize / 2;
503 
504  int w0 = wire - halfSizeW;
505  int w1 = wire + halfSizeW;
506 
507  int d0 = int(drift) - halfSizeD;
508  int d1 = int(drift) + halfSizeD;
509 
510  if (d0 < 0) d0 = 0;
511 
512  std::vector<float> tmp(dsize);
513  int wsize = fAlgView.fWireDriftData.size();
514  for (int w = w0, wpatch = 0; w < w1; ++w, ++wpatch) {
515  if ((w >= 0) && (w < wsize)) {
516  auto& src = fAlgView.fWireDriftData[w];
517  int src_size = src.size();
518  for (int d = d0, dpatch = 0; d < d1; ++d, ++dpatch) {
519  if ((d >= 0) && (d < src_size)) { tmp[dpatch] = src[d]; }
520  else {
521  tmp[dpatch] = fAdcZero;
522  }
523  }
524  }
525  else {
526  std::fill(tmp.begin(), tmp.end(), fAdcZero);
527  }
528  patch[wpatch] = downscale(patch[wpatch].size(), tmp, d0);
529  }
530 
531  return true;
532 }
533 // ------------------------------------------------------
534 
535 void
537 {
538  if (fNoiseSigma == 0) return;
539 
540  double effectiveSigma = scaleAdcSample(fNoiseSigma);
541  if (fDownscaleFullView) effectiveSigma /= fDriftWindow;
542 
543  CLHEP::RandGauss gauss(fRndEngine);
544  std::vector<double> noise(fAlgView.fNCachedDrifts);
545  for (auto& wire : fAlgView.fWireDriftData) {
546  gauss.fireArray(fAlgView.fNCachedDrifts, noise.data(), 0., effectiveSigma);
547  for (size_t d = 0; d < wire.size(); ++d) {
548  wire[d] += noise[d];
549  }
550  }
551 }
552 // ------------------------------------------------------
553 
554 void
556 {
557  if (fCoherentSigma == 0) return;
558 
559  double effectiveSigma = scaleAdcSample(fCoherentSigma);
560  if (fDownscaleFullView) effectiveSigma /= fDriftWindow;
561 
562  CLHEP::RandGauss gauss(fRndEngine);
563  std::vector<double> amps1(fAlgView.fWireDriftData.size());
564  std::vector<double> amps2(1 + (fAlgView.fWireDriftData.size() / 32));
565  gauss.fireArray(amps1.size(), amps1.data(), 1., 0.1); // 10% wire-wire ampl. variation
566  gauss.fireArray(amps2.size(), amps2.data(), 1., 0.1); // 10% group-group ampl. variation
567 
568  double group_amp = 1.0;
569  std::vector<double> noise(fAlgView.fNCachedDrifts);
570  for (size_t w = 0; w < fAlgView.fWireDriftData.size(); ++w) {
571  if ((w & 31) == 0) {
572  group_amp = amps2[w >> 5]; // div by 32
573  gauss.fireArray(fAlgView.fNCachedDrifts, noise.data(), 0., effectiveSigma);
574  } // every 32 wires
575 
576  auto& wire = fAlgView.fWireDriftData[w];
577  for (size_t d = 0; d < wire.size(); ++d) {
578  wire[d] += group_amp * amps1[w] * noise[d];
579  }
580  }
581 }
582 // ------------------------------------------------------
std::optional< std::vector< float > > setWireData(std::vector< float > const &adc, size_t wireIdx) const
std::vector< std::vector< float > > fWireDriftData
BEGIN_PROLOG true icarus_rawdigitfilter FilterTools FilterPlane1 Plane
virtual ~DataProviderAlg()
virtual DataProviderAlgView resizeView(detinfo::DetectorClocksData const &clock_data, detinfo::DetectorPropertiesData const &det_prop, size_t wires, size_t drifts)
pdgs p
Definition: selectors.fcl:22
std::size_t size(FixedBins< T, C > const &) noexcept
Definition: FixedBins.h:561
DataProviderAlg(const fhicl::ParameterSet &pset)
std::vector< float > downscaleMaxMean(std::size_t dst_size, std::vector< float > const &adc, size_t tick0) const
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:265
constexpr ChannelID_t InvalidChannelID
ID of an invalid channel.
Definition: RawTypes.h:32
std::vector< float > downscaleMax(std::size_t dst_size, std::vector< float > const &adc, size_t tick0) const
std::vector< float > downscaleMean(std::size_t dst_size, std::vector< float > const &adc, size_t tick0) const
void scaleAdcSamples(std::vector< float > &values) const
std::vector< raw::ChannelID_t > fWireChannels
void fill(const art::PtrVector< recob::Hit > &hits, int only_plane)
float scaleAdcSample(float val) const
calo::CalorimetryAlg fCalorimetryAlg
bool patchFromOriginalView(size_t wire, float drift, size_t size_w, size_t size_d, std::vector< std::vector< float >> &patch) const
bool setWireDriftData(const detinfo::DetectorClocksData &clock_data, const detinfo::DetectorPropertiesData &det_prop, const std::vector< recob::Wire > &wires, unsigned int plane, unsigned int tpc, unsigned int cryo)
Contains all timing reference information for the detector.
std::vector< float > fLifetimeCorrFactors
Interface for experiment-specific channel quality info provider.
Declaration of basic channel signal object.
bool patchFromDownsampledView(size_t wire, float drift, size_t size_w, size_t size_d, std::vector< std::vector< float >> &patch) const
pdgs k
Definition: selectors.fcl:22
float poolMax(int wire, int drift, size_t r=0) const
Pool max value in a patch around the wire/drift pixel.
Interface for experiment-specific service for channel quality info.
double LifetimeCorrection(detinfo::DetectorClocksData const &clock_data, detinfo::DetectorPropertiesData const &det_prop, double time, double T0=0) const
esac echo uname r
art framework interface to geometry description