CMS 3D CMS Logo

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