11 #include "art/Framework/Services/Registry/ServiceHandle.h"
12 #include "art/Utilities/ToolMacros.h"
13 #include "art/Utilities/make_tool.h"
14 #include "art/Utilities/Globals.h"
15 #include "art_root_io/TFileService.h"
16 #include "cetlib_except/exception.h"
43 Waveform::const_iterator,
44 Waveform::const_iterator,
45 Waveform::const_iterator,
46 Waveform::const_iterator,
47 Waveform::const_iterator,
54 Waveform::const_iterator,
61 using MaxMinPair = std::pair<Waveform::const_iterator, Waveform::const_iterator>;
63 Waveform::const_iterator,
64 Waveform::const_iterator,
65 Waveform::const_iterator>;
69 Waveform::const_iterator,
76 Waveform::const_iterator)
const;
78 Waveform::const_iterator)
const;
81 Waveform::const_iterator
findStartTick(Waveform::const_iterator,
82 Waveform::const_iterator)
const;
83 Waveform::const_iterator
findStopTick(Waveform::const_iterator, Waveform::const_iterator)
const;
127 : fPlane(pset.
get<size_t>(
"Plane", 0))
128 , fDilationThreshold(pset.
get<float>(
"DilationThreshold", 4.))
129 , fDilationFraction(pset.
get<float>(
"DilationFraction", 0.75))
130 , fErosionFraction(pset.
get<float>(
"ErosionFraction", 0.2))
131 , fMinDeltaTicks(pset.
get<int>(
"MinDeltaTicks", 0))
132 , fMinDeltaPeaks(pset.
get<float>(
"MinDeltaPeaks", 0.025))
133 , fMinHitHeight(pset.
get<float>(
"MinHitHeight", 1.0))
134 , fNumInterveningTicks(pset.
get<size_t>(
"NumInterveningTicks", 6))
135 , fStructuringElement(pset.
get<int>(
"StructuringElement", 20))
136 , fOutputHistograms(pset.
get<
bool>(
"OutputHistograms",
false))
137 , fOutputWaveforms(pset.
get<
bool>(
"OutputWaveforms",
false))
138 , fFitNSigmaFromCenter(pset.
get<float>(
"FitNSigmaFromCenter", 5.))
143 throw art::Exception(art::errors::Configuration)
144 <<
"Cannot fill histograms when multiple threads configured, please set "
145 "fOutputHistograms to false or change number of threads to 1\n";
149 throw art::Exception(art::errors::Configuration)
150 <<
"Cannot write output waveforms when multiple threads configured, please set "
151 "fOutputHistograms to false or change number of threads to 1\n";
156 art::make_tool<reco_tool::IWaveformTool>(pset.get<fhicl::ParameterSet>(
"WaveformAlgs"));
166 art::ServiceHandle<art::TFileService>
tfs;
174 dir.make<TH1F>(Form(
"DStopStart_%1zu",
fPlane),
";Delta Stop/Start;", 100, 0., 100.);
176 dir.make<TH1F>(Form(
"DMaxTMinT_%1zu",
fPlane),
";Delta Max/Min Tick;", 100, 0., 100.);
178 dir.make<TH1F>(Form(
"DMaxDMinD_%1zu",
fPlane),
";Delta Max/Min Deriv;", 200, 0., 100.);
180 dir.make<TH1F>(Form(
"MaxErosion_%1zu",
fPlane),
";Max Erosion;", 200, -50., 150.);
182 dir.make<TH1F>(Form(
"MaxDilation_%1zu",
fPlane),
";Max Dilation;", 200, -50., 150.);
184 dir.make<TH1F>(Form(
"MaxDilEroRat_%1zu",
fPlane),
";Max Dil/Ero;", 200, -1., 1.);
192 const recob::Wire::RegionsOfInterest_t::datarange_t& dataRange,
193 const size_t roiStartTick,
194 const size_t channel,
195 const size_t eventCount,
204 const Waveform& waveform = dataRange.data();
207 fWaveformTool->triangleSmooth(rawDerivativeVec, derivativeVec);
239 for (
auto& hc : hitCandidateVec) {
241 if (startCand >= 0) hc.startTick = std::max(hc.startTick,
size_t(startCand));
248 for (
auto& hitCandidate : hitCandidateVec) {
249 size_t centerIdx = hitCandidate.hitCenter;
251 hitCandidate.hitHeight = waveform.at(centerIdx);
258 size_t plane = wids[0].Plane;
259 size_t cryo = wids[0].Cryostat;
260 size_t tpc = wids[0].TPC;
261 size_t wire = wids[0].Wire;
267 Form(
"Event%04zu/c%1zuT%1zuP%1zu/Wire_%05zu", eventCount, cryo, tpc, plane, wire));
269 size_t waveformSize = waveform.size();
270 size_t waveStart = dataRange.begin_index();
273 dir.make<TProfile>(Form(
"HWfm_%03zu_roiStart-%05zu",
fChannelCnt, waveStart),
280 TProfile* derivHist =
281 dir.make<TProfile>(Form(
"HDer_%03zu_roiStart-%05zu",
fChannelCnt, waveStart),
288 TProfile* erosionHist =
289 dir.make<TProfile>(Form(
"HEro_%03zu_roiStart-%05zu",
fChannelCnt, waveStart),
296 TProfile* dilationHist =
297 dir.make<TProfile>(Form(
"HDil_%03zu_roiStart-%05zu",
fChannelCnt, waveStart),
304 TProfile* candHitHist =
305 dir.make<TProfile>(Form(
"HCan_%03zu_roiStart-%05zu",
fChannelCnt, waveStart),
312 TProfile* maxDerivHist =
313 dir.make<TProfile>(Form(
"HMax_%03zu_roiStart-%05zu",
fChannelCnt, waveStart),
320 TProfile* strtStopHist =
321 dir.make<TProfile>(Form(
"HSSS_%03zu_roiStart-%05zu",
fChannelCnt, waveStart),
330 for (
size_t idx = 0; idx < waveform.size(); idx++) {
331 waveHist->Fill(roiStartTick + idx, waveform.at(idx));
332 derivHist->Fill(roiStartTick + idx, derivativeVec.at(idx));
333 erosionHist->Fill(roiStartTick + idx, erosionVec.at(idx));
334 dilationHist->Fill(roiStartTick + idx, dilationVec.at(idx));
338 for (
const auto& hitCandidate : hitCandidateVec) {
339 candHitHist->Fill(hitCandidate.hitCenter, hitCandidate.hitHeight);
340 maxDerivHist->Fill(hitCandidate.maxTick, hitCandidate.maxDerivative);
341 maxDerivHist->Fill(hitCandidate.minTick, hitCandidate.minDerivative);
342 strtStopHist->Fill(hitCandidate.startTick, waveform.at(hitCandidate.startTick));
343 strtStopHist->Fill(hitCandidate.stopTick, waveform.at(hitCandidate.stopTick));
352 for (
const auto& hitCandidate : hitCandidateVec) {
353 fDStopStartHist->Fill(hitCandidate.stopTick - hitCandidate.startTick, 1.);
359 Waveform::const_iterator maxDilationItr =
360 std::max_element(dilationVec.begin(), dilationVec.end());
361 Waveform::const_iterator maxErosionItr =
362 std::max_element(erosionVec.begin(), erosionVec.end());
366 if (
std::abs(*maxDilationItr) > 0.) dilEroRat = *maxErosionItr / *maxDilationItr;
378 Waveform::const_iterator derivStopItr,
379 Waveform::const_iterator erosionStartItr,
380 Waveform::const_iterator erosionStopItr,
381 Waveform::const_iterator dilationStartItr,
382 Waveform::const_iterator dilationStopItr,
383 const size_t roiStartTick,
384 float dilationThreshold,
391 int ticksInInputWaveform =
std::distance(derivStartItr, derivStopItr);
396 Waveform::const_iterator maxItr = std::max_element(dilationStartItr, dilationStopItr);
397 float maxVal = *maxItr;
400 if (maxVal < dilationThreshold)
return;
406 Waveform::const_iterator firstDerItr = derivStartItr + maxBin;
407 Waveform::const_iterator erosionItr = erosionStartItr + maxBin;
409 float firstDerivValue = -1.;
413 while (firstDerItr != derivStartItr) {
415 if (*erosionItr-- < erosionCutValue) {
419 if (*firstDerItr * firstDerivValue <= 0. && firstDerivValue > 0.)
break;
422 firstDerivValue = *firstDerItr--;
426 int hitRegionStart =
std::distance(derivStartItr, firstDerItr);
429 Waveform::const_iterator lastDerItr = derivStartItr + maxBin;
432 float lastDerivValue = 1.;
434 erosionItr = erosionStartItr + maxBin;
437 while (lastDerItr != derivStopItr) {
438 if (*erosionItr++ <= erosionCutValue) {
441 if (*lastDerItr * lastDerivValue <= 0. && lastDerivValue < 0.)
break;
444 lastDerivValue = *lastDerItr++;
448 int hitRegionStop =
std::distance(derivStartItr, lastDerItr);
453 derivStartItr + hitRegionStart,
455 erosionStartItr + hitRegionStart,
457 dilationStartItr + hitRegionStart,
464 derivStartItr + hitRegionStop,
465 roiStartTick + hitRegionStart,
474 erosionStartItr + hitRegionStop,
476 dilationStartItr + hitRegionStop,
478 roiStartTick + hitRegionStop,
487 Waveform::const_iterator stopItr,
488 const size_t roiStartTick,
490 float dPeakThreshold,
499 startItr, stopItr, dTicksThreshold, dPeakThreshold, candHitParamsVec)) {
502 for (
const auto& tuple : candHitParamsVec) {
506 Waveform::const_iterator candStartItr = std::get<0>(tuple);
507 Waveform::const_iterator maxItr = std::get<1>(tuple);
508 Waveform::const_iterator minItr = std::get<2>(tuple);
509 Waveform::const_iterator candStopItr = std::get<3>(tuple);
511 Waveform::const_iterator peakItr =
512 std::min_element(maxItr, minItr, [](
const auto&
left,
const auto&
right) {
513 return std::fabs(
left) < std::fabs(
right);
523 size_t hitCandidateStartTick = roiStartTick +
std::distance(startItr, candStartItr);
525 if (!hitCandidateVec.empty()) {
526 int deltaTicks = hitCandidateStartTick - hitCandidateVec.back().stopTick;
528 if (deltaTicks > 0) {
529 hitCandidateStartTick -= deltaTicks / 2;
530 hitCandidateVec.back().stopTick += deltaTicks / 2;
534 hitCandidate.
startTick = hitCandidateStartTick;
538 hitCandidate.
maxDerivative = maxItr != stopItr ? *maxItr : 0.;
539 hitCandidate.
minDerivative = minItr != stopItr ? *minItr : 0.;
545 hitCandidateVec.push_back(hitCandidate);
640 Waveform::const_iterator stopItr,
642 float dPeakThreshold,
646 bool foundCandidate(
false);
657 MaxMinPair minMaxPair = std::minmax_element(startItr, stopItr);
659 Waveform::const_iterator maxItr = minMaxPair.second;
660 Waveform::const_iterator minItr = minMaxPair.first;
663 if (std::fabs(*maxItr) > std::fabs(*minItr))
669 float range = *maxItr - *minItr;
671 if (deltaTicks < 2)
return foundCandidate;
674 if (deltaTicks >= dTicksThreshold && range > dPeakThreshold) foundCandidate =
true;
678 Waveform::const_iterator candStartItr =
findStartTick(maxItr, startItr);
682 Waveform::const_iterator candStopItr =
findStopTick(minItr, stopItr);
686 startItr, candStartItr, dTicksThreshold, dPeakThreshold, candHitParamsVec);
689 candHitParamsVec.emplace_back(candStartItr, maxItr, minItr, candStopItr);
693 candStopItr, stopItr, dTicksThreshold, dPeakThreshold, candHitParamsVec);
695 return foundCandidate || prevTicks || postTicks;
700 const recob::Wire::RegionsOfInterest_t::datarange_t& rangeData,
705 if (hitCandidateVec.empty())
return;
713 size_t lastStopTick = hitCandidateVec.front().stopTick;
716 for (
const auto& hitCandidate : hitCandidateVec) {
721 !groupedHitVec.empty()) {
722 mergedHitsVec.emplace_back(groupedHitVec);
724 groupedHitVec.clear();
728 groupedHitVec.emplace_back(hitCandidate);
730 lastStopTick = hitCandidate.stopTick;
735 if (!groupedHitVec.empty()) mergedHitsVec.emplace_back(groupedHitVec);
740 ICandidateHitFinder::Waveform::const_iterator
742 Waveform::const_iterator stopItr)
const
745 Waveform::const_iterator lastItr = maxItr;
749 while ((lastItr + 1) != stopItr) {
750 if (*(lastItr + 1) > *lastItr)
break;
759 ICandidateHitFinder::Waveform::const_iterator
761 Waveform::const_iterator startItr)
const
764 Waveform::const_iterator lastItr = minItr;
769 while ((lastItr - 1) != startItr) {
770 if (*(lastItr - 1) < *lastItr)
break;
779 ICandidateHitFinder::Waveform::const_iterator
781 Waveform::const_iterator startItr)
const
783 Waveform::const_iterator lastItr = maxItr;
792 Waveform::const_iterator loopItr = lastItr - 1;
794 while (loopItr != startItr) {
796 if (*loopItr < 0. || !(*loopItr < *lastItr))
break;
807 ICandidateHitFinder::Waveform::const_iterator
809 Waveform::const_iterator stopItr)
const
811 Waveform::const_iterator lastItr = minItr;
816 Waveform::const_iterator loopItr = lastItr + 1;
818 while (loopItr != stopItr) {
820 if (*loopItr > 0. || !(*loopItr > *lastItr))
break;
Utilities related to art service access.
const std::string instance
std::vector< geo::WireID > ChannelToWire(raw::ChannelID_t const channel) const
Returns a list of wires connected to the specified TPC channel.
double distance(geo::Point_t const &point, CathodeDesc_t const &cathode)
Returns the distance of a point from the cathode.
Description of geometry of one entire detector.
This provides an interface for tools which are tasked with finding candidate hits on input waveforms...
art::ServiceHandle< art::TFileService > tfs
art framework interface to geometry description