39 #include "art_root_io/TFileService.h" 58 #include "tbb/concurrent_vector.h" 59 #include "tbb/parallel_for.h" 83 const std::vector<double>
94 std::vector<std::unique_ptr<reco_tool::ICandidateHitFinder>>
112 ,
fFillHists(pset.get<
bool>(
"FillHists",
false))
115 ,
fLongMaxHitsVec(pset.get<std::vector<int>>(
"LongMaxHits", std::vector<int>() = {25, 25, 25}))
117 pset.get<std::vector<int>>(
"LongPulseWidth", std::vector<int>() = {16, 16, 16}))
121 ,
fChi2NDF(pset.get<
double>(
"Chi2NDF"))
123 pset.get<std::vector<float>>(
"PulseHeightCuts", std::vector<float>() = {3.0, 3.0, 3.0}))
125 pset.get<std::vector<float>>(
"PulseWidthCuts", std::vector<float>() = {2.0, 1.5, 1.0}))
127 pset.get<std::vector<float>>(
"PulseRatioCuts", std::vector<float>() = {0.35, 0.40, 0.20}))
131 <<
"Cannot fill histograms when multiple threads configured, please set fFillHists to " 132 "false or change number of threads to 1\n";
134 async<art::InEvent>();
145 for (
const std::string& hitFinderTool : hitFinderTools.
get_pset_names()) {
148 size_t planeIdx = hitFinderToolParamSet.
get<
size_t>(
"Plane");
151 art::make_tool<reco_tool::ICandidateHitFinder>(hitFinderToolParamSet);
179 if (input.size() == 0)
180 throw std::runtime_error(
181 "GausHitFinder::FillOutHitParameterVector ERROR! Input config vector has zero size.");
183 std::vector<double> output;
185 const unsigned int N_PLANES = geom->
Nplanes();
187 if (input.size() == 1)
188 output.resize(N_PLANES, input[0]);
189 else if (input.size() == N_PLANES)
192 throw std::runtime_error(
"GausHitFinder::FillOutHitParameterVector ERROR! Input config " 193 "vector size !=1 and !=N_PLANES.");
207 fFirstChi2 = tfs->make<TH1F>(
"fFirstChi2",
"#chi^{2}", 10000, 0, 5000);
208 fChi2 = tfs->make<TH1F>(
"fChi2",
"#chi^{2}", 10000, 0, 5000);
221 TH1::AddDirectory(kFALSE);
251 tbb::concurrent_vector<hitstruct> hitstruct_vec;
252 tbb::concurrent_vector<hitstruct> filthitstruct_vec;
266 std::function<double(double, double, double, double, int, int)> chargeFunc =
272 int ) {
return std::sqrt(2 * TMath::Pi()) * peakAmp * peakWidth / areaNorm; };
278 chargeFunc = [](
double peakMean,
285 for (
int sigPos = low; sigPos < hi; sigPos++)
286 charge += peakAmp * TMath::Gaus(sigPos, peakMean, peakWidth);
296 static_cast<std::size_t>(0),
297 wireVecHandle->size(),
298 [&](
size_t& wireIter) {
309 std::vector<geo::WireID> wids = geom->
ChannelToWire(channel);
327 static_cast<std::size_t>(0),
329 [&](
size_t& rangeIter) {
330 const auto& range = signalROI.
range(rangeIter);
342 range, 0, channel, count, hitCandidateVec);
344 range, hitCandidateVec, mergedCandidateHitVec);
350 for (
auto& mergedCands : mergedCandidateHitVec) {
351 int startT = mergedCands.front().startTick;
352 int endT = mergedCands.back().stopTick;
357 if (endT - startT < 5)
continue;
364 int nGausForFit = mergedCands.size();
369 double chi2PerNDF(0.);
381 range.data(), mergedCands, peakParamsVec, chi2PerNDF, NDF);
384 if (!(chi2PerNDF < std::numeric_limits<double>::infinity())) {
400 int nHitsThisPulse = (endT - startT) / longPulseWidth;
404 longPulseWidth = (endT - startT) / nHitsThisPulse;
407 if (nHitsThisPulse * longPulseWidth < endT - startT) nHitsThisPulse++;
409 int firstTick = startT;
410 int lastTick = std::min(firstTick + longPulseWidth, endT);
412 peakParamsVec.clear();
413 nGausForFit = nHitsThisPulse;
415 chi2PerNDF = chi2PerNDF >
fChi2NDF ? chi2PerNDF : -1.;
417 for (
int hitIdx = 0; hitIdx < nHitsThisPulse; hitIdx++) {
420 std::accumulate(range.begin() + firstTick, range.begin() + lastTick, 0.);
421 double peakSigma = (lastTick - firstTick) / 3.;
422 double peakAmp = 0.3989 * sumADC / peakSigma;
423 double peakMean = (firstTick + lastTick) / 2.;
435 peakParamsVec.push_back(peakParams);
438 firstTick = lastTick;
439 lastTick = std::min(lastTick + longPulseWidth, endT);
450 std::vector<recob::Hit> filteredHitVec;
452 for (
const auto& peakParams : peakParamsVec) {
454 float peakAmp = peakParams.peakAmplitude;
455 float peakMean = peakParams.peakCenter;
456 float peakWidth = peakParams.peakSigma;
459 if (std::isnan(peakAmp)) {
460 std::cout <<
"**** hit peak amplitude is a nan! Channel: " << channel
461 <<
", start tick: " << startT << std::endl;
466 float peakAmpErr = peakParams.peakAmplitudeError;
467 float peakMeanErr = peakParams.peakCenterError;
468 float peakWidthErr = peakParams.peakSigmaError;
472 chargeFunc(peakMean, peakAmp, peakWidth,
fAreaNormsVec[plane], startT, endT);
475 std::sqrt(TMath::Pi()) * (peakAmpErr * peakWidthErr + peakWidthErr * peakAmpErr);
482 double sumADC = std::accumulate(sumStartItr, sumEndItr, 0.);
488 startT + roiFirstBinTick,
489 endT + roiFirstBinTick,
491 peakMean + roiFirstBinTick,
504 if (filteredHitCol) filteredHitVec.push_back(hitcreator.
copy());
509 hitstruct
tmp{std::move(
hit), wire};
510 hitstruct_vec.push_back(std::move(
tmp));
516 if (filteredHitCol && !filteredHitVec.empty()) {
525 std::sort(filteredHitVec.begin(),
526 filteredHitVec.end(),
527 [](
const auto&
left,
const auto&
right) {
528 return left.PeakAmplitude() >
right.PeakAmplitude();
534 filteredHitVec.clear();
537 if (filteredHitVec.size() > 1) {
539 float largestPH = filteredHitVec.front().PeakAmplitude();
545 std::find_if(filteredHitVec.begin(),
546 filteredHitVec.end(),
547 [largestPH, threshold](
const auto&
hit) {
548 return hit.PeakAmplitude() < 8. &&
549 hit.PeakAmplitude() / largestPH < threshold;
553 if (smallHitItr != filteredHitVec.end())
554 filteredHitVec.resize(std::distance(filteredHitVec.begin(), smallHitItr));
557 std::sort(filteredHitVec.begin(),
558 filteredHitVec.end(),
559 [](
const auto&
left,
const auto&
right) {
560 return left.PeakTime() <
right.PeakTime();
565 for (
const auto& filteredHit : filteredHitVec)
567 hitstruct
tmp{std::move(filteredHit), wire};
568 filthitstruct_vec.push_back(std::move(
tmp));
579 for (
size_t i = 0; i < hitstruct_vec.size(); i++) {
580 allHitCol.
emplace_back(hitstruct_vec[i].hit_tbb, hitstruct_vec[i].wire_tbb);
583 for (
size_t j = 0; j < filthitstruct_vec.size(); j++) {
584 filteredHitCol->
emplace_back(filthitstruct_vec[j].hit_tbb, filthitstruct_vec[j].wire_tbb);
590 if (filteredHitCol) {
const datarange_t & range(size_t i) const
Returns the i-th non-void range (zero-based)
size_type n_ranges() const
Returns the internal list of non-void ranges.
constexpr auto const & right(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
std::vector< WireID > ChannelToWire(raw::ChannelID_t const channel) const
Returns a list of wires connected to the specified TPC channel.
recob::Hit const & copy() const
Returns the constructed wire.
std::unique_ptr< HitFilterAlg > fHitFilterAlg
algorithm used to filter out noise hits
Declaration of signal hit object.
void produce(art::Event &evt, art::ProcessingFrame const &) override
GausHitFinder(fhicl::ParameterSet const &pset, art::ProcessingFrame const &)
unsigned int PlaneID_t
Type for the ID number.
const std::vector< int > fLongPulseWidthVec
Sets width of hits used to describe long pulses.
static void declare_products(art::ProducesCollector &collector, std::string instance_name="", bool doWireAssns=true, bool doRawDigitAssns=true)
Declares the hit products we are going to fill.
std::unique_ptr< reco_tool::IPeakFitter > fPeakFitterTool
Perform fit to candidate peaks.
const int fAreaMethod
Type of area calculation.
const std::string fCalDataModuleLabel
const std::vector< float > fPulseWidthCuts
int TDCtick_t
Type representing a TDC tick.
Class managing the creation of a new recob::Hit object.
std::vector< std::string > get_pset_names() const
Helper functions to create a hit.
A class handling a collection of hits and its associations.
#define DEFINE_ART_MODULE(klass)
raw::ChannelID_t Channel() const
Returns the ID of the channel (or InvalidChannelID)
SharedProducer(fhicl::ParameterSet const &pset)
std::vector< double > FillOutHitParameterVector(const std::vector< double > &input)
std::atomic< size_t > fEventCount
T get(std::string const &key) const
const size_t fMaxMultiHit
maximum hits for multi fit
const std::vector< int > fLongMaxHitsVec
Maximum number hits on a really long pulse train.
const RegionsOfInterest_t & SignalROI() const
Returns the list of regions of interest.
void beginJob(art::ProcessingFrame const &) override
void emplace_back(recob::Hit &&hit, art::Ptr< recob::Wire > const &wire=art::Ptr< recob::Wire >(), art::Ptr< raw::RawDigit > const &digits=art::Ptr< raw::RawDigit >())
Adds the specified hit to the data collection.
PlaneID_t Plane
Index of the plane within its TPC.
void put_into(art::Event &)
Moves the data into an event.
Detector simulation of raw signals on wires.
ProducesCollector & producesCollector() noexcept
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
constexpr auto const & left(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
bool getByLabel(std::string const &label, std::string const &instance, Handle< PROD > &result) const
This provides an interface for tools which are tasked with fitting peaks on input waveforms...
const std::vector< float > fPulseRatioCuts
This provides an interface for tools which are tasked with finding candidate hits on input waveforms...
const std::vector< float > fPulseHeightCuts
maximum Chisquared / NDF allowed for a hit to be saved
unsigned int Nplanes(TPCID const &tpcid=tpc_zero) const
Returns the total number of planes in the specified TPC.
Declaration of basic channel signal object.
const std::string fAllHitsInstanceName
2D representation of charge deposited in the TDC/wire plane
const std::vector< double > fAreaNormsVec
factors for converting area to same units as peak height
static Globals * instance()
unsigned int ChannelID_t
Type representing the ID of a readout channel.
recob::Hit && move()
Prepares the constructed hit to be moved away.
art framework interface to geometry description
std::vector< std::unique_ptr< reco_tool::ICandidateHitFinder > > fHitFinderToolVec
For finding candidate hits.