Go to the documentation of this file.00001
00002
00003 #include <RecoLocalMuon/CSCRecHitD/src/CSCFindPeakTime.h>
00004 #include <FWCore/MessageLogger/interface/MessageLogger.h>
00005
00006 #include <cmath>
00007
00008 CSCFindPeakTime::CSCFindPeakTime( const edm::ParameterSet& ps ):
00009 useAverageTime(false), useParabolaFit(false), useFivePoleFit(false) {
00010
00011 useAverageTime = ps.getParameter<bool>("UseAverageTime");
00012 useParabolaFit = ps.getParameter<bool>("UseParabolaFit");
00013 useFivePoleFit = ps.getParameter<bool>("UseFivePoleFit");
00014 LogTrace("CSCRecHit|CSCFindPeakTime") << "CSCFindPeakTime: useAverageTime=" << useAverageTime <<
00015 ", useParabolaFit=" << useParabolaFit << ", useFivePoleFit=" << useFivePoleFit;
00016 }
00017
00018 float CSCFindPeakTime::peakTime( int tmax, const float* adc, float t_peak){
00019 if ( useAverageTime ) {
00020 return averageTime( tmax, adc );
00021 }
00022 else if ( useParabolaFit ) {
00023 return parabolaFitTime( tmax, adc );
00024 }
00025 else if ( useFivePoleFit ) {
00026 return fivePoleFitTime( tmax, adc, t_peak);
00027 }
00028 else {
00029
00030 return averageTime( tmax, adc );
00031 }
00032 }
00033
00034 float CSCFindPeakTime::averageTime( int tmax, const float* adc ) {
00035 float sum = 0.;
00036 float sumt = 0.;
00037 for (size_t i=0; i<4; ++i){
00038 sum += adc[i];
00039 sumt += adc[i] * ( tmax - 1 + i );
00040
00041 }
00042 return sumt/sum * 50.;
00043 }
00044
00045 float CSCFindPeakTime::parabolaFitTime( int tmax, const float* adc ) {
00046
00047
00048
00049 float tpeak = tmax;
00050 float tcorr = 0;
00051
00052
00053 float y1 = adc[0];
00054 float y2 = adc[1];
00055 float y3 = adc[2];
00056
00057
00058
00059 if ( (y1+y3) < 2.*y2 ) tcorr = 0.5 * ( y1 - y3 ) / ( y1 - 2.*y2 + y3 );
00060 tpeak += tcorr;
00061
00062 LogTrace("CSCRecHit|CSCFindPeakTime") << "CSCFindPeakTime: tmax=" << tmax
00063 << ", parabolic peak time is tmax+" << tcorr <<" bins, or " << tpeak*50. << " ns";
00064
00065 return tpeak * 50.;
00066 }
00067
00068 float CSCFindPeakTime::fivePoleFitTime( int tmax, const float* adc, float t_peak ) {
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083 float fpNorm = adc[1];
00084 float t0 = 0.;
00085 float t0peak = 133.;
00086 float p0 = 4./t0peak;
00087
00088
00089
00090
00091 if ( tmax < 2 || tmax > 6 ) return t_peak;
00092
00093
00094
00095 float tb[4];
00096 for ( int time=0; time<4; ++time ){
00097 tb[time] = (tmax + time -1) * 50.;
00098 }
00099
00100
00101
00102 int n_fit = 4;
00103 if ( tmax == 6 ) n_fit = 3;
00104
00105 float chi_min = 1.e10;
00106 float chi_last = 1.e10;
00107 float tt0 = 0.;
00108 float chi2 = 0.;
00109 float del_t = 100.;
00110
00111 float x[4];
00112 float sx2 = 0.;
00113 float sxy = 0.;
00114 float fN = 0.;
00115
00116 while ( del_t > 1. ) {
00117 sx2 = 0.;
00118 sxy = 0.;
00119
00120 for ( int j=0; j < n_fit; ++j ) {
00121 float tdif = tb[j] - tt0;
00122 x[j] = tdif * tdif * tdif * tdif * exp( -p0 * tdif );
00123 sx2 += x[j] * x[j];
00124 sxy += x[j] * adc[j];
00125 }
00126 fN = sxy / sx2;
00127
00128
00129 chi2 = 0.0;
00130 for (int j=0; j < n_fit; ++j) chi2 += (adc[j] - fN * x[j]) * (adc[j] - fN * x[j]);
00131
00132
00133 if ( chi_last > chi2 ) {
00134 if (chi2 < chi_min ){
00135 t0 = tt0;
00136 fpNorm = fN;
00137 }
00138 chi_last = chi2;
00139 tt0 = tt0 + del_t;
00140 } else {
00141 tt0 = tt0 - 2. * del_t;
00142 del_t = del_t / 2.;
00143 tt0 = tt0 + del_t;
00144 chi_last = 1.0e10;
00145 }
00146 }
00147
00148 return t0 + t0peak;
00149 }
00150
00151
00152
00153 void CSCFindPeakTime::fivePoleFitCharge( int tmax, const float* adc, const float& t_zero, const float& t_peak, std::vector<float>& adcsFit ) {
00154
00155
00156
00157 float p0 = 4./t_peak;
00158 float tt0 = t_zero;
00159 int n_fit = 4;
00160 if ( tmax == 6 ) n_fit=3;
00161
00162 float tb[4], y[4];
00163 for ( int t = 0; t < 4; ++t ){
00164 tb[t] = (tmax + t - 1) * 50.;
00165 y[t] = adc[t];
00166 }
00167
00168
00169 float x[4];
00170 float sx2 = 0.;
00171 float sxy = 0.;
00172 for ( int j=0; j < n_fit; ++j ) {
00173 float t = tb[j];
00174 x[j] = (t-tt0)*(t-tt0)*(t-tt0)*(t-tt0) * exp( -p0 * (t-tt0) );
00175 sx2 = sx2 + x[j] * x[j];
00176 sxy = sxy + x[j] * y[j];
00177 }
00178 float N = sxy / sx2;
00179
00180
00181
00182 for ( int i = 0; i < 3; ++i ) {
00183 float t = t_peak + (i - 1) * 50.;
00184 float q_fitted = N * (t-tt0)*(t-tt0)*(t-tt0)*(t-tt0) * exp( -p0 * (t-tt0) );
00185 adcsFit.push_back(q_fitted);
00186 }
00187 return;
00188 }
00189
00190