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 t0 = 0.;
00084 float t0peak = 133.;
00085 float p0 = 4./t0peak;
00086
00087
00088
00089
00090 if ( tmax < 2 || tmax > 6 ) return t_peak;
00091
00092
00093
00094 float tb[4];
00095 for ( int time=0; time<4; ++time ){
00096 tb[time] = (tmax + time -1) * 50.;
00097 }
00098
00099
00100
00101 int n_fit = 4;
00102 if ( tmax == 6 ) n_fit = 3;
00103
00104 float chi_min = 1.e10;
00105 float chi_last = 1.e10;
00106 float tt0 = 0.;
00107 float chi2 = 0.;
00108 float del_t = 100.;
00109
00110 float x[4];
00111 float sx2 = 0.;
00112 float sxy = 0.;
00113 float fN = 0.;
00114
00115 while ( del_t > 1. ) {
00116 sx2 = 0.;
00117 sxy = 0.;
00118
00119 for ( int j=0; j < n_fit; ++j ) {
00120 float tdif = tb[j] - tt0;
00121 x[j] = tdif * tdif * tdif * tdif * exp( -p0 * tdif );
00122 sx2 += x[j] * x[j];
00123 sxy += x[j] * adc[j];
00124 }
00125 fN = sxy / sx2;
00126
00127
00128 chi2 = 0.0;
00129 for (int j=0; j < n_fit; ++j) chi2 += (adc[j] - fN * x[j]) * (adc[j] - fN * x[j]);
00130
00131
00132 if ( chi_last > chi2 ) {
00133 if (chi2 < chi_min ){
00134 t0 = tt0;
00135 }
00136 chi_last = chi2;
00137 tt0 = tt0 + del_t;
00138 } else {
00139 tt0 = tt0 - 2. * del_t;
00140 del_t = del_t / 2.;
00141 tt0 = tt0 + del_t;
00142 chi_last = 1.0e10;
00143 }
00144 }
00145
00146 return t0 + t0peak;
00147 }
00148
00149
00150
00151 void CSCFindPeakTime::fivePoleFitCharge( int tmax, const float* adc, const float& t_zero, const float& t_peak, std::vector<float>& adcsFit ) {
00152
00153
00154
00155 float p0 = 4./t_peak;
00156 float tt0 = t_zero;
00157 int n_fit = 4;
00158 if ( tmax == 6 ) n_fit=3;
00159
00160 float tb[4], y[4];
00161 for ( int t = 0; t < 4; ++t ){
00162 tb[t] = (tmax + t - 1) * 50.;
00163 y[t] = adc[t];
00164 }
00165
00166
00167 float x[4];
00168 float sx2 = 0.;
00169 float sxy = 0.;
00170 for ( int j=0; j < n_fit; ++j ) {
00171 float t = tb[j];
00172 x[j] = (t-tt0)*(t-tt0)*(t-tt0)*(t-tt0) * exp( -p0 * (t-tt0) );
00173 sx2 = sx2 + x[j] * x[j];
00174 sxy = sxy + x[j] * y[j];
00175 }
00176 float N = sxy / sx2;
00177
00178
00179
00180 for ( int i = 0; i < 3; ++i ) {
00181 float t = t_peak + (i - 1) * 50.;
00182 float q_fitted = N * (t-tt0)*(t-tt0)*(t-tt0)*(t-tt0) * exp( -p0 * (t-tt0) );
00183 adcsFit.push_back(q_fitted);
00184 }
00185 return;
00186 }
00187
00188