37 #include "larevt/CalibrationDBI/Interface/ChannelStatusService.h" 38 #include "larevt/CalibrationDBI/Interface/ChannelStatusProvider.h" 57 (
"GausFitCache_CCHitFinderAlg")
66 <<
"CCHitFinderAlg: Using no-longer-valid fcl input: MinSigInd, MinSigCol, etc";
69 fMinRMS = pset.
get<std::vector<float>>(
"MinRMS");
85 if(
fMinPeak.size() != fMinRMS.size()) {
95 <<
"CCHitFinder algorithm is currently hard-coded to support at most " 96 <<
MaxGaussians <<
" bumps per region of interest, but " << fMaxBumps
97 <<
" have been requested.\n" 99 <<
". If this is not acceptable, increase CCHitFinderAlg::MaxGaussians" 100 <<
" value and recompile.";
109 if(fUWireRange.size() != 2 || fUTickRange.size() != 2 ||
110 fVWireRange.size() != 2 || fVTickRange.size() != 2 ||
111 fWWireRange.size() != 2 || fWTickRange.size() != 2) {
112 mf::LogError(
"CCHF")<<
"Invalid vector size for StudyHits. Must be 2";
132 unsigned short maxticks = 1000;
133 float *ticks =
new float[maxticks];
135 for(
unsigned short ii = 0; ii < maxticks; ++ii) {
138 float *signl =
new float[maxticks];
145 lariov::ChannelStatusProvider
const& channelStatus
148 for(
size_t wireIter = 0; wireIter < Wires.size(); wireIter++){
185 std::vector<float> signal(theWire.
Signal());
187 unsigned short nabove = 0;
188 unsigned short tstart = 0;
189 unsigned short maxtime = signal.size() - 2;
191 unsigned short mintime = 3;
192 for(
unsigned short time = 3; time < maxtime; ++time) {
198 for(
unsigned short time = mintime; time < maxtime; ++time) {
200 if(nabove == 0) tstart = time;
204 if(nabove > minSamples) {
207 <<
"Long RAT "<<nabove<<
" "<<maxticks
208 <<
" No signal on wire "<<
theWireNum<<
" after time "<<time;
209 if(nabove > maxticks)
break;
210 unsigned short npt = 0;
214 for(
unsigned short ii = tstart; ii < time; ++ii) {
215 signl[npt] = signal[ii];
216 adcsum += signl[npt];
217 if(signal[ii ] > signal[ii - 1] &&
218 signal[ii - 1] > signal[ii - 2] &&
219 signal[ii ] > signal[ii + 1] &&
220 signal[ii + 1] > signal[ii + 2])
bumps.push_back(npt);
229 StoreHits(tstart, npt, WireInfo, adcsum);
234 unsigned short nHitsFit =
bumps.size();
235 unsigned short nfit = 0;
238 bool HitStored =
false;
242 while(nHitsFit <= nMaxFit) {
244 FitNG(nHitsFit, npt, ticks, signl);
251 StoreHits(tstart, npt, WireInfo, adcsum);
260 if( !HitStored && npt < maxticks) {
263 StoreHits(tstart, npt, WireInfo, adcsum);
283 unsigned short npt,
float const*ticks,
float const*signl,
284 std::array<double, 3>& params,
285 std::array<double, 3>& paramerrors,
293 const float time_shift = (ticks[npt - 1] + ticks[0]) / 2.F;
296 for (
size_t i = 0; i < npt; ++i) {
299 <<
"Non-positive charge encountered. Backing up to ROOT fit.";
303 fitter.
add(ticks[i] - time_shift, signl[i]);
309 LOG_DEBUG(
"CCHitFinderAlg") <<
"Fast Gaussian fit failed.";
316 chidof = chi2 / fitter.
NDF();
319 params[1] += time_shift;
324 for (
double&
par: paramerrors)
par *= std::sqrt(chidof);
332 float *ticks,
float *signl)
336 dof = npt - 3 * nGaus;
341 if(
bumps.size() == 0)
return;
344 std::vector<double> partmp;
345 std::vector<double> partmperr;
355 std::array<double, 3> params, paramerrors;
362 std::copy(params.begin(), params.end(), partmp.begin());
364 std::copy(paramerrors.begin(), paramerrors.end(), partmperr.begin());
366 else bNeedROOTfit =
true;
379 std::stringstream numConv;
380 std::string eqn =
"gaus";
381 if(nGaus > 1) eqn =
"gaus(0)";
382 for(
unsigned short ii = 3; ii < nGaus*3; ii+=3){
383 eqn.append(
" + gaus(");
386 eqn.append(numConv.str());
390 std::unique_ptr<TF1> Gn(
new TF1(
"gn",eqn.c_str()));
394 TGraph *fitn =
new TGraph(npt, ticks, signl);
400 for(
unsigned short ii = 0; ii <
bumps.size(); ++ii) {
401 unsigned short index = ii * 3;
402 unsigned short bumptime =
bumps[ii];
403 double amp = signl[bumptime];
404 Gn->SetParameter(index , amp);
405 Gn->SetParLimits(index, 0., 9999.);
406 Gn->SetParameter(index + 1, (
double)bumptime);
407 Gn->SetParLimits(index + 1, 0, (
double)npt);
409 Gn->SetParLimits(index + 2, 1., 3*(
double)
fMinRMS[thePlane]);
417 for(
unsigned short ii =
bumps.size(); ii < nGaus; ++ii) {
420 unsigned short imbig = 0;
421 for(
unsigned short jj = 0; jj < npt; ++jj) {
422 float diff = signl[jj] - Gn->Eval((Double_t)jj, 0, 0, 0);
434 unsigned short index = ii * 3;
435 Gn->SetParameter(index , (
double)big);
436 Gn->SetParLimits(index, 0., 9999.);
437 Gn->SetParameter(index + 1, (
double)imbig);
438 Gn->SetParLimits(index + 1, 0, (
double)npt);
440 Gn->SetParLimits(index + 2, 1., 5*(
double)
fMinRMS[thePlane]);
446 fitn->Fit(&*Gn,
"WNQB");
448 for(
unsigned short ipar = 0; ipar < 3 * nGaus; ++ipar) {
449 partmp.push_back(Gn->GetParameter(ipar));
450 partmperr.push_back(Gn->GetParError(ipar));
461 std::vector< std::pair<unsigned short, unsigned short> > times;
463 for(
unsigned short ii = 0; ii < nGaus; ++ii) {
464 unsigned short index = ii * 3;
465 times.push_back(std::make_pair(partmp[index + 1],ii));
467 std::sort(times.begin(), times.end());
470 for(
unsigned short ii = 0; ii < nGaus; ++ii) {
471 if(times[ii].second != ii) {
478 std::vector<double> partmpt;
479 std::vector<double> partmperrt;
480 for(
unsigned short ii = 0; ii < nGaus; ++ii) {
481 unsigned short index = times[ii].second * 3;
482 partmpt.push_back(partmp[index]);
483 partmpt.push_back(partmp[index+1]);
484 partmpt.push_back(partmp[index+2]);
485 partmperrt.push_back(partmperr[index]);
486 partmperrt.push_back(partmperr[index+1]);
487 partmperrt.push_back(partmperr[index+2]);
490 partmperr = partmperrt;
506 for(
unsigned short ii = 0; ii < nGaus; ++ii) {
507 unsigned short index = ii * 3;
509 short fittime = partmp[index + 1];
510 if(fittime < 0 || fittime > npt - 1) {
520 float rms = partmp[index + 2];
521 if(rms < 0.5 *
fMinRMS[thePlane] || rms > 5 *
fMinRMS[thePlane]) {
526 for(
unsigned short jj = 0; jj < nGaus; ++jj) {
527 if(jj == ii)
continue;
528 unsigned short jndex = jj * 3;
529 float timediff = std::abs(partmp[jndex + 1] - partmp[index + 1]);
552 float *ticks,
float *signl)
557 for(
unsigned short ii = 0; ii < npt; ++ii) {
559 sumST += signl[ii] * ticks[ii];
561 float mean = sumST / sumS;
563 for(
unsigned short ii = 0; ii < npt; ++ii) {
564 float arg = ticks[ii] -
mean;
565 rms += signl[ii] * arg * arg;
567 rms = std::sqrt(rms / sumS);
568 float amp = sumS / (
Sqrt2Pi * rms);
580 float meanerr = std::sqrt(1/sumS);
581 float rmserr = 0.2 * rms;
583 parerr.push_back(meanerr);
599 size_t nhits =
par.size() / 3;
603 <<
"Too many hits: existing " <<
allhits.size() <<
" plus new " << nhits
604 <<
" beyond the maximum " <<
allhits.max_size();
608 if(nhits == 0)
return;
613 const float loTime = TStart;
614 const float hiTime = TStart + npt;
618 for(
size_t hit = 0;
hit < nhits; ++
hit) {
619 const unsigned short index = 3 *
hit;
622 for(
size_t hit = 0;
hit < nhits; ++
hit) {
623 const size_t index = 3 *
hit;
625 const float charge_err =
SqrtPi 626 * (
parerr[index] * par[index + 2] + par[index] *
parerr[index + 2]);
632 par[index + 1] + TStart,
637 adcsum * charge / gsum,
667 float *ticks,
float *signl,
unsigned short tstart) {
683 for(
unsigned short ipl = 0; ipl < 3; ++ipl) {
739 for(
unsigned short ii = 0; ii < npt; ++ii) {
740 if(signl[ii] > big) {
764 for(
unsigned short ii = 0; ii < npt; ++ii) {
766 sumt += signl[ii] * ii;
768 float aveb = sumt / sum;
771 for(
unsigned short ii = 0; ii < npt; ++ii) {
772 float dbin = (float)ii - aveb;
773 sumt += signl[ii] * dbin * dbin;
783 if(
par.size() == 3) {
796 std::cout<<
"Check lo and hi W/T for each plane"<<std::endl;
797 for(
unsigned short ipl = 0; ipl < 3; ++ipl) {
801 std::cout<<
" ipl nRAT bCnt bChi bRMS hCnt hRMS dT/dW New_ChiNorm"<<std::endl;
802 for(
unsigned short ipl = 0; ipl < 3; ++ipl) {
811 <<std::setw(7)<<std::fixed<<std::setprecision(2)<<
bumpChi[ipl]
813 <<std::setw(7)<<
hitCnt[ipl]
814 <<std::setw(7)<<std::setprecision(1)<<
hitRMS[ipl]
816 <<std::setw(7)<<std::setprecision(2)
821 std::cout<<
"nRAT is the number of Regions Above Threshold (RAT) used in the study.\n";
822 std::cout<<
"bCnt is the number of single bumps that were successfully fitted \n";
823 std::cout<<
"bChi is the average chisq/DOF of the first fit\n";
824 std::cout<<
"bRMS is the average calculated RMS of the bumps\n";
825 std::cout<<
"hCnt is the number of RATs that have a single hit\n";
826 std::cout<<
"hRMS is the average RMS from the Gaussian fit -> use this value for fMinRMS[plane] in the fcl file\n";
827 std::cout<<
"dTdW is the slope of the track\n";
828 std::cout<<
"New_ChiNorm is the recommended values of ChiNorm that should be used in the fcl file\n";
845 if (nGaus == 0)
return;
846 MultiGausFits.resize(nGaus);
847 std::fill(MultiGausFits.begin(), MultiGausFits.end(), 0);
853 ++MultiGausFits[
std::min(nGaus, (
unsigned int) MultiGausFits.size()) - 1];
void RunCCHitFinder(std::vector< recob::Wire > const &Wires)
constexpr auto const & right(const_AssnsIter< L, R, D, Dir > const &a, const_AssnsIter< L, R, D, Dir > const &b)
bool add(Data_t x, Data_t y, Data_t sy=Data_t(1.0))
Clears all the input statistics.
void AddMultiGaus(unsigned int nGaus)
float fChiSplit
Estimated noise error on the Signal.
static constexpr float SqrtPi
void FitNG(unsigned short nGaus, unsigned short npt, float *ticks, float *signl)
Encapsulate the construction of a single cyostat.
exchange data about the originating wire
std::vector< short > fWTickRange
std::vector< short > fWWireRange
virtual void reconfigure(fhicl::ParameterSet const &pset)
raw::ChannelID_t theChannel
std::vector< float > loWire
void StoreHits(unsigned short TStart, unsigned short npt, HitChannelInfo_t info, float adcsum)
void StudyHits(unsigned short flag, unsigned short npt=0, float *ticks=0, float *signl=0, unsigned short tstart=0)
std::vector< float > hiWire
std::vector< unsigned short > bumps
std::vector< float > fChiNorms
std::vector< float > bumpRMS
std::vector< short > fUWireRange
bool fUseFastFit
whether to attempt using a fast fit on single gauss.
std::vector< short > fVWireRange
CCHitFinderAlg(fhicl::ParameterSet const &pset)
std::vector< geo::WireID > ChannelToWire(raw::ChannelID_t const channel) const
Returns a list of wires connected to the specified TPC channel.
std::vector< short > fVTickRange
FitStats_t TriedFitStats
counts of the tried fits
SigType_t SignalType(geo::PlaneID const &pid) const
Returns the type of signal on the channels of specified TPC plane.
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
Classes performing simple fits.
geo::View_t View() const
Returns the view the channel belongs to.
A set of TF1 linear sum of base functions (Gaussians)
virtual bool FillResults(FitParameters_t ¶ms, FitMatrix_t &Xmat, Data_t &det, FitMatrix_t &Smat) const override
Fills the specified parameters.
std::vector< recob::Hit > allhits
art::ServiceHandle< geo::Geometry > geom
raw::ChannelID_t Channel() const
Returns the ID of the channel (or InvalidChannelID)
T get(std::string const &key) const
void Reset(unsigned int nGaus)
void fill(const art::PtrVector< recob::Hit > &hits, int only_plane)
std::vector< float > hiTime
virtual int NDF() const override
Returns the degrees of freedom in the determination of the fit.
bool has_key(std::string const &key) const
The geometry of one entire detector, as served by art.
std::vector< int > bumpCnt
Detector simulation of raw signals on wires.
#define LOG_WARNING(category)
std::vector< float > Signal() const
Return a zero-padded full length vector filled with RoI signal.
std::vector< float > loTime
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
static bool FastGaussianFit(unsigned short npt, float const *ticks, float const *signl, std::array< double, 3 > ¶ms, std::array< double, 3 > ¶merrors, float &chidof)
Performs a "fast" fit.
double mean(const std::vector< short > &wf, size_t start, size_t nsample)
Encapsulate the construction of a single detector plane.
unsigned short theWireNum
std::vector< float > fMinPeak
Class holding the deconvoluted signals from a channel.
std::vector< int > hitCnt
static constexpr unsigned int MaxGaussians
static constexpr float Sqrt2Pi
virtual Data_t ChiSquare() const override
Returns the of the original fit.
unsigned short fMaxXtraHits
std::vector< short > fUTickRange
void MakeCrudeHit(unsigned short npt, float *ticks, float *signl)
std::vector< float > hitRMS
std::vector< int > RATCnt
FitStats_t FinalFitStats
counts of the good fits
std::vector< double > parerr
HitChannelInfo_t(recob::Wire const *w, geo::WireID wid, geo::Geometry const &geom)
std::vector< float > fMinRMS
std::vector< float > bumpChi
std::vector< double > par
art framework interface to geometry description
Encapsulate the construction of a single detector plane.