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