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 
9 
10 #include "larcore/CoreUtils/ServiceUtil.h" // lar::providerFrom<>()
11 
15 
17 namespace detinfo {
18  class DetectorProperties;
19 }
20 namespace geo {
21  class GeometryCore;
22 }
23 
24 #include "CLHEP/Random/RandGauss.h"
25 
27  : fAlgView{}
29  , fDriftWindow(10)
32  , fAdcSumOverThr(0)
33  , fAdcSumThr(10)
34  , // set fixed threshold of 10 ADC counts for counting the sum
36  , fNoiseSigma(0)
37  , fCoherentSigma(0)
38 {
41 
43  if (fCalibrateAmpl) {
44  mf::LogInfo("DataProviderAlg") << "Using calibration constants:";
45  for (size_t p = 0; p < fAmplCalibConst.size(); ++p) {
46  try {
48  mf::LogInfo("DataProviderAlg") << " plane:" << p << " const:" << 1.0 / fAmplCalibConst[p];
49  }
50  catch (...) {
51  fAmplCalibConst[p] = 1.0;
52  }
53  }
54  }
55  else {
56  mf::LogInfo("DataProviderAlg") << "No plane-to-plane calibration.";
57  for (size_t p = 0; p < fAmplCalibConst.size(); ++p) {
58  fAmplCalibConst[p] = 1.0;
59  }
60  }
61 
65 
66  std::string mode_str = config.DownscaleFn();
67  mf::LogVerbatim("DataProviderAlg") << "Downscale mode is: " << mode_str;
68  if (mode_str == "maxpool") {
69  //fnDownscale = [this](std::vector<float> & dst, std::vector<float> const & adc, size_t tick0) { downscaleMax(dst, adc, tick0); };
71  }
72  else if (mode_str == "maxmean") {
73  //fnDownscale = [this](std::vector<float> & dst, std::vector<float> const & adc, size_t tick0) { downscaleMaxMean(dst, adc, tick0); };
75  }
76  else if (mode_str == "mean") {
77  //fnDownscale = [this](std::vector<float> & dst, std::vector<float> const & adc, size_t tick0) { downscaleMean(dst, adc, tick0); };
79  }
80  else {
81  mf::LogError("DataProviderAlg") << "Downscale mode string not recognized, set to max pooling.";
82  //fnDownscale = [this](std::vector<float> & dst, std::vector<float> const & adc, size_t tick0) { downscaleMax(dst, adc, tick0); };
84  }
85 
86  fAdcMax = config.AdcMax();
87  fAdcMin = config.AdcMin();
90  fAdcZero = fAdcOffset + fAdcScale * (0 - fAdcMin); // level of zero ADC after scaling
91 
92  if (fAdcMax <= fAdcMin) {
93  throw cet::exception("img::DataProviderAlg") << "Misconfigured: AdcMax <= AdcMin" << std::endl;
94  }
95  if (fAdcScale == 0) {
96  throw cet::exception("img::DataProviderAlg") << "Misconfigured: OutMax == OutMin" << std::endl;
97  }
98 
102 }
103 // ------------------------------------------------------
104 
106 // ------------------------------------------------------
107 
110  detinfo::DetectorPropertiesData const& det_prop,
111  size_t wires,
112  size_t drifts)
113 {
115  result.fNWires = wires;
116  result.fNDrifts = drifts;
117  result.fNScaledDrifts = drifts / fDriftWindow;
118  result.fNCachedDrifts = fDownscaleFullView ? result.fNScaledDrifts : drifts;
119 
120  result.fWireChannels.resize(wires, raw::InvalidChannelID);
121 
122  result.fWireDriftData.resize(wires, std::vector<float>(result.fNCachedDrifts, fAdcZero));
123 
124  result.fLifetimeCorrFactors.resize(drifts);
125  if (fCalibrateLifetime) {
126  for (size_t t = 0; t < drifts; ++t) {
127  result.fLifetimeCorrFactors[t] = fCalorimetryAlg.LifetimeCorrection(clock_data, det_prop, t);
128  }
129  }
130  else {
131  for (size_t t = 0; t < drifts; ++t) {
132  result.fLifetimeCorrFactors[t] = 1.0;
133  }
134  }
135  return result;
136 }
137 // ------------------------------------------------------
138 
139 float
140 img::DataProviderAlg::poolMax(int wire, int drift, size_t r) const
141 {
142  size_t rw = r, rd = r;
143  if (!fDownscaleFullView) { rd *= fDriftWindow; }
144 
145  size_t didx = getDriftIndex(drift);
146  int d0 = didx - rd;
147  if (d0 < 0) { d0 = 0; }
148  int d1 = didx + rd;
149  if (d1 >= (int)fAlgView.fNCachedDrifts) { d1 = fAlgView.fNCachedDrifts - 1; }
150 
151  int w0 = wire - rw;
152  if (w0 < 0) { w0 = 0; }
153  int w1 = wire + rw;
154  if (w1 >= (int)fAlgView.fNWires) { w1 = fAlgView.fNWires - 1; }
155 
156  float adc, max_adc = 0;
157  for (int w = w0; w <= w1; ++w) {
158  auto const* col = fAlgView.fWireDriftData[w].data();
159  for (int d = d0; d <= d1; ++d) {
160  adc = col[d];
161  if (adc > max_adc) { max_adc = adc; }
162  }
163  }
164 
165  return max_adc;
166 }
167 // ------------------------------------------------------
168 
169 //float img::DataProviderAlg::poolSum(int wire, int drift, size_t r) const
170 //{
171 // size_t rw = r, rd = r;
172 // if (!fDownscaleFullView) { rd *= fDriftWindow; }
173 //
174 // size_t didx = getDriftIndex(drift);
175 // int d0 = didx - rd; if (d0 < 0) { d0 = 0; }
176 // int d1 = didx + rd; if (d1 >= (int)fNCachedDrifts) { d1 = fNCachedDrifts - 1; }
177 //
178 // int w0 = wire - rw; if (w0 < 0) { w0 = 0; }
179 // int w1 = wire + rw; if (w1 >= (int)fNWires) { w1 = fNWires - 1; }
180 //
181 // float sum = 0;
182 // for (int w = w0; w <= w1; ++w)
183 // {
184 // auto const * col = fWireDriftData[w].data();
185 // for (int d = d0; d <= d1; ++d) { sum += col[d]; }
186 // }
187 //
188 // return sum;
189 //}
190 // ------------------------------------------------------
191 std::vector<float>
193  std::vector<float> const& adc,
194  size_t tick0) const
195 {
196  size_t kStop = dst_size;
197  std::vector<float> result(dst_size);
198  if (adc.size() < kStop) { kStop = adc.size(); }
199  for (size_t i = 0, k0 = 0; i < kStop; ++i, k0 += fDriftWindow) {
200  size_t k1 = k0 + fDriftWindow;
201 
202  float max_adc = adc[k0] * fAlgView.fLifetimeCorrFactors[k0 + tick0];
203  for (size_t k = k0 + 1; k < k1; ++k) {
204  float ak = adc[k] * fAlgView.fLifetimeCorrFactors[k + tick0];
205  if (ak > max_adc) max_adc = ak;
206  }
207  result[i] = max_adc;
208  }
209  scaleAdcSamples(result);
210  return result;
211 }
212 
213 std::vector<float>
215  std::vector<float> const& adc,
216  size_t tick0) const
217 {
218  size_t kStop = dst_size;
219  std::vector<float> result(dst_size);
220  if (adc.size() < kStop) { kStop = adc.size(); }
221  for (size_t i = 0, k0 = 0; i < kStop; ++i, k0 += fDriftWindow) {
222  size_t k1 = k0 + fDriftWindow;
223  size_t max_idx = k0;
224  float max_adc = adc[k0] * fAlgView.fLifetimeCorrFactors[k0 + tick0];
225  for (size_t k = k0 + 1; k < k1; ++k) {
226  float ak = adc[k] * fAlgView.fLifetimeCorrFactors[k + tick0];
227  if (ak > max_adc) {
228  max_adc = ak;
229  max_idx = k;
230  }
231  }
232 
233  size_t n = 1;
234  if (max_idx > 0) {
235  max_adc += adc[max_idx - 1] * fAlgView.fLifetimeCorrFactors[max_idx - 1 + tick0];
236  n++;
237  }
238  if (max_idx + 1 < adc.size()) {
239  max_adc += adc[max_idx + 1] * fAlgView.fLifetimeCorrFactors[max_idx + 1 + tick0];
240  n++;
241  }
242 
243  result[i] = max_adc / n;
244  }
245  scaleAdcSamples(result);
246  return result;
247 }
248 
249 std::vector<float>
251  std::vector<float> const& adc,
252  size_t tick0) const
253 {
254  size_t kStop = dst_size;
255  std::vector<float> result(dst_size);
256  if (adc.size() < kStop) { kStop = adc.size(); }
257  for (size_t i = 0, k0 = 0; i < kStop; ++i, k0 += fDriftWindow) {
258  size_t k1 = k0 + fDriftWindow;
259 
260  float sum_adc = 0;
261  for (size_t k = k0; k < k1; ++k) {
262  if (k + tick0 < fAlgView.fLifetimeCorrFactors.size())
263  sum_adc += adc[k] * fAlgView.fLifetimeCorrFactors[k + tick0];
264  }
265  result[i] = sum_adc * fDriftWindowInv;
266  }
267  scaleAdcSamples(result);
268  return result;
269 }
270 
271 std::optional<std::vector<float>>
272 img::DataProviderAlg::setWireData(std::vector<float> const& adc, size_t wireIdx) const
273 {
274  if (wireIdx >= fAlgView.fWireDriftData.size()) return std::nullopt;
275  auto& wData = fAlgView.fWireDriftData[wireIdx];
276 
277  if (fDownscaleFullView) {
278  if (!adc.empty()) { return downscale(wData.size(), adc, 0); }
279  else {
280  return std::nullopt;
281  }
282  }
283  else {
284  if (adc.empty()) { return std::nullopt; }
285  else if (adc.size() <= wData.size())
286  return adc;
287  else {
288  return std::vector<float>(adc.begin(), adc.begin() + wData.size());
289  }
290  }
291  return std::make_optional(wData);
292 }
293 // ------------------------------------------------------
294 
295 bool
297  detinfo::DetectorPropertiesData const& det_prop,
298  const std::vector<recob::Wire>& wires,
299  unsigned int plane,
300  unsigned int tpc,
301  unsigned int cryo)
302 {
303  mf::LogInfo("DataProviderAlg") << "Create image for cryo:" << cryo << " tpc:" << tpc
304  << " plane:" << plane;
305 
306  fCryo = cryo;
307  fTPC = tpc;
308  fPlane = plane;
309 
310  fAdcSumOverThr = 0;
311  fAdcAreaOverThr = 0;
312 
313  size_t nwires = fGeometry->Nwires(plane, tpc, cryo);
314  size_t ndrifts = det_prop.NumberTimeSamples();
315 
316  fAlgView = resizeView(clock_data, det_prop, nwires, ndrifts);
317 
318  auto const& channelStatus =
320 
321  bool allWrong = true;
322  for (auto const& wire : wires) {
323  auto wireChannelNumber = wire.Channel();
324  if (!channelStatus.IsGood(wireChannelNumber)) { continue; }
325 
326  size_t w_idx = 0;
327  for (auto const& id : fGeometry->ChannelToWire(wireChannelNumber)) {
328  if ((id.Plane == plane) && (id.TPC == tpc) && (id.Cryostat == cryo)) {
329  w_idx = id.Wire;
330 
331  auto adc = wire.Signal();
332  if (adc.size() < ndrifts) {
333  mf::LogWarning("DataProviderAlg") << "Wire ADC vector size lower than NumberTimeSamples.";
334  continue; // not critical, maybe other wires are OK, so continue
335  }
336  auto wire_data = setWireData(adc, w_idx);
337  if (!wire_data) {
338  mf::LogWarning("DataProviderAlg") << "Wire data not set.";
339  continue; // also not critical, try to set other wires
340  }
341  fAlgView.fWireDriftData[w_idx] = *wire_data;
342  for (auto v : adc) {
343  if (v >= fAdcSumThr) {
344  fAdcSumOverThr += v;
345  fAdcAreaOverThr++;
346  }
347  }
348 
349  fAlgView.fWireChannels[w_idx] = wireChannelNumber;
350  allWrong = false;
351  }
352  }
353  }
354  if (allWrong) {
355  mf::LogError("DataProviderAlg")
356  << "Wires data not set in the cryo:" << cryo << " tpc:" << tpc << " plane:" << plane;
357  return false;
358  }
359 
360  applyBlur();
361  addWhiteNoise();
363 
364  return true;
365 }
366 // ------------------------------------------------------
367 
368 float
370 {
371  val *= fAmplCalibConst[fPlane]; // prescale by plane-to-plane calibration factors
372 
373  if (val < fAdcMin) { val = fAdcMin; } // saturate
374  else if (val > fAdcMax) {
375  val = fAdcMax;
376  }
377 
378  return fAdcOffset +
379  fAdcScale *
380  (val - fAdcMin); // shift and scale to the output range, shift to the output min
381 }
382 // ------------------------------------------------------
383 void
385 {
386  float calib = fAmplCalibConst[fPlane];
387  auto* data = values.data();
388 
389  size_t k = 0, size4 = values.size() >> 2, size = values.size();
390  for (size_t i = 0; i < size4; ++i) // vectorize if you can
391  {
392  data[k] *= calib; // prescale by plane-to-plane calibration factors
393  data[k + 1] *= calib;
394  data[k + 2] *= calib;
395  data[k + 3] *= calib;
396 
397  if (data[k] < fAdcMin) { data[k] = fAdcMin; } // saturate min
398  if (data[k + 1] < fAdcMin) { data[k + 1] = fAdcMin; }
399  if (data[k + 2] < fAdcMin) { data[k + 2] = fAdcMin; }
400  if (data[k + 3] < fAdcMin) { data[k + 3] = fAdcMin; }
401 
402  if (data[k] > fAdcMax) { data[k] = fAdcMax; } // saturate max
403  if (data[k + 1] > fAdcMax) { data[k + 1] = fAdcMax; }
404  if (data[k + 2] > fAdcMax) { data[k + 2] = fAdcMax; }
405  if (data[k + 3] > fAdcMax) { data[k + 3] = fAdcMax; }
406 
407  data[k] = fAdcOffset +
408  fAdcScale *
409  (data[k] - fAdcMin); // shift and scale to the output range, shift to the output min
410  data[k + 1] = fAdcOffset + fAdcScale * (data[k + 1] - fAdcMin);
411  data[k + 2] = fAdcOffset + fAdcScale * (data[k + 2] - fAdcMin);
412  data[k + 3] = fAdcOffset + fAdcScale * (data[k + 3] - fAdcMin);
413 
414  k += 4;
415  }
416  while (k < size) {
417  data[k] = scaleAdcSample(data[k]);
418  ++k;
419  } // do the tail
420 }
421 // ------------------------------------------------------
422 
423 void
425 {
426  if (fBlurKernel.size() < 2) return;
427 
428  size_t margin_left = (fBlurKernel.size() - 1) >> 1,
429  margin_right = fBlurKernel.size() - margin_left - 1;
430 
431  std::vector<std::vector<float>> src(fAlgView.fWireDriftData.size());
432  for (size_t w = 0; w < fAlgView.fWireDriftData.size(); ++w) {
433  src[w] = fAlgView.fWireDriftData[w];
434  }
435 
436  for (size_t w = margin_left; w < fAlgView.fWireDriftData.size() - margin_right; ++w) {
437  for (size_t d = 0; d < fAlgView.fWireDriftData[w].size(); ++d) {
438  float sum = 0;
439  for (size_t i = 0; i < fBlurKernel.size(); ++i) {
440  sum += fBlurKernel[i] * src[w + i - margin_left][d];
441  }
442  fAlgView.fWireDriftData[w][d] = sum;
443  }
444  }
445 }
446 // ------------------------------------------------------
447 
448 // MUST give the same result as get_patch() in scripts/utils.py
449 bool
451  float drift,
452  size_t size_w,
453  size_t size_d,
454  std::vector<std::vector<float>>& patch) const
455 {
456  int halfSizeW = size_w / 2;
457  int halfSizeD = size_d / 2;
458 
459  int w0 = wire - halfSizeW;
460  int w1 = wire + halfSizeW;
461 
462  size_t sd = (size_t)(drift / fDriftWindow);
463  int d0 = sd - halfSizeD;
464  int d1 = sd + halfSizeD;
465 
466  int wsize = fAlgView.fWireDriftData.size();
467  for (int w = w0, wpatch = 0; w < w1; ++w, ++wpatch) {
468  auto& dst = patch[wpatch];
469  if ((w >= 0) && (w < wsize)) {
470  auto& src = fAlgView.fWireDriftData[w];
471  int dsize = src.size();
472  for (int d = d0, dpatch = 0; d < d1; ++d, ++dpatch) {
473  if ((d >= 0) && (d < dsize)) { dst[dpatch] = src[d]; }
474  else {
475  dst[dpatch] = fAdcZero;
476  }
477  }
478  }
479  else {
480  std::fill(dst.begin(), dst.end(), fAdcZero);
481  }
482  }
483 
484  return true;
485 }
486 
487 bool
489  float drift,
490  size_t size_w,
491  size_t size_d,
492  std::vector<std::vector<float>>& patch) const
493 {
494  int dsize = fDriftWindow * size_d;
495  int halfSizeW = size_w / 2;
496  int halfSizeD = dsize / 2;
497 
498  int w0 = wire - halfSizeW;
499  int w1 = wire + halfSizeW;
500 
501  int d0 = int(drift) - halfSizeD;
502  int d1 = int(drift) + halfSizeD;
503 
504  if (d0 < 0) d0 = 0;
505 
506  std::vector<float> tmp(dsize);
507  int wsize = fAlgView.fWireDriftData.size();
508  for (int w = w0, wpatch = 0; w < w1; ++w, ++wpatch) {
509  if ((w >= 0) && (w < wsize)) {
510  auto& src = fAlgView.fWireDriftData[w];
511  int src_size = src.size();
512  for (int d = d0, dpatch = 0; d < d1; ++d, ++dpatch) {
513  if ((d >= 0) && (d < src_size)) { tmp[dpatch] = src[d]; }
514  else {
515  tmp[dpatch] = fAdcZero;
516  }
517  }
518  }
519  else {
520  std::fill(tmp.begin(), tmp.end(), fAdcZero);
521  }
522  patch[wpatch] = downscale(patch[wpatch].size(), tmp, d0);
523  }
524 
525  return true;
526 }
527 // ------------------------------------------------------
528 
529 void
531 {
532  if (fNoiseSigma == 0) return;
533 
534  double effectiveSigma = scaleAdcSample(fNoiseSigma);
535  if (fDownscaleFullView) effectiveSigma /= fDriftWindow;
536 
537  CLHEP::RandGauss gauss(fRndEngine);
538  std::vector<double> noise(fAlgView.fNCachedDrifts);
539  for (auto& wire : fAlgView.fWireDriftData) {
540  gauss.fireArray(fAlgView.fNCachedDrifts, noise.data(), 0., effectiveSigma);
541  for (size_t d = 0; d < wire.size(); ++d) {
542  wire[d] += noise[d];
543  }
544  }
545 }
546 // ------------------------------------------------------
547 
548 void
550 {
551  if (fCoherentSigma == 0) return;
552 
553  double effectiveSigma = scaleAdcSample(fCoherentSigma);
554  if (fDownscaleFullView) effectiveSigma /= fDriftWindow;
555 
556  CLHEP::RandGauss gauss(fRndEngine);
557  std::vector<double> amps1(fAlgView.fWireDriftData.size());
558  std::vector<double> amps2(1 + (fAlgView.fWireDriftData.size() / 32));
559  gauss.fireArray(amps1.size(), amps1.data(), 1., 0.1); // 10% wire-wire ampl. variation
560  gauss.fireArray(amps2.size(), amps2.data(), 1., 0.1); // 10% group-group ampl. variation
561 
562  double group_amp = 1.0;
563  std::vector<double> noise(fAlgView.fNCachedDrifts);
564  for (size_t w = 0; w < fAlgView.fWireDriftData.size(); ++w) {
565  if ((w & 31) == 0) {
566  group_amp = amps2[w >> 5]; // div by 32
567  gauss.fireArray(fAlgView.fNCachedDrifts, noise.data(), 0., effectiveSigma);
568  } // every 32 wires
569 
570  auto& wire = fAlgView.fWireDriftData[w];
571  for (size_t d = 0; d < wire.size(); ++d) {
572  wire[d] += group_amp * amps1[w] * noise[d];
573  }
574  }
575 }
576 // ------------------------------------------------------
geo::GeometryCore const * fGeometry
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
fhicl::Atom< float > AdcMax
std::optional< std::vector< float > > setWireData(std::vector< float > const &adc, size_t wireIdx) const
std::vector< std::vector< float > > fWireDriftData
static QCString result
fhicl::Atom< float > CoherentSigma
T * get() const
Definition: ServiceHandle.h:63
std::string string
Definition: nybbler.cc:12
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
virtual ~DataProviderAlg()
virtual DataProviderAlgView resizeView(detinfo::DetectorClocksData const &clock_data, detinfo::DetectorPropertiesData const &det_prop, size_t wires, size_t drifts)
fhicl::Atom< unsigned int > DriftWindow
struct vector vector
std::vector< float > downscale(std::size_t dst_size, std::vector< float > const &adc, size_t tick0) const
std::vector< geo::WireID > ChannelToWire(raw::ChannelID_t const channel) const
Returns a list of wires connected to the specified TPC channel.
int16_t adc
Definition: CRTFragment.hh:202
DataProviderAlg(const fhicl::ParameterSet &pset)
std::vector< float > downscaleMaxMean(std::size_t dst_size, std::vector< float > const &adc, size_t tick0) const
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
unsigned int Plane() const
unsigned int Nwires(unsigned int p, unsigned int tpc=0, unsigned int cstat=0) const
Returns the total number of wires in the specified plane.
std::vector< float > fBlurKernel
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
Definition: StdUtils.h:92
double ElectronsFromADCPeak(double adc, unsigned short plane) const
fhicl::Sequence< float > BlurKernel
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
unsigned int MaxPlanes() const
Returns the largest number of planes among all TPCs in this detector.
fhicl::Atom< bool > DownscaleFullView
std::vector< float > downscaleMean(std::size_t dst_size, std::vector< float > const &adc, size_t tick0) const
static Config * config
Definition: config.cpp:1054
std::void_t< T > n
void scaleAdcSamples(std::vector< float > &values) const
std::vector< raw::ChannelID_t > fWireChannels
p
Definition: test.py:223
string tmp
Definition: languages.py:63
Q_UINT16 values[128]
General LArSoft Utilities.
float scaleAdcSample(float val) const
fhicl::Atom< float > AdcMin
DataProviderAlgView fAlgView
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
fhicl::Atom< bool > CalibrateLifetime
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)
def fill(s)
Definition: translator.py:93
Contains all timing reference information for the detector.
std::vector< float > fLifetimeCorrFactors
fhicl::Table< calo::CalorimetryAlg::Config > CalorimetryAlg
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
std::vector< float > fAmplCalibConst
Interface for experiment-specific channel quality info provider.
fhicl::Atom< std::string > DownscaleFn
bool patchFromDownsampledView(size_t wire, float drift, size_t size_w, size_t size_d, std::vector< std::vector< float >> &patch) const
fhicl::Atom< bool > CalibrateAmpl
EDownscaleMode fDownscaleMode
fhicl::Atom< float > OutMin
fhicl::Atom< float > OutMax
CLHEP::HepJamesRandom fRndEngine
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
LArSoft geometry interface.
Definition: ChannelGeo.h:16
size_t getDriftIndex(float drift) const
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
QTextStream & endl(QTextStream &s)
fhicl::Atom< float > NoiseSigma