00001 #include "RecoLocalCalo/HcalRecAlgos/interface/ZdcSimpleRecAlgo.h"
00002 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00003 #include "CalibCalorimetry/HcalAlgos/interface/HcalTimeSlew.h"
00004 #include <algorithm>
00005 #include <iostream>
00006 #include <math.h>
00007
00008
00009
00010 static double MaximumFractionalError = 0.0005;
00011
00012 ZdcSimpleRecAlgo::ZdcSimpleRecAlgo(bool correctForTimeslew, bool correctForPulse, float phaseNS, int recoMethod) :
00013 recoMethod_(recoMethod),
00014 correctForTimeslew_(correctForTimeslew),
00015 correctForPulse_(correctForPulse) {
00016 }
00017
00018 ZdcSimpleRecAlgo::ZdcSimpleRecAlgo(int recoMethod) :
00019 recoMethod_(recoMethod),
00020 correctForTimeslew_(false) {
00021 }
00022 void ZdcSimpleRecAlgo::initPulseCorr(int toadd) {
00023 if (correctForPulse_) {
00024 pulseCorr_=std::auto_ptr<HcalPulseContainmentCorrection>(new HcalPulseContainmentCorrection(toadd,phaseNS_,MaximumFractionalError));
00025 }
00026 }
00027 static float timeshift_ns_zdc(float wpksamp);
00028
00029 namespace ZdcSimpleRecAlgoImpl {
00030 template<class Digi, class RecHit>
00031 inline RecHit reco1(const Digi& digi, const HcalCoder& coder, const HcalCalibrations& calibs,
00032 const std::vector<unsigned int>& myNoiseTS, const std::vector<unsigned int>& mySignalTS, bool slewCorrect, const HcalPulseContainmentCorrection* corr, HcalTimeSlew::BiasSetting slewFlavor) {
00033 CaloSamples tool;
00034 coder.adc2fC(digi,tool);
00035 int ifirst = mySignalTS[0];
00036 int n = mySignalTS.size();
00037 double ampl=0; int maxI = -1; double maxA = -1e10; double ta=0;
00038 double fc_ampl=0;
00039 for (int i=ifirst; i<tool.size() && i<n+ifirst; i++) {
00040 int capid=digi[i].capid();
00041 ta = (tool[i]-calibs.pedestal(capid));
00042 fc_ampl+=ta;
00043 ta*= calibs.respcorrgain(capid) ;
00044 ampl+=ta;
00045 if(ta>maxA){
00046 maxA=ta;
00047 maxI=i;
00048 }
00049 }
00050
00051 double time=-9999;
00053 if(maxI==0 || maxI==(tool.size()-1)) {
00054 LogDebug("HCAL Pulse") << "ZdcSimpleRecAlgo::reconstruct :"
00055 << " Invalid max amplitude position, "
00056 << " max Amplitude: "<< maxI
00057 << " first: "<<ifirst
00058 << " last: "<<(tool.size()-1)
00059 << std::endl;
00060 } else {
00061 maxA=fabs(maxA);
00062 int capid=digi[maxI-1].capid();
00063 double t0 = fabs((tool[maxI-1]-calibs.pedestal(capid))*calibs.respcorrgain(capid) );
00064 capid=digi[maxI+1].capid();
00065 double t2 = fabs((tool[maxI+1]-calibs.pedestal(capid))*calibs.respcorrgain(capid) );
00066 double wpksamp = (t0 + maxA + t2);
00067 if (wpksamp!=0) wpksamp=(maxA + 2.0*t2) / wpksamp;
00068 time = (maxI - digi.presamples())*25.0 + timeshift_ns_zdc(wpksamp);
00069 if (corr!=0) {
00070
00071 ampl *= corr->getCorrection(fc_ampl);
00072 }
00073
00074 if (slewCorrect) time-=HcalTimeSlew::delay(std::max(1.0,fc_ampl),slewFlavor);
00075 }
00076
00077 time=time-calibs.timecorr();
00078 return RecHit(digi.id(),ampl,time);
00079 }
00080 }
00081
00082 namespace ZdcSimpleRecAlgoImpl {
00083 template<class Digi, class RecHit>
00084 inline RecHit reco2(const Digi& digi, const HcalCoder& coder, const HcalCalibrations& calibs,
00085 const std::vector<unsigned int>& myNoiseTS, const std::vector<unsigned int>& mySignalTS, bool slewCorrect, const HcalPulseContainmentCorrection* corr, HcalTimeSlew::BiasSetting slewFlavor) {
00086 CaloSamples tool;
00087 coder.adc2fC(digi,tool);
00088
00089 int ifirst = mySignalTS[0];
00090
00091 double ampl=0; int maxI = -1; double maxA = -1e10; double ta=0;
00092 double Allnoise = 0;
00093 int noiseslices = 0;
00094 int CurrentTS = 0;
00095 double noise = 0;
00096 double fc_ampl=0;
00097
00098 for(unsigned int iv = 0; iv<myNoiseTS.size(); ++iv)
00099 {
00100 CurrentTS = myNoiseTS[iv];
00101 Allnoise += tool[CurrentTS];
00102 noiseslices++;
00103 }
00104 if(noiseslices != 0) {
00105 noise = (Allnoise)/double(noiseslices);
00106 } else {
00107 noise = 0;
00108 }
00109
00110 double noisefactor=1.;
00111 for(unsigned int ivs = 0; ivs<mySignalTS.size(); ++ivs)
00112 {
00113 if(noise<0){
00114
00115
00116 noisefactor=0.;
00117 }
00118 CurrentTS = mySignalTS[ivs];
00119 int capid=digi[CurrentTS].capid();
00120 if(noise<0){
00121
00122
00123 noisefactor=0.;
00124 }
00125 ta = tool[CurrentTS]-noisefactor*noise;
00126 fc_ampl+=ta;
00127 ta*= calibs.respcorrgain(capid) ;
00128 ampl+=ta;
00129 if(ta>maxA){
00130 maxA=ta;
00131 maxI=CurrentTS;
00132 }
00133 }
00134
00135
00136
00137
00138
00139 double time=-9999;
00141 if(maxI==0 || maxI==(tool.size()-1)) {
00142 LogDebug("HCAL Pulse") << "ZdcSimpleRecAlgo::reco2 :"
00143 << " Invalid max amplitude position, "
00144 << " max Amplitude: "<< maxI
00145 << " first: "<<ifirst
00146 << " last: "<<(tool.size()-1)
00147 << std::endl;
00148 } else {
00149 int capid=digi[maxI-1].capid();
00150 double Energy0 = ((tool[maxI-1])*calibs.respcorrgain(capid) );
00151
00152
00153 if(Energy0<0){Energy0=0.;}
00154 capid=digi[maxI].capid();
00155 double Energy1 = ((tool[maxI])*calibs.respcorrgain(capid) ) ;
00156 if(Energy1<0){Energy1=0.;}
00157 capid=digi[maxI+1].capid();
00158 double Energy2 = ((tool[maxI+1])*calibs.respcorrgain(capid) );
00159 if(Energy2<0){Energy2=0.;}
00160
00161 double TSWeightEnergy = ((maxI-1)*Energy0 + maxI*Energy1 + (maxI+1)*Energy2);
00162 double EnergySum=Energy0+Energy1+Energy2;
00163 double AvgTSPos=0.;
00164 if (EnergySum!=0) AvgTSPos=TSWeightEnergy/ EnergySum;
00165
00166
00167 if(AvgTSPos==0){
00168 time=-99;
00169 } else {
00170 time = (AvgTSPos*25.0);
00171 }
00172 if (corr!=0) {
00173
00174 ampl *= corr->getCorrection(fc_ampl);
00175 }
00176 }
00177 return RecHit(digi.id(),ampl,time);
00178 }
00179 }
00180
00181 ZDCRecHit ZdcSimpleRecAlgo::reconstruct(const ZDCDataFrame& digi, const std::vector<unsigned int>& myNoiseTS, const std::vector<unsigned int>& mySignalTS,const HcalCoder& coder, const HcalCalibrations& calibs) const {
00182
00183 if(recoMethod_ == 1)
00184 return ZdcSimpleRecAlgoImpl::reco1<ZDCDataFrame,ZDCRecHit>(digi,coder,calibs,
00185 myNoiseTS,mySignalTS,false,
00186 0,
00187 HcalTimeSlew::Fast);
00188 if(recoMethod_ == 2)
00189 return ZdcSimpleRecAlgoImpl::reco2<ZDCDataFrame,ZDCRecHit>(digi,coder,calibs,
00190 myNoiseTS,mySignalTS,false,
00191 0,HcalTimeSlew::Fast);
00192
00193 edm::LogError("ZDCSimpleRecAlgoImpl::reconstruct, recoMethod was not declared");
00194 throw cms::Exception("ZDCSimpleRecoAlgos::exiting process");
00195
00196 }
00197
00198 static const float wpksamp0_zdc = 0.500053;
00199 static const float scale_zdc = 0.999683;
00200 static const int num_bins_zdc = 100;
00201
00202 static const float actual_ns_zdc[num_bins_zdc] = {
00203 0.00250,
00204 0.08000,
00205 0.16000,
00206 0.23750,
00207 0.31750,
00208 0.39500,
00209 0.47500,
00210 0.55500,
00211 0.63000,
00212 0.70000,
00213 0.77000,
00214 0.84000,
00215 0.91000,
00216 0.98000,
00217 1.05000,
00218 1.12000,
00219 1.19000,
00220 1.26000,
00221 1.33000,
00222 1.40000,
00223 1.47000,
00224 1.54000,
00225 1.61000,
00226 1.68000,
00227 1.75000,
00228 1.82000,
00229 1.89000,
00230 1.96000,
00231 2.03000,
00232 2.10000,
00233 2.17000,
00234 2.24000,
00235 2.31000,
00236 2.38000,
00237 2.45000,
00238 2.52000,
00239 2.59000,
00240 2.68500,
00241 2.79250,
00242 2.90250,
00243 3.01000,
00244 3.11750,
00245 3.22500,
00246 3.33500,
00247 3.44250,
00248 3.55000,
00249 3.73250,
00250 4.02000,
00251 4.30750,
00252 4.59500,
00253 6.97500,
00254 10.98750,
00255 13.03750,
00256 14.39250,
00257 15.39500,
00258 16.18250,
00259 16.85250,
00260 17.42750,
00261 17.91500,
00262 18.36250,
00263 18.76500,
00264 19.11250,
00265 19.46000,
00266 19.76500,
00267 20.03500,
00268 20.30250,
00269 20.57250,
00270 20.79250,
00271 21.00250,
00272 21.21000,
00273 21.42000,
00274 21.62750,
00275 21.79000,
00276 21.95250,
00277 22.11500,
00278 22.27750,
00279 22.44000,
00280 22.60500,
00281 22.73250,
00282 22.86000,
00283 22.98500,
00284 23.11250,
00285 23.23750,
00286 23.36500,
00287 23.49000,
00288 23.61750,
00289 23.71500,
00290 23.81250,
00291 23.91250,
00292 24.01000,
00293 24.10750,
00294 24.20750,
00295 24.30500,
00296 24.40500,
00297 24.50250,
00298 24.60000,
00299 24.68250,
00300 24.76250,
00301 24.84000,
00302 24.92000
00303 };
00304
00305 float timeshift_ns_zdc(float wpksamp) {
00306 float flx = (num_bins_zdc*(wpksamp - wpksamp0_zdc)/scale_zdc);
00307 int index = (int)flx;
00308 float yval;
00309
00310 if (index < 0) return actual_ns_zdc[0];
00311 else if (index >= num_bins_zdc-1) return actual_ns_zdc[num_bins_zdc-1];
00312
00313
00314 float y1 = actual_ns_zdc[index];
00315 float y2 = actual_ns_zdc[index+1];
00316
00317
00318
00319
00320 yval = y1 + (y2-y1)*(flx-(float)index);
00321 return yval;
00322 }