RFFHitFitter.cxx
Go to the documentation of this file.
1 /*!
2  * Title: RFFHitFitter Class
3  * Author: Wes Ketchum (wketchum@lanl.gov)
4  *
5  * Description:
6  * Class that does the base RFF algorithm. RFF works by simplifiying a Gaussian
7  * fit by dividing a pulse by its derivative. for a Gaussian, the result is a
8  * line, with the slope and intercept related to the sigma and mean of the
9  * Gaussian.
10  *
11  * Input: Signal (vector of floats)
12  * Output: Guassian means and sigmas
13 */
14 
15 #include "RFFHitFitter.h"
16 #include <iostream>
17 #include <cmath>
18 #include "cetlib_except/exception.h"
19 
21  fGEAlg(step,max)
22 {}
23 
25  unsigned int min_multi,
26  float threshold,
27  float step,
28  float max):
29  fGEAlg(step,max)
30 {
31  SetFitterParams(max_mean,min_multi,threshold);
32 }
33 
35  unsigned int min_multi,
36  float threshold)
37 {
38  fMeanMatchThreshold = max_mean;
39  fMinMergeMultiplicity = min_multi;
40 
42 
43  fFinalAmpThreshold = threshold;
44 
45  ClearResults();
46 }
47 
48 void hit::RFFHitFitter::RunFitter(const std::vector<float>& signal)
49 {
50  ClearResults();
53  CalculateMergedMeansAndSigmas(signal.size());
54  CalculateAmplitudes(signal);
55 }
56 
57 void hit::RFFHitFitter::CalculateAllMeansAndSigmas(const std::vector<float>& signal)
58 {
59  if(signal.size()<=2) return;
60 
61  float prev_dev=0,this_dev=0;;
62  float slope=0; float sigma=0;
63  float intercept=0; float mean=0;
64 
65  for(size_t i_tick=1; i_tick < signal.size()-1; i_tick++)
66  {
67  this_dev = 0.5*(signal[i_tick+1]-signal[i_tick-1])/signal[i_tick];
68  slope = this_dev - prev_dev;
69 
70  prev_dev = this_dev;
71 
72  if(slope>=0) continue;
73 
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;
77 
78  fSignalSet.insert(std::make_pair(mean,sigma));
79  }
80 }
81 
83 {
84  fMergeVector.clear(); fMergeVector.reserve( fSignalSet.size() );
85 
86  float prev_mean=-9e6;
87  for(std::multiset<MeanSigmaPair>::iterator it=fSignalSet.begin(); it!=fSignalSet.end(); it++)
88  {
89  if( std::abs(it->first - prev_mean) > fMeanMatchThreshold || fMergeVector.size()==0 )
91  else
92  fMergeVector.back().push_back(it);
93  prev_mean = it->first;
94  }
95 }
96 
98 {
99  fMeanVector.reserve(fMergeVector.size());
100  fSigmaVector.reserve(fMergeVector.size());
101  fMeanErrorVector.reserve(fMergeVector.size());
102  fSigmaErrorVector.reserve(fMergeVector.size());
103 
104  for(size_t i_col=0; i_col<fMergeVector.size(); i_col++)
105  {
106  if(fMergeVector[i_col].size()<fMinMergeMultiplicity) continue;
107 
108  fMeanVector.push_back(0.0);
109  fSigmaVector.push_back(0.0);
110 
111  for(auto const& sigpair : fMergeVector[i_col])
112  {
113  fMeanVector.back() += sigpair->first;
114  fSigmaVector.back() += sigpair->second;
115  }
116 
117  fMeanVector.back() /= fMergeVector[i_col].size();
118  fSigmaVector.back() /= fMergeVector[i_col].size();
119 
120  if(fMeanVector.back() < 0 || fMeanVector.back()>signal_size-1)
121  {
122  fMeanVector.pop_back();
123  fSigmaVector.pop_back();
124  continue;
125  }
126 
127  fMeanErrorVector.push_back(0.0);
128  fSigmaErrorVector.push_back(0.0);
129 
130  for(auto const& sigpair : fMergeVector[i_col])
131  {
132  fMeanErrorVector.back() +=
133  (sigpair->first-fMeanVector.back())*(sigpair->first-fMeanVector.back());
134  fSigmaErrorVector.back() +=
135  (sigpair->second-fSigmaVector.back())*(sigpair->second-fSigmaVector.back());
136  }
137 
138  fMeanErrorVector.back() = std::sqrt(fMeanErrorVector.back()) / fMergeVector[i_col].size();
139  fSigmaErrorVector.back() = std::sqrt(fSigmaErrorVector.back()) / fMergeVector[i_col].size();
140 
141  }
142 
143 }
144 
145 void hit::RFFHitFitter::CalculateAmplitudes(const std::vector<float>& signal)
146 {
147  std::vector<float> heightVector(fMeanVector.size());
148  size_t bin=0;
149 
150  for(size_t i=0; i<fMeanVector.size(); i++)
151  {
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]);
155 
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";
160 
161  heightVector[i] = signal[bin] - (fMeanVector[i]-(float)bin)*(signal[bin]-signal[bin+1]);
162  }
163 
165 
166  while(HitsBelowThreshold())
167  {
168  for(size_t i=0; i<fAmpVector.size(); i++)
169  {
171  {
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);
178  }
179  }
181  }
182 
183  fAmpErrorVector.resize(fAmpVector.size(),0.0);
184 }
185 
187 {
188  for(auto const& amp : fAmpVector)
189  if(amp < fFinalAmpThreshold) return true;
190  return false;
191 }
192 
194 {
195  fMeanVector.clear();
196  fSigmaVector.clear();
197  fMeanErrorVector.clear();
198  fSigmaErrorVector.clear();
199  fAmpVector.clear();
200  fAmpErrorVector.clear();
201  fSignalSet.clear();
202  fMergeVector.clear();
203 }
204 
206 {
207  std::cout << "InitialSignalSet" << std::endl;
208 
209  for(auto const& sigpair : fSignalSet)
210  std::cout << "\t" << sigpair.first << " / " << sigpair.second << std::endl;
211 
212  std::cout << "\nNHits = " << NHits() << std::endl;
213  std::cout << "\tMean / Sigma / Amp" << std::endl;
214  for(size_t i=0; i<NHits(); i++)
215  std::cout << "\t"
216  << fMeanVector[i] << " +- " << fMeanErrorVector[i] << " / "
217  << fSigmaVector[i] << " +- " << fSigmaErrorVector[i] << " / "
218  << fAmpVector[i] << " +- " << fAmpErrorVector[i]
219  << std::endl;
220 }
intermediate_table::iterator iterator
std::vector< float > fAmpErrorVector
Definition: RFFHitFitter.h:70
unsigned int fMinMergeMultiplicity
Definition: RFFHitFitter.h:57
void RunFitter(const std::vector< float > &signal)
void SetFitterParams(float, unsigned int, float)
struct vector vector
void CalculateMergedMeansAndSigmas(std::size_t signal_size)
std::vector< float > fSigmaVector
Definition: RFFHitFitter.h:66
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
Definition: StdUtils.h:92
void CalculateAllMeansAndSigmas(const std::vector< float > &signal)
T abs(T value)
std::vector< std::vector< std::multiset< MeanSigmaPair >::iterator > > fMergeVector
Definition: RFFHitFitter.h:74
util::GaussianEliminationAlg fGEAlg
Definition: RFFHitFitter.h:63
float fFinalAmpThreshold
Definition: RFFHitFitter.h:58
const std::vector< float > & SolveEquations(const std::vector< float > &meanVector, const std::vector< float > &sigmaVector, const std::vector< float > &heightVector)
static int max(int a, int b)
std::multiset< MeanSigmaPair, SignalSetComp > fSignalSet
Definition: RFFHitFitter.h:72
std::vector< float > fAmpVector
Definition: RFFHitFitter.h:69
RFFHitFitter(float, unsigned int, float, float step=0.1, float max=5.0)
void CalculateAmplitudes(const std::vector< float > &signal)
std::vector< float > fSigmaErrorVector
Definition: RFFHitFitter.h:68
QTextStream & bin(QTextStream &s)
float fMeanMatchThreshold
Definition: RFFHitFitter.h:56
unsigned int NHits()
Definition: RFFHitFitter.h:49
double mean(sqlite3 *db, std::string const &table_name, std::string const &column_name)
Definition: statistics.cc:16
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
QTextStream & endl(QTextStream &s)
std::vector< float > fMeanVector
Definition: RFFHitFitter.h:65
std::vector< float > fMeanErrorVector
Definition: RFFHitFitter.h:67