CMS 3D CMS Logo

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