18 #include "cetlib_except/exception.h"
25 unsigned int min_multi,
35 unsigned int min_multi,
38 fMeanMatchThreshold = max_mean;
39 fMinMergeMultiplicity = min_multi;
41 if(fMinMergeMultiplicity==0) fMinMergeMultiplicity=1;
43 fFinalAmpThreshold = threshold;
51 CalculateAllMeansAndSigmas(signal);
53 CalculateMergedMeansAndSigmas(signal.size());
54 CalculateAmplitudes(signal);
59 if(signal.size()<=2)
return;
61 float prev_dev=0,this_dev=0;;
62 float slope=0;
float sigma=0;
63 float intercept=0;
float mean=0;
65 for(
size_t i_tick=1; i_tick < signal.size()-1; i_tick++)
67 this_dev = 0.5*(signal[i_tick+1]-signal[i_tick-1])/signal[i_tick];
68 slope = this_dev - prev_dev;
72 if(slope>=0)
continue;
74 sigma = std::sqrt(-1/slope);
75 intercept = 0.5*(signal[i_tick+1]-signal[i_tick-1])/signal[i_tick] - slope*i_tick;
76 mean = -1*intercept/slope;
78 fSignalSet.insert(std::make_pair(mean,sigma));
84 fMergeVector.clear(); fMergeVector.reserve( fSignalSet.size() );
87 for(std::multiset<MeanSigmaPair>::iterator it=fSignalSet.begin(); it!=fSignalSet.end(); it++)
89 if(
std::abs(it->first - prev_mean) > fMeanMatchThreshold || fMergeVector.size()==0 )
90 fMergeVector.push_back(
std::vector< std::multiset<MeanSigmaPair>::iterator >(1,it) );
92 fMergeVector.back().push_back(it);
93 prev_mean = it->first;
99 fMeanVector.reserve(fMergeVector.size());
100 fSigmaVector.reserve(fMergeVector.size());
101 fMeanErrorVector.reserve(fMergeVector.size());
102 fSigmaErrorVector.reserve(fMergeVector.size());
104 for(
size_t i_col=0; i_col<fMergeVector.size(); i_col++)
106 if(fMergeVector[i_col].
size()<fMinMergeMultiplicity)
continue;
108 fMeanVector.push_back(0.0);
109 fSigmaVector.push_back(0.0);
111 for(
auto const& sigpair : fMergeVector[i_col])
113 fMeanVector.back() += sigpair->first;
114 fSigmaVector.back() += sigpair->second;
117 fMeanVector.back() /= fMergeVector[i_col].size();
118 fSigmaVector.back() /= fMergeVector[i_col].size();
120 if(fMeanVector.back() < 0 || fMeanVector.back()>signal_size-1)
122 fMeanVector.pop_back();
123 fSigmaVector.pop_back();
127 fMeanErrorVector.push_back(0.0);
128 fSigmaErrorVector.push_back(0.0);
130 for(
auto const& sigpair : fMergeVector[i_col])
132 fMeanErrorVector.back() +=
133 (sigpair->first-fMeanVector.back())*(sigpair->first-fMeanVector.back());
134 fSigmaErrorVector.back() +=
135 (sigpair->second-fSigmaVector.back())*(sigpair->second-fSigmaVector.back());
138 fMeanErrorVector.back() = std::sqrt(fMeanErrorVector.back()) / fMergeVector[i_col].
size();
139 fSigmaErrorVector.back() = std::sqrt(fSigmaErrorVector.back()) / fMergeVector[i_col].
size();
147 std::vector<float> heightVector(fMeanVector.size());
150 for(
size_t i=0; i<fMeanVector.size(); i++)
152 if (fMeanVector[i]<0) bin=0;
153 else if(fMeanVector[i]+1 > signal.size()) bin=signal.size()-2;
154 else bin = std::floor(fMeanVector[i]);
156 if(bin >= signal.size()-1)
157 throw cet::exception(
"RFFHitFitter") <<
"Error in CalculatAmplitudes! bin is out of range!\n"
158 <<
"\tFor element " << i <<
" bin is " << bin <<
"(" << fMeanVector[i] <<
")"
159 <<
" but size is " << signal.size() <<
".\n";
161 heightVector[i] = signal[
bin] - (fMeanVector[i]-(float)bin)*(signal[
bin]-signal[bin+1]);
164 fAmpVector = fGEAlg.SolveEquations(fMeanVector,fSigmaVector,heightVector);
166 while(HitsBelowThreshold())
168 for(
size_t i=0; i<fAmpVector.size(); i++)
170 if(fAmpVector[i] < fFinalAmpThreshold)
172 fMeanVector.erase(fMeanVector.begin()+i);
173 fMeanErrorVector.erase(fMeanErrorVector.begin()+i);
174 fSigmaVector.erase(fSigmaVector.begin()+i);
175 fSigmaErrorVector.erase(fSigmaErrorVector.begin()+i);
176 fAmpVector.erase(fAmpVector.begin()+i);
177 heightVector.erase(heightVector.begin()+i);
180 fAmpVector = fGEAlg.SolveEquations(fMeanVector,fSigmaVector,heightVector);
183 fAmpErrorVector.resize(fAmpVector.size(),0.0);
188 for(
auto const& amp : fAmpVector)
189 if(amp < fFinalAmpThreshold)
return true;
196 fSigmaVector.clear();
197 fMeanErrorVector.clear();
198 fSigmaErrorVector.clear();
200 fAmpErrorVector.clear();
202 fMergeVector.clear();
207 std::cout <<
"InitialSignalSet" << std::endl;
209 for(
auto const& sigpair : fSignalSet)
210 std::cout <<
"\t" << sigpair.first <<
" / " << sigpair.second << std::endl;
212 std::cout <<
"\nNHits = " << NHits() << std::endl;
213 std::cout <<
"\tMean / Sigma / Amp" << std::endl;
214 for(
size_t i=0; i<NHits(); i++)
216 << fMeanVector[i] <<
" +- " << fMeanErrorVector[i] <<
" / "
217 << fSigmaVector[i] <<
" +- " << fSigmaErrorVector[i] <<
" / "
218 << fAmpVector[i] <<
" +- " << fAmpErrorVector[i]
void RunFitter(const std::vector< float > &signal)
void SetFitterParams(float, unsigned int, float)
std::size_t size(FixedBins< T, C > const &) noexcept
void CalculateMergedMeansAndSigmas(std::size_t signal_size)
constexpr details::BinObj< T > bin(T value)
Returns a wrapper to print the specified data in binary format.
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
void CalculateAllMeansAndSigmas(const std::vector< float > &signal)
bool HitsBelowThreshold()
double mean(const std::vector< short > &wf, size_t start, size_t nsample)
RFFHitFitter(float, unsigned int, float, float step=0.1, float max=5.0)
void CalculateAmplitudes(const std::vector< float > &signal)
BEGIN_PROLOG could also be cout