CMS 3D CMS Logo

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

Go to the documentation of this file.
00001 #include "RecoLocalCalo/HcalRecAlgos/interface/ZdcSimpleRecAlgo.h"
00002 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00003 #include "CalibCalorimetry/HcalAlgos/interface/HcalTimeSlew.h"
00004 #include <algorithm> // for "max"
00005 #include <iostream>
00006 #include <math.h>
00007 
00008 
00009 
00010 static double MaximumFractionalError = 0.0005; // 0.05% error allowed from this source
00011 
00012 ZdcSimpleRecAlgo::ZdcSimpleRecAlgo(int firstSample, int samplesToAdd, bool correctForTimeslew, bool correctForPulse, float phaseNS, int recoMethod) : 
00013   firstSample_(firstSample), 
00014   samplesToAdd_(samplesToAdd),
00015   recoMethod_(recoMethod),
00016   correctForTimeslew_(correctForTimeslew) {
00017   if (correctForPulse) 
00018     pulseCorr_=std::auto_ptr<HcalPulseContainmentCorrection>(new HcalPulseContainmentCorrection(samplesToAdd_,phaseNS,MaximumFractionalError));
00019 }
00020 
00021 ZdcSimpleRecAlgo::ZdcSimpleRecAlgo(int firstSample, int samplesToAdd, int recoMethod) : 
00022   firstSample_(firstSample), 
00023   samplesToAdd_(samplesToAdd),
00024   recoMethod_(recoMethod),
00025   correctForTimeslew_(false) {
00026 }
00027 
00028 static float timeshift_ns_zdc(float wpksamp);
00029 
00030 namespace ZdcSimpleRecAlgoImpl {
00031   template<class Digi, class RecHit>
00032   inline RecHit reco1(const Digi& digi, const HcalCoder& coder, const HcalCalibrations& calibs, 
00033                      int ifirst, int n, bool slewCorrect, const HcalPulseContainmentCorrection* corr, HcalTimeSlew::BiasSetting slewFlavor) {
00034     CaloSamples tool;
00035     coder.adc2fC(digi,tool);
00036     double ampl=0; int maxI = -1; double maxA = -1e10; double ta=0;
00037     double fc_ampl=0;
00038     for (int i=ifirst; i<tool.size() && i<n+ifirst; i++) {
00039       int capid=digi[i].capid();
00040       ta = (tool[i]-calibs.pedestal(capid)); // pedestal subtraction
00041       fc_ampl+=ta; 
00042       ta*= calibs.respcorrgain(capid) ; // fC --> GeV
00043       ampl+=ta;
00044       if(ta>maxA){
00045         maxA=ta;
00046         maxI=i;
00047       }
00048     }
00049     
00050     double time=-9999;
00052     if(maxI==0 || maxI==(tool.size()-1)) {      
00053       LogDebug("HCAL Pulse") << "ZdcSimpleRecAlgo::reconstruct :" 
00054                                                << " Invalid max amplitude position, " 
00055                                                << " max Amplitude: "<< maxI
00056                                                << " first: "<<ifirst
00057                                                << " last: "<<(tool.size()-1)
00058                                                << std::endl;
00059     } else {
00060       maxA=fabs(maxA);
00061       int capid=digi[maxI-1].capid();
00062       double t0 = fabs((tool[maxI-1]-calibs.pedestal(capid))*calibs.respcorrgain(capid) );
00063       capid=digi[maxI+1].capid();
00064       double t2 = fabs((tool[maxI+1]-calibs.pedestal(capid))*calibs.respcorrgain(capid) );    
00065       double wpksamp = (t0 + maxA + t2);
00066       if (wpksamp!=0) wpksamp=(maxA + 2.0*t2) / wpksamp; 
00067       time = (maxI - digi.presamples())*25.0 + timeshift_ns_zdc(wpksamp);
00068       if (corr!=0) {
00069         // Apply phase-based amplitude correction:
00070         ampl *= corr->getCorrection(fc_ampl);
00071         //      std::cout << fc_ampl << " --> " << corr->getCorrection(fc_ampl) << std::endl;
00072       }
00073     
00074       if (slewCorrect) time-=HcalTimeSlew::delay(std::max(1.0,fc_ampl),slewFlavor);
00075     }
00076 
00077     time=time-calibs.timecorr(); // time calibration
00078     return RecHit(digi.id(),ampl,time);    
00079   }
00080 }
00081 
00082 
00083 namespace ZdcSimpleRecAlgoImpl {
00084   template<class Digi, class RecHit>
00085   inline RecHit reco2(const Digi& digi, const HcalCoder& coder, const HcalCalibrations& calibs, 
00086                      int ifirst, int n, bool slewCorrect, const HcalPulseContainmentCorrection* corr, HcalTimeSlew::BiasSetting slewFlavor) {
00087     CaloSamples tool;
00088     coder.adc2fC(digi,tool);
00089     double ampl=0; int maxI = -1; double maxA = -1e10; double ta=0;
00090     double prenoise = 0; double postnoise = 0; 
00091     int noiseslices = 0;
00092     double noise = 0;
00093     double fc_ampl=0;
00094 
00095     for(int k = 0 ; k < tool.size() && k < ifirst; k++){
00096       prenoise += tool[k];
00097       noiseslices++;
00098     }
00099 //    for(int j = (n + ifirst + 1); j <tool.size(); j++){
00100 //      postnoise += tool[j];
00101 //      noiseslices++;
00102 //    }
00103 // removed postnoise due to significant signal seen in TS 7,8,9 (Heavy Ion run 2010)
00104 // Future ZdcSimpleRecAlgo will have better configurable noise calculation
00105     postnoise=0;    
00106     if(noiseslices != 0) {
00107       noise = (prenoise+postnoise)/double(noiseslices);
00108     } else {
00109       noise = 0;
00110     }
00111  // factor to multiply by noise to make 0 or 1 to handle negative noise situations
00112     double noisefactor=1.;
00113     for (int i=ifirst; i<tool.size() && i<n+ifirst; i++) {
00114       int capid=digi[i].capid();
00115       if(noise<0){
00116       // flag hit as having negative noise, and don't subtract anything, because
00117       // it will falsely increase the energy
00118          noisefactor=0.;
00119       } 
00120       ta = tool[i]-noisefactor*noise;
00121       fc_ampl+=ta; 
00122       ta*= calibs.respcorrgain(capid) ; // fC --> GeV
00123       ampl+=ta;
00124       if(ta>maxA){
00125         maxA=ta;
00126         maxI=i;
00127       }
00128     }
00129 //    if(ta<0){
00130 //      // flag hits that have negative energy
00131 //    }
00132 
00133     double time=-9999;
00135     if(maxI==0 || maxI==(tool.size()-1)) {      
00136       LogDebug("HCAL Pulse") << "ZdcSimpleRecAlgo::reco2 :" 
00137                                                << " Invalid max amplitude position, " 
00138                                                << " max Amplitude: "<< maxI
00139                                                << " first: "<<ifirst
00140                                                << " last: "<<(tool.size()-1)
00141                                                << std::endl;
00142     } else {
00143       int capid=digi[maxI-1].capid();
00144       double Energy0 = ((tool[maxI-1])*calibs.respcorrgain(capid) );
00145 // if any of the energies used in the weight are negative, make them 0 instead
00146 // these are actually QIE values, not energy
00147       if(Energy0<0){Energy0=0.;}
00148       capid=digi[maxI].capid();
00149       double Energy1 = ((tool[maxI])*calibs.respcorrgain(capid) ) ;
00150       if(Energy1<0){Energy1=0.;}
00151       capid=digi[maxI+1].capid();
00152       double Energy2 = ((tool[maxI+1])*calibs.respcorrgain(capid) );
00153       if(Energy2<0){Energy2=0.;}
00154 //
00155       double TSWeightEnergy = ((maxI-1)*Energy0 + maxI*Energy1 + (maxI+1)*Energy2);
00156       double EnergySum=Energy0+Energy1+Energy2;
00157       double AvgTSPos=0.;
00158       if (EnergySum!=0) AvgTSPos=TSWeightEnergy/ EnergySum; 
00159 // If time is zero, set it to the "nonsensical" -99
00160 // Time should be between 75ns and 175ns (Timeslices 3-7)
00161       if(AvgTSPos==0){
00162          time=-99;
00163       } else {
00164          time = (AvgTSPos*25.0);
00165       }
00166       if (corr!=0) {
00167         // Apply phase-based amplitude correction:
00168                ampl *= corr->getCorrection(fc_ampl);
00169       }
00170     }
00171     return RecHit(digi.id(),ampl,time);    
00172   }
00173 }
00174 
00175 ZDCRecHit ZdcSimpleRecAlgo::reconstruct(const ZDCDataFrame& digi, const HcalCoder& coder, const HcalCalibrations& calibs) const {
00176  
00177   if(recoMethod_ == 1)
00178    return ZdcSimpleRecAlgoImpl::reco1<ZDCDataFrame,ZDCRecHit>(digi,coder,calibs,
00179                                                               firstSample_,samplesToAdd_,false,
00180                                                               0,
00181                                                               HcalTimeSlew::Fast);
00182   if(recoMethod_ == 2)
00183    return ZdcSimpleRecAlgoImpl::reco2<ZDCDataFrame,ZDCRecHit>(digi,coder,calibs,
00184                                                               firstSample_,samplesToAdd_,false,
00185                                                               0,HcalTimeSlew::Fast);
00186 
00187      edm::LogError("ZDCSimpleRecAlgoImpl::reconstruct, recoMethod was not declared");
00188      throw cms::Exception("ZDCSimpleRecoAlgos::exiting process");
00189    
00190 }
00191 
00192 static const float wpksamp0_zdc = 0.500053;
00193 static const float scale_zdc    = 0.999683;
00194 static const int   num_bins_zdc = 100;
00195 
00196 static const float actual_ns_zdc[num_bins_zdc] = {
00197  0.00250, // 0.000-0.010
00198  0.08000, // 0.010-0.020
00199  0.16000, // 0.020-0.030
00200  0.23750, // 0.030-0.040
00201  0.31750, // 0.040-0.050
00202  0.39500, // 0.050-0.060
00203  0.47500, // 0.060-0.070
00204  0.55500, // 0.070-0.080
00205  0.63000, // 0.080-0.090
00206  0.70000, // 0.090-0.100
00207  0.77000, // 0.100-0.110
00208  0.84000, // 0.110-0.120
00209  0.91000, // 0.120-0.130
00210  0.98000, // 0.130-0.140
00211  1.05000, // 0.140-0.150
00212  1.12000, // 0.150-0.160
00213  1.19000, // 0.160-0.170
00214  1.26000, // 0.170-0.180
00215  1.33000, // 0.180-0.190
00216  1.40000, // 0.190-0.200
00217  1.47000, // 0.200-0.210
00218  1.54000, // 0.210-0.220
00219  1.61000, // 0.220-0.230
00220  1.68000, // 0.230-0.240
00221  1.75000, // 0.240-0.250
00222  1.82000, // 0.250-0.260
00223  1.89000, // 0.260-0.270
00224  1.96000, // 0.270-0.280
00225  2.03000, // 0.280-0.290
00226  2.10000, // 0.290-0.300
00227  2.17000, // 0.300-0.310
00228  2.24000, // 0.310-0.320
00229  2.31000, // 0.320-0.330
00230  2.38000, // 0.330-0.340
00231  2.45000, // 0.340-0.350
00232  2.52000, // 0.350-0.360
00233  2.59000, // 0.360-0.370
00234  2.68500, // 0.370-0.380
00235  2.79250, // 0.380-0.390
00236  2.90250, // 0.390-0.400
00237  3.01000, // 0.400-0.410
00238  3.11750, // 0.410-0.420
00239  3.22500, // 0.420-0.430
00240  3.33500, // 0.430-0.440
00241  3.44250, // 0.440-0.450
00242  3.55000, // 0.450-0.460
00243  3.73250, // 0.460-0.470
00244  4.02000, // 0.470-0.480
00245  4.30750, // 0.480-0.490
00246  4.59500, // 0.490-0.500
00247  6.97500, // 0.500-0.510
00248 10.98750, // 0.510-0.520
00249 13.03750, // 0.520-0.530
00250 14.39250, // 0.530-0.540
00251 15.39500, // 0.540-0.550
00252 16.18250, // 0.550-0.560
00253 16.85250, // 0.560-0.570
00254 17.42750, // 0.570-0.580
00255 17.91500, // 0.580-0.590
00256 18.36250, // 0.590-0.600
00257 18.76500, // 0.600-0.610
00258 19.11250, // 0.610-0.620
00259 19.46000, // 0.620-0.630
00260 19.76500, // 0.630-0.640
00261 20.03500, // 0.640-0.650
00262 20.30250, // 0.650-0.660
00263 20.57250, // 0.660-0.670
00264 20.79250, // 0.670-0.680
00265 21.00250, // 0.680-0.690
00266 21.21000, // 0.690-0.700
00267 21.42000, // 0.700-0.710
00268 21.62750, // 0.710-0.720
00269 21.79000, // 0.720-0.730
00270 21.95250, // 0.730-0.740
00271 22.11500, // 0.740-0.750
00272 22.27750, // 0.750-0.760
00273 22.44000, // 0.760-0.770
00274 22.60500, // 0.770-0.780
00275 22.73250, // 0.780-0.790
00276 22.86000, // 0.790-0.800
00277 22.98500, // 0.800-0.810
00278 23.11250, // 0.810-0.820
00279 23.23750, // 0.820-0.830
00280 23.36500, // 0.830-0.840
00281 23.49000, // 0.840-0.850
00282 23.61750, // 0.850-0.860
00283 23.71500, // 0.860-0.870
00284 23.81250, // 0.870-0.880
00285 23.91250, // 0.880-0.890
00286 24.01000, // 0.890-0.900
00287 24.10750, // 0.900-0.910
00288 24.20750, // 0.910-0.920
00289 24.30500, // 0.920-0.930
00290 24.40500, // 0.930-0.940
00291 24.50250, // 0.940-0.950
00292 24.60000, // 0.950-0.960
00293 24.68250, // 0.960-0.970
00294 24.76250, // 0.970-0.980
00295 24.84000, // 0.980-0.990
00296 24.92000  // 0.990-1.000
00297 };
00298 
00299 float timeshift_ns_zdc(float wpksamp) {
00300   float flx = (num_bins_zdc*(wpksamp - wpksamp0_zdc)/scale_zdc);
00301   int index = (int)flx;
00302   float yval;
00303   
00304   if      (index <    0)        return actual_ns_zdc[0];
00305   else if (index >= num_bins_zdc-1) return actual_ns_zdc[num_bins_zdc-1];
00306 
00307   // else interpolate:
00308   float y1       = actual_ns_zdc[index];
00309   float y2       = actual_ns_zdc[index+1];
00310 
00311   // float delta_x  = 1/(float)num_bins_zdc;
00312   // yval = y1 + (y2-y1)*(flx-(float)index)/delta_x;
00313 
00314   yval = y1 + (y2-y1)*(flx-(float)index);
00315   return yval;
00316 }