CMS 3D CMS Logo

PulseShapeFunctor.cc
Go to the documentation of this file.
1 #include <iostream>
2 #include <cmath>
3 #include <climits>
6 
7 namespace FitterFuncs {
8 
9  //Decalare the Pulse object take it in from Hcal and set some options
11  bool iPedestalConstraint,
12  bool iTimeConstraint,
13  bool iAddPulseJitter,
14  double iPulseJitter,
15  double iTimeMean,
16  double iPedMean,
17  unsigned nSamplesToFit)
18  : cntNANinfit(0),
19  acc25nsVec(HcalConst::maxPSshapeBin),
20  diff25nsItvlVec(HcalConst::maxPSshapeBin),
21  accVarLenIdxZEROVec(HcalConst::nsPerBX),
22  diffVarItvlIdxZEROVec(HcalConst::nsPerBX),
23  accVarLenIdxMinusOneVec(HcalConst::nsPerBX),
24  diffVarItvlIdxMinusOneVec(HcalConst::nsPerBX) {
25  //The raw pulse
26  for (int i = 0; i < HcalConst::maxPSshapeBin; ++i)
27  pulse_hist[i] = pulse(i);
28  // Accumulate 25ns for each starting point of 0, 1, 2, 3...
29  for (int i = 0; i < HcalConst::maxPSshapeBin; ++i) {
30  for (int j = i; j < i + HcalConst::nsPerBX; ++j) { //sum over HcalConst::nsPerBXns from point i
31  acc25nsVec[i] += (j < HcalConst::maxPSshapeBin ? pulse_hist[j] : pulse_hist[HcalConst::maxPSshapeBin - 1]);
32  }
33  diff25nsItvlVec[i] = (i + HcalConst::nsPerBX < HcalConst::maxPSshapeBin
35  : pulse_hist[HcalConst::maxPSshapeBin - 1] - pulse_hist[i]);
36  }
37  // Accumulate different ns for starting point of index either 0 or -1
38  for (int i = 0; i < HcalConst::nsPerBX; ++i) {
39  if (i == 0) {
42  } else {
44  accVarLenIdxMinusOneVec[i] = accVarLenIdxMinusOneVec[i - 1] + pulse_hist[i - 1];
45  }
47  diffVarItvlIdxMinusOneVec[i] = pulse_hist[i] - pulse_hist[0];
48  }
49  for (int i = 0; i < HcalConst::maxSamples; i++) {
50  psFit_x[i] = 0;
51  psFit_y[i] = 0;
52  psFit_erry[i] = 1.;
53  psFit_erry2[i] = 1.;
54  psFit_slew[i] = 0.;
55  }
56  //Constraints
57  pedestalConstraint_ = iPedestalConstraint;
58  timeConstraint_ = iTimeConstraint;
59  addPulseJitter_ = iAddPulseJitter;
60  pulseJitter_ = iPulseJitter * iPulseJitter;
61 
62  // for M2
63  timeMean_ = iTimeMean;
64  pedMean_ = iPedMean;
65  timeShift_ = 100.;
66  timeShift_ += 12.5; //we are trying to get BX
67 
68  nSamplesToFit_ = nSamplesToFit;
69  }
70 
71  void PulseShapeFunctor::funcShape(std::array<double, HcalConst::maxSamples> &ntmpbin,
72  const double pulseTime,
73  const double pulseHeight,
74  const double slew,
75  bool scalePulse) {
76  // pulse shape components over a range of time 0 ns to 255 ns in 1 ns steps
77  constexpr int ns_per_bx = HcalConst::nsPerBX;
78  //Get the starting time
79  int i_start = (-HcalConst::iniTimeShift - pulseTime - slew > 0
80  ? 0
81  : (int)std::abs(-HcalConst::iniTimeShift - pulseTime - slew) + 1);
82  double offset_start = i_start - HcalConst::iniTimeShift - pulseTime -
83  slew; //-199-2*pars[0]-2.*slew (for pars[0] > 98.5) or just -98.5-pars[0]-slew;
84  // zeroing output binned pulse shape
85  ntmpbin.fill(0.0f);
86 
87  if (edm::isNotFinite(offset_start)) { //Check for nan
88  ++cntNANinfit;
89  } else {
90  if (offset_start == 1.0) {
91  offset_start = 0.;
92  i_start -= 1;
93  } //Deal with boundary
94 
95  const int bin_start = (int)offset_start; //bin off to integer
96  const int bin_0_start = (offset_start < bin_start + 0.5 ? bin_start - 1 : bin_start); //Round it
97  const int iTS_start = i_start / ns_per_bx; //Time Slice for time shift
98  const int distTo25ns_start = ns_per_bx - 1 - i_start % ns_per_bx; //Delta ns
99  const double factor = offset_start - bin_0_start - 0.5; //Small correction?
100 
101  //Build the new pulse
102  ntmpbin[iTS_start] =
103  (bin_0_start == -1
104  ? // Initial bin (I'm assuming this is ok)
105  accVarLenIdxMinusOneVec[distTo25ns_start] + factor * diffVarItvlIdxMinusOneVec[distTo25ns_start]
106  : accVarLenIdxZEROVec[distTo25ns_start] + factor * diffVarItvlIdxZEROVec[distTo25ns_start]);
107  //Fill the rest of the bins
108  for (int iTS = iTS_start + 1; iTS < HcalConst::maxSamples; ++iTS) {
109  int bin_idx = distTo25ns_start + 1 + (iTS - iTS_start - 1) * ns_per_bx + bin_0_start;
110  ntmpbin[iTS] = acc25nsVec[bin_idx] + factor * diff25nsItvlVec[bin_idx];
111  }
112  //Scale the pulse
113  if (scalePulse) {
114  for (int i = iTS_start; i < HcalConst::maxSamples; ++i) {
115  ntmpbin[i] *= pulseHeight;
116  }
117  }
118  }
119 
120  return;
121  }
122 
124 
125  void PulseShapeFunctor::EvalPulse(const float *pars) {
126  int time = (pars[0] + timeShift_ - timeMean_) * HcalConst::invertnsPerBx;
127  float dummyPulseHeight = 0.f;
128  funcShape(pulse_shape_, pars[0], dummyPulseHeight, psFit_slew[time], false);
129  return;
130  }
131 
132  double PulseShapeFunctor::EvalPulseM2(const double *pars, const unsigned nPars) {
133  unsigned i = 0, j = 0;
134 
135  const double pedestal = pars[nPars - 1];
136 
137  //Stop crashes
138  for (i = 0; i < nPars; ++i)
139  if (edm::isNotFinite(pars[i])) {
140  ++cntNANinfit;
141  return 1e10;
142  }
143 
144  //calculate chisquare
145  double chisq = 0;
146  const unsigned parBy2 = (nPars - 1) / 2;
147  // std::array<float,HcalConst::maxSamples> pulse_shape_;
148 
149  if (addPulseJitter_) {
150  int time = (pars[0] + timeShift_ - timeMean_) * HcalConst::invertnsPerBx;
151  //Interpolate the fit (Quickly)
152  funcShape(pulse_shape_, pars[0], pars[1], psFit_slew[time], true);
153  for (j = 0; j < nSamplesToFit_; ++j) {
156  }
157 
158  for (i = 1; i < parBy2; ++i) {
159  time = (pars[i * 2] + timeShift_ - timeMean_) * HcalConst::invertnsPerBx;
160  //Interpolate the fit (Quickly)
161  funcShape(pulse_shape_, pars[i * 2], pars[i * 2 + 1], psFit_slew[time], true);
162  // add an uncertainty from the pulse (currently noise * pulse height =>Ecal uses full cov)
164  for (j = 0; j < nSamplesToFit_; ++j) {
167  }
168  }
169  } else {
170  int time = (pars[0] + timeShift_ - timeMean_) * HcalConst::invertnsPerBx;
171  //Interpolate the fit (Quickly)
172  funcShape(pulse_shape_, pars[0], pars[1], psFit_slew[time], true);
173  for (j = 0; j < nSamplesToFit_; ++j)
174  pulse_shape_sum_[j] = pulse_shape_[j] + pedestal;
175 
176  for (i = 1; i < parBy2; ++i) {
177  time = (pars[i * 2] + timeShift_ - timeMean_) * HcalConst::invertnsPerBx;
178  //Interpolate the fit (Quickly)
179  funcShape(pulse_shape_, pars[i * 2], pars[i * 2 + 1], psFit_slew[time], true);
180  // add an uncertainty from the pulse (currently noise * pulse height =>Ecal uses full cov)
181  for (j = 0; j < nSamplesToFit_; ++j)
183  }
184  }
185 
186  for (i = 0; i < nSamplesToFit_; ++i) {
187  const double d = psFit_y[i] - pulse_shape_sum_[i];
188  chisq += d * d / psFit_erry2[i];
189  }
190 
191  if (pedestalConstraint_) {
192  //Add the pedestal Constraint to chi2
193  chisq += invertpedSig2_ * (pedestal - pedMean_) * (pedestal - pedMean_);
194  }
195  //Add the time Constraint to chi2
196  if (timeConstraint_) {
197  for (j = 0; j < parBy2; ++j) {
198  int time = (pars[j * 2] + timeShift_ - timeMean_) * (double)HcalConst::invertnsPerBx;
199  double time1 = -100. + time * HcalConst::nsPerBX;
200  chisq += inverttimeSig2_ * (pars[j * 2] - timeMean_ - time1) * (pars[j * 2] - timeMean_ - time1);
201  }
202  }
203  return chisq;
204  }
205 } // namespace FitterFuncs
void EvalPulse(const float *pars)
void funcShape(std::array< double, HcalConst::maxSamples > &ntmpbin, const double pulseTime, const double pulseHeight, const double slew, bool scalePulse)
float invertnsPerBx
constexpr bool isNotFinite(T x)
Definition: isFinite.h:9
double psFit_erry[HcalConst::maxSamples]
std::vector< float > acc25nsVec
float iniTimeShift
std::array< double, HcalConst::maxSamples > pulse_shape_sum_
double psFit_y[HcalConst::maxSamples]
std::vector< float > diffVarItvlIdxZEROVec
PulseShapeFunctor(const HcalPulseShapes::Shape &pulse, bool iPedestalConstraint, bool iTimeConstraint, bool iAddPulseJitter, double iPulseJitter, double iTimeMean, double iPedMean, unsigned int nSamplesToFit)
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
std::array< float, HcalConst::maxPSshapeBin > pulse_hist
double f[11][100]
std::vector< float > diff25nsItvlVec
d
Definition: ztail.py:151
std::vector< float > accVarLenIdxMinusOneVec
std::vector< float > diffVarItvlIdxMinusOneVec
double pulse(double x, double y, double z, double t)
double psFit_erry2[HcalConst::maxSamples]
double psFit_x[HcalConst::maxSamples]
double psFit_slew[HcalConst::maxSamples]
std::array< double, HcalConst::maxSamples > pulse_shape_
std::vector< float > accVarLenIdxZEROVec
#define constexpr
double EvalPulseM2(const double *pars, const unsigned nPar)