38 #include "art_root_io/TFileService.h" 39 #include "canvas/Persistency/Common/FindOneP.h" 57 #include "tbb/concurrent_vector.h" 58 #include "tbb/parallel_for.h" 82 const std::vector<double>
93 std::vector<std::unique_ptr<reco_tool::ICandidateHitFinder>>
111 ,
fFillHists(pset.get<
bool>(
"FillHists",
false))
114 ,
fLongMaxHitsVec(pset.get<std::vector<int>>(
"LongMaxHits", std::vector<int>() = {25, 25, 25}))
116 pset.get<std::vector<int>>(
"LongPulseWidth", std::vector<int>() = {16, 16, 16}))
120 ,
fChi2NDF(pset.get<
double>(
"Chi2NDF"))
122 pset.get<std::vector<float>>(
"PulseHeightCuts", std::vector<float>() = {3.0, 3.0, 3.0}))
124 pset.get<std::vector<float>>(
"PulseWidthCuts", std::vector<float>() = {2.0, 1.5, 1.0}))
126 pset.get<std::vector<float>>(
"PulseRatioCuts", std::vector<float>() = {0.35, 0.40, 0.20}))
130 <<
"Cannot fill histograms when multiple threads configured, please set fFillHists to " 131 "false or change number of threads to 1\n";
133 async<art::InEvent>();
147 size_t planeIdx = hitFinderToolParamSet.
get<
size_t>(
"Plane");
150 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.");
208 fFirstChi2 = tfs->make<TH1F>(
"fFirstChi2",
"#chi^{2}", 10000, 0, 5000);
209 fChi2 = tfs->make<TH1F>(
"fChi2",
"#chi^{2}", 10000, 0, 5000);
223 TH1::AddDirectory(kFALSE);
253 tbb::concurrent_vector<hitstruct> hitstruct_vec;
254 tbb::concurrent_vector<hitstruct> filthitstruct_vec;
268 std::function<double(double, double, double, double, int, int)> chargeFunc =
269 [](
double peakMean,
double peakAmp,
double peakWidth,
double areaNorm,
int low,
int hi) {
270 return std::sqrt(2 * TMath::Pi()) * peakAmp * peakWidth / areaNorm;
278 [](
double peakMean,
double peakAmp,
double peakWidth,
double areaNorm,
int low,
int hi) {
280 for (
int sigPos = low; sigPos < hi; sigPos++)
281 charge += peakAmp * TMath::Gaus(sigPos, peakMean, peakWidth);
291 static_cast<std::size_t>(0),
292 wireVecHandle->size(),
293 [&](
size_t& wireIter) {
304 std::vector<geo::WireID> wids = geom->
ChannelToWire(channel);
320 for (
const auto& range : signalROI.
get_ranges()) {
331 fHitFinderToolVec.at(plane)->findHitCandidates(range, 0, channel, count, hitCandidateVec);
333 range, hitCandidateVec, mergedCandidateHitVec);
339 for (
auto& mergedCands : mergedCandidateHitVec) {
340 int startT = mergedCands.front().startTick;
341 int endT = mergedCands.back().stopTick;
346 if (endT - startT < 5)
continue;
353 int nGausForFit = mergedCands.size();
358 double chi2PerNDF(0.);
370 range.data(), mergedCands, peakParamsVec, chi2PerNDF, NDF);
373 if (!(chi2PerNDF < std::numeric_limits<double>::infinity())) {
389 int nHitsThisPulse = (endT - startT) / longPulseWidth;
393 longPulseWidth = (endT - startT) / nHitsThisPulse;
396 if (nHitsThisPulse * longPulseWidth < endT - startT) nHitsThisPulse++;
398 int firstTick = startT;
399 int lastTick =
std::min(firstTick + longPulseWidth, endT);
401 peakParamsVec.clear();
402 nGausForFit = nHitsThisPulse;
404 chi2PerNDF = chi2PerNDF >
fChi2NDF ? chi2PerNDF : -1.;
406 for (
int hitIdx = 0; hitIdx < nHitsThisPulse; hitIdx++) {
409 std::accumulate(range.begin() + firstTick, range.begin() + lastTick, 0.);
410 double peakSigma = (lastTick - firstTick) / 3.;
411 double peakAmp = 0.3989 * sumADC / peakSigma;
412 double peakMean = (firstTick + lastTick) / 2.;
424 peakParamsVec.push_back(peakParams);
427 firstTick = lastTick;
428 lastTick =
std::min(lastTick + longPulseWidth, endT);
439 std::vector<recob::Hit> filteredHitVec;
441 for (
const auto& peakParams : peakParamsVec) {
443 float peakAmp = peakParams.peakAmplitude;
444 float peakMean = peakParams.peakCenter;
445 float peakWidth = peakParams.peakSigma;
448 if (std::isnan(peakAmp)) {
449 std::cout <<
"**** hit peak amplitude is a nan! Channel: " << channel
450 <<
", start tick: " << startT <<
std::endl;
455 float peakAmpErr = peakParams.peakAmplitudeError;
456 float peakMeanErr = peakParams.peakCenterError;
457 float peakWidthErr = peakParams.peakSigmaError;
461 chargeFunc(peakMean, peakAmp, peakWidth,
fAreaNormsVec[plane], startT, endT);
464 std::sqrt(TMath::Pi()) * (peakAmpErr * peakWidthErr + peakWidthErr * peakAmpErr);
471 double sumADC = std::accumulate(sumStartItr, sumEndItr, 0.);
477 startT + roiFirstBinTick,
478 endT + roiFirstBinTick,
480 peakMean + roiFirstBinTick,
493 if (filteredHitCol) filteredHitVec.push_back(hitcreator.
copy());
505 if (filteredHitCol && !filteredHitVec.empty()) {
514 std::sort(filteredHitVec.begin(),
515 filteredHitVec.end(),
516 [](
const auto&
left,
const auto&
right) {
517 return left.PeakAmplitude() >
right.PeakAmplitude();
523 filteredHitVec.clear();
526 if (filteredHitVec.size() > 1) {
528 float largestPH = filteredHitVec.front().PeakAmplitude();
534 filteredHitVec.begin(),
535 filteredHitVec.end(),
536 [largestPH, threshold](
const auto&
hit) {
537 return hit.PeakAmplitude() < 8. &&
hit.PeakAmplitude() / largestPH < threshold;
541 if (smallHitItr != filteredHitVec.end())
542 filteredHitVec.resize(
std::distance(filteredHitVec.begin(), smallHitItr));
545 std::sort(filteredHitVec.begin(),
546 filteredHitVec.end(),
547 [](
const auto&
left,
const auto&
right) {
548 return left.PeakTime() <
right.PeakTime();
553 for (
const auto& filteredHit : filteredHitVec)
567 for (
size_t i = 0; i < hitstruct_vec.size(); i++) {
568 allHitCol.
emplace_back(hitstruct_vec[i].hit_tbb, hitstruct_vec[i].wire_tbb);
571 for (
size_t j = 0; j < filthitstruct_vec.size(); j++) {
572 filteredHitCol->
emplace_back(filthitstruct_vec[j].hit_tbb, filthitstruct_vec[j].wire_tbb);
578 if (filteredHitCol) {
recob::Hit const & copy() const
Returns the constructed wire.
std::unique_ptr< HitFilterAlg > fHitFilterAlg
algorithm used to filter out noise hits
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.
std::vector< geo::WireID > ChannelToWire(raw::ChannelID_t const channel) const
Returns a list of wires connected to the specified TPC channel.
const range_list_t & get_ranges() const
Returns the internal list of non-void ranges.
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.
art framework interface to geometry description
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.
bool getByLabel(std::string const &label, std::string const &instance, Handle< PROD > &result) const
unsigned int Nplanes(unsigned int tpc=0, unsigned int cstat=0) const
Returns the total number of wire planes in the specified TPC.
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.
double distance(double x1, double y1, double z1, double x2, double y2, double z2)
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
Declaration of signal hit object.
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
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
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.
QTextStream & endl(QTextStream &s)
std::vector< std::unique_ptr< reco_tool::ICandidateHitFinder > > fHitFinderToolVec
For finding candidate hits.