CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
CSCFindPeakTime.cc
Go to the documentation of this file.
1 // This is CSCFindPeakTime
2 
5 
6 #include <cmath>
7 
9  useAverageTime(false), useParabolaFit(false), useFivePoleFit(false) {
10 
11  useAverageTime = ps.getParameter<bool>("UseAverageTime");
12  useParabolaFit = ps.getParameter<bool>("UseParabolaFit");
13  useFivePoleFit = ps.getParameter<bool>("UseFivePoleFit");
14  LogTrace("CSCRecHit|CSCFindPeakTime") << "CSCFindPeakTime: useAverageTime=" << useAverageTime <<
15  ", useParabolaFit=" << useParabolaFit << ", useFivePoleFit=" << useFivePoleFit;
16 }
17 
18 float CSCFindPeakTime::peakTime( int tmax, const float* adc, float t_peak){
19  if ( useAverageTime ) {
20  return averageTime( tmax, adc );
21  }
22  else if ( useParabolaFit ) {
23  return parabolaFitTime( tmax, adc );
24  }
25  else if ( useFivePoleFit ) {
26  return fivePoleFitTime( tmax, adc, t_peak);
27  }
28  else {
29  // return something, anyway.. may as well be average
30  return averageTime( tmax, adc );
31  }
32 }
33 
34 float CSCFindPeakTime::averageTime( int tmax, const float* adc ) {
35  float sum = 0.;
36  float sumt = 0.;
37  for (size_t i=0; i<4; ++i){
38  sum += adc[i];
39  sumt += adc[i] * ( tmax - 1 + i );
40 
41  }
42  return sumt/sum * 50.; //@@ in ns. May be some bin width offset things to handle here?
43 }
44 
45 float CSCFindPeakTime::parabolaFitTime( int tmax, const float* adc ) {
46  // 3-point parabolic fit, from Andy Kubik
47 
48  // We calculate offset to tmax by finding the peak of a parabola through three points
49  float tpeak = tmax;
50  float tcorr = 0;
51 
52  // By construction, input array adc is for bins tmax-1 to tmax+2
53  float y1 = adc[0];
54  float y2 = adc[1];
55  float y3 = adc[2];
56 
57  // Checked and simplified... Tim Cox 08-Apr-2009
58  // Denominator is not zero unless we fed in nonsense values with y2 not the peak!
59  if ( (y1+y3) < 2.*y2 ) tcorr = 0.5 * ( y1 - y3 ) / ( y1 - 2.*y2 + y3 );
60  tpeak += tcorr;
61 
62  LogTrace("CSCRecHit|CSCFindPeakTime") << "CSCFindPeakTime: tmax=" << tmax
63  << ", parabolic peak time is tmax+" << tcorr <<" bins, or " << tpeak*50. << " ns";
64 
65  return tpeak * 50.; // convert to ns.
66 }
67 
68 float CSCFindPeakTime::fivePoleFitTime( int tmax, const float* adc, float t_peak ) {
69 
70  // Input is
71  // tmax = bin# 0-7 containing max SCA pulse height
72  // adc = 4-dim array containing SCA pulse heights in bins tmax-1 to tmax+2
73  // t_peak = input estimate for SCA peak time
74 
75  // Returned value is improved (we hope) estimate for SCA peak time
76 
77  // Algorithm is to fit five-pole Semi-Gaussian function for start time of SCA pulse, t0
78  // (The SCA peak is assumed to be 133 ns from t0.)
79  // Note that t^4 in time domain corresponds to 1/t^5 in frequency domain (that's the 5 poles).
80 
81  // Initialize parameters to sensible (?) values
82 
83  float fpNorm = adc[1]; // this is tmax bin
84  float t0 = 0.;
85  float t0peak = 133.; // this is offset of peak from start time t0
86  float p0 = 4./t0peak;
87 
88  // Require that tmax is in range 2-6 of bins the eight SCA time bins 0-7
89  // (Bins 0, 1 used for dynamic ped)
90 
91  if ( tmax < 2 || tmax > 6 ) return t_peak; //@@ Just return the input value
92 
93  // Set up time bins to match adc[4] input
94 
95  float tb[4];
96  for ( int time=0; time<4; ++time ){
97  tb[time] = (tmax + time -1) * 50.;
98  }
99 
100  // How many time bins are we fitting?
101 
102  int n_fit = 4;
103  if ( tmax == 6 ) n_fit = 3;
104 
105  float chi_min = 1.e10;
106  float chi_last = 1.e10;
107  float tt0 = 0.;
108  float chi2 = 0.;
109  float del_t = 100.;
110 
111  float x[4];
112  float sx2 = 0.;
113  float sxy = 0.;
114  float fN = 0.;
115 
116  while ( del_t > 1. ) {
117  sx2 = 0.;
118  sxy = 0.;
119 
120  for ( int j=0; j < n_fit; ++j ) {
121  float tdif = tb[j] - tt0;
122  x[j] = tdif * tdif * tdif * tdif * exp( -p0 * tdif );
123  sx2 += x[j] * x[j];
124  sxy += x[j] * adc[j];
125  }
126  fN = sxy / sx2; // least squares fit over time bins i to adc[i] = fN * fivePoleFunction[i]
127 
128  // Compute chi^2
129  chi2 = 0.0;
130  for (int j=0; j < n_fit; ++j) chi2 += (adc[j] - fN * x[j]) * (adc[j] - fN * x[j]);
131 
132  // Test on chi^2 to decide what to do
133  if ( chi_last > chi2 ) {
134  if (chi2 < chi_min ){
135  t0 = tt0;
136  fpNorm = fN;
137  }
138  chi_last = chi2;
139  tt0 = tt0 + del_t;
140  } else {
141  tt0 = tt0 - 2. * del_t;
142  del_t = del_t / 2.;
143  tt0 = tt0 + del_t;
144  chi_last = 1.0e10;
145  }
146  }
147 
148  return t0 + t0peak;
149 }
150 
151 
152 
153 void CSCFindPeakTime::fivePoleFitCharge( int tmax, const float* adc, const float& t_zero, const float& t_peak, std::vector<float>& adcsFit ) {
154 
155  //@@ This code can certainly be replaced by fivePoleFitTime above, but I haven't time to do that now (Tim).
156 
157  float p0 = 4./t_peak;
158  float tt0 = t_zero;
159  int n_fit = 4;
160  if ( tmax == 6 ) n_fit=3;
161 
162  float tb[4], y[4];
163  for ( int t = 0; t < 4; ++t ){
164  tb[t] = (tmax + t - 1) * 50.;
165  y[t] = adc[t];
166  }
167 
168  // Find the normalization factor for the function
169  float x[4];
170  float sx2 = 0.;
171  float sxy = 0.;
172  for ( int j=0; j < n_fit; ++j ) {
173  float t = tb[j];
174  x[j] = (t-tt0)*(t-tt0)*(t-tt0)*(t-tt0) * exp( -p0 * (t-tt0) );
175  sx2 = sx2 + x[j] * x[j];
176  sxy = sxy + x[j] * y[j];
177  }
178  float N = sxy / sx2;
179 
180 
181  // Now compute charge for a given t --> only need charges at: t_peak-50, t_peak and t_peak+50
182  for ( int i = 0; i < 3; ++i ) {
183  float t = t_peak + (i - 1) * 50.;
184  float q_fitted = N * (t-tt0)*(t-tt0)*(t-tt0)*(t-tt0) * exp( -p0 * (t-tt0) );
185  adcsFit.push_back(q_fitted);
186  }
187  return;
188 }
189 
190 
int adc(sample_type sample)
get the ADC sample (12 bits)
float parabolaFitTime(int tmax, const float *adc)
Parabolic fit to three time bins centered on maximum.
T getParameter(std::string const &) const
int i
Definition: DBlmapReader.cc:9
float fivePoleFitTime(int tmax, const float *adc, float t_peak)
Exp< T >::type exp(const T &t)
Definition: Exp.h:22
void fivePoleFitCharge(int tmax, const float *adc, const float &t_zero, const float &t_peak, std::vector< float > &adcsFit)
int j
Definition: DBlmapReader.cc:9
#define LogTrace(id)
static const double tmax[3]
CSCFindPeakTime(const edm::ParameterSet &ps)
Definition: DDAxes.h:10
float averageTime(int tmax, const float *adc)
Weighted average of time bins.
float peakTime(int tmax, const float *adc, float t_peak)
Basic result of this class.