CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch9/src/RecoLocalCalo/HcalRecAlgos/src/HcalSimpleRecAlgo.cc

Go to the documentation of this file.
00001 #include "RecoLocalCalo/HcalRecAlgos/interface/HcalSimpleRecAlgo.h"
00002 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00003 #include "CalibCalorimetry/HcalAlgos/interface/HcalTimeSlew.h"
00004 #include <algorithm> // for "max"
00005 #include <math.h>
00006 
00007 static double MaximumFractionalError = 0.0005; // 0.05% error allowed from this source
00008 
00009 HcalSimpleRecAlgo::HcalSimpleRecAlgo(int firstSample, int samplesToAdd, bool correctForTimeslew, bool correctForPulse, float phaseNS) : 
00010   firstSample_(firstSample), 
00011   samplesToAdd_(samplesToAdd), 
00012   correctForTimeslew_(correctForTimeslew) {
00013   if (correctForPulse) 
00014     pulseCorr_=std::auto_ptr<HcalPulseContainmentCorrection>(new HcalPulseContainmentCorrection(samplesToAdd_,phaseNS,MaximumFractionalError));
00015 }
00016 
00017 HcalSimpleRecAlgo::HcalSimpleRecAlgo(int firstSample, int samplesToAdd) : 
00018   firstSample_(firstSample), 
00019   samplesToAdd_(samplesToAdd), 
00020   correctForTimeslew_(false) {
00021 }
00022 
00023 
00024 void HcalSimpleRecAlgo::resetTimeSamples(int firstSample, int samplesToAdd)
00025 {
00026   firstSample_ = firstSample;
00027   samplesToAdd_ = samplesToAdd;
00028 }
00029 
00030 
00036 static float timeshift_ns_hbheho(float wpksamp);
00037 
00039 static float timeshift_ns_hf(float wpksamp);
00040 
00041 
00042 namespace HcalSimpleRecAlgoImpl {
00043   template<class Digi, class RecHit>
00044   inline RecHit reco(const Digi& digi, const HcalCoder& coder, const HcalCalibrations& calibs, 
00045                      int ifirst, int n, bool slewCorrect, const HcalPulseContainmentCorrection* corr,
00046                      HcalTimeSlew::BiasSetting slewFlavor) {
00047     CaloSamples tool;
00048     coder.adc2fC(digi,tool);
00049 
00050     double ampl=0; int maxI = -1; double maxA = -1e10; float ta=0;
00051     double fc_ampl=0;
00052     for (int i=ifirst; i<tool.size() && i<n+ifirst; i++) {
00053       int capid=digi[i].capid();
00054       ta = (tool[i]-calibs.pedestal(capid)); // pedestal subtraction
00055       fc_ampl+=ta; 
00056       ta*= calibs.respcorrgain(capid) ; // fC --> GeV
00057       ampl+=ta;
00058       if(ta>maxA){
00059         maxA=ta;
00060         maxI=i;
00061       }
00062     }
00063 
00064     float time = -9999;
00066     if(maxI==0 || maxI==(tool.size()-1)) {      
00067       LogDebug("HCAL Pulse") << "HcalSimpleRecAlgo::reconstruct :" 
00068                                                << " Invalid max amplitude position, " 
00069                                                << " max Amplitude: "<< maxI
00070                                                << " first: "<<ifirst
00071                                                << " last: "<<(tool.size()-1)
00072                                                << std::endl;
00073     } else {
00074       int capid=digi[maxI-1].capid();
00075       float t0 = ((tool[maxI-1]-calibs.pedestal(capid))*calibs.respcorrgain(capid) );
00076       capid=digi[maxI+1].capid();
00077       float t2 = ((tool[maxI+1]-calibs.pedestal(capid))*calibs.respcorrgain(capid) );
00078 
00079       // Handle negative excursions by moving "zero":
00080       float minA=t0;
00081       if (maxA<minA) minA=maxA;
00082       if (t2<minA)   minA=t2;
00083       if (minA<0) { maxA-=minA; t0-=minA; t2-=minA; } // positivizes all samples
00084 
00085       float wpksamp = (t0 + maxA + t2);
00086       if (wpksamp!=0) wpksamp=(maxA + 2.0*t2) / wpksamp; 
00087       time = (maxI - digi.presamples())*25.0 + timeshift_ns_hbheho(wpksamp);
00088       if (corr!=0) {
00089         // Apply phase-based amplitude correction:
00090         ampl *= corr->getCorrection(fc_ampl);
00091         //      std::cout << fc_ampl << " --> " << corr->getCorrection(fc_ampl) << std::endl;
00092       }
00093       if (slewCorrect) time-=HcalTimeSlew::delay(std::max(1.0,fc_ampl),slewFlavor);
00094 
00095       time=time-calibs.timecorr(); // time calibration
00096     }
00097 
00098     return RecHit(digi.id(),ampl,time);    
00099   }
00100 }
00101 
00102 HBHERecHit HcalSimpleRecAlgo::reconstruct(const HBHEDataFrame& digi, const HcalCoder& coder, const HcalCalibrations& calibs) const {
00103   return HcalSimpleRecAlgoImpl::reco<HBHEDataFrame,HBHERecHit>(digi,coder,calibs,
00104                                                                firstSample_,samplesToAdd_,correctForTimeslew_,
00105                                                                pulseCorr_.get(),
00106                                                                HcalTimeSlew::Medium);
00107 }
00108 
00109 HORecHit HcalSimpleRecAlgo::reconstruct(const HODataFrame& digi, const HcalCoder& coder, const HcalCalibrations& calibs) const {
00110   return HcalSimpleRecAlgoImpl::reco<HODataFrame,HORecHit>(digi,coder,calibs,
00111                                                            firstSample_,samplesToAdd_,correctForTimeslew_,
00112                                                            pulseCorr_.get(),
00113                                                            HcalTimeSlew::Slow);
00114 }
00115 
00116 HcalCalibRecHit HcalSimpleRecAlgo::reconstruct(const HcalCalibDataFrame& digi, const HcalCoder& coder, const HcalCalibrations& calibs) const {
00117   return HcalSimpleRecAlgoImpl::reco<HcalCalibDataFrame,HcalCalibRecHit>(digi,coder,calibs,
00118                                                                          firstSample_,samplesToAdd_,correctForTimeslew_,
00119                                                                          pulseCorr_.get(),
00120                                                                          HcalTimeSlew::Fast);
00121 }
00122 
00123 HFRecHit HcalSimpleRecAlgo::reconstruct(const HFDataFrame& digi, const HcalCoder& coder, const HcalCalibrations& calibs) const {
00124   CaloSamples tool;
00125   coder.adc2fC(digi,tool);
00126 
00127   double ampl=0; int maxI = -1; double maxA = -1e10; float ta=0; float amp_fC=0;
00128   for (int i=firstSample_; i<tool.size() && i<samplesToAdd_+firstSample_; i++) {
00129     int capid=digi[i].capid();
00130     ta = (tool[i]-calibs.pedestal(capid))*calibs.respcorrgain(capid);
00131     ampl+=ta;
00132     amp_fC += tool[i]-calibs.pedestal(capid);
00133     if(ta>maxA){
00134       maxA=ta;
00135       maxI=i;
00136     }
00137   }
00138 
00139   float time=-9999.0;
00141   if(maxI==0 || maxI==(tool.size()-1)) {
00142       LogDebug("HCAL Pulse") << "HcalSimpleRecAlgo::reconstruct :" 
00143                                                << " Invalid max amplitude position, " 
00144                                                << " max Amplitude: "<< maxI
00145                                                << " first: "<<firstSample_
00146                                                << " last: "<<(tool.size()-1)
00147                                                << std::endl;
00148   } else {
00149     int capid=digi[maxI-1].capid();
00150     float t0 = (tool[maxI-1]-calibs.pedestal(capid))*calibs.respcorrgain(capid);
00151     capid=digi[maxI+1].capid();
00152     float t2 = (tool[maxI+1]-calibs.pedestal(capid))*calibs.respcorrgain(capid);
00153 
00154     // Handle negative excursions by moving "zero":
00155     float zerocorr=std::min(t0,t2);
00156     if (zerocorr<0.f) {
00157       t0   -= zerocorr;
00158       t2   -= zerocorr;
00159       maxA -= zerocorr;
00160     }
00161     
00162     // pair the peak with the larger of the two neighboring time samples
00163     float wpksamp=0.f;
00164     if (t0>t2) {
00165       wpksamp = t0+maxA;
00166       if (wpksamp != 0.f) wpksamp = maxA/wpksamp;
00167     } else {
00168       wpksamp = maxA+t2;
00169       if (wpksamp != 0.f) wpksamp = 1.+(t2/wpksamp);
00170     }
00171 
00172     time = (maxI - digi.presamples())*25.0 + timeshift_ns_hf(wpksamp);
00173 
00174     if (correctForTimeslew_ && (amp_fC>0)) {
00175       // -5.12327 - put in calibs.timecorr()
00176       double tslew=exp(0.337681-5.94689e-4*amp_fC)+exp(2.44628-1.34888e-2*amp_fC);
00177       time -= (float)tslew;
00178     }
00179 
00180     time=time-calibs.timecorr();
00181   }
00182 
00183   return HFRecHit(digi.id(),ampl,time); 
00184 }
00185 
00186 // timeshift implementation
00187 
00188 static const float wpksamp0_hbheho = 0.5;
00189 static const int   num_bins_hbheho = 61;
00190 
00191 static const float actual_ns_hbheho[num_bins_hbheho] = {
00192 -5.44000, // 0.500, 0.000-0.017
00193 -4.84250, // 0.517, 0.017-0.033
00194 -4.26500, // 0.533, 0.033-0.050
00195 -3.71000, // 0.550, 0.050-0.067
00196 -3.18000, // 0.567, 0.067-0.083
00197 -2.66250, // 0.583, 0.083-0.100
00198 -2.17250, // 0.600, 0.100-0.117
00199 -1.69000, // 0.617, 0.117-0.133
00200 -1.23000, // 0.633, 0.133-0.150
00201 -0.78000, // 0.650, 0.150-0.167
00202 -0.34250, // 0.667, 0.167-0.183
00203  0.08250, // 0.683, 0.183-0.200
00204  0.50250, // 0.700, 0.200-0.217
00205  0.90500, // 0.717, 0.217-0.233
00206  1.30500, // 0.733, 0.233-0.250
00207  1.69500, // 0.750, 0.250-0.267
00208  2.07750, // 0.767, 0.267-0.283
00209  2.45750, // 0.783, 0.283-0.300
00210  2.82500, // 0.800, 0.300-0.317
00211  3.19250, // 0.817, 0.317-0.333
00212  3.55750, // 0.833, 0.333-0.350
00213  3.91750, // 0.850, 0.350-0.367
00214  4.27500, // 0.867, 0.367-0.383
00215  4.63000, // 0.883, 0.383-0.400
00216  4.98500, // 0.900, 0.400-0.417
00217  5.33750, // 0.917, 0.417-0.433
00218  5.69500, // 0.933, 0.433-0.450
00219  6.05000, // 0.950, 0.450-0.467
00220  6.40500, // 0.967, 0.467-0.483
00221  6.77000, // 0.983, 0.483-0.500
00222  7.13500, // 1.000, 0.500-0.517
00223  7.50000, // 1.017, 0.517-0.533
00224  7.88250, // 1.033, 0.533-0.550
00225  8.26500, // 1.050, 0.550-0.567
00226  8.66000, // 1.067, 0.567-0.583
00227  9.07000, // 1.083, 0.583-0.600
00228  9.48250, // 1.100, 0.600-0.617
00229  9.92750, // 1.117, 0.617-0.633
00230 10.37750, // 1.133, 0.633-0.650
00231 10.87500, // 1.150, 0.650-0.667
00232 11.38000, // 1.167, 0.667-0.683
00233 11.95250, // 1.183, 0.683-0.700
00234 12.55000, // 1.200, 0.700-0.717
00235 13.22750, // 1.217, 0.717-0.733
00236 13.98500, // 1.233, 0.733-0.750
00237 14.81500, // 1.250, 0.750-0.767
00238 15.71500, // 1.267, 0.767-0.783
00239 16.63750, // 1.283, 0.783-0.800
00240 17.53750, // 1.300, 0.800-0.817
00241 18.38500, // 1.317, 0.817-0.833
00242 19.16500, // 1.333, 0.833-0.850
00243 19.89750, // 1.350, 0.850-0.867
00244 20.59250, // 1.367, 0.867-0.883
00245 21.24250, // 1.383, 0.883-0.900
00246 21.85250, // 1.400, 0.900-0.917
00247 22.44500, // 1.417, 0.917-0.933
00248 22.99500, // 1.433, 0.933-0.950
00249 23.53250, // 1.450, 0.950-0.967
00250 24.03750, // 1.467, 0.967-0.983
00251 24.53250, // 1.483, 0.983-1.000
00252 25.00000  // 1.500, 1.000-1.017 - keep for interpolation
00253 };
00254 
00255 float timeshift_ns_hbheho(float wpksamp) {
00256   float flx = (num_bins_hbheho-1)*(wpksamp - wpksamp0_hbheho);
00257   int index = (int)flx;
00258   float yval;
00259 
00260   if      (index <    0)               return actual_ns_hbheho[0];
00261   else if (index >= num_bins_hbheho-1) return actual_ns_hbheho[num_bins_hbheho-1];
00262 
00263   // else interpolate:
00264   float y1 = actual_ns_hbheho[index];
00265   float y2 = actual_ns_hbheho[index+1];
00266 
00267   yval = y1 + (y2-y1)*(flx-(float)index);
00268 
00269   return yval;
00270 }
00271 
00272 static const int   num_bins_hf = 101;
00273 static const float wpksamp0_hf = 0.5;
00274 
00275 static const float actual_ns_hf[num_bins_hf] = {
00276  0.00250, // 0.000-0.010
00277  0.04500, // 0.010-0.020
00278  0.08750, // 0.020-0.030
00279  0.13000, // 0.030-0.040
00280  0.17250, // 0.040-0.050
00281  0.21500, // 0.050-0.060
00282  0.26000, // 0.060-0.070
00283  0.30250, // 0.070-0.080
00284  0.34500, // 0.080-0.090
00285  0.38750, // 0.090-0.100
00286  0.42750, // 0.100-0.110
00287  0.46000, // 0.110-0.120
00288  0.49250, // 0.120-0.130
00289  0.52500, // 0.130-0.140
00290  0.55750, // 0.140-0.150
00291  0.59000, // 0.150-0.160
00292  0.62250, // 0.160-0.170
00293  0.65500, // 0.170-0.180
00294  0.68750, // 0.180-0.190
00295  0.72000, // 0.190-0.200
00296  0.75250, // 0.200-0.210
00297  0.78500, // 0.210-0.220
00298  0.81750, // 0.220-0.230
00299  0.85000, // 0.230-0.240
00300  0.88250, // 0.240-0.250
00301  0.91500, // 0.250-0.260
00302  0.95500, // 0.260-0.270
00303  0.99250, // 0.270-0.280
00304  1.03250, // 0.280-0.290
00305  1.07000, // 0.290-0.300
00306  1.10750, // 0.300-0.310
00307  1.14750, // 0.310-0.320
00308  1.18500, // 0.320-0.330
00309  1.22500, // 0.330-0.340
00310  1.26250, // 0.340-0.350
00311  1.30000, // 0.350-0.360
00312  1.34000, // 0.360-0.370
00313  1.37750, // 0.370-0.380
00314  1.41750, // 0.380-0.390
00315  1.48750, // 0.390-0.400
00316  1.55750, // 0.400-0.410
00317  1.62750, // 0.410-0.420
00318  1.69750, // 0.420-0.430
00319  1.76750, // 0.430-0.440
00320  1.83750, // 0.440-0.450
00321  1.90750, // 0.450-0.460
00322  2.06750, // 0.460-0.470
00323  2.23250, // 0.470-0.480
00324  2.40000, // 0.480-0.490
00325  2.82250, // 0.490-0.500
00326  3.81000, // 0.500-0.510
00327  6.90500, // 0.510-0.520
00328  8.99250, // 0.520-0.530
00329 10.50000, // 0.530-0.540
00330 11.68250, // 0.540-0.550
00331 12.66250, // 0.550-0.560
00332 13.50250, // 0.560-0.570
00333 14.23750, // 0.570-0.580
00334 14.89750, // 0.580-0.590
00335 15.49000, // 0.590-0.600
00336 16.03250, // 0.600-0.610
00337 16.53250, // 0.610-0.620
00338 17.00000, // 0.620-0.630
00339 17.44000, // 0.630-0.640
00340 17.85250, // 0.640-0.650
00341 18.24000, // 0.650-0.660
00342 18.61000, // 0.660-0.670
00343 18.96750, // 0.670-0.680
00344 19.30500, // 0.680-0.690
00345 19.63000, // 0.690-0.700
00346 19.94500, // 0.700-0.710
00347 20.24500, // 0.710-0.720
00348 20.54000, // 0.720-0.730
00349 20.82250, // 0.730-0.740
00350 21.09750, // 0.740-0.750
00351 21.37000, // 0.750-0.760
00352 21.62750, // 0.760-0.770
00353 21.88500, // 0.770-0.780
00354 22.13000, // 0.780-0.790
00355 22.37250, // 0.790-0.800
00356 22.60250, // 0.800-0.810
00357 22.83000, // 0.810-0.820
00358 23.04250, // 0.820-0.830
00359 23.24500, // 0.830-0.840
00360 23.44250, // 0.840-0.850
00361 23.61000, // 0.850-0.860
00362 23.77750, // 0.860-0.870
00363 23.93500, // 0.870-0.880
00364 24.05500, // 0.880-0.890
00365 24.17250, // 0.890-0.900
00366 24.29000, // 0.900-0.910
00367 24.40750, // 0.910-0.920
00368 24.48250, // 0.920-0.930
00369 24.55500, // 0.930-0.940
00370 24.62500, // 0.940-0.950
00371 24.69750, // 0.950-0.960
00372 24.77000, // 0.960-0.970
00373 24.84000, // 0.970-0.980
00374 24.91250, // 0.980-0.990
00375 24.95500, // 0.990-1.000
00376 24.99750, // 1.000-1.010 - keep for interpolation
00377 };
00378 
00379 float timeshift_ns_hf(float wpksamp) {
00380   float flx = (num_bins_hf-1)*(wpksamp-wpksamp0_hf);
00381   int index = (int)flx;
00382   float yval;
00383   
00384   if      (index <  0)             return actual_ns_hf[0];
00385   else if (index >= num_bins_hf-1) return actual_ns_hf[num_bins_hf-1];
00386 
00387   // else interpolate:
00388   float y1       = actual_ns_hf[index];
00389   float y2       = actual_ns_hf[index+1];
00390 
00391   // float delta_x  = 1/(float)num_bins_hf;
00392   // yval = y1 + (y2-y1)*(flx-(float)index)/delta_x;
00393 
00394   yval = y1 + (y2-y1)*(flx-(float)index);
00395   return yval;
00396 }