CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
EcalUncalibRecHitFixedAlphaBetaAlgo.h
Go to the documentation of this file.
1 #ifndef RecoLocalCalo_EcalRecAlgos_EcalUncalibRecHitFixedAlphaBetaAlgo_HH
2 #define RecoLocalCalo_EcalRecAlgos_EcalUncalibRecHitFixedAlphaBetaAlgo_HH
3 
14 #include "CLHEP/Matrix/Vector.h"
15 #include "CLHEP/Matrix/SymMatrix.h"
16 //#include "CLHEP/Matrix/Matrix.h"
18 
20 
21 #include <vector>
22 #include <string>
23 
24 //#include "TROOT.h"
25 //#include "TMinuit.h"
26 //#include "TGraph.h"
27 //#include "TF1.h"
28 //#include "TMatrixD.h"
29 //#include "TVectorD.h"
30 
32 {
33 
34 
35  private:
36  double MinAmpl_;
38  double fAlpha_;//parameter of the shape
39  double fBeta_;//parameter of the shape
40  double fAmp_max_;// peak amplitude
41  double fTim_max_ ;// time of the peak (in 25ns units)
42  double fPed_max_;// pedestal value
43  double alfabeta_;
44 
45 
46  int fNb_iter_;
49 
50  float fSigma_ped;
51  double un_sur_sigma;
52  //temporary solution for different alpha and beta
53  float alpha_table_[36][1701];
54  float beta_table_[36][1701];
55 
56  bool doFit_;
57 
58  double pulseShapeFunction(double t);
59  float PerformAnalyticFit(double* samples, int max_sample);
60  void InitFitParameters(double* samples, int max_sample);
61  CLHEP::HepSymMatrix DM1_ ; CLHEP::HepVector temp_;
62  public:
63 
65  un_sur_sigma = 1./double(fSigma_ped) ;
66  for (int i=0;i<36;i++){
67  for(int j=0;j<1701;j++){
68  alpha_table_[i][j] = 1.2 ;
69  beta_table_[i][j] = 1.7 ;
70  }
71  }
72  doFit_ = false;
73  MinAmpl_ = 16;
74  dyn_pedestal = true;
75  }
76  EcalUncalibRecHitFixedAlphaBetaAlgo<C>(int n_iter, int n_bef_max =1, int n_aft_max =3, float sigma_ped = 1.1):fAlpha_(0.),fBeta_(0.),fAmp_max_(-1.),fTim_max_(-1),fPed_max_(0),alfabeta_(0),DM1_(3),temp_(3){
77 
78  fNb_iter_ = n_iter ;
79  fNum_samp_bef_max_ = n_bef_max ;
80  fNum_samp_after_max_ = n_aft_max ;
81  fSigma_ped = sigma_ped;
82  un_sur_sigma = 1./double(fSigma_ped) ;
83  for (int i=0;i<36;i++){
84  for(int j=0;j<1701;j++){
85  alpha_table_[i][j] = 1.2 ;
86  beta_table_[i][j] = 1.7 ;
87  }
88  }
89  doFit_ = false;
90  MinAmpl_ = 16;
91  dyn_pedestal = true;
92  };
93 
95  virtual EcalUncalibratedRecHit makeRecHit(const C& dataFrame, const double* pedestals,
96  const double* gainRatios,
98  const EcalWeightSet::EcalChi2WeightMatrix** chi2Matrix);
99  void SetAlphaBeta( double alpha, double beta);
100  void SetMinAmpl(double ampl);
101  void SetDynamicPedestal(bool dyn_pede);
102 };
103 
104 
105 
107 template<class C> EcalUncalibratedRecHit EcalUncalibRecHitFixedAlphaBetaAlgo<C>::makeRecHit(const C& dataFrame, const double* pedestals,
108  const double* gainRatios,
110  const EcalWeightSet::EcalChi2WeightMatrix** chi2Matrix){
111  double chi2_(-1.);
112 
113  // double Gain12Equivalent[4]={0,1,2,12};
114  double frame[C::MAXSAMPLES];// will contain the ADC values
115  double pedestal =0; // carries pedestal for gain12 i.e. gainId==1
116 
117  int gainId0 = 1; // expected gainId at the beginning of dataFrame
118  int iGainSwitch = 0; // flags whether there's any gainId other than gainId0
119  int GainId= 0; // stores gainId at every sample
120  double maxsample(-1); // ADC value of maximal ped-subtracted sample
121  int imax(-1); // sample number of maximal ped-subtracted sample
122  bool external_pede = false;
123  bool isSaturated = 0; // flag reporting whether gain0 has been found
124 
125  // Get time samples checking for Gain Switch and pedestals
126  if(pedestals){
127  external_pede = true;
128  if(dyn_pedestal) { pedestal = (double(dataFrame.sample(0).adc()) + double(dataFrame.sample(1).adc()))/2.;}
129  else{ pedestal = pedestals[0];}
130  for(int iSample = 0; iSample < C::MAXSAMPLES; iSample++) {
131  //create frame in adc gain 12 equivalent
132  GainId = dataFrame.sample(iSample).gainId();
133 
134  // FIX-ME: warning: the vector pedestal is supposed to have in the order G12, G6 and G1
135  // if GainId is zero treat it as 3 temporarily to protect against undefined
136  // frame will be set to ~max of gain1
137  if ( GainId == 0 )
138  {
139  GainId = 3;
140  isSaturated = 1;
141  }
142 
143  if (GainId != gainId0) iGainSwitch = 1;
144 
145  if(GainId==gainId0){frame[iSample] = double(dataFrame.sample(iSample).adc())-pedestal ;}
146  else {frame[iSample] = (double(dataFrame.sample(iSample).adc())-pedestals[GainId-1])*gainRatios[GainId-1];}
147 
148  if( frame[iSample]>maxsample ) {
149  maxsample = frame[iSample];
150  imax = iSample;
151  }
152  }
153  }
154  else {// pedestal from pre-sample
155  external_pede = false;
156  pedestal = (double(dataFrame.sample(0).adc()) + double(dataFrame.sample(1).adc()))/2.;
157 
158  for(int iSample = 0; iSample < C::MAXSAMPLES; iSample++) {
159  //create frame in adc gain 12 equivalent
160  GainId = dataFrame.sample(iSample).gainId();
161  //no gain switch forseen if there is no external pedestal
162  if ( GainId == 0 )
163  {
164  GainId = 3;
165  isSaturated = 1;
166  }
167 
168  frame[iSample] = double(dataFrame.sample(iSample).adc())-pedestal ;
169  // if gain has switched but no pedestals are available, no much good you can do...
170  if (GainId > gainId0) iGainSwitch = 1;
171  if( frame[iSample]>maxsample ) {
172  maxsample = frame[iSample];
173  imax = iSample;
174  }
175  }
176  }
177 
178  if( (iGainSwitch==1 && external_pede==false) || // ... thus you return dummy rechit
179  imax ==-1 ){ // protect against all frames being <-1
180  return EcalUncalibratedRecHit( dataFrame.id(), -1., -100., -1. , -1.);
181  }
182 
183  InitFitParameters(frame, imax);
184  chi2_ = PerformAnalyticFit(frame,imax);
185  uint32_t flags = 0;
186  if (isSaturated) flags = EcalUncalibratedRecHit::kSaturated;
187 
188  /* std::cout << "separate fits\nA: " << fAmp_max_ << ", ResidualPed: " << fPed_max_
189  <<", pedestal: "<<pedestal << ", tPeak " << fTim_max_ << std::endl;
190  */
191  return EcalUncalibratedRecHit( dataFrame.id(),fAmp_max_, pedestal+fPed_max_, fTim_max_ - 5 , chi2_, flags );
192 }
193 
195  if( alfabeta_ <= 0 ) return((double)0.);
196  double dtsbeta,variable,puiss;
197  double dt = t-fTim_max_ ;
198  if(dt > -alfabeta_) {
199  dtsbeta=dt/fBeta_ ;
200  variable=1.+dt/alfabeta_ ;
201  puiss=pow(variable,fAlpha_);
202  return fAmp_max_*puiss*exp(-dtsbeta)+fPed_max_ ;
203  }
204  return fPed_max_ ;
205 }
206 
207 template<class C> void EcalUncalibRecHitFixedAlphaBetaAlgo<C>::InitFitParameters(double* samples, int max_sample){
208 
209  // in a first attempt just use the value of the maximum sample
210  fAmp_max_ = samples[max_sample];
211  fTim_max_ = max_sample;
212  fPed_max_ = 0;
213 
214  // amplitude too low for fit to converge
215  // timing set correctly is assumed
216  if(fAmp_max_ < MinAmpl_){
217  fAmp_max_ = samples[5];
218  double sumA = samples[5]+samples[4]+samples[6];
219  if(sumA != 0) { fTim_max_ = 5+(samples[6]-samples[4])/sumA; }
220  else{ fTim_max_ = -993; }//-999+6
221  doFit_ = false;
222  }
223  // if timing very badly off, that just use max sample
224  else if(max_sample <1 || max_sample > 7)
225  { doFit_ = false;}
226  else{
227  //y=a*(x-xM)^2+b*(x-xM)+c
228  doFit_ = true;
229  float a = float(samples[max_sample-1]+samples[max_sample+1]-2*samples[max_sample])/2.;
230  if(a==0){doFit_ =false; return;}
231  float b = float(samples[max_sample+1]-samples[max_sample-1])/2.;
232 
233  fTim_max_ = max_sample - b/(2*a);
234  fAmp_max_ = samples[max_sample] - b*b/(4*a);
235  }
236 
237 }
238 
239 template<class C> float EcalUncalibRecHitFixedAlphaBetaAlgo<C>::PerformAnalyticFit(double* samples, int max_sample){
240 
241  //int fValue_tim_max = max_sample;
246  //| the pedestal (fPed_max_)
247 
248  double chi2=-1 , db[3] ;
249 
250 
251  //HepSymMatrix DM1(3) ; CLHEP::HepVector temp(3) ;
252 
253  int num_fit_min =(int)(max_sample - fNum_samp_bef_max_ ) ;
254  int num_fit_max =(int)(max_sample + fNum_samp_after_max_) ;
255 
256  if (num_fit_min<0) num_fit_min = 0 ;
257  //if (num_fit_max>=fNsamples-1) num_fit_max = fNsamples-2 ;
258  if (num_fit_max>= C::MAXSAMPLES ) {num_fit_max = C::MAXSAMPLES-1 ;}
259 
260  if(! doFit_ ) {
261  LogDebug("EcalUncalibRecHitFixedAlphaBetaAlgo")<<"No fit performed. The amplitude of sample 5 will be used";
262  return -1;
263  }
264 
265  double func,delta ;
266  double variation_func_max = 0. ;double variation_tim_max = 0. ; double variation_ped_max = 0. ;
268  for (int iter=0 ; iter < fNb_iter_ ; iter ++) {
270  chi2 = 0. ; //PROD.Zero() ; DM1.Zero() ;
271 
272  for(int i1=0 ; i1<3 ; i1++) {
273  temp_[i1]=0;
274  for(int j1=i1 ; j1<3 ; j1++) {
275  DM1_.fast(j1+1,i1+1) = 0; }
276  }
277 
278  fAmp_max_ += variation_func_max ;
279  fTim_max_ += variation_tim_max ;
280  fPed_max_ += variation_ped_max ;
281 
283  for( int i = num_fit_min ; i <= num_fit_max ; i++) {
284  //if(i>fsamp_edge_fit && i<num_fit_min) continue ; // remove front edge samples
286  func = pulseShapeFunction( (double)i ) ;
288  double dt =(double)i - fTim_max_ ;
289  if(dt > -alfabeta_) {
290  double dt_sur_beta = dt/fBeta_ ;
291  double variable = (double)1. + dt/alfabeta_ ;
292  double expo = exp(-dt_sur_beta) ;
293  double puissance = pow(variable,fAlpha_) ;
294 
295  db[0]=un_sur_sigma*puissance*expo ;
296  db[1]=fAmp_max_*db[0]*dt_sur_beta/(alfabeta_*variable) ;
297  }
298  else {
299  db[0]=0. ; db[1]=0. ;
300  }
301  db[2]=un_sur_sigma ;
303  for(int i1=0 ; i1<3 ; i1++) {
304  for(int j1=i1 ; j1<3 ; j1++) {
305  //double & fast(int row, int col);
306  DM1_.fast(j1+1,i1+1) += db[i1]*db[j1]; }
307  }
309  delta = (samples[i]-func)*un_sur_sigma ;
311  for(int ii=0 ; ii<3 ;ii++) {temp_[ii] += delta*db[ii] ;}
312  chi2 += delta * delta ;
313  }
314 
315  int fail=0 ;
316  DM1_.invert(fail) ;
317  if(fail != 0.) {
318  //just a guess from the value of the parameters in the previous interaction;
319  //printf("wH4PulseFitWithFunction =====> determinant error --> No Fit Provided !\n") ;
320  InitFitParameters(samples,max_sample);
321  return -101 ;
322  }
323 /* for(int i1=0 ; i1<3 ; i1++) { */
324 /* for(int j1=0 ; j1<3 ; j1++) { */
325 /* //double & fast(int row, int col); */
326 /* std::cout<<"inverted: "<<DM1[j1][i1]<<std::endl;;} */
327 /* } */
328 /* std::cout<<"vector temp: "<< temp[0]<<" "<<temp[1]<<" "<<temp[2]<<std::endl; */
330  CLHEP::HepVector PROD = DM1_*temp_ ;
331  // std::cout<<"vector PROD: "<< PROD[0]<<" "<<PROD[1]<<" "<<PROD[2]<<std::endl;
332 
333  // Probably the fastest way to protect against
334  // +-inf value in the matrix DM1_ after inversion
335  // (which is nevertheless flagged as successfull...)
336  if ( std::isnan( PROD[0] ) ) {
337  InitFitParameters(samples,max_sample);
338  return -103 ;
339  }
340 
341  variation_func_max = PROD[0] ;
342  variation_tim_max = PROD[1] ;
343  variation_ped_max = PROD[2] ;
344  //chi2 = chi2/((double)nsamp_used - 3.) ;
345  }
346 
347 
349  if( variation_func_max > 2000. || variation_func_max < -1000. ) {
350  InitFitParameters(samples,max_sample);
351  return -102;
352  }
353 
354 
356  fAmp_max_ += variation_func_max ;
357  fTim_max_ += variation_tim_max ;
358  fPed_max_ += variation_ped_max ;
359 
360 
361  // protection against unphysical results:
362  // ampli mismatched to MaxSample, ampli largely negative, time off preselected range
363  if( fAmp_max_>2*samples[max_sample] || fAmp_max_<-100 || fTim_max_<0 || 9<fTim_max_ ) {
364  InitFitParameters(samples,max_sample);
365  return -104;
366  }
367 
368 
369  //std::cout <<"chi2: "<<chi2<<" ampl: "<<fAmp_max_<<" time: "<<fTim_max_<<" pede: "<<fPed_max_<<std::endl;
370  return chi2;
371 }
372 
373 template<class C> void EcalUncalibRecHitFixedAlphaBetaAlgo<C>::SetAlphaBeta( double alpha, double beta){
374  fAlpha_ = alpha;
375  fBeta_= beta;
376  alfabeta_ = fAlpha_*fBeta_;
377 }
378 
379 template<class C> void EcalUncalibRecHitFixedAlphaBetaAlgo<C>::SetMinAmpl( double ampl){
380  MinAmpl_ = ampl;
381 }
383  dyn_pedestal = p;
384 }
385 #endif
#define LogDebug(id)
const double beta
dbl * delta
Definition: mlp_gen.cc:36
void InitFitParameters(double *samples, int max_sample)
float dt
Definition: AMPTWrapper.h:126
int i
Definition: DBlmapReader.cc:9
float alpha
Definition: AMPTWrapper.h:95
tuple db
Definition: EcalCondDB.py:151
std::vector< Variable::Flags > flags
Definition: MVATrainer.cc:135
virtual EcalUncalibratedRecHit makeRecHit(const C &dataFrame, const double *pedestals, const double *gainRatios, const EcalWeightSet::EcalWeightMatrix **weights, const EcalWeightSet::EcalChi2WeightMatrix **chi2Matrix)
Compute parameters.
bool isnan(float x)
Definition: math.h:13
int j
Definition: DBlmapReader.cc:9
math::Matrix< 10, 10 >::type EcalChi2WeightMatrix
Definition: EcalWeightSet.h:21
double b
Definition: hdecay.h:120
bool isSaturated(const Digi &digi, const int &maxADCvalue, int ifirst, int n)
double a
Definition: hdecay.h:121
#define PROD(A, B)
math::Matrix< 3, 10 >::type EcalWeightMatrix
Definition: EcalWeightSet.h:20
float PerformAnalyticFit(double *samples, int max_sample)
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:40