CMS 3D CMS Logo

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
ZdcSimpleRecAlgo.cc
Go to the documentation of this file.
4 #include <algorithm> // for "max"
5 #include <iostream>
6 #include <math.h>
7 
8 
9 
10 static double MaximumFractionalError = 0.0005; // 0.05% error allowed from this source
11 
12 ZdcSimpleRecAlgo::ZdcSimpleRecAlgo(int firstSample, int samplesToAdd, bool correctForTimeslew, bool correctForPulse, float phaseNS, int recoMethod) :
13  firstSample_(firstSample),
14  samplesToAdd_(samplesToAdd),
15  recoMethod_(recoMethod),
16  correctForTimeslew_(correctForTimeslew) {
17  if (correctForPulse)
18  pulseCorr_=std::auto_ptr<HcalPulseContainmentCorrection>(new HcalPulseContainmentCorrection(samplesToAdd_,phaseNS,MaximumFractionalError));
19 }
20 
22  firstSample_(firstSample),
23  samplesToAdd_(samplesToAdd),
24  recoMethod_(recoMethod),
25  correctForTimeslew_(false) {
26 }
27 
28 static float timeshift_ns_zdc(float wpksamp);
29 
30 namespace ZdcSimpleRecAlgoImpl {
31  template<class Digi, class RecHit>
32  inline RecHit reco1(const Digi& digi, const HcalCoder& coder, const HcalCalibrations& calibs,
33  int ifirst, int n, bool slewCorrect, const HcalPulseContainmentCorrection* corr, HcalTimeSlew::BiasSetting slewFlavor) {
34  CaloSamples tool;
35  coder.adc2fC(digi,tool);
36  double ampl=0; int maxI = -1; double maxA = -1e10; double ta=0;
37  double fc_ampl=0;
38  for (int i=ifirst; i<tool.size() && i<n+ifirst; i++) {
39  int capid=digi[i].capid();
40  ta = (tool[i]-calibs.pedestal(capid)); // pedestal subtraction
41  fc_ampl+=ta;
42  ta*= calibs.respcorrgain(capid) ; // fC --> GeV
43  ampl+=ta;
44  if(ta>maxA){
45  maxA=ta;
46  maxI=i;
47  }
48  }
49 
50  double time=-9999;
52  if(maxI==0 || maxI==(tool.size()-1)) {
53  LogDebug("HCAL Pulse") << "ZdcSimpleRecAlgo::reconstruct :"
54  << " Invalid max amplitude position, "
55  << " max Amplitude: "<< maxI
56  << " first: "<<ifirst
57  << " last: "<<(tool.size()-1)
58  << std::endl;
59  } else {
60  maxA=fabs(maxA);
61  int capid=digi[maxI-1].capid();
62  double t0 = fabs((tool[maxI-1]-calibs.pedestal(capid))*calibs.respcorrgain(capid) );
63  capid=digi[maxI+1].capid();
64  double t2 = fabs((tool[maxI+1]-calibs.pedestal(capid))*calibs.respcorrgain(capid) );
65  double wpksamp = (t0 + maxA + t2);
66  if (wpksamp!=0) wpksamp=(maxA + 2.0*t2) / wpksamp;
67  time = (maxI - digi.presamples())*25.0 + timeshift_ns_zdc(wpksamp);
68  if (corr!=0) {
69  // Apply phase-based amplitude correction:
70  ampl *= corr->getCorrection(fc_ampl);
71  // std::cout << fc_ampl << " --> " << corr->getCorrection(fc_ampl) << std::endl;
72  }
73 
74  if (slewCorrect) time-=HcalTimeSlew::delay(std::max(1.0,fc_ampl),slewFlavor);
75  }
76 
77  time=time-calibs.timecorr(); // time calibration
78  return RecHit(digi.id(),ampl,time);
79  }
80 }
81 
82 
83 namespace ZdcSimpleRecAlgoImpl {
84  template<class Digi, class RecHit>
85  inline RecHit reco2(const Digi& digi, const HcalCoder& coder, const HcalCalibrations& calibs,
86  int ifirst, int n, bool slewCorrect, const HcalPulseContainmentCorrection* corr, HcalTimeSlew::BiasSetting slewFlavor) {
87  CaloSamples tool;
88  coder.adc2fC(digi,tool);
89  double ampl=0; int maxI = -1; double maxA = -1e10; double ta=0;
90  double prenoise = 0; double postnoise = 0;
91  int noiseslices = 0;
92  double noise = 0;
93  double fc_ampl=0;
94 
95  for(int k = 0 ; k < tool.size() && k < ifirst; k++){
96  prenoise += tool[k];
97  noiseslices++;
98  }
99 // for(int j = (n + ifirst + 1); j <tool.size(); j++){
100 // postnoise += tool[j];
101 // noiseslices++;
102 // }
103 // removed postnoise due to significant signal seen in TS 7,8,9 (Heavy Ion run 2010)
104 // Future ZdcSimpleRecAlgo will have better configurable noise calculation
105  postnoise=0;
106  if(noiseslices != 0) {
107  noise = (prenoise+postnoise)/double(noiseslices);
108  } else {
109  noise = 0;
110  }
111  // factor to multiply by noise to make 0 or 1 to handle negative noise situations
112  double noisefactor=1.;
113  for (int i=ifirst; i<tool.size() && i<n+ifirst; i++) {
114  int capid=digi[i].capid();
115  if(noise<0){
116  // flag hit as having negative noise, and don't subtract anything, because
117  // it will falsely increase the energy
118  noisefactor=0.;
119  }
120  ta = tool[i]-noisefactor*noise;
121  fc_ampl+=ta;
122  ta*= calibs.respcorrgain(capid) ; // fC --> GeV
123  ampl+=ta;
124  if(ta>maxA){
125  maxA=ta;
126  maxI=i;
127  }
128  }
129 // if(ta<0){
130 // // flag hits that have negative energy
131 // }
132 
133  double time=-9999;
135  if(maxI==0 || maxI==(tool.size()-1)) {
136  LogDebug("HCAL Pulse") << "ZdcSimpleRecAlgo::reco2 :"
137  << " Invalid max amplitude position, "
138  << " max Amplitude: "<< maxI
139  << " first: "<<ifirst
140  << " last: "<<(tool.size()-1)
141  << std::endl;
142  } else {
143  int capid=digi[maxI-1].capid();
144  double Energy0 = ((tool[maxI-1])*calibs.respcorrgain(capid) );
145 // if any of the energies used in the weight are negative, make them 0 instead
146 // these are actually QIE values, not energy
147  if(Energy0<0){Energy0=0.;}
148  capid=digi[maxI].capid();
149  double Energy1 = ((tool[maxI])*calibs.respcorrgain(capid) ) ;
150  if(Energy1<0){Energy1=0.;}
151  capid=digi[maxI+1].capid();
152  double Energy2 = ((tool[maxI+1])*calibs.respcorrgain(capid) );
153  if(Energy2<0){Energy2=0.;}
154 //
155  double TSWeightEnergy = ((maxI-1)*Energy0 + maxI*Energy1 + (maxI+1)*Energy2);
156  double EnergySum=Energy0+Energy1+Energy2;
157  double AvgTSPos=0.;
158  if (EnergySum!=0) AvgTSPos=TSWeightEnergy/ EnergySum;
159 // If time is zero, set it to the "nonsensical" -99
160 // Time should be between 75ns and 175ns (Timeslices 3-7)
161  if(AvgTSPos==0){
162  time=-99;
163  } else {
164  time = (AvgTSPos*25.0);
165  }
166  if (corr!=0) {
167  // Apply phase-based amplitude correction:
168  ampl *= corr->getCorrection(fc_ampl);
169  }
170  }
171  return RecHit(digi.id(),ampl,time);
172  }
173 }
174 
175 ZDCRecHit ZdcSimpleRecAlgo::reconstruct(const ZDCDataFrame& digi, const HcalCoder& coder, const HcalCalibrations& calibs) const {
176 
177  if(recoMethod_ == 1)
178  return ZdcSimpleRecAlgoImpl::reco1<ZDCDataFrame,ZDCRecHit>(digi,coder,calibs,
180  0,
182  if(recoMethod_ == 2)
183  return ZdcSimpleRecAlgoImpl::reco2<ZDCDataFrame,ZDCRecHit>(digi,coder,calibs,
186 
187  edm::LogError("ZDCSimpleRecAlgoImpl::reconstruct, recoMethod was not declared");
188  throw cms::Exception("ZDCSimpleRecoAlgos::exiting process");
189 
190 }
191 
192 static const float wpksamp0_zdc = 0.500053;
193 static const float scale_zdc = 0.999683;
194 static const int num_bins_zdc = 100;
195 
196 static const float actual_ns_zdc[num_bins_zdc] = {
197  0.00250, // 0.000-0.010
198  0.08000, // 0.010-0.020
199  0.16000, // 0.020-0.030
200  0.23750, // 0.030-0.040
201  0.31750, // 0.040-0.050
202  0.39500, // 0.050-0.060
203  0.47500, // 0.060-0.070
204  0.55500, // 0.070-0.080
205  0.63000, // 0.080-0.090
206  0.70000, // 0.090-0.100
207  0.77000, // 0.100-0.110
208  0.84000, // 0.110-0.120
209  0.91000, // 0.120-0.130
210  0.98000, // 0.130-0.140
211  1.05000, // 0.140-0.150
212  1.12000, // 0.150-0.160
213  1.19000, // 0.160-0.170
214  1.26000, // 0.170-0.180
215  1.33000, // 0.180-0.190
216  1.40000, // 0.190-0.200
217  1.47000, // 0.200-0.210
218  1.54000, // 0.210-0.220
219  1.61000, // 0.220-0.230
220  1.68000, // 0.230-0.240
221  1.75000, // 0.240-0.250
222  1.82000, // 0.250-0.260
223  1.89000, // 0.260-0.270
224  1.96000, // 0.270-0.280
225  2.03000, // 0.280-0.290
226  2.10000, // 0.290-0.300
227  2.17000, // 0.300-0.310
228  2.24000, // 0.310-0.320
229  2.31000, // 0.320-0.330
230  2.38000, // 0.330-0.340
231  2.45000, // 0.340-0.350
232  2.52000, // 0.350-0.360
233  2.59000, // 0.360-0.370
234  2.68500, // 0.370-0.380
235  2.79250, // 0.380-0.390
236  2.90250, // 0.390-0.400
237  3.01000, // 0.400-0.410
238  3.11750, // 0.410-0.420
239  3.22500, // 0.420-0.430
240  3.33500, // 0.430-0.440
241  3.44250, // 0.440-0.450
242  3.55000, // 0.450-0.460
243  3.73250, // 0.460-0.470
244  4.02000, // 0.470-0.480
245  4.30750, // 0.480-0.490
246  4.59500, // 0.490-0.500
247  6.97500, // 0.500-0.510
248 10.98750, // 0.510-0.520
249 13.03750, // 0.520-0.530
250 14.39250, // 0.530-0.540
251 15.39500, // 0.540-0.550
252 16.18250, // 0.550-0.560
253 16.85250, // 0.560-0.570
254 17.42750, // 0.570-0.580
255 17.91500, // 0.580-0.590
256 18.36250, // 0.590-0.600
257 18.76500, // 0.600-0.610
258 19.11250, // 0.610-0.620
259 19.46000, // 0.620-0.630
260 19.76500, // 0.630-0.640
261 20.03500, // 0.640-0.650
262 20.30250, // 0.650-0.660
263 20.57250, // 0.660-0.670
264 20.79250, // 0.670-0.680
265 21.00250, // 0.680-0.690
266 21.21000, // 0.690-0.700
267 21.42000, // 0.700-0.710
268 21.62750, // 0.710-0.720
269 21.79000, // 0.720-0.730
270 21.95250, // 0.730-0.740
271 22.11500, // 0.740-0.750
272 22.27750, // 0.750-0.760
273 22.44000, // 0.760-0.770
274 22.60500, // 0.770-0.780
275 22.73250, // 0.780-0.790
276 22.86000, // 0.790-0.800
277 22.98500, // 0.800-0.810
278 23.11250, // 0.810-0.820
279 23.23750, // 0.820-0.830
280 23.36500, // 0.830-0.840
281 23.49000, // 0.840-0.850
282 23.61750, // 0.850-0.860
283 23.71500, // 0.860-0.870
284 23.81250, // 0.870-0.880
285 23.91250, // 0.880-0.890
286 24.01000, // 0.890-0.900
287 24.10750, // 0.900-0.910
288 24.20750, // 0.910-0.920
289 24.30500, // 0.920-0.930
290 24.40500, // 0.930-0.940
291 24.50250, // 0.940-0.950
292 24.60000, // 0.950-0.960
293 24.68250, // 0.960-0.970
294 24.76250, // 0.970-0.980
295 24.84000, // 0.980-0.990
296 24.92000 // 0.990-1.000
297 };
298 
299 float timeshift_ns_zdc(float wpksamp) {
300  float flx = (num_bins_zdc*(wpksamp - wpksamp0_zdc)/scale_zdc);
301  int index = (int)flx;
302  float yval;
303 
304  if (index < 0) return actual_ns_zdc[0];
305  else if (index >= num_bins_zdc-1) return actual_ns_zdc[num_bins_zdc-1];
306 
307  // else interpolate:
308  float y1 = actual_ns_zdc[index];
309  float y2 = actual_ns_zdc[index+1];
310 
311  // float delta_x = 1/(float)num_bins_zdc;
312  // yval = y1 + (y2-y1)*(flx-(float)index)/delta_x;
313 
314  yval = y1 + (y2-y1)*(flx-(float)index);
315  return yval;
316 }
#define LogDebug(id)
RecHit reco1(const Digi &digi, const HcalCoder &coder, const HcalCalibrations &calibs, int ifirst, int n, bool slewCorrect, const HcalPulseContainmentCorrection *corr, HcalTimeSlew::BiasSetting slewFlavor)
int i
Definition: DBlmapReader.cc:9
double respcorrgain(int fCapId) const
get response corrected gain for capid=0..3
static const float scale_zdc
static const float wpksamp0_zdc
double getCorrection(double fc_ampl) const
RecHit reco2(const Digi &digi, const HcalCoder &coder, const HcalCalibrations &calibs, int ifirst, int n, bool slewCorrect, const HcalPulseContainmentCorrection *corr, HcalTimeSlew::BiasSetting slewFlavor)
double pedestal(int fCapId) const
get pedestal for capid=0..3
ZDCRecHit reconstruct(const ZDCDataFrame &digi, const HcalCoder &coder, const HcalCalibrations &calibs) const
ZdcSimpleRecAlgo(int firstSample, int samplesToAdd, bool correctForTimeslew, bool correctForContainment, float fixedPhaseNs, int recoMethod)
std::auto_ptr< HcalPulseContainmentCorrection > pulseCorr_
static float timeshift_ns_zdc(float wpksamp)
const T & max(const T &a, const T &b)
static double MaximumFractionalError
static const float actual_ns_zdc[num_bins_zdc]
JetCorrectorParameters corr
Definition: classes.h:9
int k[5][pyjets_maxn]
int size() const
get the size
Definition: CaloSamples.h:24
double timecorr() const
get time correction factor
virtual void adc2fC(const HBHEDataFrame &df, CaloSamples &lf) const =0
static const int num_bins_zdc
static double delay(double fC, BiasSetting bias=Medium)
Returns the amount (ns) by which a pulse of the given number of fC will be delayed by the timeslew ef...
Definition: HcalTimeSlew.cc:8