CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
TFParams.cc
Go to the documentation of this file.
1 
13 #include "TMatrixD.h"
14 #include "TMath.h"
15 
16 #include <iostream>
17 #include <ctime>
18 
19 //ClassImp(TFParams)
20 
21 using namespace std;
22 
23 TFParams::TFParams(int size, int size_sh) {
24  //int sdim = size;
25  //int plshdim = size_sh;
26 
27  for (int i = 0; i < 10; i++) {
28  for (int j = 0; j < 10; j++) {
29  weight_matrix[i][j] = 8.;
30  }
31  }
32 }
33 
34 double TFParams::fitpj(double **adcval, double *parout, double **db_i, double noise_val, int debug) {
35 #define dimn 10
36 #define dimin 10
37 #define plshdim 300
38 #define nsamp 10
39 #define ntrack 500
40  //#define debug debug1
41 
42  // ******************************************************************
43  // * Definitions of variables used in the routine
44  // ******************************************************************
45 
46  double a1, a2, a3, b1, b2;
47  int iter, nevt;
48  //double errpj[dimmat][dimmat] ;
49  double bi[ntrack][2], dbi[ntrack][2];
50  double zi[ntrack][2];
51  double par3degre[3];
52  int ioktk[ntrack], nk, nborn_min = 0, nborn_max = 0;
53  double cti[ntrack][6], dm1i[ntrack][4];
54  double par[4], tsig[1];
55  double amp, delta[nsamp], delta2, fun;
56  double num_fit_min[ntrack], num_fit_max[ntrack];
57  int i, j, k, imax[ntrack];
58 
59  double ampmax[ntrack], dt, t;
60  double chi2, chi2s, da1[nsamp], da2[nsamp], db1[nsamp], db2[nsamp];
61  double chi2tot;
62  double fact2;
63  double albet, dtsbeta, variab, alpha, beta;
64  double unsurs1 /*,unsurs2*/;
65  // double fit3 ;
66  int numb_a, numb_b, numb_x;
67 
68  fun = 0;
69  chi2s = 0;
70  chi2tot = 0;
71  matrice DA, DAT, BK, DB, DBT, C, CT, D, DM1, CDM1, CDM1CT, Z, CDM1Z, YK, Y, B, X, XINV, RES2;
72  matrice A_CROISS, ZMCT;
73 
74  double *amplu;
75  amplu = new double[nsamp];
76 
77  parout[0] = 0.;
78  parout[1] = 0.;
79  parout[2] = 0.;
80 
81  //
82  // Initialisation of fit parameters
83  //
84 
85  a1 = a1ini;
86  a2 = a2ini;
87  a3 = a3ini;
88  if (METHODE == 2) {
89  a2 = a3ini; // for lastshape BETA is the third parameter ( ... ! )
90  }
91  if (debug == 1) {
92  printf(" ------> __> valeurs de a1 %f a2 %f a3 %f\n", a1, a2, a3);
93  }
94  for (i = 0; i < ntrack; i++) {
95  for (j = 0; j < 2; j++) {
96  bi[i][j] = (double)0.;
97  dbi[i][j] = (double)0.;
98  zi[i][j] = (double)0.;
99  cti[i][j] = (double)0.;
100  dm1i[i][j] = (double)0.;
101  }
102  }
103 
104  numb_a = 2;
105 
106  //
107  // Matrices initialisation
108  //
109 
110  numb_x = 1;
111  numb_b = 2;
112  DA = cree_mat(numb_a, numb_x);
113  DAT = cree_mat(numb_x, numb_a);
114  BK = cree_mat_prod(DA, DAT);
115  DB = cree_mat(numb_b, numb_x);
116  DBT = cree_mat(numb_x, numb_b);
117  C = cree_mat(numb_a, numb_b);
118  CT = cree_mat(numb_b, numb_a);
119  D = cree_mat_prod(DB, DBT);
120  DM1 = cree_mat_prod(DB, DBT);
121  CDM1 = cree_mat_prod(C, DM1);
122  CDM1CT = cree_mat_prod(CDM1, CT);
123  Z = cree_mat(numb_b, numb_x);
124  CDM1Z = cree_mat_prod(CDM1, Z);
125  YK = cree_mat(numb_a, numb_x);
126  Y = cree_mat(numb_a, numb_x);
127  B = cree_mat_prod(DA, DAT);
128  X = cree_mat_prod(DA, DAT);
129  XINV = cree_mat_prod(DA, DAT);
130  RES2 = cree_mat(numb_a, numb_x);
131  A_CROISS = cree_mat(numb_a, numb_x);
132  ZMCT = cree_mat(numb_b, numb_x);
133 
135  // First Loop on iterations //
137 
138  for (iter = 0; iter < 6; iter++) {
139  chi2tot = 0;
140 
141  //
142  // Set zeros for general matrices
143  //
144 
145  if (debug == 1) {
146  printf(" Debut de l'iteration numero %d \n", iter);
147  }
148  zero_mat(CDM1Z);
149  zero_mat(Y);
150  zero_mat(CDM1CT);
151  zero_mat(B);
152  zero_mat(X);
153  zero_mat(CDM1);
154 
155  nk = -1;
156  if (debug == 1) {
157  printf(" resultats injectes a iterations %d \n", iter);
158  printf(" parametre a1 = %f \n", a1);
159  printf(" parametre a2 = %f \n", a2);
160  printf(" chi2 du fit chi2s = %f \n", chi2s);
161 
162  printf(" value de nevtmax _______________ %d \n", nevtmax);
163  }
164 
166  // Loop on events //
168 
169  for (nevt = 0; nevt < nevtmax; nevt++) {
170  // B1 = BI[nk,1] est la normalisation du signal
171  // B2 = BI[nk,2] ewst le dephasage par rapport a une
172  // fonction centree en zero
173  // Nous choisissons ici de demarrer avec les resultats
174  // de l'ajustement parabolique mais il faudra bien
175  // entendu verifier que cela ne biaise pas le resultat !
176  // mise a zero des matrices utilisees dans la boucle
177 
178  zero_mat(Z);
179  zero_mat(YK);
180  zero_mat(BK);
181  zero_mat(C);
182  zero_mat(D);
183 
184  nk = nevt;
185  ampmax[nk] = 0.;
186  imax[nk] = 0;
187  for (k = 0; k < 10; k++) {
188  amplu[k] = adcval[nevt][k];
189  if (amplu[k] > ampmax[nk]) {
190  ampmax[nk] = amplu[k];
191  imax[nk] = k;
192  }
193  }
194 
195  if (iter == 0) {
196  // start with degree 3 polynomial ....
197  //fit3 =polfit(ns ,imax[nk] ,par3degre ,errpj ,amplu ) ;
198  // std::cout << "Poly Fit Param :"<< par3degre[0] <<" "<< par3degre[1]<< std::endl;
199 
200  // start with parabol
201  //fit3 = parab(amplu,4,12,par3degre) ;
202  /*fit3 =*/parab(amplu, 2, 9, par3degre);
203  //std::cout << "Parab Fit Param :"<< par3degre[0] <<" "<< par3degre[1]<< std::endl;
204 
205  // start with basic initial values
206  //par3degre[0]= ampmax+ampmax/10. ;
207  //par3degre[1]= (double)imax[nk]+0.1 ;
208  //bi[nk][0] = ampmax[nk] ;
209  //bi[nk][1] = (double)imax[nk] ;
210 
211  num_fit_min[nevt] = (double)imax[nk] - (double)nsmin;
212  num_fit_max[nevt] = (double)imax[nk] + (double)nsmax;
213 
214  bi[nk][0] = par3degre[0];
215  bi[nk][1] = par3degre[1];
216 
217  if (debug == 1) {
218  printf("---------> depart ampmax[%d]=%f maximum %f tim %f \n", nk, ampmax[nk], bi[nk][0], bi[nk][1]);
219  }
220 
221  } else {
222  // in other iterations :
223  // increment bi[][] parameters with bdi[][]
224  // calculated in previous
225  // iteration
226 
227  bi[nk][0] += dbi[nk][0];
228  bi[nk][1] += dbi[nk][1];
229 
230  if (debug == 1) {
231  printf("iter %d valeur de max %f et norma %f poly 3 \n", iter, bi[nk][1], bi[nk][0]);
232  }
233  }
234 
235  b1 = bi[nk][0];
236  b2 = bi[nk][1];
237 
239  // Loop on samples //
241 
242  chi2 = 0.;
243  ioktk[nk] = 0;
244  ns = nborn_max - nborn_min + 1;
245 
246  for (k = 0; k < 10; k++) {
247  //
248  // calculation of fonction used to fit
249  //
250 
251  dt = (double)k - b2;
252  t = (double)k;
253  amp = amplu[k];
254  if (debug == 1) {
255  printf(" CHECK sample %f ampli %f \n", t, amp);
256  }
257  //unsurs1 = 1./sig_err ;
258  //unsurs2 = 1./(sig_err*sig_err) ;
259  //unsurs1 = 0.1 ;
260  //unsurs2 = 0.01 ;
261 
262  unsurs1 = 1. / noise_val;
263  //unsurs2=(1./noise_val)*(1./noise_val);
264 
265  //
266  // Pulse shape function used: pulseShapepj
267  //
268 
269  nborn_min = (int)num_fit_min[nevt];
270  nborn_max = (int)num_fit_max[nevt];
271  if (k < nborn_min || k > nborn_max)
272  continue;
273  tsig[0] = (double)k;
274 
275  if (METHODE == 2) {
276  par[0] = b1;
277  par[1] = b2;
278  par[2] = a1;
279  par[3] = a2;
280  fun = pulseShapepj(tsig, par);
281  }
282  if (debug == 1) {
283  printf(" valeur ampli %f et function %f min %d max %d \n", amp, fun, nsmin, nsmax);
284  printf("min %f max %f \n", num_fit_min[nevt], num_fit_max[nevt]);
285  }
286 
287  // we need to determine a1,a2 which are global parameters
288  // and b1, b2 which are parameters for each individual signal:
289  // b1, b2 = amplitude and time event by event
290  // a1, a2 = alpha and beta global
291  // we first begin to calculate the derivatives used in the following calculation
292 
293  if (METHODE == 2) {
294  alpha = a1;
295  beta = a2;
296  albet = alpha * beta;
297  if (dt > -albet) {
298  variab = (double)1. + dt / albet;
299  dtsbeta = dt / beta;
300  db1[k] = unsurs1 * fun / b1;
301  fact2 = fun;
302  db2[k] = unsurs1 * fact2 * dtsbeta / (albet * variab);
303  da1[k] = unsurs1 * fact2 * (log(variab) - dtsbeta / (alpha * variab));
304  da2[k] = unsurs1 * fact2 * dtsbeta * dtsbeta / (albet * variab);
305  }
306  }
307  delta[k] = (amp - fun) * unsurs1;
308  if (debug == 1) {
309  printf(" ------->iter %d valeur de k %d amp %f fun %f delta %f \n", iter, k, amp, fun, delta[k]);
310  printf(" -----> valeur de k %d delta %f da1 %f da2 %f \n", k, delta[k], da1[k], da2[k]);
311  }
312 
313  chi2 = chi2 + delta[k] * delta[k];
314 
315  if (debug == 1) {
316  printf(" CHECK chi2 %f deltachi2 %f sample %d iter %d \n", chi2, delta[k] * delta[k], k, iter);
317  }
318  }
319 
321  // End Loop on samples //
323 
324  double wk1wk2;
325 
327  // Start Loop on samples //
329 
330  for (int k1 = nborn_min; k1 < nborn_max + 1; k1++) {
331  wk1wk2 = 1.;
332  int k2 = k1;
333 
334  DA.coeff[0][0] = da1[k1] * wk1wk2;
335  DA.coeff[1][0] = da2[k1] * wk1wk2;
336  DAT.coeff[0][0] = da1[k2];
337  DAT.coeff[0][1] = da2[k2];
338  DB.coeff[0][0] = db1[k1] * wk1wk2;
339  DB.coeff[1][0] = db2[k1] * wk1wk2;
340  DBT.coeff[0][0] = db1[k2];
341  DBT.coeff[0][1] = db2[k2];
342 
343  // Compute derivative matrix : matrix b[2][2]
344 
345  produit_mat_int(DA, DAT, BK);
346 
347  // Compute matrix c[2][2]
348 
349  produit_mat_int(DA, DBT, C);
350 
351  // Compute matrix d[2][2]
352 
353  produit_mat_int(DB, DBT, D);
354 
355  // Compute matrix y[3] and z[2] depending of delta (amp-fun)
356 
357  delta2 = delta[k2];
358 
359  somme_mat_int_scale(DA, YK, delta2);
360  somme_mat_int_scale(DB, Z, delta2);
361 
362  ioktk[nk]++;
363  }
364 
366  // End Loop on samples //
368 
369  // Remove events with a bad shape
370 
371  if (ioktk[nk] < 4) {
372  printf(" event rejected because npamp_used = %d \n", ioktk[nk]);
373  continue;
374  }
375  chi2s = chi2 / (2. + (double)ns + 2.);
376  chi2tot += chi2s;
377 
378  if (debug == 1) {
379  if (nevt == 198 || nevt == 199) {
380  std::cout << "adc123 pour l'evt " << nevt << " = " << adcval[nevt][nborn_min] << " = "
381  << adcval[nevt][imax[nevt]] << " = " << adcval[nevt][nborn_max] << std::endl;
382  std::cout << "chi2s pour l'evt " << nevt << " = " << chi2s << " " << chi2 << " " << ns << " " << iter
383  << std::endl;
384  std::cout << "chi2tot " << nevt << " = " << chi2tot << " " << iter << std::endl;
385  }
386  }
387 
388  // Transpose matrix C ---> CT
389 
390  transpose_mat(C, CT);
391 
392  // Calculate DM1 (inverse of D matrix 2x2)
393 
394  inverse_mat(D, DM1);
395 
396  // Set matrix product c*d in memory in order to compute variations
397  // of parameters B at the end of the iteration loop
398  // the variations of parameters b are dependant of the variations of
399  // parameters da[1],da[2]
400 
401  cti[nk][0] = CT.coeff[0][0];
402  cti[nk][1] = CT.coeff[0][1];
403  cti[nk][2] = CT.coeff[1][0];
404  cti[nk][3] = CT.coeff[1][1];
405 
406  dm1i[nk][0] = DM1.coeff[0][0];
407  dm1i[nk][1] = DM1.coeff[0][1];
408  dm1i[nk][2] = DM1.coeff[1][0];
409  dm1i[nk][3] = DM1.coeff[1][1];
410 
411  zi[nk][0] = Z.coeff[0][0];
412  zi[nk][1] = Z.coeff[1][0];
413 
414  // Sum the matrix b and y after every event
415 
416  for (k = 0; k < numb_a; k++) {
417  Y.coeff[k][0] += YK.coeff[k][0];
418  }
419  somme_mat_int(BK, B);
420 
421  // Calculate c(d-1)
422 
423  produit_mat(C, DM1, CDM1);
424 
425  // Compute c(d-1)ct
426 
427  produit_mat_int(CDM1, CT, CDM1CT);
428 
429  // Compute c(d-1)z
430 
431  produit_mat_int(CDM1, Z, CDM1Z);
432  }
434  // End Loop on events //
436 
437  // Compute b-cdm1ct
438 
439  diff_mat(B, CDM1CT, X);
440  inverse_mat(X, XINV);
441  diff_mat(Y, CDM1Z, RES2);
442 
443  // Calculation is now easy for da[0] da[1]
444 
445  produit_mat(XINV, RES2, A_CROISS);
446 
447  // A la fin, on peut iterer en mesurant l'accroissement a apporter
448  // des parametres globaux par la formule db[i] = dm1(z-ct*da[i])
449 
450  for (k = 0; k < nk + 1; k++) {
451  if (METHODE == 2) {
452  ZMCT.coeff[0][0] = zi[k][0] - (cti[k][0] * A_CROISS.coeff[0][0] + cti[k][1] * A_CROISS.coeff[1][0]);
453  ZMCT.coeff[1][0] = zi[k][1] - (cti[k][2] * A_CROISS.coeff[0][0] + cti[k][3] * A_CROISS.coeff[1][0]);
454  }
455 
456  dbi[k][0] = dm1i[k][0] * ZMCT.coeff[0][0] + dm1i[k][1] * ZMCT.coeff[1][0];
457  dbi[k][1] = dm1i[k][2] * ZMCT.coeff[0][0] + dm1i[k][3] * ZMCT.coeff[1][0];
458  if (debug == 1) {
459  if (k < 100) {
460  printf(" variations de b1= %f et b2= %f \n", dbi[k][0], dbi[k][1]);
461  }
462  }
463  db_i[k][0] = bi[k][0] + dbi[k][0];
464  db_i[k][1] = bi[k][1] + dbi[k][1];
465  }
466 
467  // dbi[0] et dbi[1] mesurent les variations a apporter aux
468  // parametres du signal
469 
470  a1 += A_CROISS.coeff[0][0];
471  a2 += A_CROISS.coeff[1][0];
472 
473  if (debug == 1) {
474  printf(" CHECK croiss coef0: %f croiss coef1: %f iter %d \n",
475  fabs(A_CROISS.coeff[0][0]),
476  fabs(A_CROISS.coeff[1][0]),
477  iter);
478  }
479  if (fabs(A_CROISS.coeff[0][0]) < 0.001 && fabs(A_CROISS.coeff[1][0]) < 0.001)
480  break;
481  }
482 
484  // End Loop on iterations //
486 
487  parout[0] = a1;
488  parout[1] = a2;
489  parout[2] = a3;
490  if (debug == 1) {
491  printf(" resultats trouves au bout de %d iterations \n", iter);
492  printf(" parametre a1 = %f \n", a1);
493  printf(" parametre a2 = %f \n", a2);
494  }
495 
496  if (debug == 1) {
497  std::cout << " Final chi2 / NDOF : " << chi2tot / nevtmax << std::endl;
498  std::cout << " Final (alpha,beta) : (" << a1 << "," << a2 << ")" << std::endl;
499  }
500 
501  return chi2tot / nevtmax;
502 }
503 
505 // End Fitpj //
507 
508 /**************************************************************************/
509 void TFParams::set_const(int n_samples, int sample_min, int sample_max, double alpha, double beta, int nevtmaximum) {
510  /*------------------------------------------------------------------------*/
511  ns = n_samples;
512  nsmin = sample_min;
513  nsmax = sample_max;
514  nevtmax = nevtmaximum;
515  a1ini = alpha;
516  a2ini = 0.0;
517  a3ini = beta;
518  step_shape = .04;
519  METHODE = 2;
520  if (ns > SDIM2)
521  printf("warning: NbOfsamples exceed maximum\n");
522 }
524  int i, j, k;
525  // resultat du produit A*B = M
526  if (A.nb_colonnes != B.nb_lignes) {
527  printf(" Erreur : produit de matrices de tailles incompatibles \n ");
528  M.coeff = nullptr;
529  return;
530  }
531  M.nb_lignes = A.nb_lignes;
532  M.nb_colonnes = B.nb_colonnes;
533  zero_mat(M);
534  for (i = 0; i < M.nb_lignes; i++) {
535  for (j = 0; j < M.nb_colonnes; j++) {
536  for (k = 0; k < A.nb_colonnes; k++) {
537  M.coeff[i][j] += A.coeff[i][k] * B.coeff[k][j];
538  }
539  }
540  }
541  return;
542 }
543 
545  int i, j, k;
546  if (A.nb_colonnes != B.nb_lignes) {
547  printf(" Erreur : produit de matrices de tailles incompatibles \n ");
548  M.coeff = nullptr;
549  return;
550  }
551  M.nb_lignes = A.nb_lignes;
552  M.nb_colonnes = B.nb_colonnes;
553  for (i = 0; i < M.nb_lignes; i++) {
554  for (j = 0; j < M.nb_colonnes; j++) {
555  for (k = 0; k < A.nb_colonnes; k++) {
556  M.coeff[i][j] += A.coeff[i][k] * B.coeff[k][j];
557  }
558  }
559  }
560  return;
561 }
563  int i, j;
564  //resultat de la difference A-B = M
565  if (A.nb_lignes != B.nb_lignes) {
566  printf(" Erreur : difference de matrices de tailles incompatibles \n ");
567  M.coeff = nullptr;
568  return;
569  }
570  M.nb_lignes = A.nb_lignes;
571  M.nb_colonnes = A.nb_colonnes;
572  for (i = 0; i < M.nb_lignes; i++) {
573  for (j = 0; j < M.nb_colonnes; j++) {
574  M.coeff[i][j] = A.coeff[i][j] - B.coeff[i][j];
575  }
576  }
577  return;
578 }
580  int i, j;
581  int k;
582  /* resultat de la copie de A dans un vecteur colonne M */
583  k = 0;
584  for (i = 0; i < A.nb_lignes; i++) {
585  for (j = 0; j < A.nb_colonnes; j++) {
586  M.coeff[nk][k] = A.coeff[i][j];
587  printf(" copie nk %d i %d j %d k %d A %e M %e \n ", nk, i, j, k, A.coeff[i][j], M.coeff[nk][k]);
588  k++;
589  }
590  }
591  return;
592 }
593 
595  int i, j;
596  /* resultat de la somme integree M += A */
597  if (A.nb_lignes != M.nb_lignes) {
598  printf(" Erreur : somme de matrices de tailles incompatibles \n ");
599  M.coeff = nullptr;
600  return;
601  }
602  M.nb_lignes = A.nb_lignes;
603  M.nb_colonnes = A.nb_colonnes;
604  for (i = 0; i < M.nb_lignes; i++) {
605  for (j = 0; j < M.nb_colonnes; j++)
606  M.coeff[i][j] += A.coeff[i][j];
607  }
608  return;
609 }
611  int i, j;
612  M.nb_lignes = A.nb_lignes;
613  M.nb_colonnes = A.nb_colonnes;
614  for (i = 0; i < M.nb_lignes; i++) {
615  for (j = 0; j < M.nb_colonnes; j++)
616  M.coeff[i][j] += A.coeff[i][j] * delta;
617  }
618  return;
619 }
621  int i, j;
622  // resultat de la transposition = matrice M
623  for (i = 0; i < A.nb_lignes; i++) {
624  for (j = 0; j < A.nb_colonnes; j++) {
625  M.coeff[j][i] = A.coeff[i][j];
626  }
627  }
628  return;
629 }
631  int i, j;
632  matrice M; /* resultat de la creation */
633 
634  M.nb_lignes = A.nb_lignes;
635  M.nb_colonnes = B.nb_colonnes;
636  M.coeff = (double **)malloc(M.nb_lignes * sizeof(double *));
637  for (i = 0; i < M.nb_lignes; i++)
638  M.coeff[i] = (double *)calloc(M.nb_colonnes, sizeof(double));
639  for (i = 0; i < M.nb_lignes; i++) {
640  for (j = 0; j < M.nb_colonnes; j++) {
641  M.coeff[i][j] = 0.;
642  }
643  }
644  //printf(" creation de matrice ----> nlignes %d ncolonnes %d \n",
645  // M.nb_lignes,M.nb_colonnes) ;
646  return (M);
647 }
648 matrice cree_mat(int n_lignes, int n_colonnes) {
649  int i, j;
650  matrice M; /* resultat de la creation */
651 
652  M.nb_lignes = n_lignes;
653  M.nb_colonnes = n_colonnes;
654  M.coeff = (double **)malloc(M.nb_lignes * sizeof(double *));
655  for (i = 0; i < M.nb_lignes; i++)
656  M.coeff[i] = (double *)calloc(M.nb_colonnes, sizeof(double));
657  for (i = 0; i < M.nb_lignes; i++) {
658  for (j = 0; j < M.nb_colonnes; j++) {
659  M.coeff[i][j] = 0.;
660  }
661  }
662  //printf(" creation de matrice ---> nlignes %d ncolonnes %d \n",
663  // M.nb_lignes,M.nb_colonnes) ;
664  return (M);
665 }
666 
668  int i, j;
669  /* on remplit la matrice M avec la matrice A */
670 
671  M.nb_lignes = A.nb_lignes;
672  M.nb_colonnes = A.nb_colonnes;
673  for (i = 0; i < M.nb_lignes; i++) {
674  for (j = 0; j < M.nb_colonnes; j++) {
675  M.coeff[i][j] = A.coeff[i][j];
676  printf("matrice remplie %e \n", M.coeff[i][j]);
677  }
678  }
679  return;
680 }
682  int i, j;
683  if (M.coeff == nullptr) {
684  printf(" erreur : affichage d'une matrice vide \n");
685  return;
686  }
687  printf(" m_nli %d M_ncol %d \n", M.nb_lignes, M.nb_colonnes);
688  for (i = 0; i < M.nb_lignes; i++) {
689  for (j = 0; j < M.nb_colonnes; j++)
690  printf(" MATRICE i= %d j= %d ---> %e \n", i, j, M.coeff[i][j]);
691  }
692  //printf(" apres passage d'impression \n") ;
693  return;
694 }
696  int i, j;
697  for (i = 0; i < M.nb_lignes; i++) {
698  for (j = 0; j < M.nb_colonnes; j++)
699  M.coeff[i][j] = 0.;
700  }
701  return;
702 }
704  int j;
705  for (j = 0; j < M.nb_colonnes; j++)
706  M.coeff[nk][j] = 0.;
707  return;
708 }
710  int j;
711  if (M.coeff == nullptr) {
712  printf(" erreur : affichage d'une matrice vide \n");
713  } else {
714  printf(" nk = %d m_nli %d M_ncol %d \n", nk, M.nb_lignes, M.nb_colonnes);
715  for (j = 0; j < M.nb_colonnes; j++)
716  printf(" MATRICE nk= %d j= %d ---> %e \n", nk, j, M.coeff[nk][j]);
717  printf(" apres passage d'impression \n");
718  }
719  return;
720 }
722  /* A[ligne][colonne] B[ligne][colonne] */
723  int i, j;
724  double deter = 0.;
725  /* M est la matrice inverse de A */
726 
727  if (A.nb_lignes != A.nb_colonnes) {
728  printf(" attention matrice non inversible !!!! %d lignes %d colonnes \n", A.nb_lignes, A.nb_colonnes);
729  return;
730  }
731  zero_mat(M);
732  if (A.nb_lignes == 2) {
733  deter = A.coeff[0][0] * A.coeff[1][1] - A.coeff[0][1] * A.coeff[1][0];
734  M.coeff[0][0] = A.coeff[1][1] / deter;
735  M.coeff[0][1] = -A.coeff[0][1] / deter;
736  M.coeff[1][0] = -A.coeff[1][0] / deter;
737  M.coeff[1][1] = A.coeff[0][0] / deter;
738  } else if (A.nb_lignes == 3) {
739  M.coeff[0][0] = A.coeff[1][1] * A.coeff[2][2] - A.coeff[2][1] * A.coeff[1][2];
740  M.coeff[1][1] = A.coeff[0][0] * A.coeff[2][2] - A.coeff[2][0] * A.coeff[0][2];
741 
742  M.coeff[2][2] = A.coeff[0][0] * A.coeff[1][1] - A.coeff[0][1] * A.coeff[1][0];
743  M.coeff[0][1] = A.coeff[2][1] * A.coeff[0][2] - A.coeff[0][1] * A.coeff[2][2];
744  M.coeff[0][2] = A.coeff[0][1] * A.coeff[1][2] - A.coeff[1][1] * A.coeff[0][2];
745  M.coeff[1][0] = A.coeff[1][2] * A.coeff[2][0] - A.coeff[1][0] * A.coeff[2][2];
746  M.coeff[1][2] = A.coeff[1][0] * A.coeff[0][2] - A.coeff[0][0] * A.coeff[1][2];
747  M.coeff[2][0] = A.coeff[1][0] * A.coeff[2][1] - A.coeff[1][1] * A.coeff[2][0];
748  M.coeff[2][1] = A.coeff[0][1] * A.coeff[2][0] - A.coeff[0][0] * A.coeff[2][1];
749  deter = A.coeff[0][0] * M.coeff[0][0] + A.coeff[1][0] * M.coeff[0][1] + A.coeff[2][0] * M.coeff[0][2];
750  for (i = 0; i < 3; i++) {
751  for (j = 0; j < 3; j++)
752  M.coeff[i][j] = M.coeff[i][j] / deter;
753  }
754  } else {
755  printf(" Attention , on ne peut inverser la MATRICE %d \n", A.nb_lignes);
756  return;
757  }
758 
759  return;
760 }
761 Double_t TFParams::polfit(Int_t ns, Int_t imax, Double_t par3d[dimout], Double_t errpj[dimmat][dimmat], double *adcpj) {
762  double val, val2, val3, adfmx[dimmat], parfp3[dimout];
763  double ius[dimmat] = {0.}, maskp3[dimmat];
764  double deglib, fit3, tm, h, xki2;
765  int i, nus, ilow, isup;
766  val = adcpj[imax];
767  val2 = val / 2.;
768  val3 = val / 3.;
769  ilow = 0;
770  isup = ns;
771  deglib = -4.;
772  for (i = 0; i < ns; i++) {
773  deglib = deglib + 1.;
774  ius[i] = 1.;
775  if ((adcpj[i] < val3) && (i < imax)) {
776  ilow = i;
777  }
778  if (adcpj[i] > val2) {
779  isup = i;
780  }
781  }
782  ilow = ilow + 1;
783  if (ilow == imax)
784  ilow = ilow - 1;
785  if (isup - ilow < 3)
786  isup = ilow + 3;
787  nus = 0;
788  for (i = ilow; i <= isup; i++) {
789  adfmx[nus] = adcpj[i];
790  maskp3[nus] = 0.;
791  if (ius[i] == 1) {
792  maskp3[nus] = 1.;
793  nus = nus + 1;
794  }
795  }
796  if (nus < 4)
797  return 10000.;
798  xki2 = f3deg(nus, parfp3, maskp3, adfmx, errpj);
799  tm = parfp3[4];
800  h = parfp3[5];
801  tm = tm + (double)ilow;
802  par3d[0] = h;
803  par3d[1] = tm;
804  fit3 = xki2;
805  return fit3;
806 }
808  int nmxu, double parom[dimout], double mask[dimmat], double adcpj[dimmat], double errpj[dimmat][dimmat]) {
809  /* */
810  /* fit 3rd degree polynomial */
811  /* nmxu = nb of samples in sample data array adcpj[]
812  parom values of parameters
813  errpj inverse of the error matrix
814  fplo3dg uses only the diagonal terms of errpj[][]
815 */
816  int i, k, l /*,iworst*/;
817  double h, t2, tm, delta, tmp;
818  double xki2, dif, difmx, deglib;
819  double t[dimmat], f[dimmat][4];
820  double cov[dimmat][dimmat], bv[4], invcov[dimmat][dimmat], s /*, deter*/;
821 
822  deglib = (double)nmxu - 4.;
823  for (i = 0; i < nmxu; i++) {
824  t[i] = i;
825  f[i][0] = 1.;
826  f[i][1] = t[i];
827  f[i][2] = t[i] * t[i];
828  f[i][3] = f[i][2] * t[i];
829  }
830  /* computation of covariance matrix */
831  for (k = 0; k < 4; k++) {
832  for (l = 0; l < 4; l++) {
833  s = 0.;
834  for (i = 0; i < nmxu; i++) {
835  s = s + f[i][k] * f[i][l] * errpj[i][i] * mask[i];
836  }
837  cov[k][l] = s;
838  }
839  s = 0.;
840  for (i = 0; i < nmxu; i++) {
841  s = s + f[i][k] * adcpj[i] * errpj[i][i] * mask[i];
842  }
843  bv[k] = s;
844  }
845  /* parameters */
846  /*deter =*/inverpj(4, cov, invcov);
847  for (k = 0; k < 4; k++) {
848  s = 0.;
849  for (l = 0; l < 4; l++) {
850  s = s + bv[l] * invcov[l][k];
851  }
852  parom[k] = s;
853  }
854 
855  if (parom[3] == 0.) {
856  parom[4] = -1000.;
857  parom[5] = -1000.;
858  parom[6] = -1000.;
859  return 1000000.;
860  }
861  /* worst hit and ki2 */
862  xki2 = 0.;
863  difmx = 0.;
864  for (i = 0; i < nmxu; i++) {
865  t2 = t[i] * t[i];
866  h = parom[0] + parom[1] * t[i] + parom[2] * t2 + parom[3] * t2 * t[i];
867  dif = (adcpj[i] - h) * mask[i];
868  if (dif > difmx) {
869  // iworst=i ;
870  difmx = dif;
871  }
872  }
873  if (deglib > 0.5)
874  xki2 = xki2 / deglib;
875  /* amplitude and maximum position */
876  delta = parom[2] * parom[2] - 3. * parom[3] * parom[1];
877  if (delta > 0.) {
878  delta = sqrt(delta);
879  tm = -(delta + parom[2]) / (3. * parom[3]);
880  tmp = (delta - parom[2]) / (3. * parom[3]);
881  } else {
882  parom[4] = -1000.;
883  parom[5] = -1000.;
884  parom[6] = -1000.;
885  return xki2;
886  }
887  parom[4] = tm;
888  parom[5] = parom[0] + parom[1] * tm + parom[2] * tm * tm + parom[3] * tm * tm * tm;
889  parom[6] = tmp;
890  // printf("par --------> %f %f %f %f \n",parom[3],parom[2],parom[1],parom[0]);
891 
892  return xki2;
893 }
894 /*------------------------------------------------------------------*/
895 
896 double TFParams::inverpj(int n, double g[dimmat][dimmat], double ginv[dimmat][dimmat]) {
897  /* */
898  /* inversion d une matrice symetrique definie positive de taille n */
899  /* J.P. Pansart Novembre 99 */
900  /* */
901  int i, j, k, jj;
902  double r, s;
903  double deter = 0;
904  double al[dimmat][dimmat], be[dimmat][dimmat];
905  /* initialisation */
906  for (i = 0; i < n; i++) {
907  for (j = 0; j < n; j++) {
908  al[i][j] = 0.;
909  be[i][j] = 0.;
910  }
911  }
912  /* decomposition en vecteurs sur une base orthonormee */
913  al[0][0] = sqrt(g[0][0]);
914  for (i = 1; i < n; i++) {
915  al[i][0] = g[0][i] / al[0][0];
916  for (j = 1; j <= i; j++) {
917  s = 0.;
918  for (k = 0; k <= j - 1; k++) {
919  s = s + al[i][k] * al[j][k];
920  }
921  r = g[i][j] - s;
922  if (j < i)
923  al[i][j] = r / al[j][j];
924  if (j == i)
925  al[i][j] = sqrt(r);
926  }
927  }
928  /* inversion de la matrice al */
929  be[0][0] = 1. / al[0][0];
930  for (i = 1; i < n; i++) {
931  be[i][i] = 1. / al[i][i];
932  for (j = 0; j < i; j++) {
933  jj = i - j - 1;
934  s = 0.;
935  for (k = jj + 1; k <= i; k++) {
936  s = s + be[i][k] * al[k][jj];
937  }
938  be[i][jj] = -s / al[jj][jj];
939  }
940  }
941  /* calcul de la matrice ginv */
942  for (i = 0; i < n; i++) {
943  for (j = 0; j < n; j++) {
944  s = 0.;
945  for (k = 0; k < n; k++) {
946  s = s + be[k][i] * be[k][j];
947  }
948  ginv[i][j] = s;
949  // if (debug==1){
950  //printf("valeur de la matrice %d %d %f \n",i,j,ginv[i][j]) ;
951  //}
952  }
953  }
954  return deter;
955 }
956 /* */
957 /* inversion d une matrice 3x3 */
958 /* */
959 double TFParams::inv3x3(double a[3][3], double b[3][3]) {
960  /* a[ligne][colonne] b[ligne][colonne] */
961  int i, j;
962  double deter = 0.;
963  b[0][0] = a[1][1] * a[2][2] - a[2][1] * a[1][2];
964  b[1][1] = a[0][0] * a[2][2] - a[2][0] * a[0][2];
965  b[2][2] = a[0][0] * a[1][1] - a[0][1] * a[1][0];
966  printf("a[x][x] %e %e %e %e %e %e %e \n",
967  a[0][0],
968  a[1][1],
969  a[0][1],
970  a[1][0],
971  a[0][0] * a[1][1],
972  a[0][1] * a[1][0],
973  b[2][2]);
974  b[0][1] = a[2][1] * a[0][2] - a[0][1] * a[2][2];
975  b[0][2] = a[0][1] * a[1][2] - a[1][1] * a[0][2];
976  b[1][0] = a[1][2] * a[2][0] - a[1][0] * a[2][2];
977  b[1][2] = a[1][0] * a[0][2] - a[0][0] * a[1][2];
978  b[2][0] = a[1][0] * a[2][1] - a[1][1] * a[2][0];
979  b[2][1] = a[0][1] * a[2][0] - a[0][0] * a[2][1];
980  deter = a[0][0] * b[0][0] + a[1][0] * b[0][1] + a[2][0] * b[0][2];
981  printf(" deter = %e \n", deter);
982  for (i = 0; i < 3; i++) {
983  for (j = 0; j < 3; j++) {
984  printf(" avant division a[3][3] %d %d %e \n", i, j, a[i][j]);
985  printf(" avant division b[3][3] %d %d %e %e \n", i, j, b[i][j], deter);
986  b[i][j] = b[i][j] / deter;
987  printf(" valeur de b[3][3] apres division %d %d %e %e \n", i, j, b[i][j], deter);
988  }
989  }
990  return deter;
991 }
992 
993 double TFParams::pulseShapepj(Double_t *x, Double_t *par) {
994  Double_t fitfun;
995  Double_t ped, h, tm, alpha, beta;
996  Double_t dt, dtsbeta, albet, variab, puiss;
997  Double_t b1, b2, a1, a2;
998  b1 = par[0];
999  b2 = par[1];
1000  a1 = par[2];
1001  a2 = par[3];
1002 
1003  ped = 0.;
1004  h = b1;
1005  tm = b2;
1006  alpha = a1;
1007  beta = a2;
1008  dt = x[0] - tm;
1009  //printf(" par %f %f %f %f dt = %f albet = %f",b1,b2,a1,a2,dt,albet) ;
1010  albet = alpha * beta;
1011  if (albet <= 0)
1012  return ((Double_t)0.);
1013 
1014  if (dt > -albet) {
1015  dtsbeta = dt / beta;
1016  variab = 1. + dt / albet;
1017  puiss = pow(variab, alpha);
1018  fitfun = h * puiss * exp(-dtsbeta) + ped;
1019  //printf(" dt = %f h = %f puiss = %f exp(-dtsbeta) %f \n",dt,h,puiss,
1020  // exp(-dtsbeta)) ;
1021  } else {
1022  fitfun = ped;
1023  }
1024 
1025  return fitfun;
1026 }
1027 
1028 double TFParams::lastShape(Double_t *x, Double_t *par) {
1029  Double_t fitfun;
1030  Double_t alpha, beta;
1031  Double_t dt, alphadt, exponent;
1032  Double_t b1, b2;
1033  b1 = par[0];
1034  b2 = par[1];
1035  alpha = par[2];
1036  beta = par[3];
1037  dt = x[0] - b2;
1038  alphadt = alpha * dt;
1039  exponent = -(alphadt + (exp(-alphadt) - 1.)) / beta;
1040  fitfun = b1 * exp(exponent);
1041  return fitfun;
1042 }
1043 double TFParams::lastShape2(Double_t *x, Double_t *par) {
1044  Double_t fitfun;
1045  Double_t alpha, beta;
1046  Double_t dt, expo1, dt2, exponent;
1047  Double_t b1, b2;
1048  b1 = par[0];
1049  b2 = par[1];
1050  alpha = par[2];
1051  beta = par[3];
1052  dt = x[0] - b2;
1053  expo1 = exp(-beta * dt);
1054  dt2 = dt * dt;
1055  exponent = -(alpha * dt2 + (expo1 - 1.));
1056  fitfun = b1 * exp(exponent);
1057  return fitfun;
1058 }
1059 
1060 Double_t TFParams::pulseShapepj2(Double_t *x, Double_t *par) {
1061  Double_t fitfun;
1062  Double_t ped, h, /*tm,*/ alpha, beta;
1063  Double_t dt, dtsbeta, albet, variab, puiss;
1064  Double_t b1, /*b2,*/ a1, a2;
1065  b1 = par[0];
1066  //b2 = par[1] ;
1067  a1 = par[2];
1068  a2 = par[3];
1069  ped = 0.;
1070  h = b1;
1071  //tm = b2 ;
1072  alpha = a1;
1073  beta = a2;
1074  dt = x[0];
1075  albet = alpha * beta;
1076  if (albet <= 0)
1077  return ((Double_t)0.);
1078 
1079  if (dt > -albet) {
1080  dtsbeta = dt / beta;
1081  variab = 1. + dt / albet;
1082  puiss = pow(variab, alpha);
1083  fitfun = h * puiss * exp(-dtsbeta) + ped;
1084  } else {
1085  fitfun = ped;
1086  }
1087 
1088  /* printf( "fitfun %f %f %f %f, %f %f %f\n", ped, h, tm, alpha, beta, *x, fitfun ); */
1089 
1090  return fitfun;
1091 }
1092 
1093 double TFParams::parab(Double_t ampl[nsamp], Int_t nmin, Int_t nmax, Double_t parout[3]) {
1094  /* Now we calculate the parabolic adjustement in order to get */
1095  /* maximum and time max */
1096 
1097  double denom, dt, amp1, amp2, amp3;
1098  double ampmax = 0.;
1099  int imax = 0;
1100  int k;
1101  /*
1102  */
1103  for (k = nmin; k < nmax; k++) {
1104  if (ampl[k] > ampmax) {
1105  ampmax = ampl[k];
1106  imax = k;
1107  }
1108  }
1109  amp1 = ampl[imax - 1];
1110  amp2 = ampl[imax];
1111  amp3 = ampl[imax + 1];
1112  denom = 2. * amp2 - amp1 - amp3;
1113  /* */
1114  if (denom > 0.) {
1115  dt = 0.5 * (amp3 - amp1) / denom;
1116  } else {
1117  //printf("denom =%f\n",denom) ;
1118  dt = 0.5;
1119  }
1120  /* */
1121  /* ampmax correspond au maximum d'amplitude parabolique et dt */
1122  /* decalage en temps par rapport au sample maximum soit k + dt */
1123 
1124  parout[0] = amp2 + (amp3 - amp1) * dt * 0.25;
1125  parout[1] = (double)imax + dt;
1126  parout[2] = (double)imax;
1127  return denom;
1128 }
1129 
1130 double TFParams::mixShape(Double_t *x, Double_t *par) {
1131  Double_t fitval0, fitval;
1132  Double_t alpha, beta, fact, puiss;
1133  Double_t dt, alpha2dt, exponent;
1134  Double_t b1, b2, alpha2, t;
1135  b1 = par[0];
1136  b2 = par[1];
1137  alpha = par[2];
1138  alpha2 = par[3];
1139  beta = par[4];
1140  //
1141  t = x[0];
1142  dt = x[0] - b2;
1143  //
1144  if (t > 0.) {
1145  fact = t / b2;
1146  puiss = pow(fact, alpha);
1147  fitval0 = puiss * exp(-alpha * dt / b2);
1148  } else {
1149  fitval0 = 1.;
1150  }
1151  dt = x[0] - b2;
1152  alpha2dt = dt * alpha2;
1153  exponent = -(alpha2dt + (exp(-alpha2dt) - 1.)) / beta;
1154  fitval = b1 * fitval0 * exp(exponent);
1155  return fitval;
1156 }
1157 //=========================
1158 // Method computePulseWidth
1159 //=========================
1160 double TFParams::computePulseWidth(int methode, double alpha_here, double beta_here) {
1161  // level of amplitude where we calculate the width ( level = 0.5 if at 50 % )
1162  // (level = 0.3 if at 30 % )
1163  double level = 0.30;
1164  // fixed parameters
1165  double amplitude = 1.00;
1166  double offset = 7.00;
1167  double amp_max = amplitude;
1168 
1169  // steps in time
1170  double t_min = offset - 4.50;
1171  double t_max = offset + 12.50;
1172 
1173  int t_step_max = 3000;
1174  double delta_t = (double)((t_max - t_min) / t_step_max);
1175 
1176  // Loop over time ( Loop 2 --> get width )
1177  int t_amp_half_flag = 0;
1178  double t_amp_half_min = 999.;
1179  double t_amp_half_max = -999.;
1180 
1181  for (int t_step = 0; t_step < t_step_max; t_step++) {
1182  double t_val = t_min + (double)t_step * delta_t;
1183  double albet = alpha_here * beta_here;
1184  double dt = t_val - offset;
1185  double amp = 0;
1186 
1187  if (methode == 2) { // electronic function
1188  if ((t_val - offset) > -albet) {
1189  amp = amplitude * TMath::Power((1 + (dt / (alpha_here * beta_here))), alpha_here) *
1190  TMath::Exp(-1.0 * (dt / beta_here));
1191  } else {
1192  amp = 1.;
1193  }
1194  }
1195 
1196  if (amp > (amp_max * level) && t_amp_half_flag == 0) {
1197  t_amp_half_flag = 1;
1198  t_amp_half_min = t_val;
1199  }
1200 
1201  if (amp < (amp_max * level) && t_amp_half_flag == 1) {
1202  t_amp_half_flag = 2;
1203  t_amp_half_max = t_val;
1204  }
1205  }
1206 
1207  // Compute Width
1208  double width = (t_amp_half_max - t_amp_half_min);
1209 
1210  return width;
1211 }
double pulseShapepj(Double_t *, Double_t *)
Definition: TFParams.cc:993
float dt
Definition: AMPTWrapper.h:136
float alpha
Definition: AMPTWrapper.h:105
static std::vector< std::string > checklist log
Definition: APVGainStruct.h:7
Double_t polfit(Int_t ns, Int_t imax, Double_t par3d[dimout], Double_t errpj[dimmat][dimmat], double *)
Definition: TFParams.cc:761
void print_mat_nk(matrice, int)
Definition: TFParams.cc:709
double computePulseWidth(int, double, double)
Definition: TFParams.cc:1160
#define X(str)
Definition: MuonsGrabber.cc:38
void somme_mat_int_scale(matrice, matrice, double)
Definition: TFParams.cc:610
void zero_mat(matrice)
Definition: TFParams.cc:695
void produit_mat(matrice, matrice, matrice)
Definition: TFParams.cc:523
Exp< T >::type exp(const T &t)
Definition: Exp.h:22
double inverpj(int, double g[dimmat][dimmat], double ginv[dimmat][dimmat])
Definition: TFParams.cc:896
#define nsamp
double ** coeff
Definition: TFParams.h:30
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e g
Definition: Activities.doc:4
void somme_mat_int(matrice, matrice)
Definition: TFParams.cc:594
void print_mat(matrice)
Definition: TFParams.cc:681
void transpose_mat(matrice, matrice)
Definition: TFParams.cc:620
void set_const(int, int, int, double, double, int)
Definition: TFParams.cc:509
double parab(double *, Int_t, Int_t, double *)
Definition: TFParams.cc:1093
T sqrt(T t)
Definition: SSEVec.h:19
printf("params %d %f %f %f\n", minT, eps, errmax, chi2max)
matrice cree_mat_prod(matrice, matrice)
Definition: TFParams.cc:630
int nb_lignes
Definition: TFParams.h:28
Quality *__restrict__ uint16_t nmin
void copie_colonne_mat(matrice, matrice, int)
Definition: TFParams.cc:579
matrice cree_mat(int, int)
Definition: TFParams.cc:648
double pulseShapepj2(Double_t *, Double_t *)
Definition: TFParams.cc:1060
void inverse_mat(matrice, matrice)
Definition: TFParams.cc:721
double f3deg(int, double parom[dimout], double mask[dimmat], double adcpj[dimmat], double errpj[dimmat][dimmat])
Definition: TFParams.cc:807
#define debug
Definition: HDRShower.cc:19
const double fact
DecomposeProduct< arg, typename Div::arg > D
Definition: Factorize.h:141
void zero_mat_nk(matrice, int)
Definition: TFParams.cc:703
void fill_mat(matrice, matrice)
Definition: TFParams.cc:667
double b
Definition: hdecay.h:118
int nb_colonnes
Definition: TFParams.h:29
double lastShape(Double_t *, Double_t *)
Definition: TFParams.cc:1028
double a
Definition: hdecay.h:119
void produit_mat_int(matrice, matrice, matrice)
Definition: TFParams.cc:544
TFParams(int size=SDIM2, int size_sh=PLSHDIM)
Definition: TFParams.cc:23
tuple cout
Definition: gather_cfg.py:144
Definition: APVGainStruct.h:7
tuple level
Definition: testEve_cfg.py:47
double mixShape(Double_t *, Double_t *)
Definition: TFParams.cc:1130
void diff_mat(matrice, matrice, matrice)
Definition: TFParams.cc:562
#define ntrack
static constexpr float b2
double lastShape2(Double_t *, Double_t *)
Definition: TFParams.cc:1043
The Signals That Services Can Subscribe To This is based on ActivityRegistry h
Helper function to determine trigger accepts.
Definition: Activities.doc:4
tmp
align.sh
Definition: createJobs.py:716
double inv3x3(double a[3][3], double b[3][3])
Definition: TFParams.cc:959
double fitpj(double **, double *, double **, double noise_val, int debug)
Definition: TFParams.cc:34
tuple size
Write out results.
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:29
static constexpr float b1