00001 #include "RecoLocalCalo/CastorReco/interface/CastorSimpleRecAlgo.h"
00002 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00003 #include "CalibCalorimetry/CastorCalib/interface/CastorTimeSlew.h"
00004 #include <algorithm>
00005 #include <math.h>
00006
00007 static double MaximumFractionalError = 0.0005;
00008
00009 CastorSimpleRecAlgo::CastorSimpleRecAlgo(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<CastorPulseContainmentCorrection>(new CastorPulseContainmentCorrection(samplesToAdd_,phaseNS,MaximumFractionalError));
00015 }
00016
00017 CastorSimpleRecAlgo::CastorSimpleRecAlgo(int firstSample, int samplesToAdd) :
00018 firstSample_(firstSample),
00019 samplesToAdd_(samplesToAdd),
00020 correctForTimeslew_(false) {
00021 }
00022
00028
00029
00031 static float timeshift_ns_hf(float wpksamp);
00032
00033
00034 namespace CastorSimpleRecAlgoImpl {
00035 template<class Digi, class RecHit>
00036 inline RecHit reco(const Digi& digi, const CastorCoder& coder, const CastorCalibrations& calibs,
00037 int ifirst, int n, bool slewCorrect, const CastorPulseContainmentCorrection* corr, CastorTimeSlew::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.gain(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
00059
00060
00061
00062
00063
00064
00065
00066
00067 } else {
00068 maxA=fabs(maxA);
00069 int capid=digi[maxI-1].capid();
00070 float t0 = fabs((tool[maxI-1]-calibs.pedestal(capid))*calibs.gain(capid));
00071 capid=digi[maxI+1].capid();
00072 float t2 = fabs((tool[maxI+1]-calibs.pedestal(capid))*calibs.gain(capid));
00073 float wpksamp = (t0 + maxA + t2);
00074 if (wpksamp!=0) wpksamp=(maxA + 2.0*t2) / wpksamp;
00075 time = (maxI - digi.presamples())*25.0 + timeshift_ns_hf(wpksamp);
00076
00077 if (corr!=0) {
00078
00079 ampl *= corr->getCorrection(fc_ampl);
00080
00081 }
00082
00083
00084 if (slewCorrect) time-=CastorTimeSlew::delay(std::max(1.0,fc_ampl),slewFlavor);
00085 }
00086 return RecHit(digi.id(),ampl,time);
00087 }
00088 }
00089
00090 CastorRecHit CastorSimpleRecAlgo::reconstruct(const CastorDataFrame& digi, const CastorCoder& coder, const CastorCalibrations& calibs) const {
00091 return CastorSimpleRecAlgoImpl::reco<CastorDataFrame,CastorRecHit>(digi,coder,calibs,
00092 firstSample_,samplesToAdd_,false,
00093 0,
00094 CastorTimeSlew::Fast);
00095 }
00096
00097
00098
00099 static const float wpksamp0_hf = 0.500635;
00100 static const float scale_hf = 0.999301;
00101 static const int num_bins_hf = 100;
00102
00103 static const float actual_ns_hf[num_bins_hf] = {
00104 0.00000,
00105 0.03750,
00106 0.07250,
00107 0.10750,
00108 0.14500,
00109 0.18000,
00110 0.21500,
00111 0.25000,
00112 0.28500,
00113 0.32000,
00114 0.35500,
00115 0.39000,
00116 0.42500,
00117 0.46000,
00118 0.49500,
00119 0.53000,
00120 0.56500,
00121 0.60000,
00122 0.63500,
00123 0.67000,
00124 0.70750,
00125 0.74250,
00126 0.78000,
00127 0.81500,
00128 0.85250,
00129 0.89000,
00130 0.92750,
00131 0.96500,
00132 1.00250,
00133 1.04250,
00134 1.08250,
00135 1.12250,
00136 1.16250,
00137 1.20500,
00138 1.24500,
00139 1.29000,
00140 1.33250,
00141 1.38000,
00142 1.42500,
00143 1.47500,
00144 1.52500,
00145 1.57750,
00146 1.63250,
00147 1.69000,
00148 1.75250,
00149 1.82000,
00150 1.89250,
00151 1.97500,
00152 2.07250,
00153 2.20000,
00154 19.13000,
00155 21.08750,
00156 21.57750,
00157 21.89000,
00158 22.12250,
00159 22.31000,
00160 22.47000,
00161 22.61000,
00162 22.73250,
00163 22.84500,
00164 22.94750,
00165 23.04250,
00166 23.13250,
00167 23.21500,
00168 23.29250,
00169 23.36750,
00170 23.43750,
00171 23.50500,
00172 23.57000,
00173 23.63250,
00174 23.69250,
00175 23.75000,
00176 23.80500,
00177 23.86000,
00178 23.91250,
00179 23.96500,
00180 24.01500,
00181 24.06500,
00182 24.11250,
00183 24.16000,
00184 24.20500,
00185 24.25000,
00186 24.29500,
00187 24.33750,
00188 24.38000,
00189 24.42250,
00190 24.46500,
00191 24.50500,
00192 24.54500,
00193 24.58500,
00194 24.62500,
00195 24.66500,
00196 24.70250,
00197 24.74000,
00198 24.77750,
00199 24.81500,
00200 24.85250,
00201 24.89000,
00202 24.92750,
00203 24.96250,
00204 };
00205
00206
00207 float timeshift_ns_hf(float wpksamp) {
00208 float flx = (num_bins_hf*(wpksamp - wpksamp0_hf)/scale_hf);
00209 int index = (int)flx;
00210 float yval;
00211
00212 if (index < 0) return actual_ns_hf[0];
00213 else if (index >= num_bins_hf-1) return actual_ns_hf[num_bins_hf-1];
00214
00215
00216 float y1 = actual_ns_hf[index];
00217 float y2 = actual_ns_hf[index+1];
00218
00219
00220
00221
00222 yval = y1 + (y2-y1)*(flx-(float)index);
00223 return yval;
00224 }