00001 #include "RecoLocalCalo/HcalRecAlgos/interface/HcalSimpleRecAlgo.h"
00002 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00003 #include "CalibCalorimetry/HcalAlgos/interface/HcalTimeSlew.h"
00004 #include <algorithm>
00005 #include <math.h>
00006
00007 static double MaximumFractionalError = 0.0005;
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
00028 static float timeshift_ns_hbheho(float wpksamp);
00029
00031 static float timeshift_ns_hf(float wpksamp);
00032
00033
00034 namespace HcalSimpleRecAlgoImpl {
00035 template<class Digi, class RecHit>
00036 inline RecHit reco(const Digi& digi, const HcalCoder& coder, const HcalCalibrations& calibs,
00037 int ifirst, int n, bool slewCorrect, const HcalPulseContainmentCorrection* corr, HcalTimeSlew::BiasSetting slewFlavor) {
00038 CaloSamples tool;
00039 coder.adc2fC(digi,tool);
00040
00041 double ampl=0; int maxI = -1; double maxA = -1e10; float ta=0;
00042 double fc_ampl=0;
00043 for (int i=ifirst; i<tool.size() && i<n+ifirst; i++) {
00044 int capid=digi[i].capid();
00045 ta = (tool[i]-calibs.pedestal(capid));
00046 fc_ampl+=ta;
00047 ta*= calibs.respcorrgain(capid) ;
00048 ampl+=ta;
00049 if(ta>maxA){
00050 maxA=ta;
00051 maxI=i;
00052 }
00053 }
00054
00055 float time=-9999;
00057 if(maxI==0 || maxI==(tool.size()-1)) {
00058 LogDebug("HCAL Pulse") << "HcalSimpleRecAlgo::reconstruct :"
00059 << " Invalid max amplitude position, "
00060 << " max Amplitude: "<< maxI
00061 << " first: "<<ifirst
00062 << " last: "<<(tool.size()-1)
00063 << std::endl;
00064 } else {
00065 maxA=fabs(maxA);
00066 int capid=digi[maxI-1].capid();
00067 float t0 = fabs((tool[maxI-1]-calibs.pedestal(capid))*calibs.respcorrgain(capid) );
00068 capid=digi[maxI+1].capid();
00069 float t2 = fabs((tool[maxI+1]-calibs.pedestal(capid))*calibs.respcorrgain(capid) );
00070 float wpksamp = (t0 + maxA + t2);
00071 if (wpksamp!=0) wpksamp=(maxA + 2.0*t2) / wpksamp;
00072 time = (maxI - digi.presamples())*25.0 + timeshift_ns_hbheho(wpksamp);
00073
00074 if (corr!=0) {
00075
00076 ampl *= corr->getCorrection(fc_ampl);
00077
00078 }
00079
00080
00081 if (slewCorrect) time-=HcalTimeSlew::delay(std::max(1.0,fc_ampl),slewFlavor);
00082 }
00083 return RecHit(digi.id(),ampl,time);
00084 }
00085 }
00086
00087 HBHERecHit HcalSimpleRecAlgo::reconstruct(const HBHEDataFrame& digi, const HcalCoder& coder, const HcalCalibrations& calibs) const {
00088 return HcalSimpleRecAlgoImpl::reco<HBHEDataFrame,HBHERecHit>(digi,coder,calibs,
00089 firstSample_,samplesToAdd_,correctForTimeslew_,
00090 pulseCorr_.get(),
00091 HcalTimeSlew::Medium);
00092 }
00093
00094 HORecHit HcalSimpleRecAlgo::reconstruct(const HODataFrame& digi, const HcalCoder& coder, const HcalCalibrations& calibs) const {
00095 return HcalSimpleRecAlgoImpl::reco<HODataFrame,HORecHit>(digi,coder,calibs,
00096 firstSample_,samplesToAdd_,correctForTimeslew_,
00097 pulseCorr_.get(),
00098 HcalTimeSlew::Slow);
00099 }
00100
00101 ZDCRecHit HcalSimpleRecAlgo::reconstruct(const ZDCDataFrame& digi, const HcalCoder& coder, const HcalCalibrations& calibs) const {
00102 return HcalSimpleRecAlgoImpl::reco<ZDCDataFrame,ZDCRecHit>(digi,coder,calibs,
00103 firstSample_,samplesToAdd_,false,
00104 0,
00105 HcalTimeSlew::Fast);
00106 }
00107
00108 HcalCalibRecHit HcalSimpleRecAlgo::reconstruct(const HcalCalibDataFrame& digi, const HcalCoder& coder, const HcalCalibrations& calibs) const {
00109 return HcalSimpleRecAlgoImpl::reco<HcalCalibDataFrame,HcalCalibRecHit>(digi,coder,calibs,
00110 firstSample_,samplesToAdd_,correctForTimeslew_,
00111 pulseCorr_.get(),
00112 HcalTimeSlew::Fast);
00113 }
00114
00115 HFRecHit HcalSimpleRecAlgo::reconstruct(const HFDataFrame& digi, const HcalCoder& coder, const HcalCalibrations& calibs) const {
00116 CaloSamples tool;
00117 coder.adc2fC(digi,tool);
00118
00119 double ampl=0; int maxI = -1; double maxA = -1e10; float ta=0;
00120 for (int i=firstSample_; i<tool.size() && i<samplesToAdd_+firstSample_; i++) {
00121 int capid=digi[i].capid();
00122 ta = (tool[i]-calibs.pedestal(capid))*calibs.respcorrgain(capid);
00123 ampl+=ta;
00124 if(ta>maxA){
00125 maxA=ta;
00126 maxI=i;
00127 }
00128 }
00129
00130 float time=-9999.0;
00132 if(maxI==0 || maxI==(tool.size()-1)) {
00133 LogDebug("HCAL Pulse") << "HcalSimpleRecAlgo::reconstruct :"
00134 << " Invalid max amplitude position, "
00135 << " max Amplitude: "<< maxI
00136 << " first: "<<firstSample_
00137 << " last: "<<(tool.size()-1)
00138 << std::endl;
00139 } else {
00140 maxA=fabs(maxA);
00141 int capid=digi[maxI-1].capid();
00142 float t0 = fabs((tool[maxI-1]-calibs.pedestal(capid))*calibs.respcorrgain(capid) );
00143 capid=digi[maxI+1].capid();
00144 float t2 = fabs((tool[maxI+1]-calibs.pedestal(capid))*calibs.respcorrgain(capid) );
00145 float wpksamp = (t0 + maxA + t2);
00146 if (wpksamp!=0) wpksamp=(maxA + 2.0*t2) / wpksamp;
00147 time = (maxI - digi.presamples())*25.0 + timeshift_ns_hf(wpksamp);
00148 }
00149
00150 return HFRecHit(digi.id(),ampl,time);
00151 }
00152
00153
00154
00155 static const float wpksamp0_hbheho = 0.680178;
00156 static const float scale_hbheho = 0.819786;
00157 static const int num_bins_hbheho = 50;
00158
00159 static const float actual_ns_hbheho[num_bins_hbheho] = {
00160 0.00000,
00161 0.41750,
00162 0.81500,
00163 1.21000,
00164 1.59500,
00165 1.97250,
00166 2.34750,
00167 2.71250,
00168 3.07500,
00169 3.43500,
00170 3.79000,
00171 4.14250,
00172 4.49250,
00173 4.84250,
00174 5.19000,
00175 5.53750,
00176 5.89000,
00177 6.23750,
00178 6.59250,
00179 6.95250,
00180 7.31000,
00181 7.68000,
00182 8.05500,
00183 8.43000,
00184 8.83250,
00185 9.23250,
00186 9.65500,
00187 10.09500,
00188 10.54750,
00189 11.04500,
00190 11.55750,
00191 12.13000,
00192 12.74500,
00193 13.41250,
00194 14.18500,
00195 15.02750,
00196 15.92250,
00197 16.82500,
00198 17.70000,
00199 18.52500,
00200 19.28750,
00201 19.99750,
00202 20.67250,
00203 21.31250,
00204 21.90750,
00205 22.48750,
00206 23.02750,
00207 23.55250,
00208 24.05000,
00209 24.53750,
00210 };
00211
00212 float timeshift_ns_hbheho(float wpksamp) {
00213 int index=(int)(0.5+num_bins_hbheho*(wpksamp-wpksamp0_hbheho)/scale_hbheho);
00214
00215 if (index < 0) return actual_ns_hbheho[0];
00216 else if (index >= num_bins_hbheho) return actual_ns_hbheho[num_bins_hbheho-1];
00217
00218 return actual_ns_hbheho[index];
00219 }
00220
00221
00222 static const float wpksamp0_hf = 0.500635;
00223 static const float scale_hf = 0.999301;
00224 static const int num_bins_hf = 100;
00225
00226 static const float actual_ns_hf[num_bins_hf] = {
00227 0.00000,
00228 0.03750,
00229 0.07250,
00230 0.10750,
00231 0.14500,
00232 0.18000,
00233 0.21500,
00234 0.25000,
00235 0.28500,
00236 0.32000,
00237 0.35500,
00238 0.39000,
00239 0.42500,
00240 0.46000,
00241 0.49500,
00242 0.53000,
00243 0.56500,
00244 0.60000,
00245 0.63500,
00246 0.67000,
00247 0.70750,
00248 0.74250,
00249 0.78000,
00250 0.81500,
00251 0.85250,
00252 0.89000,
00253 0.92750,
00254 0.96500,
00255 1.00250,
00256 1.04250,
00257 1.08250,
00258 1.12250,
00259 1.16250,
00260 1.20500,
00261 1.24500,
00262 1.29000,
00263 1.33250,
00264 1.38000,
00265 1.42500,
00266 1.47500,
00267 1.52500,
00268 1.57750,
00269 1.63250,
00270 1.69000,
00271 1.75250,
00272 1.82000,
00273 1.89250,
00274 1.97500,
00275 2.07250,
00276 2.20000,
00277 19.13000,
00278 21.08750,
00279 21.57750,
00280 21.89000,
00281 22.12250,
00282 22.31000,
00283 22.47000,
00284 22.61000,
00285 22.73250,
00286 22.84500,
00287 22.94750,
00288 23.04250,
00289 23.13250,
00290 23.21500,
00291 23.29250,
00292 23.36750,
00293 23.43750,
00294 23.50500,
00295 23.57000,
00296 23.63250,
00297 23.69250,
00298 23.75000,
00299 23.80500,
00300 23.86000,
00301 23.91250,
00302 23.96500,
00303 24.01500,
00304 24.06500,
00305 24.11250,
00306 24.16000,
00307 24.20500,
00308 24.25000,
00309 24.29500,
00310 24.33750,
00311 24.38000,
00312 24.42250,
00313 24.46500,
00314 24.50500,
00315 24.54500,
00316 24.58500,
00317 24.62500,
00318 24.66500,
00319 24.70250,
00320 24.74000,
00321 24.77750,
00322 24.81500,
00323 24.85250,
00324 24.89000,
00325 24.92750,
00326 24.96250,
00327 };
00328
00329 float timeshift_ns_hf(float wpksamp) {
00330 float flx = (num_bins_hf*(wpksamp - wpksamp0_hf)/scale_hf);
00331 int index = (int)flx;
00332 float yval;
00333
00334 if (index < 0) return actual_ns_hf[0];
00335 else if (index >= num_bins_hf-1) return actual_ns_hf[num_bins_hf-1];
00336
00337
00338 float y1 = actual_ns_hf[index];
00339 float y2 = actual_ns_hf[index+1];
00340
00341
00342
00343
00344 yval = y1 + (y2-y1)*(flx-(float)index);
00345 return yval;
00346 }