1 #ifndef DPRAWHITFINDER_H 2 #define DPRAWHITFINDER_H 70 #include "TGraphErrors.h" 72 #include "TDecompSVD.h" 76 #include "TStopwatch.h" 95 using PeakDevVec = std::vector<std::tuple<double,int,int,int>>;
102 int firstTick)
const;
134 void AddPeak(std::tuple<double,int,int,int> fPeakDevCand,
137 void SplitPeak(std::tuple<double,int,int,int> fPeakDevCand,
146 double fPeakMeanTrue);
152 double fChargeNormFactor,
153 double fPeakMeanTrue);
156 std::vector<double>& output);
159 std::vector<float>& outputVec,
160 size_t binsToAverage)
const;
162 void reBin(
const std::vector<float>& inputVec,
163 std::vector<float>& outputVec,
164 size_t nBinsToCombine)
const;
172 {
return std::get<0>(p) < s; }
174 {
return s < std::get<0>(p); }
228 pset.get<
std::string>(
"module_label"),
"",
229 art::ServiceHandle<
art::TriggerNamesService>()->getProcessName()),
249 std::vector<double>& output)
252 throw std::runtime_error(
"DPRawHitFinder::FillOutHitParameterVector ERROR! Input config vector has zero size.");
255 const unsigned int N_PLANES = geom->
Nplanes();
258 output.resize(N_PLANES,input[0]);
259 else if(input.size()==N_PLANES)
262 throw std::runtime_error(
"DPRawHitFinder::FillOutHitParameterVector ERROR! Input config vector size !=1 and !=N_PLANES.");
315 fFirstChi2 = tfs->
make<TH1F>(
"fFirstChi2",
"#chi^{2}", 10000, 0, 5000);
316 fChi2 = tfs->
make<TH1F>(
"fChi2",
"#chi^{2}", 10000, 0, 5000);
330 TH1::AddDirectory(kFALSE);
367 for(
size_t wireIter = 0; wireIter < wireVecHandle->size(); wireIter++)
377 std::vector<geo::WireID> wids = geom->
ChannelToWire(channel);
383 std::cout << std::endl;
384 std::cout << std::endl;
385 std::cout << std::endl;
386 std::cout <<
"-----------------------------------------------------------------------------------------------------------" << std::endl;
387 std::cout <<
"Channel: " << channel << std::endl;
388 std::cout <<
"Cryostat: " << wid.
Cryostat << std::endl;
389 std::cout <<
"TPC: " << wid.
TPC << std::endl;
390 std::cout <<
"Plane: " << wid.
Plane << std::endl;
391 std::cout <<
"Wire: " << wid.
Wire << std::endl;
401 for(
const auto& range : signalROI.
get_ranges())
406 const std::vector<float>& signal = range.data();
423 std::vector<float> timeAve;
435 if (timeValsVec.empty())
continue;
456 std::cout << std::endl;
457 std::cout << std::endl;
458 std::cout <<
"-------------------- ROI #" << CountROI <<
" -------------------- " << std::endl;
459 if(timeValsVec.size() == 1) std::cout <<
"ROI #" << CountROI <<
" (" << timeValsVec.size() <<
" peak): ROIStartTick: " << range.offset <<
" ROIEndTick:" << range.offset+range.size() << std::endl;
460 else std::cout <<
"ROI #" << CountROI <<
" (" << timeValsVec.size() <<
" peaks): ROIStartTick: " << range.offset <<
" ROIEndTick:" << range.offset+range.size() << std::endl;
467 for(
auto const& timeValsTmp : timeValsVec )
469 std::cout <<
"Peak #" << CountPeak <<
": PeakStartTick: " << range.offset + std::get<0>(timeValsTmp) <<
" PeakMaxTick: " << range.offset + std::get<1>(timeValsTmp) <<
" PeakEndTick: " << range.offset + std::get<2>(timeValsTmp) << std::endl;
476 if (timeValsVec.empty())
continue;
491 int NumberOfPeaksBeforeFit=0;
492 unsigned int nExponentialsForFit=0;
493 double chi2PerNDF=0.;
496 unsigned int NumberOfMergedVecs = mergedVec.size();
502 for(
unsigned int j=0; j < NumberOfMergedVecs; j++)
504 int startT = std::get<0>(mergedVec.at(j));
505 int endT = std::get<1>(mergedVec.at(j));
506 int width = endT + 1 - startT;
509 int NFluctuations = std::get<3>(mergedVec.at(j));
513 std::cout << std::endl;
514 if(peakVals.size() == 1) std::cout <<
"- Group #" << j <<
" (" << peakVals.size() <<
" peak): GroupStartTick: " << range.offset + startT <<
" GroupEndTick: " << range.offset + endT << std::endl;
515 else std::cout <<
"- Group #" << j <<
" (" << peakVals.size() <<
" peaks): GroupStartTick: " << range.offset + startT <<
" GroupEndTick: " << range.offset + endT << std::endl;
516 std::cout <<
"Fluctuations in this group: " << NFluctuations << std::endl;
517 int CountPeakInGroup=0;
518 for(
auto const& peakValsTmp : peakVals )
520 std::cout <<
"Peak #" << CountPeakInGroup <<
" in group #" << j <<
": PeakInGroupStartTick: " << range.offset + std::get<2>(peakValsTmp) <<
" PeakInGroupMaxTick: " << range.offset + std::get<0>(peakValsTmp) <<
" PeakInGroupEndTick: " << range.offset + std::get<3>(peakValsTmp) << std::endl;
526 if (width <
fMinWidth || (
double)std::accumulate(signal.begin()+startT, signal.begin()+endT+1, 0) <
fMinADCSum || (
double)std::accumulate(signal.begin()+startT, signal.begin()+endT+1, 0)/width <
fMinADCSumOverWidth)
530 std::cout <<
"Delete this group of peaks because width, integral or width/intergral is too small." << std::endl;
539 NumberOfPeaksBeforeFit = peakVals.size();
540 nExponentialsForFit = peakVals.size();
553 std::cout << std::endl;
554 std::cout <<
"--- First fit ---" << std::endl;
555 if (nExponentialsForFit == 1) std::cout <<
"- Fitted " << nExponentialsForFit <<
" peak in group #" << j <<
":" << std::endl;
556 else std::cout <<
"- Fitted " << nExponentialsForFit <<
" peaks in group #" << j <<
":" << std::endl;
557 std::cout <<
"chi2/ndf = " << std::setprecision(2) << std::fixed << chi2PerNDF << std::endl;
561 std::cout <<
"tau1 [mus] = " << std::setprecision(3) << std::fixed << paramVec[0].first << std::endl;
562 std::cout <<
"tau2 [mus] = " << std::setprecision(3) << std::fixed << paramVec[1].first << std::endl;
564 for(
unsigned int i = 0; i < nExponentialsForFit; i++)
566 std::cout <<
"Peak #" << i <<
": A [ADC] = " << std::setprecision(1) << std::fixed << paramVec[2*(i+1)].first << std::endl;
567 std::cout <<
"Peak #" << i <<
": t0 [ticks] = " << std::setprecision(1) << std::fixed << range.offset + paramVec[2*(i+1)+1].first << std::endl;
572 for(
unsigned int i = 0; i < nExponentialsForFit; i++)
574 std::cout <<
"Peak #" << i <<
": A [ADC] = " << std::setprecision(1) << std::fixed << paramVec[4*i+2].first << std::endl;
575 std::cout <<
"Peak #" << i <<
": t0 [ticks] = " << std::setprecision(1) << std::fixed << range.offset + paramVec[4*i+3].first << std::endl;
576 std::cout <<
"Peak #" << i <<
": tau1 [mus] = " << std::setprecision(3) << std::fixed << paramVec[4*i].first << std::endl;
577 std::cout <<
"Peak #" << i <<
": tau2 [mus] = " << std::setprecision(3) << std::fixed << paramVec[4*i+1].first << std::endl;
583 if (!(chi2PerNDF < std::numeric_limits<double>::infinity()))
continue;
594 unsigned int nExponentialsBeforeRefit=nExponentialsForFit;
595 unsigned int nExponentialsAfterRefit=nExponentialsForFit;
596 double oldChi2PerNDF = chi2PerNDF;
601 while( (nExponentialsForFit == 1 && nExponentialsAfterRefit < 3*nExponentialsBeforeRefit && chi2PerNDF > fChi2NDFRetry) ||
602 (nExponentialsForFit > 1 && nExponentialsAfterRefit < 3*nExponentialsBeforeRefit && chi2PerNDF >
fChi2NDFRetryFactorMultiHits*fChi2NDFRetry) )
604 RefitSuccess =
false;
609 for(
auto& PeakDevCand : PeakDev)
614 peakValsTemp = peakVals;
616 AddPeak(PeakDevCand, peakValsTemp);
619 if (chi2PerNDF2 < chi2PerNDF)
621 paramVec = paramVecRefit;
622 peakVals = peakValsTemp;
623 nExponentialsForFit = peakVals.size();
624 chi2PerNDF = chi2PerNDF2;
626 nExponentialsAfterRefit++;
633 if(RefitSuccess ==
false)
635 for(
auto& PeakDevCand : PeakDev)
640 peakValsTemp=peakVals;
645 if (chi2PerNDF2 < chi2PerNDF)
647 paramVec = paramVecRefit;
648 peakVals = peakValsTemp;
649 nExponentialsForFit = peakVals.size();
650 chi2PerNDF = chi2PerNDF2;
652 nExponentialsAfterRefit++;
659 if(RefitSuccess ==
false)
667 std::cout << std::endl;
668 std::cout <<
"--- Refit ---" << std::endl;
669 if( chi2PerNDF == oldChi2PerNDF) std::cout <<
"chi2/ndf didn't improve. Keep first fit." << std::endl;
672 std::cout <<
"- Added peaks to group #" << j <<
". This group now has " << nExponentialsForFit <<
" peaks:" << std::endl;
673 std::cout <<
"- Group #" << j <<
" (" << peakVals.size() <<
" peaks): GroupStartTick: " << range.offset + startT <<
" GroupEndTick: " << range.offset + endT << std::endl;
675 int CountPeakInGroup=0;
676 for(
auto const& peakValsTmp : peakVals )
678 std::cout <<
"Peak #" << CountPeakInGroup <<
" in group #" << j <<
": PeakInGroupStartTick: " << range.offset + std::get<2>(peakValsTmp) <<
" PeakInGroupMaxTick: " << range.offset + std::get<0>(peakValsTmp) <<
" PeakInGroupEndTick: " << range.offset + std::get<3>(peakValsTmp) << std::endl;
682 std::cout <<
"chi2/ndf = " << std::setprecision(2) << std::fixed << chi2PerNDF << std::endl;
686 std::cout <<
"tau1 [mus] = " << std::setprecision(3) << std::fixed << paramVec[0].first << std::endl;
687 std::cout <<
"tau2 [mus] = " << std::setprecision(3) << std::fixed << paramVec[1].first << std::endl;
689 for(
unsigned int i = 0; i < nExponentialsForFit; i++)
691 std::cout <<
"Peak #" << i <<
": A [ADC] = " << std::setprecision(1) << std::fixed << paramVec[2*(i+1)].first << std::endl;
692 std::cout <<
"Peak #" << i <<
": t0 [ticks] = " << std::setprecision(1) << std::fixed << range.offset + paramVec[2*(i+1)+1].first << std::endl;
697 for(
unsigned int i = 0; i < nExponentialsForFit; i++)
699 std::cout <<
"Peak #" << i <<
": A [ADC] = " << std::setprecision(1) << std::fixed << paramVec[4*i+2].first << std::endl;
700 std::cout <<
"Peak #" << i <<
": t0 [ticks] = " << std::setprecision(1) << std::fixed << range.offset + paramVec[4*i+3].first << std::endl;
701 std::cout <<
"Peak #" << i <<
": tau1 [mus] = " << std::setprecision(3) << std::fixed << paramVec[4*i].first << std::endl;
702 std::cout <<
"Peak #" << i <<
": tau2 [mus] = " << std::setprecision(3) << std::fixed << paramVec[4*i+1].first << std::endl;
714 for(
unsigned int i = 0; i < nExponentialsForFit; i++)
724 peakTau1 = paramVec[0].first;
725 peakTau2 = paramVec[1].first;
726 peakAmp = paramVec[2*(i+1)].first;
727 peakMean = paramVec[2*(i+1)+1].first;
731 peakTau1 = paramVec[4*i].first;
732 peakTau2 = paramVec[4*i+1].first;
733 peakAmp = paramVec[4*i+2].first;
734 peakMean = paramVec[4*i+3].first;
738 double peakAmpTrue = signal[std::get<0>(peakVals.at(i))];
739 double peakAmpErr = 1.;
742 TF1 Exponentials(
"Exponentials",
"( [0] * exp(0.4*(x-[1])/[2]) / ( 1 + exp(0.4*(x-[1])/[3]) ) )",startT,endT);
743 Exponentials.SetParameter(0, peakAmp);
744 Exponentials.SetParameter(1, peakMean);
745 Exponentials.SetParameter(2, peakTau1);
746 Exponentials.SetParameter(3, peakTau2);
747 double peakMeanTrue = Exponentials.GetMaximumX(startT,endT);
748 Exponentials.Delete();
751 double peakWidth =
WidthFunc(peakMean, peakAmp, peakTau1, peakTau2, startT, endT, peakMeanTrue);
759 peakMeanErr = paramVec[2*(i+1)+1].second;
763 peakMeanErr = paramVec[4*i+3].second;
765 double peakWidthErr = 0.1*peakWidth;
769 double chargeErr = std::sqrt(TMath::Pi()) * (peakAmpErr*peakWidthErr + peakWidthErr*peakAmpErr);
772 int startTthisHit = std::get<2>(peakVals.at(i));
773 int endTthisHit = std::get<3>(peakVals.at(i));
778 double sumADC = std::accumulate(sumStartItr, sumEndItr + 1, 0.);
786 std::cout << std::endl;
787 std::cout <<
"WARNING: For peak #" << i <<
" in this group:" << std::endl;
788 if( peakWidth <= 0 || charge <= 0. || charge != charge) std::cout <<
"Fit function returned width < 0 or charge < 0 or charge = nan." << std::endl;
789 if( ( nExponentialsForFit == 1 && chi2PerNDF > fChi2NDFMax ) || ( nExponentialsForFit >= 2 && chi2PerNDF >
fChi2NDFMaxFactorMultiHits*fChi2NDFMax ) )
791 std::cout << std::endl;
792 std::cout <<
"WARNING: For fit of this group (" << NumberOfPeaksBeforeFit <<
" peaks before refit, " << nExponentialsForFit <<
" peaks after refit): " << std::endl;
793 if ( nExponentialsForFit == 1 && chi2PerNDF > fChi2NDFMax ) std::cout <<
"chi2/ndf of this fit (" << chi2PerNDF <<
") is higher than threshold (" << fChi2NDFMax <<
")." << std::endl;
796 std::cout <<
"---> DO NOT create hit object from fit parameters but use peak values instead." << std::endl;
797 std::cout <<
"---> Set fit parameter so that a sharp peak with a width of 1 tick is shown in the event display. This indicates that the fit failed." << std::endl;
800 peakMeanErr=peakWidth/2;
802 peakMeanTrue = std::get<0>(peakVals.at(i));
805 peakMean = peakMeanTrue;
814 startT+roiFirstBinTick,
815 endT+roiFirstBinTick,
817 peakMeanTrue+roiFirstBinTick,
832 std::cout << std::endl;
833 std::cout <<
"- Created hit object for peak #" << i <<
" in this group with the following parameters (obtained from fit):" << std::endl;
834 std::cout <<
"HitStartTick: " << startT+roiFirstBinTick << std::endl;
835 std::cout <<
"HitEndTick: " << endT+roiFirstBinTick << std::endl;
836 std::cout <<
"HitWidthTicks: " << std::setprecision(2) << std::fixed << peakWidth << std::endl;
837 std::cout <<
"HitMeanTick: " << std::setprecision(2) << std::fixed << peakMeanTrue+roiFirstBinTick <<
" +- " << peakMeanErr << std::endl;
838 std::cout <<
"HitAmplitude [ADC]: " << std::setprecision(1) << std::fixed << peakAmpTrue <<
" +- " << peakAmpErr << std::endl;
839 std::cout <<
"HitIntegral [ADC*ticks]: " << std::setprecision(1) << std::fixed << charge <<
" +- " << chargeErr << std::endl;
840 std::cout <<
"HitADCSum [ADC*ticks]: " << std::setprecision(1) << std::fixed << sumADC << std::endl;
841 std::cout <<
"HitMultiplicity: " << nExponentialsForFit << std::endl;
842 std::cout <<
"HitIndex in group: " << numHits << std::endl;
843 std::cout <<
"Hitchi2/ndf: " << std::setprecision(2) << std::fixed << chi2PerNDF << std::endl;
844 std::cout <<
"HitNDF: " << NDF << std::endl;
851 std::array<float, 4> fitParams;
852 fitParams[0] = peakMean+roiFirstBinTick;
853 fitParams[1] = peakTau1;
854 fitParams[2] = peakTau2;
855 fitParams[3] = peakAmp;
879 if (nHitsInThisGroup *
fLongPulseWidth < (endT - startT + 1) ) nHitsInThisGroup++;
881 int firstTick = startT;
888 std::cout << std::endl;
889 std::cout <<
"WARNING: Number of peaks in this group (" << NumberOfPeaksBeforeFit <<
") is higher than threshold (" <<
fMaxMultiHit <<
")." << std::endl;
890 std::cout <<
"---> DO NOT fit. Split group of peaks into hits with equal length instead." << std::endl;
894 std::cout << std::endl;
895 std::cout <<
"WARNING: group of peak is longer (" << width <<
" ticks) than threshold (" <<
fMaxGroupLength <<
" ticks)." << std::endl;
896 std::cout <<
"---> DO NOT fit. Split group of peaks into hits with equal length instead." << std::endl;
900 std::cout << std::endl;
901 std::cout <<
"WARNING: fluctuations (" << NFluctuations <<
") higher than threshold (" <<
fMaxFluctuations <<
")." << std::endl;
902 std::cout <<
"---> DO NOT fit. Split group of peaks into hits with equal length instead." << std::endl;
913 std::cout <<
"---> Group goes from tick " << roiFirstBinTick+startT <<
" to " << roiFirstBinTick+endT <<
". Split group into (" << roiFirstBinTick+endT <<
" - " << roiFirstBinTick+startT <<
")/" <<
fLongPulseWidth <<
" = " << (endT - startT) <<
"/" <<
fLongPulseWidth <<
" = " << nHitsInThisGroup <<
" peaks (" <<
fLongPulseWidth <<
" = LongPulseWidth), or maximum LongMaxHits = " <<
fLongMaxHits <<
" peaks." << std::endl;
917 for(
int hitIdx = 0; hitIdx < nHitsInThisGroup; hitIdx++)
921 double peakMeanTrue = (firstTick + lastTick) / 2.;
922 if( NumberOfPeaksBeforeFit == 1 && nHitsInThisGroup == 1) peakMeanTrue = std::get<0>(peakVals.at(0));
923 double peakMeanErr = (lastTick - firstTick) / 2.;
924 double sumADC = std::accumulate(signal.begin() + firstTick, signal.begin() + lastTick + 1, 0.);
925 double charge = sumADC;
926 double chargeErr = 0.1*sumADC;
927 double peakAmpTrue = 0;
929 for(
int tick = firstTick; tick <= lastTick; tick++)
931 if(signal[tick] > peakAmpTrue) peakAmpTrue = signal[tick];
934 double peakAmpErr = 1.;
935 nExponentialsForFit = nHitsInThisGroup;
939 double peakMean = peakMeanTrue-2;
940 double peakTau1 = 0.008;
941 double peakTau2 = 0.0065;
942 double peakAmp = 20.;
946 firstTick+roiFirstBinTick,
947 lastTick+roiFirstBinTick,
949 peakMeanTrue+roiFirstBinTick,
965 std::cout << std::endl;
966 std::cout <<
"- Created hit object for peak #" << hitIdx <<
" in this group with the following parameters (obtained from waveform):" << std::endl;
967 std::cout <<
"HitStartTick: " << firstTick+roiFirstBinTick << std::endl;
968 std::cout <<
"HitEndTick: " << lastTick+roiFirstBinTick << std::endl;
969 std::cout <<
"HitWidthTicks: " << std::setprecision(2) << std::fixed << peakWidth << std::endl;
970 std::cout <<
"HitMeanTick: " << std::setprecision(2) << std::fixed << peakMeanTrue+roiFirstBinTick <<
" +- " << peakMeanErr << std::endl;
971 std::cout <<
"HitAmplitude [ADC]: " << std::setprecision(1) << std::fixed << peakAmpTrue <<
" +- " << peakAmpErr << std::endl;
972 std::cout <<
"HitIntegral [ADC*ticks]: " << std::setprecision(1) << std::fixed << charge <<
" +- " << chargeErr << std::endl;
973 std::cout <<
"HitADCSum [ADC*ticks]: " << std::setprecision(1) << std::fixed << sumADC << std::endl;
974 std::cout <<
"HitMultiplicity: " << nExponentialsForFit << std::endl;
975 std::cout <<
"HitIndex in group: " << hitIdx << std::endl;
976 std::cout <<
"Hitchi2/ndf: " << std::setprecision(2) << std::fixed << chi2PerNDF << std::endl;
977 std::cout <<
"HitNDF: " << NDF << std::endl;
982 std::array<float, 4> fitParams;
983 fitParams[0] = peakMean+roiFirstBinTick;
984 fitParams[1] = peakTau1;
985 fitParams[2] = peakTau2;
986 fitParams[3] = peakAmp;
990 firstTick = lastTick+1;
995 fChi2->Fill(chi2PerNDF);
1016 std::vector<std::tuple<int,int,int>>& timeValsVec,
1018 int firstTick)
const 1021 if (std::distance(startItr,stopItr) > 4)
1024 auto maxItr = std::max_element(startItr, stopItr);
1026 float maxValue = *maxItr;
1027 int maxTime = std::distance(startItr,maxItr);
1029 if (maxValue >= PeakMin)
1032 auto firstItr = std::distance(startItr,maxItr) > 2 ? maxItr - 1 : startItr;
1033 bool PeakStartIsHere =
true;
1035 while(firstItr != startItr)
1038 PeakStartIsHere =
true;
1041 if( *firstItr >= *(firstItr-i) )
1043 PeakStartIsHere =
false;
1048 if (*firstItr <= 0 || PeakStartIsHere)
break;
1052 int firstTime = std::distance(startItr,firstItr);
1058 auto lastItr = std::distance(maxItr,stopItr) > 2 ? maxItr + 1 : stopItr - 1;
1059 bool PeakEndIsHere =
true;
1061 while(lastItr != stopItr)
1064 PeakEndIsHere =
true;
1067 if( *lastItr >= *(lastItr+i) )
1069 PeakEndIsHere =
false;
1073 if (*lastItr <= 0 || PeakEndIsHere)
break;
1077 int lastTime = std::distance(startItr,lastItr);
1080 timeValsVec.push_back(std::make_tuple(firstTick+firstTime,firstTick+maxTime,firstTick+lastTime));
1083 findCandidatePeaks(lastItr + 1, stopItr, timeValsVec, PeakMin, firstTick + std::distance(startItr,lastItr + 1));
1099 auto timeValsVecItr = timeValsVec.begin();
1100 unsigned int PeaksInThisMergedPeak = 0;
1102 while(timeValsVecItr != timeValsVec.end())
1107 auto& timeVal = *timeValsVecItr++;
1108 int startT = std::get<0>(timeVal);
1109 int maxT = std::get<1>(timeVal);
1110 int endT = std::get<2>(timeVal);
1111 int widT = endT - startT;
1112 int FinalStartT=startT;
1117 peakVals.emplace_back(maxT,widT,startT,endT);
1121 bool checkNextHit = timeValsVecItr != timeValsVec.end();
1127 int NextStartT = std::get<0>(*timeValsVecItr);
1129 double MinADC = signalVec[endT];
1130 for(
int i = endT; i <= NextStartT; i++)
1132 if(signalVec[i]<MinADC)
1134 MinADC = signalVec[i];
1141 int CurrentStartT=startT;
1142 int CurrentMaxT=maxT;
1143 int CurrentEndT=endT;
1146 timeVal = *timeValsVecItr++;
1147 int NextMaxT = std::get<1>(timeVal);
1148 int NextEndT = std::get<2>(timeVal);
1149 int NextWidT = NextEndT - NextStartT;
1154 int CurrentSumADC = 0;
1155 for(
int i = CurrentStartT; i<= CurrentEndT; i++)
1157 CurrentSumADC+=signalVec[i];
1161 for (
int i = NextStartT; i<= NextEndT; i++)
1163 NextSumADC+=signalVec[i];
1172 startT=CurrentStartT;
1175 peakVals.pop_back();
1176 peakVals.emplace_back(maxT,widT,startT,endT);
1181 startT=CurrentStartT;
1184 peakVals.pop_back();
1185 peakVals.emplace_back(maxT,widT,startT,endT);
1193 peakVals.emplace_back(maxT,widT,startT,endT);
1194 PeaksInThisMergedPeak++;
1203 peakVals.emplace_back(maxT,widT,startT,endT);
1204 PeaksInThisMergedPeak++;
1206 checkNextHit = timeValsVecItr != timeValsVec.end();
1210 checkNextHit =
false;
1211 PeaksInThisMergedPeak = 0;
1216 mergedVec.emplace_back(FinalStartT, FinalEndT, peakVals, NFluctuations);
1229 int NFluctuations=0;
1231 for(
int j = peakMean-1; j >= peakStart; j--)
1233 if(fsignalVec[j] < 5)
break;
1235 if(fsignalVec[j] > fsignalVec[j+1])
1241 for(
int j = peakMean+1; j <= peakEnd; j++)
1243 if(fsignalVec[j] < 5)
break;
1245 if(fsignalVec[j] > fsignalVec[j-1])
1251 return NFluctuations;
1262 double& fchi2PerNDF,
1266 int size = fEndTime - fStartTime + 1;
1267 int NPeaks = fPeakVals.size();
1272 if(fEndTime - fStartTime < 0){size = 0;}
1275 TH1F hitSignal(
"hitSignal",
"",
std::max(size,1),fStartTime,fEndTime+1);
1281 for(
int i = fStartTime; i < fEndTime+1; i++)
1283 hitSignal.Fill(i,fSignalVector[i]);
1284 hitSignal.SetBinError(i,0.288675);
1296 TF1 Exponentials(
"Exponentials",eqn.c_str(),fStartTime,fEndTime+1);
1300 std::cout << std::endl;
1301 std::cout <<
"--- Preparing fit ---" << std::endl;
1302 std::cout <<
"--- Lower limits, seed, upper limit:" << std::endl;
1307 Exponentials.SetParameter(0, 0.5);
1308 Exponentials.SetParameter(1, 0.5);
1314 double peakMeanShift=2;
1315 double peakMeanSeed=0;
1316 double peakMeanRangeLow=0;
1317 double peakMeanRangeHi=0;
1321 for(
int i = 0; i < NPeaks; i++)
1323 peakMean = std::get<0>(fPeakVals.at(i));
1324 peakStart = std::get<2>(fPeakVals.at(i));
1325 peakEnd = std::get<3>(fPeakVals.at(i));
1326 peakMeanSeed=peakMean-peakMeanShift;
1329 amplitude = fSignalVector[peakMean];
1331 Exponentials.SetParameter(2*(i+1), 1.65*amplitude);
1332 Exponentials.SetParLimits(2*(i+1), 0.3*1.65*amplitude, 2*1.65*amplitude);
1333 Exponentials.SetParameter(2*(i+1)+1, peakMeanSeed);
1337 Exponentials.SetParLimits(2*(i+1)+1, peakMeanRangeLow, peakMeanRangeHi);
1339 else if(NPeaks >= 2 && i == 0)
1341 double HalfDistanceToNextMean = 0.5*(std::get<0>(fPeakVals.at(i+1)) - peakMean);
1342 Exponentials.SetParLimits( 2*(i+1)+1, peakMeanRangeLow,
std::min(peakMeanRangeHi, peakMeanSeed+HalfDistanceToNextMean) );
1344 else if(NPeaks >= 2 && i == NPeaks-1)
1346 double HalfDistanceToPrevMean = 0.5*(peakMean - std::get<0>(fPeakVals.at(i-1)));
1347 Exponentials.SetParLimits(2*(i+1)+1,
std::max(peakMeanRangeLow, peakMeanSeed-HalfDistanceToPrevMean), peakMeanRangeHi );
1351 double HalfDistanceToNextMean = 0.5*(std::get<0>(fPeakVals.at(i+1)) - peakMean);
1352 double HalfDistanceToPrevMean = 0.5*(peakMean - std::get<0>(fPeakVals.at(i-1)));
1353 Exponentials.SetParLimits(2*(i+1)+1,
std::max(peakMeanRangeLow, peakMeanSeed-HalfDistanceToPrevMean),
std::min(peakMeanRangeHi, peakMeanSeed+HalfDistanceToNextMean) );
1358 double t0low, t0high;
1359 Exponentials.GetParLimits(2*(i+1)+1, t0low, t0high);
1360 std::cout <<
"Peak #" << i <<
": A [ADC] = " << std::setprecision(1) << std::fixed << 0.3*1.65*amplitude <<
" , " << 1.65*amplitude <<
" , " << 2*1.65*amplitude << std::endl;
1361 std::cout <<
"Peak #" << i <<
": t0 [ticks] = " << std::setprecision(1) << std::fixed << t0low <<
" , " << peakMeanSeed <<
" , " << t0high << std::endl;
1370 double peakMeanShift=2;
1371 double peakMeanSeed=0;
1372 double peakMeanRangeLow=0;
1373 double peakMeanRangeHi=0;
1378 for(
int i = 0; i < NPeaks; i++)
1380 Exponentials.SetParameter(4*i, 0.5);
1381 Exponentials.SetParameter(4*i+1, 0.5);
1385 peakMean = std::get<0>(fPeakVals.at(i));
1386 peakStart = std::get<2>(fPeakVals.at(i));
1387 peakEnd = std::get<3>(fPeakVals.at(i));
1388 peakMeanSeed=peakMean-peakMeanShift;
1391 amplitude = fSignalVector[peakMean];
1393 Exponentials.SetParameter(4*i+2, 1.65*amplitude);
1394 Exponentials.SetParLimits(4*i+2, 0.3*1.65*amplitude, 2*1.65*amplitude);
1395 Exponentials.SetParameter(4*i+3, peakMeanSeed);
1399 Exponentials.SetParLimits(4*i+3, peakMeanRangeLow, peakMeanRangeHi);
1401 else if(NPeaks >= 2 && i == 0)
1403 double HalfDistanceToNextMean = 0.5*(std::get<0>(fPeakVals.at(i+1)) - peakMean);
1404 Exponentials.SetParLimits( 4*i+3, peakMeanRangeLow,
std::min(peakMeanRangeHi, peakMeanSeed+HalfDistanceToNextMean) );
1406 else if(NPeaks >= 2 && i == NPeaks-1)
1408 double HalfDistanceToPrevMean = 0.5*(peakMean - std::get<0>(fPeakVals.at(i-1)));
1409 Exponentials.SetParLimits(4*i+3,
std::max(peakMeanRangeLow, peakMeanSeed-HalfDistanceToPrevMean), peakMeanRangeHi );
1413 double HalfDistanceToNextMean = 0.5*(std::get<0>(fPeakVals.at(i+1)) - peakMean);
1414 double HalfDistanceToPrevMean = 0.5*(peakMean - std::get<0>(fPeakVals.at(i-1)));
1415 Exponentials.SetParLimits(4*i+3,
std::max(peakMeanRangeLow, peakMeanSeed-HalfDistanceToPrevMean),
std::min(peakMeanRangeHi, peakMeanSeed+HalfDistanceToNextMean) );
1420 double t0low, t0high;
1421 Exponentials.GetParLimits(4*i+3, t0low, t0high);
1422 std::cout <<
"Peak #" << i <<
": A [ADC] = " << std::setprecision(1) << std::fixed << 0.3*1.65*amplitude <<
" , " << 1.65*amplitude <<
" , " << 2*1.65*amplitude << std::endl;
1423 std::cout <<
"Peak #" << i <<
": t0 [ticks] = " << std::setprecision(1) << std::fixed << t0low <<
" , " << peakMeanSeed <<
" , " << t0high << std::endl;
1433 { hitSignal.Fit(&Exponentials,
"QNRWM",
"", fStartTime, fEndTime+1);}
1435 {
mf::LogWarning(
"DPRawHitFinder") <<
"Fitter failed finding a hit";}
1440 fchi2PerNDF = (Exponentials.GetChisquare() / Exponentials.GetNDF());
1441 fNDF = Exponentials.GetNDF();
1445 fparamVec.emplace_back(Exponentials.GetParameter(0),Exponentials.GetParError(0));
1446 fparamVec.emplace_back(Exponentials.GetParameter(1),Exponentials.GetParError(1));
1448 for(
int i = 0; i < NPeaks; i++)
1450 fparamVec.emplace_back(Exponentials.GetParameter(2*(i+1)),Exponentials.GetParError(2*(i+1)));
1451 fparamVec.emplace_back(Exponentials.GetParameter(2*(i+1)+1),Exponentials.GetParError(2*(i+1)+1));
1456 for(
int i = 0; i < NPeaks; i++)
1458 fparamVec.emplace_back(Exponentials.GetParameter(4*i),Exponentials.GetParError(4*i));
1459 fparamVec.emplace_back(Exponentials.GetParameter(4*i+1),Exponentials.GetParError(4*i+1));
1460 fparamVec.emplace_back(Exponentials.GetParameter(4*i+2),Exponentials.GetParError(4*i+2));
1461 fparamVec.emplace_back(Exponentials.GetParameter(4*i+3),Exponentials.GetParError(4*i+3));
1464 Exponentials.Delete();
1484 TF1 Exponentials(
"Exponentials",eqn.c_str(),fStartTime,fEndTime+1);
1486 for(
size_t i=0; i < fparamVec.size(); i++)
1488 Exponentials.SetParameter(i, fparamVec[i].first);
1494 double Chi2PerNDFPeak;
1495 double MaxPosDeviation;
1496 double MaxNegDeviation;
1497 int BinMaxPosDeviation;
1498 int BinMaxNegDeviation;
1499 for(
int i = 0; i < fNPeaks; i++)
1501 Chi2PerNDFPeak = 0.;
1504 BinMaxPosDeviation=0;
1505 BinMaxNegDeviation=0;
1507 for(
int j = std::get<2>(fpeakVals.at(i)); j < std::get<3>(fpeakVals.at(i))+1; j++)
1509 if( (Exponentials(j+0.5)-fSignalVector[j]) > MaxPosDeviation && j != std::get<0>(fpeakVals.at(i)) )
1511 MaxPosDeviation = Exponentials(j+0.5)-fSignalVector[j];
1512 BinMaxPosDeviation = j;
1514 if( (Exponentials(j+0.5)-fSignalVector[j]) < MaxNegDeviation && j != std::get<0>(fpeakVals.at(i)) )
1516 MaxNegDeviation = Exponentials(j+0.5)-fSignalVector[j];
1517 BinMaxNegDeviation = j;
1519 Chi2PerNDFPeak += pow((Exponentials(j+0.5)-fSignalVector[j])/sqrt(fSignalVector[j]),2);
1522 if(BinMaxNegDeviation != 0)
1524 Chi2PerNDFPeak /=
static_cast<double>((std::get<3>(fpeakVals.at(i))-std::get<2>(fpeakVals.at(i))));
1525 fPeakDev.emplace_back(Chi2PerNDFPeak,i,BinMaxNegDeviation,BinMaxPosDeviation);
1529 std::sort(fPeakDev.begin(),fPeakDev.end(), [](std::tuple<double,int,int,int>
const &
t1, std::tuple<double,int,int,int>
const &
t2) {
return std::get<0>(
t1) > std::get<0>(
t2);} );
1530 Exponentials.Delete();
1536 std::string feqn =
"";
1537 std::stringstream numConv;
1541 for(
int i = 0; i < fNPeaks; i++)
1543 feqn.append(
"+( [");
1546 feqn.append(numConv.str());
1547 feqn.append(
"] * exp(0.4*(x-[");
1549 numConv << 2*(i+1)+1;
1550 feqn.append(numConv.str());
1551 feqn.append(
"])/[");
1554 feqn.append(numConv.str());
1555 feqn.append(
"]) / ( 1 + exp(0.4*(x-[");
1557 numConv << 2*(i+1)+1;
1558 feqn.append(numConv.str());
1559 feqn.append(
"])/[");
1562 feqn.append(numConv.str());
1563 feqn.append(
"]) ) )");
1568 for(
int i = 0; i < fNPeaks; i++)
1570 feqn.append(
"+( [");
1573 feqn.append(numConv.str());
1574 feqn.append(
"] * exp(0.4*(x-[");
1577 feqn.append(numConv.str());
1578 feqn.append(
"])/[");
1581 feqn.append(numConv.str());
1582 feqn.append(
"]) / ( 1 + exp(0.4*(x-[");
1584 numConv << 2*(i+1)+1;
1585 feqn.append(numConv.str());
1586 feqn.append(
"])/[");
1589 feqn.append(numConv.str());
1590 feqn.append(
"]) ) )");
1601 int PeakNumberWithNewPeak = std::get<1>(fPeakDevCand);
1602 int NewPeakMax = std::get<2>(fPeakDevCand);
1603 int OldPeakMax = std::get<0>(fpeakValsTemp.at(PeakNumberWithNewPeak));
1604 int OldPeakOldStart = std::get<2>(fpeakValsTemp.at(PeakNumberWithNewPeak));
1605 int OldPeakOldEnd = std::get<3>(fpeakValsTemp.at(PeakNumberWithNewPeak));
1609 int OldPeakNewStart=0;
1610 int OldPeakNewEnd=0;
1611 int DistanceBwOldAndNewPeak=0;
1613 if(NewPeakMax<OldPeakMax)
1615 NewPeakStart = OldPeakOldStart;
1616 OldPeakNewEnd = OldPeakOldEnd;
1617 DistanceBwOldAndNewPeak = OldPeakMax - NewPeakMax;
1618 NewPeakEnd = NewPeakMax+0.5*(DistanceBwOldAndNewPeak-(DistanceBwOldAndNewPeak%2));
1619 if(DistanceBwOldAndNewPeak%2 == 0) NewPeakEnd -= 1;
1620 OldPeakNewStart = NewPeakEnd+1;
1622 else if(OldPeakMax<NewPeakMax)
1624 NewPeakEnd = OldPeakOldEnd;
1625 OldPeakNewStart = OldPeakOldStart;
1626 DistanceBwOldAndNewPeak = NewPeakMax - OldPeakMax;
1627 OldPeakNewEnd = OldPeakMax+0.5*(DistanceBwOldAndNewPeak-(DistanceBwOldAndNewPeak%2));
1628 if(DistanceBwOldAndNewPeak%2 == 0) OldPeakNewEnd -= 1;
1629 NewPeakStart = OldPeakNewEnd+1;
1631 else if(OldPeakMax==NewPeakMax){
return;}
1633 fpeakValsTemp.at(PeakNumberWithNewPeak) = std::make_tuple(OldPeakMax,0,OldPeakNewStart,OldPeakNewEnd);
1634 fpeakValsTemp.emplace_back(NewPeakMax,0,NewPeakStart,NewPeakEnd);
1635 std::sort(fpeakValsTemp.begin(),fpeakValsTemp.end(), [](std::tuple<int,int,int,int>
const &
t1, std::tuple<int,int,int,int>
const &
t2) {
return std::get<0>(
t1) < std::get<0>(
t2);} );
1645 int PeakNumberWithNewPeak = std::get<1>(fPeakDevCand);
1646 int OldPeakOldStart = std::get<2>(fpeakValsTemp.at(PeakNumberWithNewPeak));
1647 int OldPeakOldEnd = std::get<3>(fpeakValsTemp.at(PeakNumberWithNewPeak));
1648 int WidthOldPeakOld = OldPeakOldEnd - OldPeakOldStart;
1650 if(WidthOldPeakOld<3) {
return;}
1653 int NewPeakStart = 0;
1655 int OldPeakNewMax = 0;
1656 int OldPeakNewStart = 0;
1657 int OldPeakNewEnd = 0;
1660 OldPeakNewStart = OldPeakOldStart;
1661 NewPeakEnd = OldPeakOldEnd;
1663 OldPeakNewEnd = OldPeakNewStart + 0.5*(WidthOldPeakOld + (WidthOldPeakOld%2));
1664 NewPeakStart = OldPeakNewEnd+1;
1666 int WidthOldPeakNew = OldPeakNewEnd-OldPeakNewStart;
1667 int WidthNewPeak = NewPeakEnd-NewPeakStart;
1669 OldPeakNewMax = OldPeakNewStart + 0.5*(WidthOldPeakNew - (WidthOldPeakNew%2));
1670 NewPeakMax = NewPeakStart + 0.5*(WidthNewPeak - (WidthNewPeak%2));
1672 fpeakValsTemp.at(PeakNumberWithNewPeak) = std::make_tuple(OldPeakNewMax,0,OldPeakNewStart,OldPeakNewEnd);
1673 fpeakValsTemp.emplace_back(NewPeakMax,0,NewPeakStart,NewPeakEnd);
1674 std::sort(fpeakValsTemp.begin(),fpeakValsTemp.end(), [](std::tuple<int,int,int,int>
const &
t1, std::tuple<int,int,int,int>
const &
t2) {
return std::get<0>(
t1) < std::get<0>(
t2);} );
1686 double fPeakMeanTrue)
1688 double MaxValue = ( fPeakAmp * exp(0.4*(fPeakMeanTrue-fPeakMean)/fPeakTau1)) / ( 1 + exp(0.4*(fPeakMeanTrue-fPeakMean)/fPeakTau2) );
1689 double FuncValue = 0.;
1690 double HalfMaxLeftTime = 0.;
1691 double HalfMaxRightTime = 0.;
1695 for(
double x = fPeakMeanTrue;
x > fStartTime-1000.;
x--)
1697 FuncValue = ( fPeakAmp * exp(0.4*(
x-fPeakMean)/fPeakTau1)) / ( 1 + exp(0.4*(
x-fPeakMean)/fPeakTau2) );
1698 if( FuncValue < 0.5*MaxValue )
1700 HalfMaxLeftTime =
x;
1705 for(
double x = fPeakMeanTrue;
x < fEndTime+1000.;
x++)
1707 FuncValue = ( fPeakAmp * exp(0.4*(
x-fPeakMean)/fPeakTau1)) / ( 1 + exp(0.4*(
x-fPeakMean)/fPeakTau2) );
1708 if( FuncValue < 0.5*MaxValue )
1710 HalfMaxRightTime =
x;
1716 for(
double x = HalfMaxLeftTime+1;
x > HalfMaxLeftTime;
x-=(1/ReBin))
1718 FuncValue = ( fPeakAmp * exp(0.4*(
x-fPeakMean)/fPeakTau1)) / ( 1 + exp(0.4*(
x-fPeakMean)/fPeakTau2) );
1719 if( FuncValue < 0.5*MaxValue )
1721 HalfMaxLeftTime =
x;
1726 for(
double x = HalfMaxRightTime-1;
x < HalfMaxRightTime;
x+=(1/ReBin))
1728 FuncValue = ( fPeakAmp * exp(0.4*(
x-fPeakMean)/fPeakTau1)) / ( 1 + exp(0.4*(
x-fPeakMean)/fPeakTau2) );
1729 if( FuncValue < 0.5*MaxValue )
1731 HalfMaxRightTime =
x;
1737 for(
double x = HalfMaxLeftTime+1/ReBin;
x > HalfMaxLeftTime;
x-=1/(ReBin*ReBin))
1739 FuncValue = ( fPeakAmp * exp(0.4*(
x-fPeakMean)/fPeakTau1)) / ( 1 + exp(0.4*(
x-fPeakMean)/fPeakTau2) );
1740 if( FuncValue < 0.5*MaxValue )
1742 HalfMaxLeftTime =
x;
1747 for(
double x = HalfMaxRightTime-1/ReBin;
x < HalfMaxRightTime;
x+=1/(ReBin*ReBin))
1749 FuncValue = ( fPeakAmp * exp(0.4*(
x-fPeakMean)/fPeakTau1)) / ( 1 + exp(0.4*(
x-fPeakMean)/fPeakTau2) );
1750 if( FuncValue < 0.5*MaxValue )
1752 HalfMaxRightTime =
x;
1757 return HalfMaxRightTime-HalfMaxLeftTime;
1765 double fChargeNormFactor,
1766 double fPeakMeanTrue)
1769 double ChargeSum = 0.;
1773 bool ChargeBigEnough=
true;
1774 for(
double x = fPeakMeanTrue - 1/ReBin; ChargeBigEnough &&
x > fPeakMeanTrue-1000.;
x-=1.)
1776 for(
double i=0.; i > -1.; i-=(1/ReBin))
1778 Charge = ( fPeakAmp * exp(0.4*(
x+i-fPeakMean)/fPeakTau1)) / ( 1 + exp(0.4*(
x+i-fPeakMean)/fPeakTau2) );
1779 ChargeSum += Charge;
1781 if(Charge < 0.01) ChargeBigEnough =
false;
1784 ChargeBigEnough=
true;
1785 for(
double x = fPeakMeanTrue; ChargeBigEnough &&
x < fPeakMeanTrue+1000.;
x+=1.)
1787 for(
double i=0.; i < 1.; i+=(1/ReBin))
1789 Charge = ( fPeakAmp * exp(0.4*(
x+i-fPeakMean)/fPeakTau1)) / ( 1 + exp(0.4*(
x+i-fPeakMean)/fPeakTau2) );
1790 ChargeSum += Charge;
1792 if(Charge < 0.01) ChargeBigEnough =
false;
1796 return ChargeSum*fChargeNormFactor/ReBin;
1801 std::vector<float>& outputVec,
1802 size_t binsToAverage)
const 1804 size_t halfBinsToAverage(binsToAverage/2);
1806 float runningSum(0.);
1808 for(
size_t idx = 0; idx < halfBinsToAverage; idx++) runningSum += inputVec[idx];
1810 outputVec.resize(inputVec.size());
1816 size_t startOffset = std::distance(inputVec.begin(),inputItr);
1817 size_t stopOffset = std::distance(inputItr,inputVec.end());
1818 size_t count =
std::min(2 * halfBinsToAverage,
std::min(startOffset + halfBinsToAverage + 1, halfBinsToAverage + stopOffset - 1));
1820 if (startOffset >= halfBinsToAverage) runningSum -= *(inputItr - halfBinsToAverage);
1821 if (stopOffset > halfBinsToAverage) runningSum += *(inputItr + halfBinsToAverage);
1823 *outputVecItr++ = runningSum / float(count);
1831 std::vector<float>& outputVec,
1832 size_t nBinsToCombine)
const 1834 size_t nNewBins = inputVec.size() / nBinsToCombine;
1836 if (inputVec.size() % nBinsToCombine > 0) nNewBins++;
1838 outputVec.resize(nNewBins, 0.);
1840 size_t outputBin = 0;
1842 for(
size_t inputIdx = 0; inputIdx < inputVec.size();)
1844 outputVec[outputBin] += inputVec[inputIdx++];
1846 if (inputIdx % nBinsToCombine == 0) outputBin++;
1848 if (outputBin > outputVec.size())
1850 std::cout <<
"***** DISASTER!!! ****** outputBin: " << outputBin <<
", inputIdx = " << inputIdx << std::endl;
1862 #endif // DPRawHitFinder_H
void findCandidatePeaks(std::vector< float >::const_iterator startItr, std::vector< float >::const_iterator stopItr, TimeValsVec &timeValsVec, float &PeakMin, int firstTick) const
int fTicksToStopPeakFinder
Encapsulate the construction of a single cyostat.
double fMergeADCSumThreshold
void mergeCandidatePeaks(const std::vector< float > signalVec, TimeValsVec, MergedTimeWidVec &)
bool operator()(std::tuple< int, int, int, int > p, int s) const
Declaration of signal hit object.
std::vector< std::tuple< int, int, PeakTimeWidVec, int >> MergedTimeWidVec
void produce(art::Event &evt) override
void FindPeakWithMaxDeviation(const std::vector< float > fSignalVector, int fNPeaks, int fStartTime, int fEndTime, bool fSameShape, ParameterVec fparamVec, PeakTimeWidVec fpeakVals, PeakDevVec &fPeakDev)
std::vector< std::tuple< double, int, int, int >> PeakDevVec
std::vector< geo::WireID > ChannelToWire(raw::ChannelID_t const channel) const
Returns a list of wires connected to the specified TPC channel.
CryostatID_t Cryostat
Index of cryostat.
const range_list_t & get_ranges() const
Returns the internal list of non-void ranges.
WireID_t Wire
Index of the wire within its plane.
static void declare_products(ModuleType &producer, std::string instance_name="", bool doWireAssns=true, bool doRawDigitAssns=true)
Declares the hit products we are going to fill.
void SplitPeak(std::tuple< double, int, int, int > fPeakDevCand, PeakTimeWidVec &fpeakValsTemp)
double fChi2NDFMaxFactorMultiHits
DPRawHitFinder(fhicl::ParameterSet const &pset)
void addVector(FVector_ID id, std::array< float, N > const &values)
int TDCtick_t
Type representing a TDC tick.
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
std::vector< std::tuple< int, int, int, int >> PeakTimeWidVec
Class managing the creation of a new recob::Hit object.
void FillOutHitParameterVector(const std::vector< double > &input, std::vector< double > &output)
Helper functions to create a hit.
FVector_ID initOutputs(std::string const &dataTag, size_t dataSize, std::vector< std::string > const &names=std::vector< std::string >(N,""))
unsigned int Nplanes(unsigned int tpc=0, unsigned int cstat=0) const
Returns the total number of wire planes in the specified TPC.
constexpr ChannelID_t InvalidChannelID
ID of an invalid channel.
void AddPeak(std::tuple< double, int, int, int > fPeakDevCand, PeakTimeWidVec &fpeakValsTemp)
double fChi2NDFRetryFactorMultiHits
A class handling a collection of hits and its associations.
#define DEFINE_ART_MODULE(klass)
std::vector< std::pair< double, double >> ParameterVec
double fMergeMaxADCThreshold
double fWidthNormalization
raw::ChannelID_t Channel() const
Returns the ID of the channel (or InvalidChannelID)
anab::FVectorWriter< 4 > fHitParamWriter
void reconfigure(fhicl::ParameterSet const &p)
T get(std::string const &key) const
std::string CreateFitFunction(int fNPeaks, bool fSameShape)
const RegionsOfInterest_t & SignalROI() const
Returns the list of regions of interest.
double ChargeFunc(double fPeakMean, double fPeakAmp, double fPeakTau1, double fPeakTau2, double fChargeNormFactor, double fPeakMeanTrue)
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 fMinADCSumOverWidth
double fMinRelativePeakHeightLeft
PlaneID_t Plane
Index of the plane within its TPC.
void put_into(art::Event &)
Moves the data into an event.
void saveOutputs(art::Event &evt)
Check consistency and save all the results in the event.
Detector simulation of raw signals on wires.
void FitExponentials(const std::vector< float > fSignalVector, const PeakTimeWidVec fPeakVals, int fStartTime, int fEndTime, ParameterVec &fparamVec, double &fchi2PerNDF, int &fNDF, bool fSameShape)
std::string fCalDataModuleLabel
T * make(ARGS...args) const
std::vector< std::tuple< int, int, int >> TimeValsVec
Encapsulate the construction of a single detector plane.
bool getByLabel(std::string const &label, std::string const &productInstanceName, Handle< PROD > &result) const
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
Declaration of basic channel signal object.
int EstimateFluctuations(const std::vector< float > fsignalVec, int peakStart, int peakMean, int peakEnd)
void doBinAverage(const std::vector< float > &inputVec, std::vector< float > &outputVec, size_t binsToAverage) const
2D representation of charge deposited in the TDC/wire plane
unsigned int ChannelID_t
Type representing the ID of a readout channel.
TPCID_t TPC
Index of the TPC within its cryostat.
recob::Hit && move()
Prepares the constructed hit to be moved away.
art::InputTag fNewHitsTag
double WidthFunc(double fPeakMean, double fPeakAmp, double fPeakTau1, double fPeakTau2, double fStartTime, double fEndTime, double fPeakMeanTrue)
void reBin(const std::vector< float > &inputVec, std::vector< float > &outputVec, size_t nBinsToCombine) const
art framework interface to geometry description
double fMinRelativePeakHeightRight
Encapsulate the construction of a single detector plane.
bool operator()(int s, std::tuple< int, int, int, int > p) const