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