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