51 (
"GausFitCache_CCHitFinderAlg")
60 <<
"CCHitFinderAlg: Using no-longer-valid fcl input: MinSigInd, MinSigCol, etc";
63 fMinRMS = pset.
get<std::vector<float>>(
"MinRMS");
79 if(
fMinPeak.size() != fMinRMS.size()) {
89 <<
"CCHitFinder algorithm is currently hard-coded to support at most " 90 <<
MaxGaussians <<
" bumps per region of interest, but " << fMaxBumps
91 <<
" have been requested.\n" 93 <<
". If this is not acceptable, increase CCHitFinderAlg::MaxGaussians" 94 <<
" value and recompile.";
103 if(fUWireRange.size() != 2 || fUTickRange.size() != 2 ||
104 fVWireRange.size() != 2 || fVTickRange.size() != 2 ||
105 fWWireRange.size() != 2 || fWTickRange.size() != 2) {
106 mf::LogError(
"CCHF")<<
"Invalid vector size for StudyHits. Must be 2";
126 unsigned short maxticks = 1000;
127 float *
ticks =
new float[maxticks];
129 for(
unsigned short ii = 0; ii < maxticks; ++ii) {
132 float *signl =
new float[maxticks];
142 for(
size_t wireIter = 0; wireIter < Wires.size(); wireIter++){
179 std::vector<float> signal(theWire.
Signal());
181 unsigned short nabove = 0;
182 unsigned short tstart = 0;
183 unsigned short maxtime = signal.size() - 2;
185 unsigned short mintime = 3;
192 for(
unsigned short time = mintime;
time < maxtime; ++
time) {
194 if(nabove == 0) tstart =
time;
198 if(nabove > minSamples) {
201 <<
"Long RAT "<<nabove<<
" "<<maxticks
203 if(nabove > maxticks)
break;
204 unsigned short npt = 0;
208 for(
unsigned short ii = tstart; ii < time; ++ii) {
209 signl[npt] = signal[ii];
210 adcsum += signl[npt];
211 if(signal[ii ] > signal[ii - 1] &&
212 signal[ii - 1] > signal[ii - 2] &&
213 signal[ii ] > signal[ii + 1] &&
214 signal[ii + 1] > signal[ii + 2])
bumps.push_back(npt);
223 StoreHits(tstart, npt, WireInfo, adcsum);
228 unsigned short nHitsFit =
bumps.size();
229 unsigned short nfit = 0;
232 bool HitStored =
false;
236 while(nHitsFit <= nMaxFit) {
238 FitNG(nHitsFit, npt, ticks, signl);
245 StoreHits(tstart, npt, WireInfo, adcsum);
254 if( !HitStored && npt < maxticks) {
257 StoreHits(tstart, npt, WireInfo, adcsum);
277 unsigned short npt,
float const*
ticks,
float const*signl,
278 std::array<double, 3>&
params,
279 std::array<double, 3>& paramerrors,
287 const float time_shift = (ticks[npt - 1] + ticks[0]) / 2.F;
290 for (
size_t i = 0; i < npt; ++i) {
293 <<
"Non-positive charge encountered. Backing up to ROOT fit.";
297 fitter.
add(ticks[i] - time_shift, signl[i]);
303 MF_LOG_DEBUG(
"CCHitFinderAlg") <<
"Fast Gaussian fit failed.";
310 chidof = chi2 / fitter.
NDF();
313 params[1] += time_shift;
318 for (
double&
par: paramerrors)
par *= std::sqrt(chidof);
326 float *
ticks,
float *signl)
330 dof = npt - 3 * nGaus;
335 if(
bumps.size() == 0)
return;
338 std::vector<double> partmp;
339 std::vector<double> partmperr;
349 std::array<double, 3>
params, paramerrors;
356 std::copy(params.begin(), params.end(), partmp.begin());
358 std::copy(paramerrors.begin(), paramerrors.end(), partmperr.begin());
360 else bNeedROOTfit =
true;
373 std::stringstream numConv;
375 if(nGaus > 1) eqn =
"gaus(0)";
376 for(
unsigned short ii = 3; ii < nGaus*3; ii+=3){
377 eqn.append(
" + gaus(");
380 eqn.append(numConv.str());
384 auto Gn = std::make_unique<TF1>(
"gn",eqn.c_str());
388 TGraph *fitn =
new TGraph(npt, ticks, signl);
394 for(
unsigned short ii = 0; ii <
bumps.size(); ++ii) {
395 unsigned short index = ii * 3;
396 unsigned short bumptime =
bumps[ii];
397 double amp = signl[bumptime];
398 Gn->SetParameter(index , amp);
399 Gn->SetParLimits(index, 0., 9999.);
400 Gn->SetParameter(index + 1, (
double)bumptime);
401 Gn->SetParLimits(index + 1, 0, (
double)npt);
403 Gn->SetParLimits(index + 2, 1., 3*(
double)
fMinRMS[thePlane]);
411 for(
unsigned short ii =
bumps.size(); ii < nGaus; ++ii) {
414 unsigned short imbig = 0;
415 for(
unsigned short jj = 0; jj < npt; ++jj) {
416 float diff = signl[jj] - Gn->Eval((Double_t)jj, 0, 0, 0);
428 unsigned short index = ii * 3;
429 Gn->SetParameter(index , (
double)big);
430 Gn->SetParLimits(index, 0., 9999.);
431 Gn->SetParameter(index + 1, (
double)imbig);
432 Gn->SetParLimits(index + 1, 0, (
double)npt);
434 Gn->SetParLimits(index + 2, 1., 5*(
double)
fMinRMS[thePlane]);
440 fitn->Fit(&*Gn,
"WNQB");
442 for(
unsigned short ipar = 0; ipar < 3 * nGaus; ++ipar) {
443 partmp.push_back(Gn->GetParameter(ipar));
444 partmperr.push_back(Gn->GetParError(ipar));
455 std::vector< std::pair<unsigned short, unsigned short> > times;
457 for(
unsigned short ii = 0; ii < nGaus; ++ii) {
458 unsigned short index = ii * 3;
459 times.push_back(std::make_pair(partmp[index + 1],ii));
461 std::sort(times.begin(), times.end());
464 for(
unsigned short ii = 0; ii < nGaus; ++ii) {
465 if(times[ii].
second != ii) {
472 std::vector<double> partmpt;
473 std::vector<double> partmperrt;
474 for(
unsigned short ii = 0; ii < nGaus; ++ii) {
475 unsigned short index = times[ii].second * 3;
476 partmpt.push_back(partmp[index]);
477 partmpt.push_back(partmp[index+1]);
478 partmpt.push_back(partmp[index+2]);
479 partmperrt.push_back(partmperr[index]);
480 partmperrt.push_back(partmperr[index+1]);
481 partmperrt.push_back(partmperr[index+2]);
484 partmperr = partmperrt;
500 for(
unsigned short ii = 0; ii < nGaus; ++ii) {
501 unsigned short index = ii * 3;
503 short fittime = partmp[index + 1];
504 if(fittime < 0 || fittime > npt - 1) {
514 float rms = partmp[index + 2];
515 if(rms < 0.5 *
fMinRMS[thePlane] || rms > 5 *
fMinRMS[thePlane]) {
520 for(
unsigned short jj = 0; jj < nGaus; ++jj) {
521 if(jj == ii)
continue;
522 unsigned short jndex = jj * 3;
523 float timediff =
std::abs(partmp[jndex + 1] - partmp[index + 1]);
546 float *
ticks,
float *signl)
551 for(
unsigned short ii = 0; ii < npt; ++ii) {
553 sumST += signl[ii] * ticks[ii];
555 float mean = sumST / sumS;
557 for(
unsigned short ii = 0; ii < npt; ++ii) {
558 float arg = ticks[ii] -
mean;
559 rms += signl[ii] * arg * arg;
561 rms = std::sqrt(rms / sumS);
574 float meanerr = std::sqrt(1/sumS);
575 float rmserr = 0.2 *
rms;
577 parerr.push_back(meanerr);
593 size_t nhits =
par.size() / 3;
597 <<
"Too many hits: existing " <<
allhits.size() <<
" plus new " << nhits
598 <<
" beyond the maximum " <<
allhits.max_size();
602 if(nhits == 0)
return;
607 const float loTime = TStart;
608 const float hiTime = TStart + npt;
612 for(
size_t hit = 0;
hit < nhits; ++
hit) {
613 const unsigned short index = 3 *
hit;
616 for(
size_t hit = 0;
hit < nhits; ++
hit) {
619 const float charge_err =
SqrtPi 626 par[index + 1] + TStart,
631 adcsum * charge / gsum,
661 float *
ticks,
float *signl,
unsigned short tstart) {
677 for(
unsigned short ipl = 0; ipl < 3; ++ipl) {
733 for(
unsigned short ii = 0; ii < npt; ++ii) {
734 if(signl[ii] > big) {
758 for(
unsigned short ii = 0; ii < npt; ++ii) {
760 sumt += signl[ii] * ii;
762 float aveb = sumt / sum;
765 for(
unsigned short ii = 0; ii < npt; ++ii) {
766 float dbin = (
float)ii - aveb;
767 sumt += signl[ii] * dbin * dbin;
777 if(
par.size() == 3) {
790 std::cout<<
"Check lo and hi W/T for each plane"<<
std::endl;
791 for(
unsigned short ipl = 0; ipl < 3; ++ipl) {
795 std::cout<<
" ipl nRAT bCnt bChi bRMS hCnt hRMS dT/dW New_ChiNorm"<<
std::endl;
796 for(
unsigned short ipl = 0; ipl < 3; ++ipl) {
815 std::cout<<
"nRAT is the number of Regions Above Threshold (RAT) used in the study.\n";
816 std::cout<<
"bCnt is the number of single bumps that were successfully fitted \n";
817 std::cout<<
"bChi is the average chisq/DOF of the first fit\n";
818 std::cout<<
"bRMS is the average calculated RMS of the bumps\n";
819 std::cout<<
"hCnt is the number of RATs that have a single hit\n";
820 std::cout<<
"hRMS is the average RMS from the Gaussian fit -> use this value for fMinRMS[plane] in the fcl file\n";
821 std::cout<<
"dTdW is the slope of the track\n";
822 std::cout<<
"New_ChiNorm is the recommended values of ChiNorm that should be used in the fcl file\n";
839 if (nGaus == 0)
return;
840 MultiGausFits.resize(nGaus);
841 std::fill(MultiGausFits.begin(), MultiGausFits.end(), 0);
847 ++MultiGausFits[
std::min(nGaus, (
unsigned int) MultiGausFits.size()) - 1];
virtual bool IsBad(raw::ChannelID_t channel) const =0
Returns whether the specified channel is bad in the current run.
void RunCCHitFinder(std::vector< recob::Wire > const &Wires)
bool add(Data_t x, Data_t y, Data_t sy=Data_t(1.0))
void AddMultiGaus(unsigned int nGaus)
float fChiSplit
Estimated noise error on the Signal.
static constexpr float SqrtPi
art::ServiceHandle< geo::Geometry const > geom
void FitNG(unsigned short nGaus, unsigned short npt, float *ticks, float *signl)
double rms(sqlite3 *db, std::string const &table_name, std::string const &column_name)
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
tick ticks
Alias for common language habits.
Q_EXPORT QTSManip setprecision(int p)
art framework interface to geometry description
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
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)
Class providing information about the quality of channels.
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.
std::vector< float > Signal() const
Return a zero-padded full length vector filled with RoI signal.
Q_EXPORT QTSManip setw(int w)
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.
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
unsigned short theWireNum
std::vector< float > fMinPeak
Interface for experiment-specific channel quality info provider.
Class holding the regions of interest of signal 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
#define MF_LOG_WARNING(category)
Interface for experiment-specific service for channel quality info.
std::vector< int > RATCnt
second_as<> second
Type of time stored in seconds, in double precision.
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
double mean(sqlite3 *db, std::string const &table_name, std::string const &column_name)
std::vector< double > par
QTextStream & endl(QTextStream &s)