Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TSpectrum2Fit.cxx
Go to the documentation of this file.
1// @(#)root/spectrum:$Id$
2// Author: Miroslav Morhac 25/09/2006
3
4/** \class TSpectrum2Fit
5 \ingroup Spectrum
6 \brief Advanced 2-dimensional spectra fitting functions
7 \author Miroslav Morhac
8
9 \legacy{TSpectrum2Fit, For modeling a spectrum fitting and estimating the background one can use RooFit while for deconvolution and unfolding one can use TUnfold.}
10
11Class for fitting 2D spectra using AWMI (algorithm without matrix
12inversion) and conjugate gradient algorithms for symmetrical
13matrices (Stiefel-Hestens method). AWMI method allows to fit
14simultaneously 100s up to 1000s peaks. Stiefel method is very stable,
15it converges faster, but is more time consuming.
16
17
18 The algorithms in this class have been published in the following references:
19
20 1. M. Morhac et al.: Efficient fitting algorithms applied to
21 analysis of coincidence gamma-ray spectra. Computer Physics
22 Communications, Vol 172/1 (2005) pp. 19-41.
23
24 2. M. Morhac et al.: Study of fitting algorithms applied to
25 simultaneous analysis of large number of peaks in gamma-ray spectra.
26 Applied Spectroscopy, Vol. 57, No. 7, pp. 753-760, 2003.
27*/
28
29#include "TSpectrum2Fit.h"
30#include "TMath.h"
31
32
33////////////////////////////////////////////////////////////////////////////////
34/// Default constructor
35
36TSpectrum2Fit::TSpectrum2Fit() :TNamed("Spectrum2Fit", "Miroslav Morhac peak fitter")
37{
38 fNPeaks = 0;
40 fXmin = 0;
41 fXmax = 100;
42 fYmin = 0;
43 fYmax = 100;
48 fAlpha = 1;
49 fChi = 0;
50 fPositionInitX = nullptr;
51 fPositionCalcX = nullptr;
52 fPositionErrX = nullptr;
53 fPositionInitY = nullptr;
54 fPositionCalcY = nullptr;
55 fPositionErrY = nullptr;
56 fPositionInitX1 = nullptr;
57 fPositionCalcX1 = nullptr;
58 fPositionErrX1 = nullptr;
59 fPositionInitY1 = nullptr;
60 fPositionCalcY1 = nullptr;
61 fPositionErrY1 = nullptr;
62 fAmpInit = nullptr;
63 fAmpCalc = nullptr;
64 fAmpErr = nullptr;
65 fAmpInitX1 = nullptr;
66 fAmpCalcX1 = nullptr;
67 fAmpErrX1 = nullptr;
68 fAmpInitY1 = nullptr;
69 fAmpCalcY1 = nullptr;
70 fAmpErrY1 = nullptr;
71 fVolume = nullptr;
72 fVolumeErr = nullptr;
73 fSigmaInitX = 2;
74 fSigmaCalcX = 0;
75 fSigmaErrX = 0;
76 fSigmaInitY = 2;
77 fSigmaCalcY = 0;
78 fSigmaErrY = 0;
79 fRoInit = 0;
80 fRoCalc = 0;
81 fRoErr = 0;
82 fTxyInit = 0;
83 fTxyCalc = 0;
84 fTxyErr = 0;
85 fTxInit = 0;
86 fTxCalc = 0;
87 fTxErr = 0;
88 fTyInit = 0;
89 fTyCalc = 0;
90 fTyErr = 0;
91 fBxInit = 1;
92 fBxCalc = 0;
93 fBxErr = 0;
94 fByInit = 1;
95 fByCalc = 0;
96 fByErr = 0;
97 fSxyInit = 0;
98 fSxyCalc = 0;
99 fSxyErr = 0;
100 fSxInit = 0;
101 fSxCalc = 0;
102 fSxErr = 0;
103 fSyInit = 0;
104 fSyCalc = 0;
105 fSyErr = 0;
106 fA0Init = 0;
107 fA0Calc = 0;
108 fA0Err = 0;
109 fAxInit = 0;
110 fAxCalc = 0;
111 fAxErr = 0;
112 fAyInit = 0;
113 fAyCalc = 0;
114 fAyErr = 0;
115 fFixPositionX = nullptr;
116 fFixPositionY = nullptr;
117 fFixPositionX1 = nullptr;
118 fFixPositionY1 = nullptr;
119 fFixAmp = nullptr;
120 fFixAmpX1 = nullptr;
121 fFixAmpY1 = nullptr;
122 fFixSigmaX = false;
123 fFixSigmaY = false;
124 fFixRo = true;
125 fFixTxy = true;
126 fFixTx = true;
127 fFixTy = true;
128 fFixBx = true;
129 fFixBy = true;
130 fFixSxy = true;
131 fFixSx = true;
132 fFixSy = true;
133 fFixA0 = true;
134 fFixAx = true;
135 fFixAy = true;
136
137}
138
139////////////////////////////////////////////////////////////////////////////////
140/// numberPeaks: number of fitted peaks (must be greater than zero)
141/// the constructor allocates arrays for all fitted parameters (peak positions,
142/// amplitudes etc) and sets the member variables to their default values. One
143/// can change these variables by member functions (setters) of TSpectrumFit class.
144///
145/// Shape function of the fitted
146/// peaks contains the two-dimensional symmetrical Gaussian two one-dimensional
147/// symmetrical Gaussian ridges as well as non-symmetrical terms and background.
148///
149/// \image html spectrum2fit_constructor_image001.gif
150
151TSpectrum2Fit::TSpectrum2Fit(Int_t numberPeaks) :TNamed("Spectrum2Fit", "Miroslav Morhac peak fitter")
152{
153 if (numberPeaks <= 0){
154 Error ("TSpectrum2Fit","Invalid number of peaks, must be > than 0");
155 return;
156 }
159 fXmin = 0;
160 fXmax = 100;
161 fYmin = 0;
162 fYmax = 100;
167 fAlpha = 1;
168 fChi = 0;
192 fSigmaInitX = 2;
193 fSigmaCalcX = 0;
194 fSigmaErrX = 0;
195 fSigmaInitY = 2;
196 fSigmaCalcY = 0;
197 fSigmaErrY = 0;
198 fRoInit = 0;
199 fRoCalc = 0;
200 fRoErr = 0;
201 fTxyInit = 0;
202 fTxyCalc = 0;
203 fTxyErr = 0;
204 fTxInit = 0;
205 fTxCalc = 0;
206 fTxErr = 0;
207 fTyInit = 0;
208 fTyCalc = 0;
209 fTyErr = 0;
210 fBxInit = 1;
211 fBxCalc = 0;
212 fBxErr = 0;
213 fByInit = 1;
214 fByCalc = 0;
215 fByErr = 0;
216 fSxyInit = 0;
217 fSxyCalc = 0;
218 fSxyErr = 0;
219 fSxInit = 0;
220 fSxCalc = 0;
221 fSxErr = 0;
222 fSyInit = 0;
223 fSyCalc = 0;
224 fSyErr = 0;
225 fA0Init = 0;
226 fA0Calc = 0;
227 fA0Err = 0;
228 fAxInit = 0;
229 fAxCalc = 0;
230 fAxErr = 0;
231 fAyInit = 0;
232 fAyCalc = 0;
233 fAyErr = 0;
241 fFixSigmaX = false;
242 fFixSigmaY = false;
243 fFixRo = true;
244 fFixTxy = true;
245 fFixTx = true;
246 fFixTy = true;
247 fFixBx = true;
248 fFixBy = true;
249 fFixSxy = true;
250 fFixSx = true;
251 fFixSy = true;
252 fFixA0 = true;
253 fFixAx = true;
254 fFixAy = true;
255}
256
257////////////////////////////////////////////////////////////////////////////////
258/// Destructor
259
261{
262 delete [] fPositionInitX;
263 delete [] fPositionCalcX;
264 delete [] fPositionErrX;
265 delete [] fFixPositionX;
266 delete [] fPositionInitY;
267 delete [] fPositionCalcY;
268 delete [] fPositionErrY;
269 delete [] fFixPositionY;
270 delete [] fPositionInitX1;
271 delete [] fPositionCalcX1;
272 delete [] fPositionErrX1;
273 delete [] fFixPositionX1;
274 delete [] fPositionInitY1;
275 delete [] fPositionCalcY1;
276 delete [] fPositionErrY1;
277 delete [] fFixPositionY1;
278 delete [] fAmpInit;
279 delete [] fAmpCalc;
280 delete [] fAmpErr;
281 delete [] fFixAmp;
282 delete [] fAmpInitX1;
283 delete [] fAmpCalcX1;
284 delete [] fAmpErrX1;
285 delete [] fFixAmpX1;
286 delete [] fAmpInitY1;
287 delete [] fAmpCalcY1;
288 delete [] fAmpErrY1;
289 delete [] fFixAmpY1;
290 delete [] fVolume;
291 delete [] fVolumeErr;
292}
293
294
295////////////////////////////////////////////////////////////////////////////////
296/// This function calculates error function of x.
297
298
300{
301 Double_t da1 = 0.1740121, da2 = -0.0479399, da3 = 0.3739278, dap =
302 0.47047;
303 Double_t a, t, c, w;
304 a = TMath::Abs(x);
305 w = 1. + dap * a;
306 t = 1. / w;
307 w = a * a;
308 if (w < 700)
309 c = exp(-w);
310
311 else {
312 c = 0;
313 }
314 c = c * t * (da1 + t * (da2 + t * da3));
315 if (x < 0)
316 c = 1. - c;
317 return (c);
318}
319
320////////////////////////////////////////////////////////////////////////////////
321/// This function calculates derivative of error function of x.
322
324{
325 Double_t a, t, c, w;
326 Double_t da1 = 0.1740121, da2 = -0.0479399, da3 = 0.3739278, dap =
327 0.47047;
328 a = TMath::Abs(x);
329 w = 1. + dap * a;
330 t = 1. / w;
331 w = a * a;
332 if (w < 700)
333 c = exp(-w);
334
335 else {
336 c = 0;
337 }
338 c = (-1.) * dap * c * t * t * (da1 + t * (2. * da2 + t * 3. * da3)) -
339 2. * a * Erfc(a);
340 return (c);
341}
342
343////////////////////////////////////////////////////////////////////////////////
344/// power function
345
347{
348 Double_t c;
349 Double_t a2 = a*a;
350 c = 1;
351 if (pw > 0) c *= a2;
352 if (pw > 2) c *= a2;
353 if (pw > 4) c *= a2;
354 if (pw > 6) c *= a2;
355 if (pw > 8) c *= a2;
356 if (pw > 10) c *= a2;
357 if (pw > 12) c *= a2;
358 return (c);
359}
360
361////////////////////////////////////////////////////////////////////////////////
362/// This function calculates solution of the system of linear equations.
363/// The matrix a should have a dimension size*(size+4)
364/// The calling function should fill in the matrix, the column size should
365/// contain vector y (right side of the system of equations). The result is
366/// placed into size+1 column of the matrix.
367/// according to sigma of peaks.
368///
369/// Function parameters:
370/// - a-matrix with dimension size*(size+4)
371/// - size-number of rows of the matrix
372
374{
375 Int_t i, j, k = 0;
376 Double_t sk = 0, b, lambdak, normk, normk_old = 0;
377
378 do {
379 normk = 0;
380
381 //calculation of rk and norm
382 for (i = 0; i < size; i++) {
383 a[i][size + 2] = -a[i][size]; //rk=-C
384 for (j = 0; j < size; j++) {
385 a[i][size + 2] += a[i][j] * a[j][size + 1]; //A*xk-C
386 }
387 normk += a[i][size + 2] * a[i][size + 2]; //calculation normk
388 }
389
390 //calculation of sk
391 if (k != 0) {
392 sk = normk / normk_old;
393 }
394
395 //calculation of uk
396 for (i = 0; i < size; i++) {
397 a[i][size + 3] = -a[i][size + 2] + sk * a[i][size + 3]; //uk=-rk+sk*uk-1
398 }
399
400 //calculation of lambdak
401 lambdak = 0;
402 for (i = 0; i < size; i++) {
403 for (j = 0, b = 0; j < size; j++) {
404 b += a[i][j] * a[j][size + 3]; //A*uk
405 }
406 lambdak += b * a[i][size + 3];
407 }
408 if (TMath::Abs(lambdak) > 1e-50) //computer zero
410
411 else
412 lambdak = 0;
413 for (i = 0; i < size; i++)
414 a[i][size + 1] += lambdak * a[i][size + 3]; //xk+1=xk+lambdak*uk
416 k += 1;
417 } while (k < size && TMath::Abs(normk) > 1e-50); //computer zero
418 return;
419}
420
421////////////////////////////////////////////////////////////////////////////////
422/// This function calculates 2D peaks shape function (see manual)
423///
424/// Function parameters:
425/// - numOfFittedPeaks-number of fitted peaks
426/// - x-channel in x-dimension
427/// - y-channel in y-dimension
428/// - parameter-array of peaks parameters (amplitudes and positions)
429/// - sigmax-sigmax of peaks
430/// - sigmay-sigmay of peaks
431/// - ro-correlation coefficient
432/// - a0,ax,ay-bac kground coefficients
433/// - txy,tx,ty, sxy,sy,sx-relative amplitudes
434/// - bx, by-slopes
435
441 Double_t by)
442{
443 Int_t j;
444 Double_t r, p, r1, e, ex, ey, vx, s2, px, py, rx, ry, erx, ery;
445 vx = 0;
446 s2 = TMath::Sqrt(2.0);
447 for (j = 0; j < numOfFittedPeaks; j++) {
448 p = (x - parameter[7 * j + 1]) / sigmax;
449 r = (y - parameter[7 * j + 2]) / sigmay;
450 if (TMath::Abs(p) < 3 && TMath::Abs(r) < 3) {
451 e = (p * p - 2 * ro * p * r + r * r) / (2 * (1 - ro * ro));
452 if (e < 700)
453 r1 = exp(-e);
454
455 else {
456 r1 = 0;
457 }
458 if (txy != 0) {
459 px = 0, py = 0;
460 erx = Erfc(p / s2 + 1 / (2 * bx)), ery =
461 Erfc(r / s2 + 1 / (2 * by));
462 ex = p / (s2 * bx), ey = r / (s2 * by);
463 if (TMath::Abs(ex) < 9 && TMath::Abs(ey) < 9) {
464 px = exp(ex) * erx, py = exp(ey) * ery;
465 }
466 r1 += 0.5 * txy * px * py;
467 }
468 if (sxy != 0) {
469 rx = Erfc(p / s2), ry = Erfc(r / s2);
470 r1 += 0.5 * sxy * rx * ry;
471 }
472 vx = vx + parameter[7 * j] * r1;
473 }
474 p = (x - parameter[7 * j + 5]) / sigmax;
475 if (TMath::Abs(p) < 3) {
476 e = p * p / 2;
477 if (e < 700)
478 r1 = exp(-e);
479
480 else {
481 r1 = 0;
482 }
483 if (tx != 0) {
484 px = 0;
485 erx = Erfc(p / s2 + 1 / (2 * bx));
486 ex = p / (s2 * bx);
487 if (TMath::Abs(ex) < 9) {
488 px = exp(ex) * erx;
489 }
490 r1 += 0.5 * tx * px;
491 }
492 if (sx != 0) {
493 rx = Erfc(p / s2);
494 r1 += 0.5 * sx * rx;
495 }
496 vx = vx + parameter[7 * j + 3] * r1;
497 }
498 r = (y - parameter[7 * j + 6]) / sigmay;
499 if (TMath::Abs(r) < 3) {
500 e = r * r / 2;
501 if (e < 700)
502 r1 = exp(-e);
503
504 else {
505 r1 = 0;
506 }
507 if (ty != 0) {
508 py = 0;
509 ery = Erfc(r / s2 + 1 / (2 * by));
510 ey = r / (s2 * by);
511 if (TMath::Abs(ey) < 9) {
512 py = exp(ey) * ery;
513 }
514 r1 += 0.5 * ty * py;
515 }
516 if (sy != 0) {
517 ry = Erfc(r / s2);
518 r1 += 0.5 * sy * ry;
519 }
520 vx = vx + parameter[7 * j + 4] * r1;
521 }
522 }
523 vx = vx + a0 + ax * x + ay * y;
524 return (vx);
525}
526
527////////////////////////////////////////////////////////////////////////////////
528/// This function calculates derivative of 2D peaks shape function (see manual)
529/// according to amplitude of 2D peak
530///
531/// Function parameters:
532/// - x-channel in x-dimension
533/// - y-channel in y-dimension
534/// - x0-position of peak in x-dimension
535/// - y0-position of peak in y-dimension
536/// - sigmax-sigmax of peaks
537/// - sigmay-sigmay of peaks
538/// - ro-correlation coefficient
539/// - txy, sxy-relative amplitudes
540/// - bx, by-slopes
541
545{
546 Double_t p, r, r1 = 0, e, ex, ey, px, py, rx, ry, erx, ery, s2;
547 p = (x - x0) / sigmax;
548 r = (y - y0) / sigmay;
549 if (TMath::Abs(p) < 3 && TMath::Abs(r) < 3) {
550 s2 = TMath::Sqrt(2.0);
551 e = (p * p - 2 * ro * p * r + r * r) / (2 * (1 - ro * ro));
552 if (e < 700)
553 r1 = exp(-e);
554
555 else {
556 r1 = 0;
557 }
558 if (txy != 0) {
559 px = 0, py = 0;
560 erx = Erfc(p / s2 + 1 / (2 * bx)), ery =
561 Erfc(r / s2 + 1 / (2 * by));
562 ex = p / (s2 * bx), ey = r / (s2 * by);
563 if (TMath::Abs(ex) < 9 && TMath::Abs(ey) < 9) {
564 px = exp(ex) * erx, py = exp(ey) * ery;
565 }
566 r1 += 0.5 * txy * px * py;
567 }
568 if (sxy != 0) {
569 rx = Erfc(p / s2), ry = Erfc(r / s2);
570 r1 += 0.5 * sxy * rx * ry;
571 }
572 }
573 return (r1);
574}
575
576////////////////////////////////////////////////////////////////////////////////
577/// This function calculates derivative of 2D peaks shape function (see manual)
578/// according to amplitude of the ridge
579///
580/// Function parameters:
581/// - x-channel in x-dimension
582/// - x0-position of peak in x-dimension
583/// - y0-position of peak in y-dimension
584/// - sigmax-sigmax of peaks
585/// - ro-correlation coefficient
586/// - tx, sx-relative amplitudes
587/// - bx-slope
588
591{
592 Double_t p, r1 = 0, px, erx, rx, ex, s2;
593 p = (x - x0) / sigmax;
594 if (TMath::Abs(p) < 3) {
595 s2 = TMath::Sqrt(2.0);
596 p = p * p / 2;
597 if (p < 700)
598 r1 = exp(-p);
599
600 else {
601 r1 = 0;
602 }
603 if (tx != 0) {
604 px = 0;
605 erx = Erfc(p / s2 + 1 / (2 * bx));
606 ex = p / (s2 * bx);
607 if (TMath::Abs(ex) < 9) {
608 px = exp(ex) * erx;
609 }
610 r1 += 0.5 * tx * px;
611 }
612 if (sx != 0) {
613 rx = Erfc(p / s2);
614 r1 += 0.5 * sx * rx;
615 }
616 }
617 return (r1);
618}
619
620////////////////////////////////////////////////////////////////////////////////
621/// This function calculates derivative of 2D peaks shape function (see manual)
622/// according to x position of 2D peak
623///
624/// Function parameters:
625/// - x-channel in x-dimension
626/// - y-channel in y-dimension
627/// - a-amplitude
628/// - x0-position of peak in x-dimension
629/// - y0-position of peak in y-dimension
630/// - sigmax-sigmax of peaks
631/// - sigmay-sigmay of peaks
632/// - ro-correlation coefficient
633/// - txy, sxy-relative amplitudes
634/// - bx, by-slopes
635
639 Double_t by)
640{
641 Double_t p, r, r1 = 0, e, ex, ey, px, py, rx, ry, erx, ery, s2;
642 p = (x - x0) / sigmax;
643 r = (y - y0) / sigmay;
644 if (TMath::Abs(p) < 3 && TMath::Abs(r) < 3) {
645 s2 = TMath::Sqrt(2.0);
646 e = (p * p - 2 * ro * p * r + r * r) / (2 * (1 - ro * ro));
647 if (e < 700)
648 r1 = exp(-e);
649
650 else {
651 r1 = 0;
652 }
653 e = -(ro * r - p) / sigmax;
654 e = e / (1 - ro * ro);
655 r1 = r1 * e;
656 if (txy != 0) {
657 px = 0, py = 0;
658 erx =
659 (-Erfc(p / s2 + 1 / (2 * bx)) / (s2 * bx * sigmax) -
660 Derfc(p / s2 + 1 / (2 * bx)) / (s2 * sigmax)), ery =
661 Erfc(r / s2 + 1 / (2 * by));
662 ex = p / (s2 * bx), ey = r / (s2 * by);
663 if (TMath::Abs(ex) < 9 && TMath::Abs(ey) < 9) {
664 px = exp(ex) * erx, py = exp(ey) * ery;
665 }
666 r1 += 0.5 * txy * px * py;
667 }
668 if (sxy != 0) {
669 rx = -Derfc(p / s2) / (s2 * sigmax), ry = Erfc(r / s2);
670 r1 += 0.5 * sxy * rx * ry;
671 }
672 r1 = a * r1;
673 }
674 return (r1);
675}
676
677////////////////////////////////////////////////////////////////////////////////
678/// This function calculates second derivative of 2D peaks shape function
679/// (see manual) according to x position of 2D peak
680///
681/// Function parameters:
682/// - x-channel in x-dimension
683/// - y-channel in y-dimension
684/// - a-amplitude
685/// - x0-position of peak in x-dimension
686/// - y0-position of peak in y-dimension
687/// - sigmax-sigmax of peaks
688/// - sigmay-sigmay of peaks
689/// - ro-correlation coefficient
690
693 Double_t ro)
694{
695 Double_t p, r, r1 = 0, e;
696 p = (x - x0) / sigmax;
697 r = (y - y0) / sigmay;
698 if (TMath::Abs(p) < 3 && TMath::Abs(r) < 3) {
699 e = (p * p - 2 * ro * p * r + r * r) / (2 * (1 - ro * ro));
700 if (e < 700)
701 r1 = exp(-e);
702
703 else {
704 r1 = 0;
705 }
706 e = -(ro * r - p) / sigmax;
707 e = e / (1 - ro * ro);
708 r1 = r1 * (e * e - 1 / ((1 - ro * ro) * sigmax * sigmax));
709 r1 = a * r1;
710 }
711 return (r1);
712}
713
714////////////////////////////////////////////////////////////////////////////////
715/// This function calculates derivative of 2D peaks shape function (see manual)
716/// according to y position of 2D peak
717/// Function parameters:
718/// - x-channel in x-dimension
719/// - y-channel in y-dimension
720/// - a-amplitude
721/// - x0-position of peak in x-dimension
722/// - y0-position of peak in y-dimension
723/// - sigmax-sigmax of peaks
724/// - sigmay-sigmay of peaks
725/// - ro-correlation coefficient
726/// - txy, sxy-relative amplitudes
727/// - bx, by-slopes
728
732 Double_t by)
733{
734
735
736 Double_t p, r, r1 = 0, e, ex, ey, px, py, rx, ry, erx, ery, s2;
737 p = (x - x0) / sigmax;
738 r = (y - y0) / sigmay;
739 if (TMath::Abs(p) < 3 && TMath::Abs(r) < 3) {
740 s2 = TMath::Sqrt(2.0);
741 e = (p * p - 2 * ro * p * r + r * r) / (2 * (1 - ro * ro));
742 if (e < 700)
743 r1 = exp(-e);
744
745 else {
746 r1 = 0;
747 }
748 e = -(ro * p - r) / sigmay;
749 e = e / (1 - ro * ro);
750 r1 = r1 * e;
751 if (txy != 0) {
752 px = 0, py = 0;
753 ery =
754 (-Erfc(r / s2 + 1 / (2 * by)) / (s2 * by * sigmay) -
755 Derfc(r / s2 + 1 / (2 * by)) / (s2 * sigmay)), erx =
756 Erfc(p / s2 + 1 / (2 * bx));
757 ex = p / (s2 * bx), ey = r / (s2 * by);
758 if (TMath::Abs(ex) < 9 && TMath::Abs(ey) < 9) {
759 px = exp(ex) * erx, py = exp(ey) * ery;
760 }
761 r1 += 0.5 * txy * px * py;
762 }
763 if (sxy != 0) {
764 ry = -Derfc(r / s2) / (s2 * sigmay), rx = Erfc(p / s2);
765 r1 += 0.5 * sxy * rx * ry;
766 }
767 r1 = a * r1;
768 }
769 return (r1);
770}
771
772////////////////////////////////////////////////////////////////////////////////
773/// This function calculates second derivative of 2D peaks shape function
774/// (see manual) according to y position of 2D peak
775///
776/// Function parameters:
777/// - x-channel in x-dimension
778/// - y-channel in y-dimension
779/// - a-amplitude
780/// - x0-position of peak in x-dimension
781/// - y0-position of peak in y-dimension
782/// - sigmax-sigmax of peaks
783/// - sigmay-sigmay of peaks
784/// - ro-correlation coefficient
785
788 Double_t ro)
789{
790 Double_t p, r, r1 = 0, e;
791 p = (x - x0) / sigmax;
792 r = (y - y0) / sigmay;
793 if (TMath::Abs(p) < 3 && TMath::Abs(r) < 3) {
794 e = (p * p - 2 * ro * p * r + r * r) / (2 * (1 - ro * ro));
795 if (e < 700)
796 r1 = exp(-e);
797
798 else {
799 r1 = 0;
800 }
801 e = -(ro * p - r) / sigmay;
802 e = e / (1 - ro * ro);
803 r1 = r1 * (e * e - 1 / ((1 - ro * ro) * sigmay * sigmay));
804 r1 = a * r1;
805 }
806 return (r1);
807}
808
809////////////////////////////////////////////////////////////////////////////////
810/// This function calculates derivative of 2D peaks shape function (see manual)
811/// according to x position of 1D ridge
812///
813/// Function parameters:
814/// - x-channel in x-dimension
815/// - ax-amplitude of ridge
816/// - x0-position of peak in x-dimension
817/// - sigmax-sigmax of peaks
818/// - ro-correlation coefficient
819/// - tx, sx-relative amplitudes
820/// - bx-slope
821
824{
825 Double_t p, e, r1 = 0, px, rx, erx, ex, s2;
826 p = (x - x0) / sigmax;
827 if (TMath::Abs(p) < 3) {
828 s2 = TMath::Sqrt(2.0);
829 e = p * p / 2;
830 if (e < 700)
831 r1 = exp(-e);
832
833 else {
834 r1 = 0;
835 }
836 r1 = r1 * p / sigmax;
837 if (tx != 0) {
838 px = 0;
839 erx =
840 (-Erfc(p / s2 + 1 / (2 * bx)) / (s2 * bx * sigmax) -
841 Derfc(p / s2 + 1 / (2 * bx)) / (s2 * sigmax));
842 ex = p / (s2 * bx);
843 if (TMath::Abs(ex) < 9)
844 px = exp(ex) * erx;
845 r1 += 0.5 * tx * px;
846 }
847 if (sx != 0) {
848 rx = -Derfc(p / s2) / (s2 * sigmax);
849 r1 += 0.5 * sx * rx;
850 }
851 r1 = ax * r1;
852 }
853 return (r1);
854}
855
856////////////////////////////////////////////////////////////////////////////////
857/// This function calculates second derivative of 2D peaks shape function
858/// (see manual) according to x position of 1D ridge
859///
860/// Function parameters:
861/// - x-channel in x-dimension
862/// - ax-amplitude of ridge
863/// - x0-position of peak in x-dimension
864/// - sigmax-sigmax of peaks
865
868{
869 Double_t p, e, r1 = 0;
870 p = (x - x0) / sigmax;
871 if (TMath::Abs(p) < 3) {
872 e = p * p / 2;
873 if (e < 700)
874 r1 = exp(-e);
875
876 else {
877 r1 = 0;
878 }
879 r1 = r1 * (p * p / (sigmax * sigmax) - 1 / (sigmax * sigmax));
880 r1 = ax * r1;
881 }
882 return (r1);
883}
884
885////////////////////////////////////////////////////////////////////////////////
886/// This function calculates derivative of peaks shape function (see manual)
887/// according to sigmax of peaks.
888///
889/// Function parameters:
890/// - numOfFittedPeaks-number of fitted peaks
891/// - x,y-position of channel
892/// - parameter-array of peaks parameters (amplitudes and positions)
893/// - sigmax-sigmax of peaks
894/// - sigmay-sigmay of peaks
895/// - ro-correlation coefficient
896/// - txy, sxy, tx, sx-relative amplitudes
897/// - bx, by-slopes
898
903 Double_t by)
904{
905 Double_t p, r, r1 =
906 0, e, a, b, x0, y0, s2, px, py, rx, ry, erx, ery, ex, ey;
907 Int_t j;
908 s2 = TMath::Sqrt(2.0);
909 for (j = 0; j < numOfFittedPeaks; j++) {
910 a = parameter[7 * j];
911 x0 = parameter[7 * j + 1];
912 y0 = parameter[7 * j + 2];
913 p = (x - x0) / sigmax;
914 r = (y - y0) / sigmay;
915 if (TMath::Abs(p) < 3 && TMath::Abs(r) < 3) {
916 e = (p * p - 2 * ro * p * r + r * r) / (2 * (1 - ro * ro));
917 if (e < 700)
918 e = exp(-e);
919
920 else {
921 e = 0;
922 }
923 b = -(ro * p * r - p * p) / sigmax;
924 e = e * b / (1 - ro * ro);
925 if (txy != 0) {
926 px = 0, py = 0;
927 erx =
928 -Erfc(p / s2 + 1 / (2 * bx)) * p / (s2 * bx * sigmax) -
929 Derfc(p / s2 + 1 / (2 * bx)) * p / (s2 * sigmax), ery =
930 Erfc(r / s2 + 1 / (2 * by));
931 ex = p / (s2 * bx), ey = r / (s2 * by);
932 if (TMath::Abs(ex) < 9 && TMath::Abs(ey) < 9) {
933 px = exp(ex) * erx, py = exp(ey) * ery;
934 }
935 e += 0.5 * txy * px * py;
936 }
937 if (sxy != 0) {
938 rx = -Derfc(p / s2) * p / (s2 * sigmax), ry = Erfc(r / s2);
939 e += 0.5 * sxy * rx * ry;
940 }
941 r1 = r1 + a * e;
942 }
943 if (TMath::Abs(p) < 3) {
944 x0 = parameter[7 * j + 5];
945 p = (x - x0) / sigmax;
946 b = p * p / 2;
947 if (b < 700)
948 e = exp(-b);
949
950 else {
951 e = 0;
952 }
953 e = 2 * b * e / sigmax;
954 if (tx != 0) {
955 px = 0;
956 erx =
957 (-Erfc(p / s2 + 1 / (2 * bx)) * p / (s2 * bx * sigmax) -
958 Derfc(p / s2 + 1 / (2 * bx)) * p / (s2 * sigmax));
959 ex = p / (s2 * bx);
960 if (TMath::Abs(ex) < 9)
961 px = exp(ex) * erx;
962 e += 0.5 * tx * px;
963 }
964 if (sx != 0) {
965 rx = -Derfc(p / s2) * p / (s2 * sigmax);
966 e += 0.5 * sx * rx;
967 }
968 r1 += parameter[7 * j + 3] * e;
969 }
970 }
971 return (r1);
972}
973
974////////////////////////////////////////////////////////////////////////////////
975/// This function calculates second derivative of peaks shape function
976/// (see manual) according to sigmax of peaks.
977///
978/// Function parameters:
979/// - numOfFittedPeaks-number of fitted peaks
980/// - x,y-position of channel
981/// - parameter-array of peaks parameters (amplitudes and positions)
982/// - sigmax-sigmax of peaks
983/// - sigmay-sigmay of peaks
984/// - ro-correlation coefficient
985
989 Double_t ro)
990{
991 Double_t p, r, r1 = 0, e, a, b, x0, y0;
992 Int_t j;
993 for (j = 0; j < numOfFittedPeaks; j++) {
994 a = parameter[7 * j];
995 x0 = parameter[7 * j + 1];
996 y0 = parameter[7 * j + 2];
997 p = (x - x0) / sigmax;
998 r = (y - y0) / sigmay;
999 if (TMath::Abs(p) < 3 && TMath::Abs(r) < 3) {
1000 e = (p * p - 2 * ro * p * r + r * r) / (2 * (1 - ro * ro));
1001 if (e < 700)
1002 e = exp(-e);
1003
1004 else {
1005 e = 0;
1006 }
1007 b = -(ro * p * r - p * p) / sigmax;
1008 e = e * (b * b / (1 - ro * ro) -
1009 (3 * p * p - 2 * ro * p * r) / (sigmax * sigmax)) / (1 -
1010 ro
1011 *
1012 ro);
1013 r1 = r1 + a * e;
1014 }
1015 if (TMath::Abs(p) < 3) {
1016 x0 = parameter[7 * j + 5];
1017 p = (x - x0) / sigmax;
1018 b = p * p / 2;
1019 if (b < 700)
1020 e = exp(-b);
1021
1022 else {
1023 e = 0;
1024 }
1025 e = e * (4 * b * b - 6 * b) / (sigmax * sigmax);
1026 r1 += parameter[7 * j + 3] * e;
1027 }
1028 }
1029 return (r1);
1030}
1031
1032////////////////////////////////////////////////////////////////////////////////
1033/// This function calculates derivative of peaks shape function (see manual)
1034/// according to sigmax of peaks.
1035///
1036/// Function parameters:
1037/// - numOfFittedPeaks-number of fitted peaks
1038/// - x,y-position of channel
1039/// - parameter-array of peaks parameters (amplitudes and positions)
1040/// - sigmax-sigmax of peaks
1041/// - sigmay-sigmay of peaks
1042/// - ro-correlation coefficient
1043/// - txy, sxy, ty, sy-relative amplitudes
1044/// - bx, by-slopes
1045
1050 Double_t by)
1051{
1052 Double_t p, r, r1 =
1053 0, e, a, b, x0, y0, s2, px, py, rx, ry, erx, ery, ex, ey;
1054 Int_t j;
1055 s2 = TMath::Sqrt(2.0);
1056 for (j = 0; j < numOfFittedPeaks; j++) {
1057 a = parameter[7 * j];
1058 x0 = parameter[7 * j + 1];
1059 y0 = parameter[7 * j + 2];
1060 p = (x - x0) / sigmax;
1061 r = (y - y0) / sigmay;
1062 if (TMath::Abs(p) < 3 && TMath::Abs(r) < 3) {
1063 e = (p * p - 2 * ro * p * r + r * r) / (2 * (1 - ro * ro));
1064 if (e < 700)
1065 e = exp(-e);
1066
1067 else {
1068 e = 0;
1069 }
1070 b = -(ro * p * r - r * r) / sigmay;
1071 e = e * b / (1 - ro * ro);
1072 if (txy != 0) {
1073 px = 0, py = 0;
1074 ery =
1075 -Erfc(r / s2 + 1 / (2 * by)) * r / (s2 * by * sigmay) -
1076 Derfc(r / s2 + 1 / (2 * by)) * r / (s2 * sigmay), erx =
1077 Erfc(p / s2 + 1 / (2 * bx));
1078 ex = p / (s2 * bx), ey = r / (s2 * by);
1079 if (TMath::Abs(ex) < 9 && TMath::Abs(ey) < 9) {
1080 px = exp(ex) * erx, py = exp(ey) * ery;
1081 }
1082 e += 0.5 * txy * px * py;
1083 }
1084 if (sxy != 0) {
1085 ry = -Derfc(r / s2) * r / (s2 * sigmay), rx = Erfc(p / s2);
1086 e += 0.5 * sxy * rx * ry;
1087 }
1088 r1 = r1 + a * e;
1089 }
1090 if (TMath::Abs(r) < 3) {
1091 y0 = parameter[7 * j + 6];
1092 r = (y - y0) / sigmay;
1093 b = r * r / 2;
1094 if (b < 700)
1095 e = exp(-b);
1096
1097 else {
1098 e = 0;
1099 }
1100 e = 2 * b * e / sigmay;
1101 if (ty != 0) {
1102 py = 0;
1103 ery =
1104 (-Erfc(r / s2 + 1 / (2 * by)) * r / (s2 * by * sigmay) -
1105 Derfc(r / s2 + 1 / (2 * by)) * r / (s2 * sigmay));
1106 ey = r / (s2 * by);
1107 if (TMath::Abs(ey) < 9)
1108 py = exp(ey) * ery;
1109 e += 0.5 * ty * py;
1110 }
1111 if (sy != 0) {
1112 ry = -Derfc(r / s2) * r / (s2 * sigmay);
1113 e += 0.5 * sy * ry;
1114 }
1115 r1 += parameter[7 * j + 4] * e;
1116 }
1117 }
1118 return (r1);
1119}
1120
1121////////////////////////////////////////////////////////////////////////////////
1122/// This function calculates second derivative of peaks shape function
1123/// (see manual) according to sigmay of peaks.
1124///
1125/// Function parameters:
1126/// - numOfFittedPeaks-number of fitted peaks
1127/// - x,y-position of channel
1128/// - parameter-array of peaks parameters (amplitudes and positions)
1129/// - sigmax-sigmax of peaks
1130/// - sigmay-sigmay of peaks
1131/// - ro-correlation coefficient
1132
1134 Double_t y, const Double_t *parameter,
1136 Double_t ro)
1137{
1138 Double_t p, r, r1 = 0, e, a, b, x0, y0;
1139 Int_t j;
1140 for (j = 0; j < numOfFittedPeaks; j++) {
1141 a = parameter[7 * j];
1142 x0 = parameter[7 * j + 1];
1143 y0 = parameter[7 * j + 2];
1144 p = (x - x0) / sigmax;
1145 r = (y - y0) / sigmay;
1146 if (TMath::Abs(p) < 3 && TMath::Abs(r) < 3) {
1147 e = (p * p - 2 * ro * p * r + r * r) / (2 * (1 - ro * ro));
1148 if (e < 700)
1149 e = exp(-e);
1150
1151 else {
1152 e = 0;
1153 }
1154 b = -(ro * p * r - r * r) / sigmay;
1155 e = e * (b * b / (1 - ro * ro) -
1156 (3 * r * r - 2 * ro * r * p) / (sigmay * sigmay)) / (1 -
1157 ro
1158 *
1159 ro);
1160 r1 = r1 + a * e;
1161 }
1162 if (TMath::Abs(r) < 3) {
1163 y0 = parameter[7 * j + 6];
1164 r = (y - y0) / sigmay;
1165 b = r * r / 2;
1166 if (b < 700)
1167 e = exp(-b);
1168
1169 else {
1170 e = 0;
1171 }
1172 e = e * (4 * b * b - 6 * b) / (sigmay * sigmay);
1173 r1 += parameter[7 * j + 4] * e;
1174 }
1175 }
1176 return (r1);
1177}
1178
1179////////////////////////////////////////////////////////////////////////////////
1180/// This function calculates derivative of peaks shape function (see manual)
1181/// according to correlation coefficient ro.
1182///
1183/// Function parameters:
1184/// - numOfFittedPeaks-number of fitted peaks
1185/// - x,y-position of channel
1186/// - parameter-array of peaks parameters (amplitudes and positions)
1187/// - sx-sigmax of peaks
1188/// - sy-sigmay of peaks
1189/// - r-correlation coefficient ro
1190
1193 Double_t r)
1194{
1195 Double_t px, qx, rx, vx, x0, y0, a, ex, tx;
1196 Int_t j;
1197 vx = 0;
1198 for (j = 0; j < numOfFittedPeaks; j++) {
1199 a = parameter[7 * j];
1200 x0 = parameter[7 * j + 1];
1201 y0 = parameter[7 * j + 2];
1202 px = (x - x0) / sx;
1203 qx = (y - y0) / sy;
1204 if (TMath::Abs(px) < 3 && TMath::Abs(qx) < 3) {
1205 rx = (px * px - 2 * r * px * qx + qx * qx);
1206 ex = rx / (2 * (1 - r * r));
1207 if ((ex) < 700)
1208 ex = exp(-ex);
1209
1210 else {
1211 ex = 0;
1212 }
1213 tx = px * qx / (1 - r * r);
1214 tx = tx - r * rx / ((1 - r * r) * (1 - r * r));
1215 vx = vx + a * ex * tx;
1216 }
1217 }
1218 return (vx);
1219}
1220
1221////////////////////////////////////////////////////////////////////////////////
1222/// This function calculates derivative of peaks shape function (see manual)
1223/// according to relative amplitude txy.
1224///
1225/// Function parameters:
1226/// - numOfFittedPeaks-number of fitted peaks
1227/// - x,y-position of channel
1228/// - parameter-array of peaks parameters (amplitudes and positions)
1229/// - sigmax-sigmax of peaks
1230/// - sigmay-sigmay of peaks
1231/// - bx, by-slopes
1232
1236{
1237 Double_t p, r, r1 = 0, ex, ey, px, py, erx, ery, s2, x0, y0, a;
1238 Int_t j;
1239 s2 = TMath::Sqrt(2.0);
1240 for (j = 0; j < numOfFittedPeaks; j++) {
1241 a = parameter[7 * j];
1242 x0 = parameter[7 * j + 1];
1243 y0 = parameter[7 * j + 2];
1244 p = (x - x0) / sigmax;
1245 r = (y - y0) / sigmay;
1246 px = 0, py = 0;
1247 erx = Erfc(p / s2 + 1 / (2 * bx)), ery =
1248 Erfc(r / s2 + 1 / (2 * by));
1249 ex = p / (s2 * bx), ey = r / (s2 * by);
1250 if (TMath::Abs(ex) < 9 && TMath::Abs(ey) < 9) {
1251 px = exp(ex) * erx, py = exp(ey) * ery;
1252 }
1253 r1 += 0.5 * a * px * py;
1254 }
1255 return (r1);
1256}
1257
1258////////////////////////////////////////////////////////////////////////////////
1259/// This function calculates derivative of peaks shape function (see manual)
1260/// according to relative amplitude sxy.
1261///
1262/// Function parameters:
1263/// - numOfFittedPeaks-number of fitted peaks
1264/// - x,y-position of channel
1265/// - parameter-array of peaks parameters (amplitudes and positions)
1266/// - sigmax-sigmax of peaks
1267/// - sigmay-sigmay of peaks
1268
1272{
1273 Double_t p, r, r1 = 0, rx, ry, x0, y0, a, s2;
1274 Int_t j;
1275 s2 = TMath::Sqrt(2.0);
1276 for (j = 0; j < numOfFittedPeaks; j++) {
1277 a = parameter[7 * j];
1278 x0 = parameter[7 * j + 1];
1279 y0 = parameter[7 * j + 2];
1280 p = (x - x0) / sigmax;
1281 r = (y - y0) / sigmay;
1282 rx = Erfc(p / s2), ry = Erfc(r / s2);
1283 r1 += 0.5 * a * rx * ry;
1284 }
1285 return (r1);
1286}
1287
1288////////////////////////////////////////////////////////////////////////////////
1289/// This function calculates derivative of peaks shape function (see manual)
1290/// according to relative amplitude tx.
1291///
1292/// Function parameters:
1293/// - numOfFittedPeaks-number of fitted peaks
1294/// - x-position of channel
1295/// - parameter-array of peaks parameters (amplitudes and positions)
1296/// - sigmax-sigma of 1D ridge
1297/// - bx-slope
1298
1301 Double_t bx)
1302{
1303 Double_t p, r1 = 0, ex, px, erx, s2, ax, x0;
1304 Int_t j;
1305 s2 = TMath::Sqrt(2.0);
1306 for (j = 0; j < numOfFittedPeaks; j++) {
1307 ax = parameter[7 * j + 3];
1308 x0 = parameter[7 * j + 5];
1309 p = (x - x0) / sigmax;
1310 px = 0;
1311 erx = Erfc(p / s2 + 1 / (2 * bx));
1312 ex = p / (s2 * bx);
1313 if (TMath::Abs(ex) < 9) {
1314 px = exp(ex) * erx;
1315 }
1316 r1 += 0.5 * ax * px;
1317 }
1318 return (r1);
1319}
1320
1321////////////////////////////////////////////////////////////////////////////////
1322/// This function calculates derivative of peaks shape function (see manual)
1323/// according to relative amplitude ty.
1324///
1325/// Function parameters:
1326/// - numOfFittedPeaks-number of fitted peaks
1327/// - x-position of channel
1328/// - parameter-array of peaks parameters (amplitudes and positions)
1329/// - sigmax-sigma of 1D ridge
1330/// - bx-slope
1331
1334 Double_t bx)
1335{
1336 Double_t p, r1 = 0, ex, px, erx, s2, ax, x0;
1337 Int_t j;
1338 s2 = TMath::Sqrt(2.0);
1339 for (j = 0; j < numOfFittedPeaks; j++) {
1340 ax = parameter[7 * j + 4];
1341 x0 = parameter[7 * j + 6];
1342 p = (x - x0) / sigmax;
1343 px = 0;
1344 erx = Erfc(p / s2 + 1 / (2 * bx));
1345 ex = p / (s2 * bx);
1346 if (TMath::Abs(ex) < 9) {
1347 px = exp(ex) * erx;
1348 }
1349 r1 += 0.5 * ax * px;
1350 }
1351 return (r1);
1352}
1353
1354////////////////////////////////////////////////////////////////////////////////
1355/// This function calculates derivative of peaks shape function (see manual)
1356/// according to relative amplitude sx.
1357///
1358/// Function parameters:
1359/// - numOfFittedPeaks-number of fitted peaks
1360/// - x-position of channel
1361/// - parameter-array of peaks parameters (amplitudes and positions)
1362/// - sigmax-sigma of 1D ridge
1363
1366{
1367 Double_t p, r1 = 0, rx, ax, x0, s2;
1368 Int_t j;
1369 s2 = TMath::Sqrt(2.0);
1370 for (j = 0; j < numOfFittedPeaks; j++) {
1371 ax = parameter[7 * j + 3];
1372 x0 = parameter[7 * j + 5];
1373 p = (x - x0) / sigmax;
1374 s2 = TMath::Sqrt(2.0);
1375 rx = Erfc(p / s2);
1376 r1 += 0.5 * ax * rx;
1377 }
1378 return (r1);
1379}
1380
1381////////////////////////////////////////////////////////////////////////////////
1382/// This function calculates derivative of peaks shape function (see manual)
1383/// according to relative amplitude sy.
1384///
1385/// Function parameters:
1386/// - numOfFittedPeaks-number of fitted peaks
1387/// - x-position of channel
1388/// - parameter-array of peaks parameters (amplitudes and positions)
1389/// - sigmax-sigma of 1D ridge
1390
1393{
1394 Double_t p, r1 = 0, rx, ax, x0, s2;
1395 Int_t j;
1396 s2 = TMath::Sqrt(2.0);
1397 for (j = 0; j < numOfFittedPeaks; j++) {
1398 ax = parameter[7 * j + 4];
1399 x0 = parameter[7 * j + 6];
1400 p = (x - x0) / sigmax;
1401 s2 = TMath::Sqrt(2.0);
1402 rx = Erfc(p / s2);
1403 r1 += 0.5 * ax * rx;
1404 }
1405 return (r1);
1406}
1407
1408////////////////////////////////////////////////////////////////////////////////
1409/// This function calculates derivative of peaks shape function (see manual)
1410/// according to slope bx.
1411///
1412/// Function parameters:
1413/// - numOfFittedPeaks-number of fitted peaks
1414/// - x,y-position of channel
1415/// - parameter-array of peaks parameters (amplitudes and positions)
1416/// - sigmax-sigmax of peaks
1417/// - sigmay-sigmay of peaks
1418/// - txy, tx-relative amplitudes
1419/// - bx, by-slopes
1420
1424 Double_t by)
1425{
1426 Double_t p, r, r1 = 0, a, x0, y0, s2, px, py, erx, ery, ex, ey;
1427 Int_t j;
1428 s2 = TMath::Sqrt(2.0);
1429 for (j = 0; j < numOfFittedPeaks; j++) {
1430 a = parameter[7 * j];
1431 x0 = parameter[7 * j + 1];
1432 y0 = parameter[7 * j + 2];
1433 p = (x - x0) / sigmax;
1434 r = (y - y0) / sigmay;
1435 if (txy != 0) {
1436 px = 0, py = 0;
1437 erx =
1438 -Erfc(p / s2 + 1 / (2 * bx)) * p / (s2 * bx * bx) -
1439 Derfc(p / s2 + 1 / (2 * bx)) / (s2 * bx * bx), ery =
1440 Erfc(r / s2 + 1 / (2 * by));
1441 ex = p / (s2 * bx), ey = r / (s2 * by);
1442 if (TMath::Abs(ex) < 9 && TMath::Abs(ey) < 9) {
1443 px = exp(ex) * erx, py = exp(ey) * ery;
1444 }
1445 r1 += 0.5 * a * txy * px * py;
1446 }
1447 a = parameter[7 * j + 3];
1448 x0 = parameter[7 * j + 5];
1449 p = (x - x0) / sigmax;
1450 if (tx != 0) {
1451 px = 0;
1452 erx =
1453 (-Erfc(p / s2 + 1 / (2 * bx)) * p / (s2 * bx * bx) -
1454 Derfc(p / s2 + 1 / (2 * bx)) / (s2 * bx * bx));
1455 ex = p / (s2 * bx);
1456 if (TMath::Abs(ex) < 9)
1457 px = exp(ex) * erx;
1458 r1 += 0.5 * a * tx * px;
1459 }
1460 }
1461 return (r1);
1462}
1463
1464////////////////////////////////////////////////////////////////////////////////
1465/// This function calculates derivative of peaks shape function (see manual)
1466/// according to slope by.
1467///
1468/// Function parameters:
1469/// - numOfFittedPeaks-number of fitted peaks
1470/// - x,y-position of channel
1471/// - parameter-array of peaks parameters (amplitudes and positions)
1472/// - sigmax-sigmax of peaks
1473/// - sigmay-sigmay of peaks
1474/// - txy, ty-relative amplitudes
1475/// - bx, by-slopes
1476
1480 Double_t by)
1481{
1482 Double_t p, r, r1 = 0, a, x0, y0, s2, px, py, erx, ery, ex, ey;
1483 Int_t j;
1484 s2 = TMath::Sqrt(2.0);
1485 for (j = 0; j < numOfFittedPeaks; j++) {
1486 a = parameter[7 * j];
1487 x0 = parameter[7 * j + 1];
1488 y0 = parameter[7 * j + 2];
1489 p = (x - x0) / sigmax;
1490 r = (y - y0) / sigmay;
1491 if (txy != 0) {
1492 px = 0, py = 0;
1493 ery =
1494 -Erfc(r / s2 + 1 / (2 * by)) * r / (s2 * by * by) -
1495 Derfc(r / s2 + 1 / (2 * by)) / (s2 * by * by), erx =
1496 Erfc(p / s2 + 1 / (2 * bx));
1497 ex = p / (s2 * bx), ey = r / (s2 * by);
1498 if (TMath::Abs(ex) < 9 && TMath::Abs(ey) < 9) {
1499 px = exp(ex) * erx, py = exp(ey) * ery;
1500 }
1501 r1 += 0.5 * a * txy * px * py;
1502 }
1503 a = parameter[7 * j + 4];
1504 y0 = parameter[7 * j + 6];
1505 r = (y - y0) / sigmay;
1506 if (ty != 0) {
1507 py = 0;
1508 ery =
1509 (-Erfc(r / s2 + 1 / (2 * by)) * r / (s2 * by * by) -
1510 Derfc(r / s2 + 1 / (2 * by)) / (s2 * by * by));
1511 ey = r / (s2 * by);
1512 if (TMath::Abs(ey) < 9)
1513 py = exp(ey) * ery;
1514 r1 += 0.5 * a * ty * py;
1515 }
1516 }
1517 return (r1);
1518}
1519
1520////////////////////////////////////////////////////////////////////////////////
1521/// This function calculates volume of a peak
1522///
1523/// Function parameters:
1524/// - a-amplitude of the peak
1525/// - sx,sy-sigmas of peak
1526/// - ro-correlation coefficient
1527
1529{
1530 Double_t pi = 3.1415926535, r;
1531 r = 1 - ro * ro;
1532 if (r > 0)
1533 r = TMath::Sqrt(r);
1534
1535 else {
1536 return (0);
1537 }
1538 r = 2 * a * pi * sx * sy * r;
1539 return (r);
1540}
1541
1542////////////////////////////////////////////////////////////////////////////////
1543/// This function calculates derivative of the volume of a peak
1544/// according to amplitude
1545///
1546/// Function parameters:
1547/// - sx,sy-sigmas of peak
1548/// - ro-correlation coefficient
1549
1551{
1552 Double_t pi = 3.1415926535, r;
1553 r = 1 - ro * ro;
1554 if (r > 0)
1555 r = TMath::Sqrt(r);
1556
1557 else {
1558 return (0);
1559 }
1560 r = 2 * pi * sx * sy * r;
1561 return (r);
1562}
1563
1564////////////////////////////////////////////////////////////////////////////////
1565/// This function calculates derivative of the volume of a peak
1566/// according to sigmax
1567///
1568/// Function parameters:
1569/// - a-amplitude of peak
1570/// - sy-sigma of peak
1571/// - ro-correlation coefficient
1572
1574{
1575 Double_t pi = 3.1415926535, r;
1576 r = 1 - ro * ro;
1577 if (r > 0)
1578 r = TMath::Sqrt(r);
1579
1580 else {
1581 return (0);
1582 }
1583 r = a * 2 * pi * sy * r;
1584 return (r);
1585}
1586
1587////////////////////////////////////////////////////////////////////////////////
1588/// This function calculates derivative of the volume of a peak
1589/// according to sigmay
1590///
1591/// Function parameters:
1592/// - a-amplitude of peak
1593/// - sx-sigma of peak
1594/// - ro-correlation coefficient
1595
1597{
1598 Double_t pi = 3.1415926535, r;
1599 r = 1 - ro * ro;
1600 if (r > 0)
1601 r = TMath::Sqrt(r);
1602
1603 else {
1604 return (0);
1605 }
1606 r = a * 2 * pi * sx * r;
1607 return (r);
1608}
1609
1610////////////////////////////////////////////////////////////////////////////////
1611/// This function calculates derivative of the volume of a peak
1612/// according to ro
1613///
1614/// Function parameters:
1615/// - a-amplitude of peak
1616/// - sx,sy-sigmas of peak
1617/// - ro-correlation coefficient
1618
1620{
1621 Double_t pi = 3.1415926535, r;
1622 r = 1 - ro * ro;
1623 if (r > 0)
1624 r = TMath::Sqrt(r);
1625
1626 else {
1627 return (0);
1628 }
1629 r = -a * 2 * pi * sx * sy * ro / r;
1630 return (r);
1631}
1632
1633
1634////////////////////////////////////////////////////////////////////////////////
1635/// This function fits the source spectrum. The calling program should
1636/// fill in input parameters of the TSpectrum2Fit class.
1637/// The fitted parameters are written into
1638/// TSpectrum2Fit class output parameters and fitted data are written into
1639/// source spectrum.
1640///
1641/// Function parameters:
1642/// - source-pointer to the matrix of source spectrum
1643///
1644/// ### Fitting
1645///
1646/// Goal: to estimate simultaneously peak shape parameters in spectra with large
1647/// number of peaks
1648///
1649/// - peaks can be fitted separately, each peak (or multiplets) in a region or
1650/// together all peaks in a spectrum. To fit separately each peak one needs to
1651/// determine the fitted region. However it can happen that the regions of
1652/// neighbouring peaks are overlapping. Then the results of fitting are very poor.
1653/// On the other hand, when fitting together all peaks found in a spectrum, one
1654/// needs to have a method that is stable (converges) and fast enough to carry out
1655/// fitting in reasonable time
1656///
1657/// - we have implemented the non-symmetrical semiempirical peak shape function
1658///
1659/// - it contains the two-dimensional symmetrical Gaussian two one-dimensional
1660/// symmetrical Gaussian ridges as well as non-symmetrical terms and background.
1661///
1662/// \image html spectrum2fit_awmi_image001.gif
1663///
1664/// where Txy, Tx, Ty, Sxy, Sx, Sy are relative amplitudes and Bx, By are slopes.
1665///
1666/// - algorithm without matrix inversion (AWMI) allows fitting tens, hundreds
1667/// of peaks simultaneously that represent sometimes thousands of parameters [2],[5].
1668///
1669/// #### References:
1670///
1671/// [1] Phillps G.W., Marlow K.W.,
1672/// NIM 137 (1976) 525.
1673///
1674/// [2] I. A. Slavic: Nonlinear
1675/// least-squares fitting without matrix inversion applied to complex Gaussian
1676/// spectra analysis. NIM 134 (1976) 285-289.
1677///
1678/// [3] T. Awaya: A new method for
1679/// curve fitting to the data with low statistics not using chi-square method. NIM
1680/// 165 (1979) 317-323.
1681///
1682/// [4] T. Hauschild, M. Jentschel:
1683/// Comparison of maximum likelihood estimation and chi-square statistics applied
1684/// to counting experiments. NIM A 457 (2001) 384-401.
1685///
1686/// [5] M. Morh, J.
1687/// Kliman, M. Jandel, Krupa, V. Matouoek: Study of fitting algorithms
1688/// applied to simultaneous analysis of large number of peaks in -ray spectra.
1689/// Applied Spectroscopy, Vol. 57, No. 7, pp. 753-760, 2003
1690///
1691/// ### Example 1 - script FitAwmi2.c:
1692///
1693/// \image html spectrum2fit_awmi_image002.jpg Original Fig. 1 two-dimensional spectrum with found peaks (using TSpectrum2 peak searching function). The positions of peaks were used as initial estimates in fitting procedure.
1694///
1695/// \image html spectrum2fit_awmi_image003.jpg Fig. 2 Fitted (generated from fitted parameters) spectrum of the data from Fig. 1 using Algorithm Without Matrix Inversion. Each peak was represented by 7 parameters, which together with Sigmax, Sigmay and a0 resulted in 38 fitted parameters. The chi-squareafter 1000 iterations was 0.642342.
1696///
1697/// #### Script:
1698///
1699/// Example to illustrate fitting function, algorithm without matrix inversion (AWMI) (class TSpectrumFit2).
1700/// To execute this example, do
1701///
1702/// `root > .x FitAwmi2.C`
1703///
1704/// ~~~ {.cpp}
1705/// void FitAwmi2() {
1706/// Int_t i, j, nfound;
1707/// Int_t nbinsx = 64;
1708/// Int_t nbinsy = 64;
1709/// Int_t xmin = 0;
1710/// Int_t xmax = nbinsx;
1711/// Int_t ymin = 0;
1712/// Int_t ymax = nbinsy;
1713/// Double_t ** source = new float *[nbinsx];
1714/// Double_t ** dest = new float *[nbinsx];
1715/// for (i=0;i<nbinsx;i++)
1716/// source[i]=new float[nbinsy];
1717/// for (i=0;i<nbinsx;i++)
1718/// dest[i]=new float[nbinsy];
1719/// TH2F *search = new TH2F("search","High resolution peak searching",nbinsx,xmin,xmax,nbinsy,ymin,ymax);
1720/// TFile *f = new TFile("TSpectrum2.root");
1721/// search=(TH2F*) f->Get("search4;1");
1722/// TCanvas *Searching = new TCanvas("Searching","Two-dimensional fitting using Algorithm Without Matrix Inversion",10,10,1000,700);
1723/// TSpectrum2 *s = new TSpectrum2();
1724/// for (i = 0; i < nbinsx; i++){
1725/// for (j = 0; j < nbinsy; j++){
1726/// source[i][j] = search->GetBinContent(i + 1,j + 1);
1727/// }
1728/// }
1729/// //searching for candidate peaks positions
1730/// nfound = s->SearchHighRes(source, dest, nbinsx, nbinsy, 2, 5, kTRUE, 3, kFALSE, 3);
1731/// Bool_t *FixPosX = new Bool_t[nfound];
1732/// Bool_t *FixPosY = new Bool_t[nfound];
1733/// Bool_t *FixAmp = new Bool_t[nfound];
1734/// Double_t *PosX = new Double_t[nfound];
1735/// Double_t *PosY = new Double_t[nfound];
1736/// Double_t *Amp = new Double_t[nfound];
1737/// Double_t *AmpXY = new Double_t[nfound];
1738/// PosX = s->GetPositionX();
1739/// PosY = s->GetPositionY();
1740/// printf("Found %d candidate peaks\n",nfound);
1741/// for(i = 0; i< nfound ; i++){
1742/// FixPosX[i] = kFALSE;
1743/// FixPosY[i] = kFALSE;
1744/// FixAmp[i] = kFALSE;
1745/// Amp[i] = source[(Int_t)(PosX[i]+0.5)][(Int_t)(PosY[i]+0.5)]; //initial values of peaks amplitudes, input parameters
1746/// AmpXY[i] = 0;
1747/// }
1748/// //filling in the initial estimates of the input parameters
1749/// TSpectrumFit2 *pfit=new TSpectrumFit2(nfound);
1750/// pfit->SetFitParameters(xmin, xmax-1, ymin, ymax-1, 1000, 0.1, pfit->kFitOptimChiCounts,
1751/// pfit->kFitAlphaHalving, pfit->kFitPower2,
1752/// pfit->kFitTaylorOrderFirst);
1753/// pfit->SetPeakParameters(2, kFALSE, 2, kFALSE, 0, kTRUE, PosX, (Bool_t *)
1754/// FixPosX, PosY, (Bool_t *) FixPosY, PosX, (Bool_t *) FixPosX, PosY, (Bool_t *)
1755/// FixPosY, Amp, (Bool_t *) FixAmp, AmpXY, (Bool_t *) FixAmp, AmpXY, (Bool_t *)
1756/// FixAmp);
1757/// pfit->SetBackgroundParameters(0, kFALSE, 0, kTRUE, 0, kTRUE);
1758/// pfit->FitAwmi(source);
1759/// for (i = 0; i < nbinsx; i++){
1760/// for (j = 0; j < nbinsy; j++){
1761/// search->SetBinContent(i + 1, j + 1,source[i][j]);
1762/// }
1763/// }
1764/// search->Draw("SURF");
1765/// }
1766/// ~~~
1767///
1768/// ### Example 2 - script FitAwmi2.c:
1769///
1770/// \image html spectrum2fit_awmi_image004.jpg Fig. 3 Original two-dimensional gamma-gamma-ray spectrum with found peaks (using TSpectrum2 peak searching function).
1771///
1772/// \image html spectrum2fit_awmi_image005.jpg Fig. 4 Fitted (generated from fitted parameters) spectrum of the data from Fig. 3 using Algorithm Without Matrix Inversion. 152 peaks were identified. Each peak was represented by 7 parameters, which together with Sigmax, Sigmay and a0 resulted in 1067 fitted parameters. The chi-square after 1000 iterations was 0.728675. One can observe good correspondence with the original data.
1773///
1774/// #### Script:
1775///
1776////
1777/// Example to illustrate fitting function, algorithm without matrix inversion
1778/// (AWMI) (class TSpectrumFit2). To execute this example, do:
1779///
1780/// `root > .x FitA2.C`
1781///
1782/// ~~~ {.cpp}
1783/// void FitA2() {
1784/// Int_t i, j, nfound;
1785/// Int_t nbinsx = 256;
1786/// Int_t nbinsy = 256;
1787/// Int_t xmin = 0;
1788/// Int_t xmax = nbinsx;
1789/// Int_t ymin = 0;
1790/// Int_t ymax = nbinsy;
1791/// Double_t ** source = new float *[nbinsx];
1792/// Double_t ** dest = new float *[nbinsx];
1793/// for (i=0;i<nbinsx;i++)
1794/// source[i]=new
1795/// float[nbinsy];
1796/// for (i=0;i<nbinsx;i++)
1797/// dest[i]=new
1798/// float[nbinsy];
1799/// TH2F *search = new TH2F("search","High resolution peak
1800/// searching",nbinsx,xmin,xmax,nbinsy,ymin,ymax);
1801/// TFile *f = new TFile("TSpectrum2.root");
1802/// search=(TH2F*) f->Get("fit1;1");
1803/// TCanvas *Searching = new TCanvas("Searching","Two-dimensional fitting using Algorithm Without Matrix Inversion",10,10,1000,700);
1804/// TSpectrum2 *s = new TSpectrum2(1000,1);
1805/// for (i = 0; i < nbinsx; i++){
1806/// for (j = 0; j < nbinsy; j++){
1807/// source[i][j] = search->GetBinContent(i + 1,j + 1);
1808/// }
1809/// }
1810/// nfound = s->SearchHighRes(source, dest, nbinsx, nbinsy, 2, 2, kTRUE, 100, kFALSE, 3);
1811/// printf("Found %d candidate peaks\n",nfound);
1812/// Bool_t *FixPosX = new Bool_t[nfound];
1813/// Bool_t *FixPosY = new Bool_t[nfound];
1814/// Bool_t *FixAmp = new Bool_t[nfound];
1815/// Double_t *PosX = new Double_t[nfound];
1816/// Double_t *PosY = new Double_t[nfound];
1817/// Double_t *Amp = new Double_t[nfound];
1818/// Double_t *AmpXY = new Double_t[nfound];
1819/// PosX = s->GetPositionX();
1820/// PosY = s->GetPositionY();
1821/// for(i = 0; i< nfound ; i++){
1822/// FixPosX[i] = kFALSE;
1823/// FixPosY[i] = kFALSE;
1824/// FixAmp[i] = kFALSE;
1825/// Amp[i] = source[(Int_t)(PosX[i]+0.5)][(Int_t)(PosY[i]+0.5)]; //initial values of peaks amplitudes, input parameters
1826/// AmpXY[i] = 0;
1827/// }
1828/// //filling in the initial estimates of the input parameters
1829/// TSpectrumFit2 *pfit=new TSpectrumFit2(nfound);
1830/// pfit->SetFitParameters(xmin, xmax-1, ymin, ymax-1, 1000, 0.1,
1831/// pfit->kFitOptimChiCounts, pfit->kFitAlphaHalving, pfit->kFitPower2,
1832/// pfit->kFitTaylorOrderFirst);
1833/// pfit->SetPeakParameters(2, kFALSE, 2, kFALSE, 0, kTRUE, PosX, (Bool_t *)
1834/// FixPosX, PosY, (Bool_t *) FixPosY, PosX, (Bool_t *) FixPosX, PosY, (Bool_t *)
1835/// FixPosY, Amp, (Bool_t *) FixAmp, AmpXY, (Bool_t *) FixAmp, AmpXY, (Bool_t *)
1836/// FixAmp);
1837/// pfit->SetBackgroundParameters(0, kFALSE, 0, kTRUE, 0, kTRUE);
1838/// pfit->FitAwmi(source);
1839/// for (i = 0; i < nbinsx; i++){
1840/// for (j = 0; j < nbinsy; j++){
1841/// search->SetBinContent(i + 1, j + 1,source[i][j]);
1842/// }
1843/// }
1844/// search->Draw("SURF");
1845/// }
1846/// ~~~
1847
1849{
1850
1851
1852 Int_t i, i1, i2, j, k, shift =
1853 7 * fNPeaks + 14, peak_vel, size, iter, pw,
1855 Double_t a, b, c, d = 0, alpha, chi_opt, yw, ywm, f, chi2, chi_min, chi =
1856 0, pi, pmin = 0, chi_cel = 0, chi_er;
1857 Double_t *working_space = new Double_t[5 * (7 * fNPeaks + 14)];
1858 for (i = 0, j = 0; i < fNPeaks; i++) {
1859 working_space[7 * i] = fAmpInit[i]; //vector parameter
1860 if (fFixAmp[i] == false) {
1861 working_space[shift + j] = fAmpInit[i]; //vector xk
1862 j += 1;
1863 }
1864 working_space[7 * i + 1] = fPositionInitX[i]; //vector parameter
1865 if (fFixPositionX[i] == false) {
1866 working_space[shift + j] = fPositionInitX[i]; //vector xk
1867 j += 1;
1868 }
1869 working_space[7 * i + 2] = fPositionInitY[i]; //vector parameter
1870 if (fFixPositionY[i] == false) {
1871 working_space[shift + j] = fPositionInitY[i]; //vector xk
1872 j += 1;
1873 }
1874 working_space[7 * i + 3] = fAmpInitX1[i]; //vector parameter
1875 if (fFixAmpX1[i] == false) {
1876 working_space[shift + j] = fAmpInitX1[i]; //vector xk
1877 j += 1;
1878 }
1879 working_space[7 * i + 4] = fAmpInitY1[i]; //vector parameter
1880 if (fFixAmpY1[i] == false) {
1881 working_space[shift + j] = fAmpInitY1[i]; //vector xk
1882 j += 1;
1883 }
1884 working_space[7 * i + 5] = fPositionInitX1[i]; //vector parameter
1885 if (fFixPositionX1[i] == false) {
1886 working_space[shift + j] = fPositionInitX1[i]; //vector xk
1887 j += 1;
1888 }
1889 working_space[7 * i + 6] = fPositionInitY1[i]; //vector parameter
1890 if (fFixPositionY1[i] == false) {
1891 working_space[shift + j] = fPositionInitY1[i]; //vector xk
1892 j += 1;
1893 }
1894 }
1895 peak_vel = 7 * i;
1896 working_space[7 * i] = fSigmaInitX; //vector parameter
1897 if (fFixSigmaX == false) {
1898 working_space[shift + j] = fSigmaInitX; //vector xk
1899 j += 1;
1900 }
1901 working_space[7 * i + 1] = fSigmaInitY; //vector parameter
1902 if (fFixSigmaY == false) {
1903 working_space[shift + j] = fSigmaInitY; //vector xk
1904 j += 1;
1905 }
1906 working_space[7 * i + 2] = fRoInit; //vector parameter
1907 if (fFixRo == false) {
1908 working_space[shift + j] = fRoInit; //vector xk
1909 j += 1;
1910 }
1911 working_space[7 * i + 3] = fA0Init; //vector parameter
1912 if (fFixA0 == false) {
1913 working_space[shift + j] = fA0Init; //vector xk
1914 j += 1;
1915 }
1916 working_space[7 * i + 4] = fAxInit; //vector parameter
1917 if (fFixAx == false) {
1918 working_space[shift + j] = fAxInit; //vector xk
1919 j += 1;
1920 }
1921 working_space[7 * i + 5] = fAyInit; //vector parameter
1922 if (fFixAy == false) {
1923 working_space[shift + j] = fAyInit; //vector xk
1924 j += 1;
1925 }
1926 working_space[7 * i + 6] = fTxyInit; //vector parameter
1927 if (fFixTxy == false) {
1928 working_space[shift + j] = fTxyInit; //vector xk
1929 j += 1;
1930 }
1931 working_space[7 * i + 7] = fSxyInit; //vector parameter
1932 if (fFixSxy == false) {
1933 working_space[shift + j] = fSxyInit; //vector xk
1934 j += 1;
1935 }
1936 working_space[7 * i + 8] = fTxInit; //vector parameter
1937 if (fFixTx == false) {
1938 working_space[shift + j] = fTxInit; //vector xk
1939 j += 1;
1940 }
1941 working_space[7 * i + 9] = fTyInit; //vector parameter
1942 if (fFixTy == false) {
1943 working_space[shift + j] = fTyInit; //vector xk
1944 j += 1;
1945 }
1946 working_space[7 * i + 10] = fSxyInit; //vector parameter
1947 if (fFixSx == false) {
1948 working_space[shift + j] = fSxInit; //vector xk
1949 j += 1;
1950 }
1951 working_space[7 * i + 11] = fSyInit; //vector parameter
1952 if (fFixSy == false) {
1953 working_space[shift + j] = fSyInit; //vector xk
1954 j += 1;
1955 }
1956 working_space[7 * i + 12] = fBxInit; //vector parameter
1957 if (fFixBx == false) {
1958 working_space[shift + j] = fBxInit; //vector xk
1959 j += 1;
1960 }
1961 working_space[7 * i + 13] = fByInit; //vector parameter
1962 if (fFixBy == false) {
1963 working_space[shift + j] = fByInit; //vector xk
1964 j += 1;
1965 }
1966 size = j;
1967 for (iter = 0; iter < fNumberIterations; iter++) {
1968 for (j = 0; j < size; j++) {
1969 working_space[2 * shift + j] = 0, working_space[3 * shift + j] = 0; //der,temp
1970 }
1971
1972 //filling vectors
1973 alpha = fAlpha;
1974 chi_opt = 0, pw = fPower - 2;
1975 for (i1 = fXmin; i1 <= fXmax; i1++) {
1976 for (i2 = fYmin; i2 <= fYmax; i2++) {
1977 yw = source[i1][i2];
1978 ywm = yw;
1979 f = Shape2(fNPeaks, i1, i2,
1990 working_space[peak_vel + 10],
1991 working_space[peak_vel + 11],
1992 working_space[peak_vel + 12],
1993 working_space[peak_vel + 13]);
1995 if (f > 0.00001)
1996 chi_opt += yw * TMath::Log(f) - f;
1997 }
1998
1999 else {
2000 if (ywm != 0)
2001 chi_opt += (yw - f) * (yw - f) / ywm;
2002 }
2004 ywm = f;
2005 if (f < 0.00001)
2006 ywm = 0.00001;
2007 }
2008
2010 ywm = f;
2011 if (f < 0.00001)
2012 ywm = 0.00001;
2013 }
2014
2015 else {
2016 if (ywm == 0)
2017 ywm = 1;
2018 }
2019
2020 //calculation of gradient vector
2021 for (j = 0, k = 0; j < fNPeaks; j++) {
2022 if (fFixAmp[j] == false) {
2023 a = Deramp2(i1, i2,
2024 working_space[7 * j + 1],
2025 working_space[7 * j + 2],
2031 working_space[peak_vel + 12],
2032 working_space[peak_vel + 13]);
2033 if (ywm != 0) {
2034 c = Ourpowl(a, pw);
2036 b = a * (yw * yw - f * f) / (ywm * ywm);
2037 working_space[2 * shift + k] += b * c; //der
2038 b = a * a * (4 * yw - 2 * f) / (ywm * ywm);
2039 working_space[3 * shift + k] += b * c; //temp
2040 }
2041
2042 else {
2043 b = a * (yw - f) / ywm;
2044 working_space[2 * shift + k] += b * c; //der
2045 b = a * a / ywm;
2046 working_space[3 * shift + k] += b * c; //temp
2047 }
2048 }
2049 k += 1;
2050 }
2051 if (fFixPositionX[j] == false) {
2052 a = Deri02(i1, i2,
2053 working_space[7 * j],
2054 working_space[7 * j + 1],
2055 working_space[7 * j + 2],
2061 working_space[peak_vel + 12],
2062 working_space[peak_vel + 13]);
2064 d = Derderi02(i1, i2,
2065 working_space[7 * j],
2066 working_space[7 * j + 1],
2067 working_space[7 * j + 2],
2070 working_space[peak_vel + 2]);
2071 if (ywm != 0) {
2072 c = Ourpowl(a, pw);
2073 if (TMath::Abs(a) > 0.00000001
2075 d = d * TMath::Abs(yw - f) / (2 * a * ywm);
2076 if (((a + d) <= 0 && a >= 0) || ((a + d) >= 0
2077 && a <= 0))
2078 d = 0;
2079 }
2080
2081 else
2082 d = 0;
2083 a = a + d;
2085 b = a * (yw * yw - f * f) / (ywm * ywm);
2086 working_space[2 * shift + k] += b * c; //der
2087 b = a * a * (4 * yw - 2 * f) / (ywm * ywm);
2088 working_space[3 * shift + k] += b * c; //temp
2089 }
2090
2091 else {
2092 b = a * (yw - f) / ywm;
2093 working_space[2 * shift + k] += b * c; //der
2094 b = a * a / ywm;
2095 working_space[3 * shift + k] += b * c; //temp
2096 }
2097 }
2098 k += 1;
2099 }
2100 if (fFixPositionY[j] == false) {
2101 a = Derj02(i1, i2,
2102 working_space[7 * j],
2103 working_space[7 * j + 1],
2104 working_space[7 * j + 2],
2110 working_space[peak_vel + 12],
2111 working_space[peak_vel + 13]);
2113 d = Derderj02(i1, i2,
2114 working_space[7 * j],
2115 working_space[7 * j + 1],
2116 working_space[7 * j + 2],
2119 working_space[peak_vel + 2]);
2120 if (ywm != 0) {
2121 c = Ourpowl(a, pw);
2122 if (TMath::Abs(a) > 0.00000001
2124 d = d * TMath::Abs(yw - f) / (2 * a * ywm);
2125 if (((a + d) <= 0 && a >= 0) || ((a + d) >= 0
2126 && a <= 0))
2127 d = 0;
2128 }
2129
2130 else
2131 d = 0;
2132 a = a + d;
2134 b = a * (yw * yw - f * f) / (ywm * ywm);
2135 working_space[2 * shift + k] += b * c; //der
2136 b = a * a * (4 * yw - 2 * f) / (ywm * ywm);
2137 working_space[3 * shift + k] += b * c; //temp
2138 }
2139
2140 else {
2141 b = a * (yw - f) / ywm;
2142 working_space[2 * shift + k] += b * c; //der
2143 b = a * a / ywm;
2144 working_space[3 * shift + k] += b * c; //temp
2145 }
2146 }
2147 k += 1;
2148 }
2149 if (fFixAmpX1[j] == false) {
2150 a = Derampx(i1, working_space[7 * j + 5],
2153 working_space[peak_vel + 10],
2154 working_space[peak_vel + 12]);
2155 if (ywm != 0) {
2156 c = Ourpowl(a, pw);
2158 b = a * (yw * yw - f * f) / (ywm * ywm);
2159 working_space[2 * shift + k] += b * c; //der
2160 b = a * a * (4 * yw - 2 * f) / (ywm * ywm);
2161 working_space[3 * shift + k] += b * c; //temp
2162 }
2163
2164 else {
2165 b = a * (yw - f) / ywm;
2166 working_space[2 * shift + k] += b * c; //der
2167 b = a * a / ywm;
2168 working_space[3 * shift + k] += b * c; //temp
2169 }
2170 }
2171 k += 1;
2172 }
2173 if (fFixAmpY1[j] == false) {
2174 a = Derampx(i2, working_space[7 * j + 6],
2177 working_space[peak_vel + 11],
2178 working_space[peak_vel + 13]);
2179 if (ywm != 0) {
2180 c = Ourpowl(a, pw);
2182 b = a * (yw * yw - f * f) / (ywm * ywm);
2183 working_space[2 * shift + k] += b * c; //der
2184 b = a * a * (4 * yw - 2 * f) / (ywm * ywm);
2185 working_space[3 * shift + k] += b * c; //temp
2186 }
2187
2188 else {
2189 b = a * (yw - f) / ywm;
2190 working_space[2 * shift + k] += b * c; //der
2191 b = a * a / ywm;
2192 working_space[3 * shift + k] += b * c; //temp
2193 }
2194 }
2195 k += 1;
2196 }
2197 if (fFixPositionX1[j] == false) {
2198 a = Deri01(i1, working_space[7 * j + 3],
2199 working_space[7 * j + 5],
2202 working_space[peak_vel + 10],
2203 working_space[peak_vel + 12]);
2205 d = Derderi01(i1, working_space[7 * j + 3],
2206 working_space[7 * j + 5],
2208 if (ywm != 0) {
2209 c = Ourpowl(a, pw);
2210 if (TMath::Abs(a) > 0.00000001
2212 d = d * TMath::Abs(yw - f) / (2 * a * ywm);
2213 if (((a + d) <= 0 && a >= 0) || ((a + d) >= 0
2214 && a <= 0))
2215 d = 0;
2216 }
2217
2218 else
2219 d = 0;
2220 a = a + d;
2222 b = a * (yw * yw - f * f) / (ywm * ywm);
2223 working_space[2 * shift + k] += b * c; //Der
2224 b = a * a * (4 * yw - 2 * f) / (ywm * ywm);
2225 working_space[3 * shift + k] += b * c; //temp
2226 }
2227
2228 else {
2229 b = a * (yw - f) / ywm;
2230 working_space[2 * shift + k] += b * c; //Der
2231 b = a * a / ywm;
2232 working_space[3 * shift + k] += b * c; //temp
2233 }
2234 }
2235 k += 1;
2236 }
2237 if (fFixPositionY1[j] == false) {
2238 a = Deri01(i2, working_space[7 * j + 4],
2239 working_space[7 * j + 6],
2242 working_space[peak_vel + 11],
2243 working_space[peak_vel + 13]);
2245 d = Derderi01(i2, working_space[7 * j + 4],
2246 working_space[7 * j + 6],
2247 working_space[peak_vel + 1]);
2248 if (ywm != 0) {
2249 c = Ourpowl(a, pw);
2250 if (TMath::Abs(a) > 0.00000001
2252 d = d * TMath::Abs(yw - f) / (2 * a * ywm);
2253 if (((a + d) <= 0 && a >= 0) || ((a + d) >= 0
2254 && a <= 0))
2255 d = 0;
2256 }
2257
2258 else
2259 d = 0;
2260 a = a + d;
2262 b = a * (yw * yw - f * f) / (ywm * ywm);
2263 working_space[2 * shift + k] += b * c; //der
2264 b = a * a * (4 * yw - 2 * f) / (ywm * ywm);
2265 working_space[3 * shift + k] += b * c; //temp
2266 }
2267
2268 else {
2269 b = a * (yw - f) / ywm;
2270 working_space[2 * shift + k] += b * c; //der
2271 b = a * a / ywm;
2272 working_space[3 * shift + k] += b * c; //temp
2273 }
2274 }
2275 k += 1;
2276 }
2277 }
2278 if (fFixSigmaX == false) {
2279 a = Dersigmax(fNPeaks, i1, i2,
2286 working_space[peak_vel + 10],
2287 working_space[peak_vel + 12],
2288 working_space[peak_vel + 13]);
2294 working_space[peak_vel + 2]);
2295 if (ywm != 0) {
2296 c = Ourpowl(a, pw);
2297 if (TMath::Abs(a) > 0.00000001
2299 d = d * TMath::Abs(yw - f) / (2 * a * ywm);
2300 if (((a + d) <= 0 && a >= 0) || ((a + d) >= 0 && a <= 0))
2301 d = 0;
2302 }
2303
2304 else
2305 d = 0;
2306 a = a + d;
2308 b = a * (yw * yw - f * f) / (ywm * ywm);
2309 working_space[2 * shift + k] += b * c; //der
2310 b = a * a * (4 * yw - 2 * f) / (ywm * ywm);
2311 working_space[3 * shift + k] += b * c; //temp
2312 }
2313
2314 else {
2315 b = a * (yw - f) / ywm;
2316 working_space[2 * shift + k] += b * c; //der
2317 b = a * a / ywm;
2318 working_space[3 * shift + k] += b * c; //temp
2319 }
2320 }
2321 k += 1;
2322 }
2323 if (fFixSigmaY == false) {
2324 a = Dersigmay(fNPeaks, i1, i2,
2331 working_space[peak_vel + 11],
2332 working_space[peak_vel + 12],
2333 working_space[peak_vel + 13]);
2339 working_space[peak_vel + 2]);
2340 if (ywm != 0) {
2341 c = Ourpowl(a, pw);
2342 if (TMath::Abs(a) > 0.00000001
2344 d = d * TMath::Abs(yw - f) / (2 * a * ywm);
2345 if (((a + d) <= 0 && a >= 0) || ((a + d) >= 0 && a <= 0))
2346 d = 0;
2347 }
2348
2349 else
2350 d = 0;
2351 a = a + d;
2353 b = a * (yw * yw - f * f) / (ywm * ywm);
2354 working_space[2 * shift + k] += b * c; //der
2355 b = a * a * (4 * yw - 2 * f) / (ywm * ywm);
2356 working_space[3 * shift + k] += b * c; //temp
2357 }
2358
2359 else {
2360 b = a * (yw - f) / ywm;
2361 working_space[2 * shift + k] += b * c; //der
2362 b = a * a / ywm;
2363 working_space[3 * shift + k] += b * c; //temp
2364 }
2365 }
2366 k += 1;
2367 }
2368 if (fFixRo == false) {
2369 a = Derro(fNPeaks, i1, i2,
2372 working_space[peak_vel + 2]);
2373 if (ywm != 0) {
2374 c = Ourpowl(a, pw);
2375 if (TMath::Abs(a) > 0.00000001
2377 d = d * TMath::Abs(yw - f) / (2 * a * ywm);
2378 if (((a + d) <= 0 && a >= 0) || ((a + d) >= 0 && a <= 0))
2379 d = 0;
2380 }
2381
2382 else
2383 d = 0;
2384 a = a + d;
2386 b = a * (yw * yw - f * f) / (ywm * ywm);
2387 working_space[2 * shift + k] += b * c; //der
2388 b = a * a * (4 * yw - 2 * f) / (ywm * ywm);
2389 working_space[3 * shift + k] += b * c; //temp
2390 }
2391
2392 else {
2393 b = a * (yw - f) / ywm;
2394 working_space[2 * shift + k] += b * c; //der
2395 b = a * a / ywm;
2396 working_space[3 * shift + k] += b * c; //temp
2397 }
2398 }
2399 k += 1;
2400 }
2401 if (fFixA0 == false) {
2402 a = 1.;
2403 if (ywm != 0) {
2404 c = Ourpowl(a, pw);
2406 b = a * (yw * yw - f * f) / (ywm * ywm);
2407 working_space[2 * shift + k] += b * c; //der
2408 b = a * a * (4 * yw - 2 * f) / (ywm * ywm);
2409 working_space[3 * shift + k] += b * c; //temp
2410 }
2411
2412 else {
2413 b = a * (yw - f) / ywm;
2414 working_space[2 * shift + k] += b * c; //der
2415 b = a * a / ywm;
2416 working_space[3 * shift + k] += b * c; //temp
2417 }
2418 }
2419 k += 1;
2420 }
2421 if (fFixAx == false) {
2422 a = i1;
2423 if (ywm != 0) {
2424 c = Ourpowl(a, pw);
2426 b = a * (yw * yw - f * f) / (ywm * ywm);
2427 working_space[2 * shift + k] += b * c; //der
2428 b = a * a * (4 * yw - 2 * f) / (ywm * ywm);
2429 working_space[3 * shift + k] += b * c; //temp
2430 }
2431
2432 else {
2433 b = a * (yw - f) / ywm;
2434 working_space[2 * shift + k] += b * c; //der
2435 b = a * a / ywm;
2436 working_space[3 * shift + k] += b * c; //temp
2437 }
2438 }
2439 k += 1;
2440 }
2441 if (fFixAy == false) {
2442 a = i2;
2443 if (ywm != 0) {
2444 c = Ourpowl(a, pw);
2446 b = a * (yw * yw - f * f) / (ywm * ywm);
2447 working_space[2 * shift + k] += b * c; //der
2448 b = a * a * (4 * yw - 2 * f) / (ywm * ywm);
2449 working_space[3 * shift + k] += b * c; //temp
2450 }
2451
2452 else {
2453 b = a * (yw - f) / ywm;
2454 working_space[2 * shift + k] += b * c; //der
2455 b = a * a / ywm;
2456 working_space[3 * shift + k] += b * c; //temp
2457 }
2458 }
2459 k += 1;
2460 }
2461 if (fFixTxy == false) {
2462 a = Dertxy(fNPeaks, i1, i2,
2465 working_space[peak_vel + 12],
2466 working_space[peak_vel + 13]);
2467 if (ywm != 0) {
2468 c = Ourpowl(a, pw);
2470 b = a * (yw * yw - f * f) / (ywm * ywm);
2471 working_space[2 * shift + k] += b * c; //der
2472 b = a * a * (4 * yw - 2 * f) / (ywm * ywm);
2473 working_space[3 * shift + k] += b * c; //temp
2474 }
2475
2476 else {
2477 b = a * (yw - f) / ywm;
2478 working_space[2 * shift + k] += b * c; //der
2479 b = a * a / ywm;
2480 working_space[3 * shift + k] += b * c; //temp
2481 }
2482 }
2483 k += 1;
2484 }
2485 if (fFixSxy == false) {
2486 a = Dersxy(fNPeaks, i1, i2,
2488 working_space[peak_vel + 1]);
2489 if (ywm != 0) {
2490 c = Ourpowl(a, pw);
2492 b = a * (yw * yw - f * f) / (ywm * ywm);
2493 working_space[2 * shift + k] += b * c; //der
2494 b = a * a * (4 * yw - 2 * f) / (ywm * ywm);
2495 working_space[3 * shift + k] += b * c; //temp
2496 }
2497
2498 else {
2499 b = a * (yw - f) / ywm;
2500 working_space[2 * shift + k] += b * c; //der
2501 b = a * a / ywm;
2502 working_space[3 * shift + k] += b * c; //temp
2503 }
2504 }
2505 k += 1;
2506 }
2507 if (fFixTx == false) {
2510 working_space[peak_vel + 12]);
2511 if (ywm != 0) {
2512 c = Ourpowl(a, pw);
2514 b = a * (yw * yw - f * f) / (ywm * ywm);
2515 working_space[2 * shift + k] += b * c; //der
2516 b = a * a * (4 * yw - 2 * f) / (ywm * ywm);
2517 working_space[3 * shift + k] += b * c; //temp
2518 }
2519
2520 else {
2521 b = a * (yw - f) / ywm;
2522 working_space[2 * shift + k] += b * c; //der
2523 b = a * a / ywm;
2524 working_space[3 * shift + k] += b * c; //temp
2525 }
2526 }
2527 k += 1;
2528 }
2529 if (fFixTy == false) {
2532 working_space[peak_vel + 13]);
2533 if (ywm != 0) {
2534 c = Ourpowl(a, pw);
2536 b = a * (yw * yw - f * f) / (ywm * ywm);
2537 working_space[2 * shift + k] += b * c; //der
2538 b = a * a * (4 * yw - 2 * f) / (ywm * ywm);
2539 working_space[3 * shift + k] += b * c; //temp
2540 }
2541
2542 else {
2543 b = a * (yw - f) / ywm;
2544 working_space[2 * shift + k] += b * c; //der
2545 b = a * a / ywm;
2546 working_space[3 * shift + k] += b * c; //temp
2547 }
2548 }
2549 k += 1;
2550 }
2551 if (fFixSx == false) {
2554 if (ywm != 0) {
2555 c = Ourpowl(a, pw);
2557 b = a * (yw * yw - f * f) / (ywm * ywm);
2558 working_space[2 * shift + k] += b * c; //der
2559 b = a * a * (4 * yw - 2 * f) / (ywm * ywm);
2560 working_space[3 * shift + k] += b * c; //temp
2561 }
2562
2563 else {
2564 b = a * (yw - f) / ywm;
2565 working_space[2 * shift + k] += b * c; //der
2566 b = a * a / ywm;
2567 working_space[3 * shift + k] += b * c; //temp
2568 }
2569 }
2570 k += 1;
2571 }
2572 if (fFixSy == false) {
2574 working_space[peak_vel + 1]);
2575 if (ywm != 0) {
2576 c = Ourpowl(a, pw);
2578 b = a * (yw * yw - f * f) / (ywm * ywm);
2579 working_space[2 * shift + k] += b * c; //der
2580 b = a * a * (4 * yw - 2 * f) / (ywm * ywm);
2581 working_space[3 * shift + k] += b * c; //temp
2582 }
2583
2584 else {
2585 b = a * (yw - f) / ywm;
2586 working_space[2 * shift + k] += b * c; //der
2587 b = a * a / ywm;
2588 working_space[3 * shift + k] += b * c; //temp
2589 }
2590 }
2591 k += 1;
2592 }
2593 if (fFixBx == false) {
2594 a = Derbx(fNPeaks, i1, i2,
2599 working_space[peak_vel + 12],
2600 working_space[peak_vel + 13]);
2601 if (ywm != 0) {
2602 c = Ourpowl(a, pw);
2604 b = a * (yw * yw - f * f) / (ywm * ywm);
2605 working_space[2 * shift + k] += b * c; //der
2606 b = a * a * (4 * yw - 2 * f) / (ywm * ywm);
2607 working_space[3 * shift + k] += b * c; //temp
2608 }
2609
2610 else {
2611 b = a * (yw - f) / ywm;
2612 working_space[2 * shift + k] += b * c; //der
2613 b = a * a / ywm;
2614 working_space[3 * shift + k] += b * c; //temp
2615 }
2616 }
2617 k += 1;
2618 }
2619 if (fFixBy == false) {
2620 a = Derby(fNPeaks, i1, i2,
2625 working_space[peak_vel + 12],
2626 working_space[peak_vel + 13]);
2627 if (ywm != 0) {
2628 c = Ourpowl(a, pw);
2630 b = a * (yw * yw - f * f) / (ywm * ywm);
2631 working_space[2 * shift + k] += b * c; //der
2632 b = a * a * (4 * yw - 2 * f) / (ywm * ywm);
2633 working_space[3 * shift + k] += b * c; //temp
2634 }
2635
2636 else {
2637 b = a * (yw - f) / ywm;
2638 working_space[2 * shift + k] += b * c; //der
2639 b = a * a / ywm;
2640 working_space[3 * shift + k] += b * c; //temp
2641 }
2642 }
2643 k += 1;
2644 }
2645 }
2646 }
2647 for (j = 0; j < size; j++) {
2648 if (TMath::Abs(working_space[3 * shift + j]) > 0.000001)
2649 working_space[2 * shift + j] = working_space[2 * shift + j] / TMath::Abs(working_space[3 * shift + j]); //der[j]=der[j]/temp[j]
2650 else
2651 working_space[2 * shift + j] = 0; //der[j]
2652 }
2653
2654 //calculate chi_opt
2655 chi2 = chi_opt;
2657
2658 //calculate new parameters
2659 regul_cycle = 0;
2660 for (j = 0; j < size; j++) {
2661 working_space[4 * shift + j] = working_space[shift + j]; //temp_xk[j]=xk[j]
2662 }
2663
2664 do {
2667 chi_min = 10000 * chi2;
2668
2669 else
2670 chi_min = 0.1 * chi2;
2671 flag = 0;
2672 for (pi = 0.1; flag == 0 && pi <= 100; pi += 0.1) {
2673 for (j = 0; j < size; j++) {
2674 working_space[shift + j] = working_space[4 * shift + j] + pi * alpha * working_space[2 * shift + j]; //xk[j]=temp_xk[j]+pi*alpha*der[j]
2675 }
2676 for (i = 0, j = 0; i < fNPeaks; i++) {
2677 if (fFixAmp[i] == false) {
2678 if (working_space[shift + j] < 0) //xk[j]
2679 working_space[shift + j] = 0; //xk[j]
2680 working_space[7 * i] = working_space[shift + j]; //parameter[7*i]=xk[j]
2681 j += 1;
2682 }
2683 if (fFixPositionX[i] == false) {
2684 if (working_space[shift + j] < fXmin) //xk[j]
2685 working_space[shift + j] = fXmin; //xk[j]
2686 if (working_space[shift + j] > fXmax) //xk[j]
2687 working_space[shift + j] = fXmax; //xk[j]
2688 working_space[7 * i + 1] = working_space[shift + j]; //parameter[7*i+1]=xk[j]
2689 j += 1;
2690 }
2691 if (fFixPositionY[i] == false) {
2692 if (working_space[shift + j] < fYmin) //xk[j]
2693 working_space[shift + j] = fYmin; //xk[j]
2694 if (working_space[shift + j] > fYmax) //xk[j]
2695 working_space[shift + j] = fYmax; //xk[j]
2696 working_space[7 * i + 2] = working_space[shift + j]; //parameter[7*i+2]=xk[j]
2697 j += 1;
2698 }
2699 if (fFixAmpX1[i] == false) {
2700 if (working_space[shift + j] < 0) //xk[j]
2701 working_space[shift + j] = 0; //xk[j]
2702 working_space[7 * i + 3] = working_space[shift + j]; //parameter[7*i+3]=xk[j]
2703 j += 1;
2704 }
2705 if (fFixAmpY1[i] == false) {
2706 if (working_space[shift + j] < 0) //xk[j]
2707 working_space[shift + j] = 0; //xk[j]
2708 working_space[7 * i + 4] = working_space[shift + j]; //parameter[7*i+4]=xk[j]
2709 j += 1;
2710 }
2711 if (fFixPositionX1[i] == false) {
2712 if (working_space[shift + j] < fXmin) //xk[j]
2713 working_space[shift + j] = fXmin; //xk[j]
2714 if (working_space[shift + j] > fXmax) //xk[j]
2715 working_space[shift + j] = fXmax; //xk[j]
2716 working_space[7 * i + 5] = working_space[shift + j]; //parameter[7*i+5]=xk[j]
2717 j += 1;
2718 }
2719 if (fFixPositionY1[i] == false) {
2720 if (working_space[shift + j] < fYmin) //xk[j]
2721 working_space[shift + j] = fYmin; //xk[j]
2722 if (working_space[shift + j] > fYmax) //xk[j]
2723 working_space[shift + j] = fYmax; //xk[j]
2724 working_space[7 * i + 6] = working_space[shift + j]; //parameter[7*i+6]=xk[j]
2725 j += 1;
2726 }
2727 }
2728 if (fFixSigmaX == false) {
2729 if (working_space[shift + j] < 0.001) { //xk[j]
2730 working_space[shift + j] = 0.001; //xk[j]
2731 }
2732 working_space[peak_vel] = working_space[shift + j]; //parameter[peak_vel]=xk[j]
2733 j += 1;
2734 }
2735 if (fFixSigmaY == false) {
2736 if (working_space[shift + j] < 0.001) { //xk[j]
2737 working_space[shift + j] = 0.001; //xk[j]
2738 }
2739 working_space[peak_vel + 1] = working_space[shift + j]; //parameter[peak_vel+1]=xk[j]
2740 j += 1;
2741 }
2742 if (fFixRo == false) {
2743 if (working_space[shift + j] < -1) { //xk[j]
2744 working_space[shift + j] = -1; //xk[j]
2745 }
2746 if (working_space[shift + j] > 1) { //xk[j]
2747 working_space[shift + j] = 1; //xk[j]
2748 }
2749 working_space[peak_vel + 2] = working_space[shift + j]; //parameter[peak_vel+2]=xk[j]
2750 j += 1;
2751 }
2752 if (fFixA0 == false) {
2753 working_space[peak_vel + 3] = working_space[shift + j]; //parameter[peak_vel+3]=xk[j]
2754 j += 1;
2755 }
2756 if (fFixAx == false) {
2757 working_space[peak_vel + 4] = working_space[shift + j]; //parameter[peak_vel+4]=xk[j]
2758 j += 1;
2759 }
2760 if (fFixAy == false) {
2761 working_space[peak_vel + 5] = working_space[shift + j]; //parameter[peak_vel+5]=xk[j]
2762 j += 1;
2763 }
2764 if (fFixTxy == false) {
2765 working_space[peak_vel + 6] = working_space[shift + j]; //parameter[peak_vel+6]=xk[j]
2766 j += 1;
2767 }
2768 if (fFixSxy == false) {
2769 working_space[peak_vel + 7] = working_space[shift + j]; //parameter[peak_vel+7]=xk[j]
2770 j += 1;
2771 }
2772 if (fFixTx == false) {
2773 working_space[peak_vel + 8] = working_space[shift + j]; //parameter[peak_vel+8]=xk[j]
2774 j += 1;
2775 }
2776 if (fFixTy == false) {
2777 working_space[peak_vel + 9] = working_space[shift + j]; //parameter[peak_vel+9]=xk[j]
2778 j += 1;
2779 }
2780 if (fFixSx == false) {
2781 working_space[peak_vel + 10] = working_space[shift + j]; //parameter[peak_vel+10]=xk[j]
2782 j += 1;
2783 }
2784 if (fFixSy == false) {
2785 working_space[peak_vel + 11] = working_space[shift + j]; //parameter[peak_vel+11]=xk[j]
2786 j += 1;
2787 }
2788 if (fFixBx == false) {
2789 if (TMath::Abs(working_space[shift + j]) < 0.001) { //xk[j]
2790 if (working_space[shift + j] < 0) //xk[j]
2791 working_space[shift + j] = -0.001; //xk[j]
2792 else
2793 working_space[shift + j] = 0.001; //xk[j]
2794 }
2795 working_space[peak_vel + 12] = working_space[shift + j]; //parameter[peak_vel+12]=xk[j]
2796 j += 1;
2797 }
2798 if (fFixBy == false) {
2799 if (TMath::Abs(working_space[shift + j]) < 0.001) { //xk[j]
2800 if (working_space[shift + j] < 0) //xk[j]
2801 working_space[shift + j] = -0.001; //xk[j]
2802 else
2803 working_space[shift + j] = 0.001; //xk[j]
2804 }
2805 working_space[peak_vel + 13] = working_space[shift + j]; //parameter[peak_vel+13]=xk[j]
2806 j += 1;
2807 }
2808 chi2 = 0;
2809 for (i1 = fXmin; i1 <= fXmax; i1++) {
2810 for (i2 = fYmin; i2 <= fYmax; i2++) {
2811 yw = source[i1][i2];
2812 ywm = yw;
2813 f = Shape2(fNPeaks, i1,
2825 working_space[peak_vel + 10],
2826 working_space[peak_vel + 11],
2827 working_space[peak_vel + 12],
2828 working_space[peak_vel + 13]);
2830 ywm = f;
2831 if (f < 0.00001)
2832 ywm = 0.00001;
2833 }
2835 if (f > 0.00001)
2836 chi2 += yw * TMath::Log(f) - f;
2837 }
2838
2839 else {
2840 if (ywm != 0)
2841 chi2 += (yw - f) * (yw - f) / ywm;
2842 }
2843 }
2844 }
2845 if ((chi2 < chi_min
2847 || (chi2 > chi_min
2849 pmin = pi, chi_min = chi2;
2850 }
2851
2852 else
2853 flag = 1;
2854 if (pi == 0.1)
2855 chi_min = chi2;
2856 chi = chi_min;
2857 }
2858 if (pmin != 0.1) {
2859 for (j = 0; j < size; j++) {
2860 working_space[shift + j] = working_space[4 * shift + j] + pmin * alpha * working_space[2 * shift + j]; //xk[j]=temp_xk[j]+pmin*alpha*der[j]
2861 }
2862 for (i = 0, j = 0; i < fNPeaks; i++) {
2863 if (fFixAmp[i] == false) {
2864 if (working_space[shift + j] < 0) //xk[j]
2865 working_space[shift + j] = 0; //xk[j]
2866 working_space[7 * i] = working_space[shift + j]; //parameter[7*i]=xk[j]
2867 j += 1;
2868 }
2869 if (fFixPositionX[i] == false) {
2870 if (working_space[shift + j] < fXmin) //xk[j]
2871 working_space[shift + j] = fXmin; //xk[j]
2872 if (working_space[shift + j] > fXmax) //xk[j]
2873 working_space[shift + j] = fXmax; //xk[j]
2874 working_space[7 * i + 1] = working_space[shift + j]; //parameter[7*i+1]=xk[j]
2875 j += 1;
2876 }
2877 if (fFixPositionY[i] == false) {
2878 if (working_space[shift + j] < fYmin) //xk[j]
2879 working_space[shift + j] = fYmin; //xk[j]
2880 if (working_space[shift + j] > fYmax) //xk[j]
2881 working_space[shift + j] = fYmax; //xk[j]
2882 working_space[7 * i + 2] = working_space[shift + j]; //parameter[7*i+2]=xk[j]
2883 j += 1;
2884 }
2885 if (fFixAmpX1[i] == false) {
2886 if (working_space[shift + j] < 0) //xk[j]
2887 working_space[shift + j] = 0; //xk[j]
2888 working_space[7 * i + 3] = working_space[shift + j]; //parameter[7*i+3]=xk[j]
2889 j += 1;
2890 }
2891 if (fFixAmpY1[i] == false) {
2892 if (working_space[shift + j] < 0) //xk[j]
2893 working_space[shift + j] = 0; //xk[j]
2894 working_space[7 * i + 4] = working_space[shift + j]; //parameter[7*i+4]=xk[j]
2895 j += 1;
2896 }
2897 if (fFixPositionX1[i] == false) {
2898 if (working_space[shift + j] < fXmin) //xk[j]
2899 working_space[shift + j] = fXmin; //xk[j]
2900 if (working_space[shift + j] > fXmax) //xk[j]
2901 working_space[shift + j] = fXmax; //xk[j]
2902 working_space[7 * i + 5] = working_space[shift + j]; //parameter[7*i+5]=xk[j]
2903 j += 1;
2904 }
2905 if (fFixPositionY1[i] == false) {
2906 if (working_space[shift + j] < fYmin) //xk[j]
2907 working_space[shift + j] = fYmin; //xk[j]
2908 if (working_space[shift + j] > fYmax) //xk[j]
2909 working_space[shift + j] = fYmax; //xk[j]
2910 working_space[7 * i + 6] = working_space[shift + j]; //parameter[7*i+6]=xk[j]
2911 j += 1;
2912 }
2913 }
2914 if (fFixSigmaX == false) {
2915 if (working_space[shift + j] < 0.001) { //xk[j]
2916 working_space[shift + j] = 0.001; //xk[j]
2917 }
2918 working_space[peak_vel] = working_space[shift + j]; //parameter[peak_vel]=xk[j]
2919 j += 1;
2920 }
2921 if (fFixSigmaY == false) {
2922 if (working_space[shift + j] < 0.001) { //xk[j]
2923 working_space[shift + j] = 0.001; //xk[j]
2924 }
2925 working_space[peak_vel + 1] = working_space[shift + j]; //parameter[peak_vel+1]=xk[j]
2926 j += 1;
2927 }
2928 if (fFixRo == false) {
2929 if (working_space[shift + j] < -1) { //xk[j]
2930 working_space[shift + j] = -1; //xk[j]
2931 }
2932 if (working_space[shift + j] > 1) { //xk[j]
2933 working_space[shift + j] = 1; //xk[j]
2934 }
2935 working_space[peak_vel + 2] = working_space[shift + j]; //parameter[peak_vel+2]=xk[j]
2936 j += 1;
2937 }
2938 if (fFixA0 == false) {
2939 working_space[peak_vel + 3] = working_space[shift + j]; //parameter[peak_vel+3]=xk[j]
2940 j += 1;
2941 }
2942 if (fFixAx == false) {
2943 working_space[peak_vel + 4] = working_space[shift + j]; //parameter[peak_vel+4]=xk[j]
2944 j += 1;
2945 }
2946 if (fFixAy == false) {
2947 working_space[peak_vel + 5] = working_space[shift + j]; //parameter[peak_vel+5]=xk[j]
2948 j += 1;
2949 }
2950 if (fFixTxy == false) {
2951 working_space[peak_vel + 6] = working_space[shift + j]; //parameter[peak_vel+6]=xk[j]
2952 j += 1;
2953 }
2954 if (fFixSxy == false) {
2955 working_space[peak_vel + 7] = working_space[shift + j]; //parameter[peak_vel+7]=xk[j]
2956 j += 1;
2957 }
2958 if (fFixTx == false) {
2959 working_space[peak_vel + 8] = working_space[shift + j]; //parameter[peak_vel+8]=xk[j]
2960 j += 1;
2961 }
2962 if (fFixTy == false) {
2963 working_space[peak_vel + 9] = working_space[shift + j]; //parameter[peak_vel+9]=xk[j]
2964 j += 1;
2965 }
2966 if (fFixSx == false) {
2967 working_space[peak_vel + 10] = working_space[shift + j]; //parameter[peak_vel+10]=xk[j]
2968 j += 1;
2969 }
2970 if (fFixSy == false) {
2971 working_space[peak_vel + 11] = working_space[shift + j]; //parameter[peak_vel+11]=xk[j]
2972 j += 1;
2973 }
2974 if (fFixBx == false) {
2975 if (TMath::Abs(working_space[shift + j]) < 0.001) { //xk[j]
2976 if (working_space[shift + j] < 0) //xk[j]
2977 working_space[shift + j] = -0.001; //xk[j]
2978 else
2979 working_space[shift + j] = 0.001; //xk[j]
2980 }
2981 working_space[peak_vel + 12] = working_space[shift + j]; //parameter[peak_vel+12]=xk[j]
2982 j += 1;
2983 }
2984 if (fFixBy == false) {
2985 if (TMath::Abs(working_space[shift + j]) < 0.001) { //xk[j]
2986 if (working_space[shift + j] < 0) //xk[j]
2987 working_space[shift + j] = -0.001; //xk[j]
2988 else
2989 working_space[shift + j] = 0.001; //xk[j]
2990 }
2991 working_space[peak_vel + 13] = working_space[shift + j]; //parameter[peak_vel+13]=xk[j]
2992 j += 1;
2993 }
2994 chi = chi_min;
2995 }
2996 }
2997
2998 else {
2999 for (j = 0; j < size; j++) {
3000 working_space[shift + j] = working_space[4 * shift + j] + alpha * working_space[2 * shift + j]; //xk[j]=temp_xk[j]+pi*alpha*der[j]
3001 }
3002 for (i = 0, j = 0; i < fNPeaks; i++) {
3003 if (fFixAmp[i] == false) {
3004 if (working_space[shift + j] < 0) //xk[j]
3005 working_space[shift + j] = 0; //xk[j]
3006 working_space[7 * i] = working_space[shift + j]; //parameter[7*i]=xk[j]
3007 j += 1;
3008 }
3009 if (fFixPositionX[i] == false) {
3010 if (working_space[shift + j] < fXmin) //xk[j]
3011 working_space[shift + j] = fXmin; //xk[j]
3012 if (working_space[shift + j] > fXmax) //xk[j]
3013 working_space[shift + j] = fXmax; //xk[j]
3014 working_space[7 * i + 1] = working_space[shift + j]; //parameter[7*i+1]=xk[j]
3015 j += 1;
3016 }
3017 if (fFixPositionY[i] == false) {
3018 if (working_space[shift + j] < fYmin) //xk[j]
3019 working_space[shift + j] = fYmin; //xk[j]
3020 if (working_space[shift + j] > fYmax) //xk[j]
3021 working_space[shift + j] = fYmax; //xk[j]
3022 working_space[7 * i + 2] = working_space[shift + j]; //parameter[7*i+2]=xk[j]
3023 j += 1;
3024 }
3025 if (fFixAmpX1[i] == false) {
3026 if (working_space[shift + j] < 0) //xk[j]
3027 working_space[shift + j] = 0; //xk[j]
3028 working_space[7 * i + 3] = working_space[shift + j]; //parameter[7*i+3]=xk[j]
3029 j += 1;
3030 }
3031 if (fFixAmpY1[i] == false) {
3032 if (working_space[shift + j] < 0) //xk[j]
3033 working_space[shift + j] = 0; //xk[j]
3034 working_space[7 * i + 4] = working_space[shift + j]; //parameter[7*i+4]=xk[j]
3035 j += 1;
3036 }
3037 if (fFixPositionX1[i] == false) {
3038 if (working_space[shift + j] < fXmin) //xk[j]
3039 working_space[shift + j] = fXmin; //xk[j]
3040 if (working_space[shift + j] > fXmax) //xk[j]
3041 working_space[shift + j] = fXmax; //xk[j]
3042 working_space[7 * i + 5] = working_space[shift + j]; //parameter[7*i+5]=xk[j]
3043 j += 1;
3044 }
3045 if (fFixPositionY1[i] == false) {
3046 if (working_space[shift + j] < fYmin) //xk[j]
3047 working_space[shift + j] = fYmin; //xk[j]
3048 if (working_space[shift + j] > fYmax) //xk[j]
3049 working_space[shift + j] = fYmax; //xk[j]
3050 working_space[7 * i + 6] = working_space[shift + j]; //parameter[7*i+6]=xk[j]
3051 j += 1;
3052 }
3053 }
3054 if (fFixSigmaX == false) {
3055 if (working_space[shift + j] < 0.001) { //xk[j]
3056 working_space[shift + j] = 0.001; //xk[j]
3057 }
3058 working_space[peak_vel] = working_space[shift + j]; //parameter[peak_vel]=xk[j]
3059 j += 1;
3060 }
3061 if (fFixSigmaY == false) {
3062 if (working_space[shift + j] < 0.001) { //xk[j]
3063 working_space[shift + j] = 0.001; //xk[j]
3064 }
3065 working_space[peak_vel + 1] = working_space[shift + j]; //parameter[peak_vel+1]=xk[j]
3066 j += 1;
3067 }
3068 if (fFixRo == false) {
3069 if (working_space[shift + j] < -1) { //xk[j]
3070 working_space[shift + j] = -1; //xk[j]
3071 }
3072 if (working_space[shift + j] > 1) { //xk[j]
3073 working_space[shift + j] = 1; //xk[j]
3074 }
3075 working_space[peak_vel + 2] = working_space[shift + j]; //parameter[peak_vel+2]=xk[j]
3076 j += 1;
3077 }
3078 if (fFixA0 == false) {
3079 working_space[peak_vel + 3] = working_space[shift + j]; //parameter[peak_vel+3]=xk[j]
3080 j += 1;
3081 }
3082 if (fFixAx == false) {
3083 working_space[peak_vel + 4] = working_space[shift + j]; //parameter[peak_vel+4]=xk[j]
3084 j += 1;
3085 }
3086 if (fFixAy == false) {
3087 working_space[peak_vel + 5] = working_space[shift + j]; //parameter[peak_vel+5]=xk[j]
3088 j += 1;
3089 }
3090 if (fFixTxy == false) {
3091 working_space[peak_vel + 6] = working_space[shift + j]; //parameter[peak_vel+6]=xk[j]
3092 j += 1;
3093 }
3094 if (fFixSxy == false) {
3095 working_space[peak_vel + 7] = working_space[shift + j]; //parameter[peak_vel+7]=xk[j]
3096 j += 1;
3097 }
3098 if (fFixTx == false) {
3099 working_space[peak_vel + 8] = working_space[shift + j]; //parameter[peak_vel+8]=xk[j]
3100 j += 1;
3101 }
3102 if (fFixTy == false) {
3103 working_space[peak_vel + 9] = working_space[shift + j]; //parameter[peak_vel+9]=xk[j]
3104 j += 1;
3105 }
3106 if (fFixSx == false) {
3107 working_space[peak_vel + 10] = working_space[shift + j]; //parameter[peak_vel+10]=xk[j]
3108 j += 1;
3109 }
3110 if (fFixSy == false) {
3111 working_space[peak_vel + 11] = working_space[shift + j]; //parameter[peak_vel+11]=xk[j]
3112 j += 1;
3113 }
3114 if (fFixBx == false) {
3115 if (TMath::Abs(working_space[shift + j]) < 0.001) { //xk[j]
3116 if (working_space[shift + j] < 0) //xk[j]
3117 working_space[shift + j] = -0.001; //xk[j]
3118 else
3119 working_space[shift + j] = 0.001; //xk[j]
3120 }
3121 working_space[peak_vel + 12] = working_space[shift + j]; //parameter[peak_vel+12]=xk[j]
3122 j += 1;
3123 }
3124 if (fFixBy == false) {
3125 if (TMath::Abs(working_space[shift + j]) < 0.001) { //xk[j]
3126 if (working_space[shift + j] < 0) //xk[j]
3127 working_space[shift + j] = -0.001; //xk[j]
3128 else
3129 working_space[shift + j] = 0.001; //xk[j]
3130 }
3131 working_space[peak_vel + 13] = working_space[shift + j]; //parameter[peak_vel+13]=xk[j]
3132 j += 1;
3133 }
3134 chi = 0;
3135 for (i1 = fXmin; i1 <= fXmax; i1++) {
3136 for (i2 = fYmin; i2 <= fYmax; i2++) {
3137 yw = source[i1][i2];
3138 ywm = yw;
3139 f = Shape2(fNPeaks, i1, i2,
3150 working_space[peak_vel + 10],
3151 working_space[peak_vel + 11],
3152 working_space[peak_vel + 12],
3153 working_space[peak_vel + 13]);
3155 ywm = f;
3156 if (f < 0.00001)
3157 ywm = 0.00001;
3158 }
3160 if (f > 0.00001)
3161 chi += yw * TMath::Log(f) - f;
3162 }
3163
3164 else {
3165 if (ywm != 0)
3166 chi += (yw - f) * (yw - f) / ywm;
3167 }
3168 }
3169 }
3170 }
3171 chi2 = chi;
3173 if (fAlphaOptim == kFitAlphaHalving && chi > 1E-6)
3174 alpha = alpha * chi_opt / (2 * chi);
3175
3176 else if (fAlphaOptim == kFitAlphaOptimal)
3177 alpha = alpha / 10.0;
3178 iter += 1;
3179 regul_cycle += 1;
3180 } while (((chi > chi_opt
3182 || (chi < chi_opt
3185 for (j = 0; j < size; j++) {
3186 working_space[4 * shift + j] = 0; //temp_xk[j]
3187 working_space[2 * shift + j] = 0; //der[j]
3188 }
3189 for (i1 = fXmin, chi_cel = 0; i1 <= fXmax; i1++) {
3190 for (i2 = fYmin; i2 <= fYmax; i2++) {
3191 yw = source[i1][i2];
3192 if (yw == 0)
3193 yw = 1;
3194 f = Shape2(fNPeaks, i1, i2,
3205 working_space[peak_vel + 10],
3206 working_space[peak_vel + 11],
3207 working_space[peak_vel + 12],
3208 working_space[peak_vel + 13]);
3209 chi_opt = (yw - f) * (yw - f) / yw;
3210 chi_cel += (yw - f) * (yw - f) / yw;
3211
3212 //calculate gradient vector
3213 for (j = 0, k = 0; j < fNPeaks; j++) {
3214 if (fFixAmp[j] == false) {
3215 a = Deramp2(i1, i2,
3216 working_space[7 * j + 1],
3217 working_space[7 * j + 2],
3223 working_space[peak_vel + 12],
3224 working_space[peak_vel + 13]);
3225 if (yw != 0) {
3226 c = Ourpowl(a, pw);
3227 working_space[2 * shift + k] += chi_opt * c; //der[k]
3228 b = a * a / yw;
3229 working_space[4 * shift + k] += b * c; //temp_xk[k]
3230 }
3231 k += 1;
3232 }
3233 if (fFixPositionX[j] == false) {
3234 a = Deri02(i1, i2,
3235 working_space[7 * j],
3236 working_space[7 * j + 1],
3237 working_space[7 * j + 2],
3243 working_space[peak_vel + 12],
3244 working_space[peak_vel + 13]);
3245 if (yw != 0) {
3246 c = Ourpowl(a, pw);
3247 working_space[2 * shift + k] += chi_opt * c; //der[k]
3248 b = a * a / yw;
3249 working_space[4 * shift + k] += b * c; //temp_xk[k]
3250 }
3251 k += 1;
3252 }
3253 if (fFixPositionY[j] == false) {
3254 a = Derj02(i1, i2,
3255 working_space[7 * j],
3256 working_space[7 * j + 1],
3257 working_space[7 * j + 2],
3263 working_space[peak_vel + 12],
3264 working_space[peak_vel + 13]);
3265 if (yw != 0) {
3266 c = Ourpowl(a, pw);
3267 working_space[2 * shift + k] += chi_opt * c; //der[k]
3268 b = a * a / yw;
3269 working_space[4 * shift + k] += b * c; //temp_xk[k]
3270 }
3271 k += 1;
3272 }
3273 if (fFixAmpX1[j] == false) {
3274 a = Derampx(i1, working_space[7 * j + 5],
3277 working_space[peak_vel + 10],
3278 working_space[peak_vel + 12]);
3279 if (yw != 0) {
3280 c = Ourpowl(a, pw);
3281 working_space[2 * shift + k] += chi_opt * c; //der[k]
3282 b = a * a / yw;
3283 working_space[4 * shift + k] += b * c; //temp_xk[k]
3284 }
3285 k += 1;
3286 }
3287 if (fFixAmpY1[j] == false) {
3288 a = Derampx(i2, working_space[7 * j + 6],
3291 working_space[peak_vel + 11],
3292 working_space[peak_vel + 13]);
3293 if (yw != 0) {
3294 c = Ourpowl(a, pw);
3295 working_space[2 * shift + k] += chi_opt * c; //der[k]
3296 b = a * a / yw;
3297 working_space[4 * shift + k] += b * c; //temp_xk[k]
3298 }
3299 k += 1;
3300 }
3301 if (fFixPositionX1[j] == false) {
3302 a = Deri01(i1, working_space[7 * j + 3],
3303 working_space[7 * j + 5],
3306 working_space[peak_vel + 10],
3307 working_space[peak_vel + 12]);
3308 if (yw != 0) {
3309 c = Ourpowl(a, pw);
3310 working_space[2 * shift + k] += chi_opt * c; //der[k]
3311 b = a * a / yw;
3312 working_space[4 * shift + k] += b * c; //temp_xk[k]
3313 }
3314 k += 1;
3315 }
3316 if (fFixPositionY1[j] == false) {
3317 a = Deri01(i2, working_space[7 * j + 4],
3318 working_space[7 * j + 6],
3321 working_space[peak_vel + 11],
3322 working_space[peak_vel + 13]);
3323 if (yw != 0) {
3324 c = Ourpowl(a, pw);
3325 working_space[2 * shift + k] += chi_opt * c; //der[k]
3326 b = a * a / yw;
3327 working_space[4 * shift + k] += b * c; //temp_xk[k]
3328 }
3329 k += 1;
3330 }
3331 }
3332 if (fFixSigmaX == false) {
3333 a = Dersigmax(fNPeaks, i1, i2,
3340 working_space[peak_vel + 10],
3341 working_space[peak_vel + 12],
3342 working_space[peak_vel + 13]);
3343 if (yw != 0) {
3344 c = Ourpowl(a, pw);
3345 working_space[2 * shift + k] += chi_opt * c; //der[k]
3346 b = a * a / yw;
3347 working_space[4 * shift + k] += b * c; //temp_xk[k]
3348 }
3349 k += 1;
3350 }
3351 if (fFixSigmaY == false) {
3352 a = Dersigmay(fNPeaks, i1, i2,
3359 working_space[peak_vel + 11],
3360 working_space[peak_vel + 12],
3361 working_space[peak_vel + 13]);
3362 if (yw != 0) {
3363 c = Ourpowl(a, pw);
3364 working_space[2 * shift + k] += chi_opt * c; //der[k]
3365 b = a * a / yw;
3366 working_space[4 * shift + k] += b * c; //temp_xk[k]
3367 }
3368 k += 1;
3369 }
3370 if (fFixRo == false) {
3371 a = Derro(fNPeaks, i1, i2,
3374 working_space[peak_vel + 2]);
3375 if (yw != 0) {
3376 c = Ourpowl(a, pw);
3377 working_space[2 * shift + k] += chi_opt * c; //der[k]
3378 b = a * a / yw;
3379 working_space[4 * shift + k] += b * c; //temp_xk[k]
3380 }
3381 k += 1;
3382 }
3383 if (fFixA0 == false) {
3384 a = 1.;
3385 if (yw != 0) {
3386 c = Ourpowl(a, pw);
3387 working_space[2 * shift + k] += chi_opt * c; //der[k]
3388 b = a * a / yw;
3389 working_space[4 * shift + k] += b * c; //temp_xk[k]
3390 }
3391 k += 1;
3392 }
3393 if (fFixAx == false) {
3394 a = i1;
3395 if (yw != 0) {
3396 c = Ourpowl(a, pw);
3397 working_space[2 * shift + k] += chi_opt * c; //der[k]
3398 b = a * a / yw;
3399 working_space[4 * shift + k] += b * c; //temp_xk[k]
3400 }
3401 k += 1;
3402 }
3403 if (fFixAy == false) {
3404 a = i2;
3405 if (yw != 0) {
3406 c = Ourpowl(a, pw);
3407 working_space[2 * shift + k] += chi_opt * c; //der[k]
3408 b = a * a / yw;
3409 working_space[4 * shift + k] += b * c; //temp_xk[k]
3410 }
3411 k += 1;
3412 }
3413 if (fFixTxy == false) {
3414 a = Dertxy(fNPeaks, i1, i2,
3417 working_space[peak_vel + 12],
3418 working_space[peak_vel + 13]);
3419 if (yw != 0) {
3420 c = Ourpowl(a, pw);
3421 working_space[2 * shift + k] += chi_opt * c; //der[k]
3422 b = a * a / yw;
3423 working_space[4 * shift + k] += b * c; //temp_xk[k]
3424 }
3425 k += 1;
3426 }
3427 if (fFixSxy == false) {
3428 a = Dersxy(fNPeaks, i1, i2,
3430 working_space[peak_vel + 1]);
3431 if (yw != 0) {
3432 c = Ourpowl(a, pw);
3433 working_space[2 * shift + k] += chi_opt * c; //der[k]
3434 b = a * a / yw;
3435 working_space[4 * shift + k] += b * c; //temp_xk[k]
3436 }
3437 k += 1;
3438 }
3439 if (fFixTx == false) {
3442 working_space[peak_vel + 12]);
3443 if (yw != 0) {
3444 c = Ourpowl(a, pw);
3445 working_space[2 * shift + k] += chi_opt * c; //der[k]
3446 b = a * a / yw;
3447 working_space[4 * shift + k] += b * c; //temp_xk[k]
3448 }
3449 k += 1;
3450 }
3451 if (fFixTy == false) {
3454 working_space[peak_vel + 13]);
3455 if (yw != 0) {
3456 c = Ourpowl(a, pw);
3457 working_space[2 * shift + k] += chi_opt * c; //der[k]
3458 b = a * a / yw;
3459 working_space[4 * shift + k] += b * c; //temp_xk[k]
3460 }
3461 k += 1;
3462 }
3463 if (fFixSx == false) {
3466 if (yw != 0) {
3467 c = Ourpowl(a, pw);
3468 working_space[2 * shift + k] += chi_opt * c; //der[k]
3469 b = a * a / yw;
3470 working_space[4 * shift + k] += b * c; //temp_xk[k]
3471 }
3472 k += 1;
3473 }
3474 if (fFixSy == false) {
3476 working_space[peak_vel + 1]);
3477 if (yw != 0) {
3478 c = Ourpowl(a, pw);
3479 working_space[2 * shift + k] += chi_opt * c; //der[k]
3480 b = a * a / yw;
3481 working_space[4 * shift + k] += b * c; //temp_xk[k]
3482 }
3483 k += 1;
3484 }
3485 if (fFixBx == false) {
3486 a = Derbx(fNPeaks, i1, i2,
3491 working_space[peak_vel + 12],
3492 working_space[peak_vel + 13]);
3493 if (yw != 0) {
3494 c = Ourpowl(a, pw);
3495 working_space[2 * shift + k] += chi_opt * c; //der[k]
3496 b = a * a / yw;
3497 working_space[4 * shift + k] += b * c; //temp_xk[k]
3498 }
3499 k += 1;
3500 }
3501 if (fFixBy == false) {
3502 a = Derby(fNPeaks, i1, i2,
3507 working_space[peak_vel + 12],
3508 working_space[peak_vel + 13]);
3509 if (yw != 0) {
3510 c = Ourpowl(a, pw);
3511 working_space[2 * shift + k] += chi_opt * c; //der[k]
3512 b = a * a / yw;
3513 working_space[4 * shift + k] += b * c; //temp_xk[k]
3514 }
3515 k += 1;
3516 }
3517 }
3518 }
3519 }
3520 b = (fXmax - fXmin + 1) * (fYmax - fYmin + 1) - size;
3521 chi_er = chi_cel / b;
3522 for (i = 0, j = 0; i < fNPeaks; i++) {
3523 fVolume[i] =
3526 if (fVolume[i] > 0) {
3527 c = 0;
3528 if (fFixAmp[i] == false) {
3531 working_space[peak_vel + 2]);
3532 b = working_space[4 * shift + j]; //temp_xk[j]
3533 if (b == 0)
3534 b = 1;
3535
3536 else
3537 b = 1 / b;
3538 c = c + a * a * b;
3539 }
3540 if (fFixSigmaX == false) {
3541 a = Derpsigmax(working_space[shift + j],
3543 working_space[peak_vel + 2]);
3544 b = working_space[4 * shift + peak_vel]; //temp_xk[j]
3545 if (b == 0)
3546 b = 1;
3547
3548 else
3549 b = 1 / b;
3550 c = c + a * a * b;
3551 }
3552 if (fFixSigmaY == false) {
3553 a = Derpsigmay(working_space[shift + j],
3555 working_space[peak_vel + 2]);
3556 b = working_space[4 * shift + peak_vel + 1]; //temp_xk[j]
3557 if (b == 0)
3558 b = 1;
3559
3560 else
3561 b = 1 / b;
3562 c = c + a * a * b;
3563 }
3564 if (fFixRo == false) {
3567 working_space[peak_vel + 2]);
3568 b = working_space[4 * shift + peak_vel + 2]; //temp_xk[j]
3569 if (b == 0)
3570 b = 1;
3571
3572 else
3573 b = 1 / b;
3574 c = c + a * a * b;
3575 }
3577 }
3578
3579 else {
3580 fVolumeErr[i] = 0;
3581 }
3582 if (fFixAmp[i] == false) {
3583 fAmpCalc[i] = working_space[shift + j]; //xk[j]
3584 if (working_space[3 * shift + j] != 0)
3585 fAmpErr[i] = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
3586 j += 1;
3587 }
3588
3589 else {
3590 fAmpCalc[i] = fAmpInit[i];
3591 fAmpErr[i] = 0;
3592 }
3593 if (fFixPositionX[i] == false) {
3594 fPositionCalcX[i] = working_space[shift + j]; //xk[j]
3595 if (working_space[3 * shift + j] != 0)
3596 fPositionErrX[i] = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
3597 j += 1;
3598 }
3599
3600 else {
3602 fPositionErrX[i] = 0;
3603 }
3604 if (fFixPositionY[i] == false) {
3605 fPositionCalcY[i] = working_space[shift + j]; //xk[j]
3606 if (working_space[3 * shift + j] != 0)
3607 fPositionErrY[i] = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
3608 j += 1;
3609 }
3610
3611 else {
3613 fPositionErrY[i] = 0;
3614 }
3615 if (fFixAmpX1[i] == false) {
3616 fAmpCalcX1[i] = working_space[shift + j]; //xk[j]
3617 if (working_space[3 * shift + j] != 0)
3618 fAmpErrX1[i] = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
3619 j += 1;
3620 }
3621
3622 else {
3623 fAmpCalcX1[i] = fAmpInitX1[i];
3624 fAmpErrX1[i] = 0;
3625 }
3626 if (fFixAmpY1[i] == false) {
3627 fAmpCalcY1[i] = working_space[shift + j]; //xk[j]
3628 if (working_space[3 * shift + j] != 0)
3629 fAmpErrY1[i] = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
3630 j += 1;
3631 }
3632
3633 else {
3634 fAmpCalcY1[i] = fAmpInitY1[i];
3635 fAmpErrY1[i] = 0;
3636 }
3637 if (fFixPositionX1[i] == false) {
3638 fPositionCalcX1[i] = working_space[shift + j]; //xk[j]
3639 if (working_space[3 * shift + j] != 0)
3640 fPositionErrX1[i] = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
3641 j += 1;
3642 }
3643
3644 else {
3646 fPositionErrX1[i] = 0;
3647 }
3648 if (fFixPositionY1[i] == false) {
3649 fPositionCalcY1[i] = working_space[shift + j]; //xk[j]
3650 if (working_space[3 * shift + j] != 0)
3651 fPositionErrY1[i] = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
3652 j += 1;
3653 }
3654
3655 else {
3657 fPositionErrY1[i] = 0;
3658 }
3659 }
3660 if (fFixSigmaX == false) {
3661 fSigmaCalcX = working_space[shift + j]; //xk[j]
3662 if (working_space[3 * shift + j] != 0) //temp[j]
3663 fSigmaErrX = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
3664 j += 1;
3665 }
3666
3667 else {
3669 fSigmaErrX = 0;
3670 }
3671 if (fFixSigmaY == false) {
3672 fSigmaCalcY = working_space[shift + j]; //xk[j]
3673 if (working_space[3 * shift + j] != 0) //temp[j]
3674 fSigmaErrY = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
3675 j += 1;
3676 }
3677
3678 else {
3680 fSigmaErrY = 0;
3681 }
3682 if (fFixRo == false) {
3683 fRoCalc = working_space[shift + j]; //xk[j]
3684 if (working_space[3 * shift + j] != 0) //temp[j]
3685 fRoErr = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
3686 j += 1;
3687 }
3688
3689 else {
3690 fRoCalc = fRoInit;
3691 fRoErr = 0;
3692 }
3693 if (fFixA0 == false) {
3694 fA0Calc = working_space[shift + j]; //xk[j]
3695 if (working_space[3 * shift + j] != 0) //temp[j]
3696 fA0Err = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
3697 j += 1;
3698 }
3699
3700 else {
3701 fA0Calc = fA0Init;
3702 fA0Err = 0;
3703 }
3704 if (fFixAx == false) {
3705 fAxCalc = working_space[shift + j]; //xk[j]
3706 if (working_space[3 * shift + j] != 0) //temp[j]
3707 fAxErr = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
3708 j += 1;
3709 }
3710
3711 else {
3712 fAxCalc = fAxInit;
3713 fAxErr = 0;
3714 }
3715 if (fFixAy == false) {
3716 fAyCalc = working_space[shift + j]; //xk[j]
3717 if (working_space[3 * shift + j] != 0) //temp[j]
3718 fAyErr = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
3719 j += 1;
3720 }
3721
3722 else {
3723 fAyCalc = fAyInit;
3724 fAyErr = 0;
3725 }
3726 if (fFixTxy == false) {
3727 fTxyCalc = working_space[shift + j]; //xk[j]
3728 if (working_space[3 * shift + j] != 0) //temp[j]
3729 fTxyErr = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
3730 j += 1;
3731 }
3732
3733 else {
3735 fTxyErr = 0;
3736 }
3737 if (fFixSxy == false) {
3738 fSxyCalc = working_space[shift + j]; //xk[j]
3739 if (working_space[3 * shift + j] != 0) //temp[j]
3740 fSxyErr = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
3741 j += 1;
3742 }
3743
3744 else {
3746 fSxyErr = 0;
3747 }
3748 if (fFixTx == false) {
3749 fTxCalc = working_space[shift + j]; //xk[j]
3750 if (working_space[3 * shift + j] != 0) //temp[j]
3751 fTxErr = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
3752 j += 1;
3753 }
3754
3755 else {
3756 fTxCalc = fTxInit;
3757 fTxErr = 0;
3758 }
3759 if (fFixTy == false) {
3760 fTyCalc = working_space[shift + j]; //xk[j]
3761 if (working_space[3 * shift + j] != 0) //temp[j]
3762 fTyErr = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
3763 j += 1;
3764 }
3765
3766 else {
3767 fTyCalc = fTyInit;
3768 fTyErr = 0;
3769 }
3770 if (fFixSx == false) {
3771 fSxCalc = working_space[shift + j]; //xk[j]
3772 if (working_space[3 * shift + j] != 0) //temp[j]
3773 fSxErr = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
3774 j += 1;
3775 }
3776
3777 else {
3778 fSxCalc = fSxInit;
3779 fSxErr = 0;
3780 }
3781 if (fFixSy == false) {
3782 fSyCalc = working_space[shift + j]; //xk[j]
3783 if (working_space[3 * shift + j] != 0) //temp[j]
3784 fSyErr = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
3785 j += 1;
3786 }
3787
3788 else {
3789 fSyCalc = fSyInit;
3790 fSyErr = 0;
3791 }
3792 if (fFixBx == false) {
3793 fBxCalc = working_space[shift + j]; //xk[j]
3794 if (working_space[3 * shift + j] != 0) //temp[j]
3795 fBxErr = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
3796 j += 1;
3797 }
3798
3799 else {
3800 fBxCalc = fBxInit;
3801 fBxErr = 0;
3802 }
3803 if (fFixBy == false) {
3804 fByCalc = working_space[shift + j]; //xk[j]
3805 if (working_space[3 * shift + j] != 0) //temp[j]
3806 fByErr = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
3807 j += 1;
3808 }
3809
3810 else {
3811 fByCalc = fByInit;
3812 fByErr = 0;
3813 }
3814 b = (fXmax - fXmin + 1) * (fYmax - fYmin + 1) - size;
3815 fChi = chi_cel / b;
3816 for (i1 = fXmin; i1 <= fXmax; i1++) {
3817 for (i2 = fYmin; i2 <= fYmax; i2++) {
3818 f = Shape2(fNPeaks, i1, i2,
3829 working_space[peak_vel + 10],
3830 working_space[peak_vel + 11],
3831 working_space[peak_vel + 12],
3832 working_space[peak_vel + 13]);
3833 source[i1][i2] = f;
3834 }
3835 }
3836 delete [] working_space;
3837 return;
3838}
3839
3840
3841
3842////////////////////////////////////////////////////////////////////////////////
3843/// This function fits the source spectrum. The calling program should
3844/// fill in input parameters of the TSpectrum2Fit class.
3845/// The fitted parameters are written into
3846/// TSpectrum2Fit class output parameters and fitted data are written into
3847/// source spectrum.
3848///
3849/// Function parameters:
3850/// - source-pointer to the matrix of source spectrum
3851///
3852/// ### Stiefel fitting algorithm
3853///
3854/// This function fits the source
3855/// spectrum using Stiefel-Hestens method [1]. The calling program should fill in
3856/// input fitting parameters of the TSpectrumFit2 class using a set of
3857/// TSpectrumFit2 setters. The fitted parameters are written into the class and the
3858/// fitted data are written into source spectrum. It converges faster than Awmi
3859/// method.
3860///
3861/// #### Reference:
3862///
3863/// [1] B. Mihaila: Analysis of
3864/// complex gamma spectra, Rom. Jorn. Phys., Vol. 39, No. 2, (1994), 139-148.
3865///
3866/// Example 1 - script FitS.c:
3867///
3868/// \image html spectrum2fit_stiefel_image001.jpg Fig. 1 Original two-dimensional spectrum with found peaks (using TSpectrum2 peak searching function). The positions of peaks were used as initial estimates in fitting procedure.
3869///
3870/// \image html spectrum2fit_stiefel_image002.jpg Fig. 2 Fitted (generated from fitted parameters) spectrum of the data from Fig. 1 using Stiefel-Hestens method. Each peak was represented by 7 parameters, which together with Sigmax, Sigmay and a0 resulted in 38 fitted parameters. The chi-square after 1000 iterations was 0.642157.
3871///
3872/// #### Script:
3873///
3874/// Example to illustrate fitting function, algorithm without matrix inversion (AWMI) (class
3875/// TSpectrumFit2). To execute this example, do
3876///
3877/// `root > .x FitStiefel2.C`
3878///
3879/// ~~~ {.cpp}
3880/// void FitStiefel2() {
3881/// Int_t i, j, nfound;
3882/// Int_t nbinsx = 64;
3883/// Int_t nbinsy = 64;
3884/// Int_t xmin = 0;
3885/// Int_t xmax = nbinsx;
3886/// Int_t ymin = 0;
3887/// Int_t ymax = nbinsy;
3888/// Double_t ** source = new float *[nbinsx];
3889/// Double_t ** dest = new float *[nbinsx];
3890/// for (i=0;i<nbinsx;i++)
3891/// source[i]=new float[nbinsy];
3892/// for (i=0;i<nbinsx;i++)
3893/// dest[i]= new float[nbinsy];
3894/// TH2F *search = new TH2F("search","High resolution peak searching",nbinsx,xmin,xmax,nbinsy,ymin,ymax);
3895/// TFile *f = new TFile("TSpectrum2.root");
3896/// search=(TH2F*)f->Get("search4;1");
3897/// TCanvas *Searching = new TCanvas("Searching","Two-dimensional fitting using Stiefel-Hestens method",10,10,1000,700);
3898/// TSpectrum2 *s = new TSpectrum2();
3899/// for (i = 0; i < nbinsx; i++){
3900/// for (j = 0; j < nbinsy; j++){
3901/// source[i][j] = search->GetBinContent(i + 1,j + 1);
3902/// }
3903/// }
3904/// nfound = s->SearchHighRes(source, dest, nbinsx, nbinsy, 2, 5, kTRUE, 3, kFALSE, 3);
3905/// printf("Found %d candidate peaks\n",nfound);
3906/// Bool_t *FixPosX = new Bool_t[nfound];
3907/// Bool_t *FixPosY = new Bool_t[nfound];
3908/// Bool_t *FixAmp = new Bool_t[nfound];
3909/// Double_t *PosX = new Double_t[nfound];
3910/// Double_t *PosY = new Double_t[nfound];
3911/// Double_t *Amp = new Double_t[nfound];
3912/// Double_t *AmpXY = new Double_t[nfound];
3913/// PosX = s->GetPositionX();
3914/// PosY = s->GetPositionY();
3915/// for(i = 0; i< nfound ; i++){
3916/// FixPosX[i] = kFALSE;
3917/// FixPosY[i] = kFALSE;
3918/// FixAmp[i] = kFALSE;
3919/// Amp[i] = source[(Int_t)(PosX[i]+0.5)][(Int_t)(PosY[i]+0.5)]; //initial values of peaks amplitudes, input parameters
3920/// AmpXY[i] = 0;
3921/// }
3922/// //filling in the initial estimates of the input parameters
3923/// TSpectrumFit2 *pfit=new
3924/// TSpectrumFit2(nfound);
3925/// pfit->SetFitParameters(xmin, xmax-1, ymin, ymax-1, 1000, 0.1,
3926/// pfit->kFitOptimChiCounts, pfit->kFitAlphaHalving, pfit->kFitPower2,
3927/// pfit->kFitTaylorOrderFirst);
3928/// pfit->SetPeakParameters(2, kFALSE, 2, kFALSE, 0, kTRUE, PosX, (Bool_t *)
3929/// FixPosX, PosY, (Bool_t *) FixPosY, PosX, (Bool_t *) FixPosX, PosY, (Bool_t *)
3930/// FixPosY, Amp, (Bool_t *) FixAmp, AmpXY, (Bool_t *) FixAmp, AmpXY, (Bool_t *)
3931/// FixAmp);
3932/// pfit->SetBackgroundParameters(0, kFALSE, 0, kTRUE, 0, kTRUE);
3933/// pfit->FitStiefel(source);
3934/// for (i = 0; i < nbinsx; i++){
3935/// for (j = 0; j < nbinsy; j++){
3936/// search->SetBinContent(i + 1, j + 1,source[i][j]);
3937/// }
3938/// }
3939/// search->Draw("SURF");
3940/// }
3941/// ~~~
3942
3944{
3945
3946 Int_t i, i1, i2, j, k, shift =
3947 7 * fNPeaks + 14, peak_vel, size, iter, regul_cycle,
3948 flag;
3949 Double_t a, b, c, alpha, chi_opt, yw, ywm, f, chi2, chi_min, chi = 0
3950 , pi, pmin = 0, chi_cel = 0, chi_er;
3951 Double_t *working_space = new Double_t[5 * (7 * fNPeaks + 14)];
3952 for (i = 0, j = 0; i < fNPeaks; i++) {
3953 working_space[7 * i] = fAmpInit[i]; //vector parameter
3954 if (fFixAmp[i] == false) {
3955 working_space[shift + j] = fAmpInit[i]; //vector xk
3956 j += 1;
3957 }
3958 working_space[7 * i + 1] = fPositionInitX[i]; //vector parameter
3959 if (fFixPositionX[i] == false) {
3960 working_space[shift + j] = fPositionInitX[i]; //vector xk
3961 j += 1;
3962 }
3963 working_space[7 * i + 2] = fPositionInitY[i]; //vector parameter
3964 if (fFixPositionY[i] == false) {
3965 working_space[shift + j] = fPositionInitY[i]; //vector xk
3966 j += 1;
3967 }
3968 working_space[7 * i + 3] = fAmpInitX1[i]; //vector parameter
3969 if (fFixAmpX1[i] == false) {
3970 working_space[shift + j] = fAmpInitX1[i]; //vector xk
3971 j += 1;
3972 }
3973 working_space[7 * i + 4] = fAmpInitY1[i]; //vector parameter
3974 if (fFixAmpY1[i] == false) {
3975 working_space[shift + j] = fAmpInitY1[i]; //vector xk
3976 j += 1;
3977 }
3978 working_space[7 * i + 5] = fPositionInitX1[i]; //vector parameter
3979 if (fFixPositionX1[i] == false) {
3980 working_space[shift + j] = fPositionInitX1[i]; //vector xk
3981 j += 1;
3982 }
3983 working_space[7 * i + 6] = fPositionInitY1[i]; //vector parameter
3984 if (fFixPositionY1[i] == false) {
3985 working_space[shift + j] = fPositionInitY1[i]; //vector xk
3986 j += 1;
3987 }
3988 }
3989 peak_vel = 7 * i;
3990 working_space[7 * i] = fSigmaInitX; //vector parameter
3991 if (fFixSigmaX == false) {
3992 working_space[shift + j] = fSigmaInitX; //vector xk
3993 j += 1;
3994 }
3995 working_space[7 * i + 1] = fSigmaInitY; //vector parameter
3996 if (fFixSigmaY == false) {
3997 working_space[shift + j] = fSigmaInitY; //vector xk
3998 j += 1;
3999 }
4000 working_space[7 * i + 2] = fRoInit; //vector parameter
4001 if (fFixRo == false) {
4002 working_space[shift + j] = fRoInit; //vector xk
4003 j += 1;
4004 }
4005 working_space[7 * i + 3] = fA0Init; //vector parameter
4006 if (fFixA0 == false) {
4007 working_space[shift + j] = fA0Init; //vector xk
4008 j += 1;
4009 }
4010 working_space[7 * i + 4] = fAxInit; //vector parameter
4011 if (fFixAx == false) {
4012 working_space[shift + j] = fAxInit; //vector xk
4013 j += 1;
4014 }
4015 working_space[7 * i + 5] = fAyInit; //vector parameter
4016 if (fFixAy == false) {
4017 working_space[shift + j] = fAyInit; //vector xk
4018 j += 1;
4019 }
4020 working_space[7 * i + 6] = fTxyInit; //vector parameter
4021 if (fFixTxy == false) {
4022 working_space[shift + j] = fTxyInit; //vector xk
4023 j += 1;
4024 }
4025 working_space[7 * i + 7] = fSxyInit; //vector parameter
4026 if (fFixSxy == false) {
4027 working_space[shift + j] = fSxyInit; //vector xk
4028 j += 1;
4029 }
4030 working_space[7 * i + 8] = fTxInit; //vector parameter
4031 if (fFixTx == false) {
4032 working_space[shift + j] = fTxInit; //vector xk
4033 j += 1;
4034 }
4035 working_space[7 * i + 9] = fTyInit; //vector parameter
4036 if (fFixTy == false) {
4037 working_space[shift + j] = fTyInit; //vector xk
4038 j += 1;
4039 }
4040 working_space[7 * i + 10] = fSxyInit; //vector parameter
4041 if (fFixSx == false) {
4042 working_space[shift + j] = fSxInit; //vector xk
4043 j += 1;
4044 }
4045 working_space[7 * i + 11] = fSyInit; //vector parameter
4046 if (fFixSy == false) {
4047 working_space[shift + j] = fSyInit; //vector xk
4048 j += 1;
4049 }
4050 working_space[7 * i + 12] = fBxInit; //vector parameter
4051 if (fFixBx == false) {
4052 working_space[shift + j] = fBxInit; //vector xk
4053 j += 1;
4054 }
4055 working_space[7 * i + 13] = fByInit; //vector parameter
4056 if (fFixBy == false) {
4057 working_space[shift + j] = fByInit; //vector xk
4058 j += 1;
4059 }
4060 size = j;
4062 for (i = 0; i < size; i++)
4063 working_matrix[i] = new Double_t[size + 4];
4064 for (iter = 0; iter < fNumberIterations; iter++) {
4065 for (j = 0; j < size; j++) {
4066 working_space[3 * shift + j] = 0; //temp
4067 for (k = 0; k < (size + 4); k++) {
4068 working_matrix[j][k] = 0;
4069 }
4070 }
4071
4072 //filling working matrix
4073 alpha = fAlpha;
4074 chi_opt = 0;
4075 for (i1 = fXmin; i1 <= fXmax; i1++) {
4076 for (i2 = fYmin; i2 <= fYmax; i2++) {
4077 //calculation of gradient vector
4078 for (j = 0, k = 0; j < fNPeaks; j++) {
4079 if (fFixAmp[j] == false) {
4080 working_space[2 * shift + k] =
4081 Deramp2(i1, i2,
4082 working_space[7 * j + 1],
4083 working_space[7 * j + 2],
4089 working_space[peak_vel + 12],
4090 working_space[peak_vel + 13]);
4091 k += 1;
4092 }
4093 if (fFixPositionX[j] == false) {
4094 working_space[2 * shift + k] =
4095 Deri02(i1, i2,
4096 working_space[7 * j],
4097 working_space[7 * j + 1],
4098 working_space[7 * j + 2],
4104 working_space[peak_vel + 12],
4105 working_space[peak_vel + 13]);
4106 k += 1;
4107 }
4108 if (fFixPositionY[j] == false) {
4109 working_space[2 * shift + k] =
4110 Derj02(i1, i2,
4111 working_space[7 * j],
4112 working_space[7 * j + 1],
4113 working_space[7 * j + 2],
4119 working_space[peak_vel + 12],
4120 working_space[peak_vel + 13]);
4121 k += 1;
4122 }
4123 if (fFixAmpX1[j] == false) {
4124 working_space[2 * shift + k] =
4125 Derampx(i1, working_space[7 * j + 5],
4128 working_space[peak_vel + 10],
4129 working_space[peak_vel + 12]);
4130 k += 1;
4131 }
4132 if (fFixAmpY1[j] == false) {
4133 working_space[2 * shift + k] =
4134 Derampx(i2, working_space[7 * j + 6],
4137 working_space[peak_vel + 11],
4138 working_space[peak_vel + 13]);
4139 k += 1;
4140 }
4141 if (fFixPositionX1[j] == false) {
4142 working_space[2 * shift + k] =
4143 Deri01(i1, working_space[7 * j + 3],
4144 working_space[7 * j + 5],
4147 working_space[peak_vel + 10],
4148 working_space[peak_vel + 12]);
4149 k += 1;
4150 }
4151 if (fFixPositionY1[j] == false) {
4152 working_space[2 * shift + k] =
4153 Deri01(i2, working_space[7 * j + 4],
4154 working_space[7 * j + 6],
4157 working_space[peak_vel + 11],
4158 working_space[peak_vel + 13]);
4159 k += 1;
4160 }
4161 } if (fFixSigmaX == false) {
4162 working_space[2 * shift + k] =
4170 working_space[peak_vel + 10],
4171 working_space[peak_vel + 12],
4172 working_space[peak_vel + 13]);
4173 k += 1;
4174 }
4175 if (fFixSigmaY == false) {
4176 working_space[2 * shift + k] =
4184 working_space[peak_vel + 11],
4185 working_space[peak_vel + 12],
4186 working_space[peak_vel + 13]);
4187 k += 1;
4188 }
4189 if (fFixRo == false) {
4190 working_space[2 * shift + k] =
4191 Derro(fNPeaks, i1, i2,
4194 working_space[peak_vel + 2]);
4195 k += 1;
4196 }
4197 if (fFixA0 == false) {
4198 working_space[2 * shift + k] = 1.;
4199 k += 1;
4200 }
4201 if (fFixAx == false) {
4202 working_space[2 * shift + k] = i1;
4203 k += 1;
4204 }
4205 if (fFixAy == false) {
4206 working_space[2 * shift + k] = i2;
4207 k += 1;
4208 }
4209 if (fFixTxy == false) {
4210 working_space[2 * shift + k] =
4211 Dertxy(fNPeaks, i1, i2,
4214 working_space[peak_vel + 12],
4215 working_space[peak_vel + 13]);
4216 k += 1;
4217 }
4218 if (fFixSxy == false) {
4219 working_space[2 * shift + k] =
4220 Dersxy(fNPeaks, i1, i2,
4222 working_space[peak_vel + 1]);
4223 k += 1;
4224 }
4225 if (fFixTx == false) {
4226 working_space[2 * shift + k] =
4229 working_space[peak_vel + 12]);
4230 k += 1;
4231 }
4232 if (fFixTy == false) {
4233 working_space[2 * shift + k] =
4236 working_space[peak_vel + 13]);
4237 k += 1;
4238 }
4239 if (fFixSx == false) {
4240 working_space[2 * shift + k] =
4243 k += 1;
4244 }
4245 if (fFixSy == false) {
4246 working_space[2 * shift + k] =
4248 working_space[peak_vel + 1]);
4249 k += 1;
4250 }
4251 if (fFixBx == false) {
4252 working_space[2 * shift + k] =
4253 Derbx(fNPeaks, i1, i2,
4258 working_space[peak_vel + 12],
4259 working_space[peak_vel + 13]);
4260 k += 1;
4261 }
4262 if (fFixBy == false) {
4263 working_space[2 * shift + k] =
4264 Derby(fNPeaks, i1, i2,
4269 working_space[peak_vel + 12],
4270 working_space[peak_vel + 13]);
4271 k += 1;
4272 }
4273 yw = source[i1][i2];
4274 ywm = yw;
4275 f = Shape2(fNPeaks, i1, i2,
4286 working_space[peak_vel + 10],
4287 working_space[peak_vel + 11],
4288 working_space[peak_vel + 12],
4289 working_space[peak_vel + 13]);
4291 if (f > 0.00001)
4292 chi_opt += yw * TMath::Log(f) - f;
4293 }
4294
4295 else {
4296 if (ywm != 0)
4297 chi_opt += (yw - f) * (yw - f) / ywm;
4298 }
4300 ywm = f;
4301 if (f < 0.00001)
4302 ywm = 0.00001;
4303 }
4304
4306 ywm = f;
4307 if (f < 0.00001)
4308 ywm = 0.00001;
4309 }
4310
4311 else {
4312 if (ywm == 0)
4313 ywm = 1;
4314 }
4315 for (j = 0; j < size; j++) {
4316 for (k = 0; k < size; k++) {
4317 b = working_space[2 * shift +
4318 j] * working_space[2 * shift +
4319 k] / ywm;
4321 b = b * (4 * yw - 2 * f) / ywm;
4322 working_matrix[j][k] += b;
4323 if (j == k)
4324 working_space[3 * shift + j] += b;
4325 }
4326 }
4328 b = (f * f - yw * yw) / (ywm * ywm);
4329
4330 else
4331 b = (f - yw) / ywm;
4332 for (j = 0; j < size; j++) {
4333 working_matrix[j][size] -=
4334 b * working_space[2 * shift + j];
4335 }
4336 }
4337 }
4338 for (i = 0; i < size; i++) {
4339 working_matrix[i][size + 1] = 0; //xk
4340 }
4342 for (i = 0; i < size; i++) {
4343 working_space[2 * shift + i] = working_matrix[i][size + 1]; //der
4344 }
4345
4346 //calculate chi_opt
4347 chi2 = chi_opt;
4349
4350 //calculate new parameters
4351 regul_cycle = 0;
4352 for (j = 0; j < size; j++) {
4353 working_space[4 * shift + j] = working_space[shift + j]; //temp_xk[j]=xk[j]
4354 }
4355
4356 do {
4359 chi_min = 10000 * chi2;
4360
4361 else
4362 chi_min = 0.1 * chi2;
4363 flag = 0;
4364 for (pi = 0.1; flag == 0 && pi <= 100; pi += 0.1) {
4365 for (j = 0; j < size; j++) {
4366 working_space[shift + j] = working_space[4 * shift + j] + pi * alpha * working_space[2 * shift + j]; //xk[j]=temp_xk[j]+pi*alpha*der[j]
4367 }
4368 for (i = 0, j = 0; i < fNPeaks; i++) {
4369 if (fFixAmp[i] == false) {
4370 if (working_space[shift + j] < 0) //xk[j]
4371 working_space[shift + j] = 0; //xk[j]
4372 working_space[7 * i] = working_space[shift + j]; //parameter[7*i]=xk[j]
4373 j += 1;
4374 }
4375 if (fFixPositionX[i] == false) {
4376 if (working_space[shift + j] < fXmin) //xk[j]
4377 working_space[shift + j] = fXmin; //xk[j]
4378 if (working_space[shift + j] > fXmax) //xk[j]
4379 working_space[shift + j] = fXmax; //xk[j]
4380 working_space[7 * i + 1] = working_space[shift + j]; //parameter[7*i+1]=xk[j]
4381 j += 1;
4382 }
4383 if (fFixPositionY[i] == false) {
4384 if (working_space[shift + j] < fYmin) //xk[j]
4385 working_space[shift + j] = fYmin; //xk[j]
4386 if (working_space[shift + j] > fYmax) //xk[j]
4387 working_space[shift + j] = fYmax; //xk[j]
4388 working_space[7 * i + 2] = working_space[shift + j]; //parameter[7*i+2]=xk[j]
4389 j += 1;
4390 }
4391 if (fFixAmpX1[i] == false) {
4392 if (working_space[shift + j] < 0) //xk[j]
4393 working_space[shift + j] = 0; //xk[j]
4394 working_space[7 * i + 3] = working_space[shift + j]; //parameter[7*i+3]=xk[j]
4395 j += 1;
4396 }
4397 if (fFixAmpY1[i] == false) {
4398 if (working_space[shift + j] < 0) //xk[j]
4399 working_space[shift + j] = 0; //xk[j]
4400 working_space[7 * i + 4] = working_space[shift + j]; //parameter[7*i+4]=xk[j]
4401 j += 1;
4402 }
4403 if (fFixPositionX1[i] == false) {
4404 if (working_space[shift + j] < fXmin) //xk[j]
4405 working_space[shift + j] = fXmin; //xk[j]
4406 if (working_space[shift + j] > fXmax) //xk[j]
4407 working_space[shift + j] = fXmax; //xk[j]
4408 working_space[7 * i + 5] = working_space[shift + j]; //parameter[7*i+5]=xk[j]
4409 j += 1;
4410 }
4411 if (fFixPositionY1[i] == false) {
4412 if (working_space[shift + j] < fYmin) //xk[j]
4413 working_space[shift + j] = fYmin; //xk[j]
4414 if (working_space[shift + j] > fYmax) //xk[j]
4415 working_space[shift + j] = fYmax; //xk[j]
4416 working_space[7 * i + 6] = working_space[shift + j]; //parameter[7*i+6]=xk[j]
4417 j += 1;
4418 }
4419 }
4420 if (fFixSigmaX == false) {
4421 if (working_space[shift + j] < 0.001) { //xk[j]
4422 working_space[shift + j] = 0.001; //xk[j]
4423 }
4424 working_space[peak_vel] = working_space[shift + j]; //parameter[peak_vel]=xk[j]
4425 j += 1;
4426 }
4427 if (fFixSigmaY == false) {
4428 if (working_space[shift + j] < 0.001) { //xk[j]
4429 working_space[shift + j] = 0.001; //xk[j]
4430 }
4431 working_space[peak_vel + 1] = working_space[shift + j]; //parameter[peak_vel+1]=xk[j]
4432 j += 1;
4433 }
4434 if (fFixRo == false) {
4435 if (working_space[shift + j] < -1) { //xk[j]
4436 working_space[shift + j] = -1; //xk[j]
4437 }
4438 if (working_space[shift + j] > 1) { //xk[j]
4439 working_space[shift + j] = 1; //xk[j]
4440 }
4441 working_space[peak_vel + 2] = working_space[shift + j]; //parameter[peak_vel+2]=xk[j]
4442 j += 1;
4443 }
4444 if (fFixA0 == false) {
4445 working_space[peak_vel + 3] = working_space[shift + j]; //parameter[peak_vel+3]=xk[j]
4446 j += 1;
4447 }
4448 if (fFixAx == false) {
4449 working_space[peak_vel + 4] = working_space[shift + j]; //parameter[peak_vel+4]=xk[j]
4450 j += 1;
4451 }
4452 if (fFixAy == false) {
4453 working_space[peak_vel + 5] = working_space[shift + j]; //parameter[peak_vel+5]=xk[j]
4454 j += 1;
4455 }
4456 if (fFixTxy == false) {
4457 working_space[peak_vel + 6] = working_space[shift + j]; //parameter[peak_vel+6]=xk[j]
4458 j += 1;
4459 }
4460 if (fFixSxy == false) {
4461 working_space[peak_vel + 7] = working_space[shift + j]; //parameter[peak_vel+7]=xk[j]
4462 j += 1;
4463 }
4464 if (fFixTx == false) {
4465 working_space[peak_vel + 8] = working_space[shift + j]; //parameter[peak_vel+8]=xk[j]
4466 j += 1;
4467 }
4468 if (fFixTy == false) {
4469 working_space[peak_vel + 9] = working_space[shift + j]; //parameter[peak_vel+9]=xk[j]
4470 j += 1;
4471 }
4472 if (fFixSx == false) {
4473 working_space[peak_vel + 10] = working_space[shift + j]; //parameter[peak_vel+10]=xk[j]
4474 j += 1;
4475 }
4476 if (fFixSy == false) {
4477 working_space[peak_vel + 11] = working_space[shift + j]; //parameter[peak_vel+11]=xk[j]
4478 j += 1;
4479 }
4480 if (fFixBx == false) {
4481 if (TMath::Abs(working_space[shift + j]) < 0.001) { //xk[j]
4482 if (working_space[shift + j] < 0) //xk[j]
4483 working_space[shift + j] = -0.001; //xk[j]
4484 else
4485 working_space[shift + j] = 0.001; //xk[j]
4486 }
4487 working_space[peak_vel + 12] = working_space[shift + j]; //parameter[peak_vel+12]=xk[j]
4488 j += 1;
4489 }
4490 if (fFixBy == false) {
4491 if (TMath::Abs(working_space[shift + j]) < 0.001) { //xk[j]
4492 if (working_space[shift + j] < 0) //xk[j]
4493 working_space[shift + j] = -0.001; //xk[j]
4494 else
4495 working_space[shift + j] = 0.001; //xk[j]
4496 }
4497 working_space[peak_vel + 13] = working_space[shift + j]; //parameter[peak_vel+13]=xk[j]
4498 j += 1;
4499 }
4500 chi2 = 0;
4501 for (i1 = fXmin; i1 <= fXmax; i1++) {
4502 for (i2 = fYmin; i2 <= fYmax; i2++) {
4503 yw = source[i1][i2];
4504 ywm = yw;
4505 f = Shape2(fNPeaks, i1,
4517 working_space[peak_vel + 10],
4518 working_space[peak_vel + 11],
4519 working_space[peak_vel + 12],
4520 working_space[peak_vel + 13]);
4522 ywm = f;
4523 if (f < 0.00001)
4524 ywm = 0.00001;
4525 }
4527 if (f > 0.00001)
4528 chi2 += yw * TMath::Log(f) - f;
4529 }
4530
4531 else {
4532 if (ywm != 0)
4533 chi2 += (yw - f) * (yw - f) / ywm;
4534 }
4535 }
4536 }
4537 if ((chi2 < chi_min
4539 || (chi2 > chi_min
4541 pmin = pi, chi_min = chi2;
4542 }
4543
4544 else
4545 flag = 1;
4546 if (pi == 0.1)
4547 chi_min = chi2;
4548 chi = chi_min;
4549 }
4550 if (pmin != 0.1) {
4551 for (j = 0; j < size; j++) {
4552 working_space[shift + j] = working_space[4 * shift + j] + pmin * alpha * working_space[2 * shift + j]; //xk[j]=temp_xk[j]+pmin*alpha*der[j]
4553 }
4554 for (i = 0, j = 0; i < fNPeaks; i++) {
4555 if (fFixAmp[i] == false) {
4556 if (working_space[shift + j] < 0) //xk[j]
4557 working_space[shift + j] = 0; //xk[j]
4558 working_space[7 * i] = working_space[shift + j]; //parameter[7*i]=xk[j]
4559 j += 1;
4560 }
4561 if (fFixPositionX[i] == false) {
4562 if (working_space[shift + j] < fXmin) //xk[j]
4563 working_space[shift + j] = fXmin; //xk[j]
4564 if (working_space[shift + j] > fXmax) //xk[j]
4565 working_space[shift + j] = fXmax; //xk[j]
4566 working_space[7 * i + 1] = working_space[shift + j]; //parameter[7*i+1]=xk[j]
4567 j += 1;
4568 }
4569 if (fFixPositionY[i] == false) {
4570 if (working_space[shift + j] < fYmin) //xk[j]
4571 working_space[shift + j] = fYmin; //xk[j]
4572 if (working_space[shift + j] > fYmax) //xk[j]
4573 working_space[shift + j] = fYmax; //xk[j]
4574 working_space[7 * i + 2] = working_space[shift + j]; //parameter[7*i+2]=xk[j]
4575 j += 1;
4576 }
4577 if (fFixAmpX1[i] == false) {
4578 if (working_space[shift + j] < 0) //xk[j]
4579 working_space[shift + j] = 0; //xk[j]
4580 working_space[7 * i + 3] = working_space[shift + j]; //parameter[7*i+3]=xk[j]
4581 j += 1;
4582 }
4583 if (fFixAmpY1[i] == false) {
4584 if (working_space[shift + j] < 0) //xk[j]
4585 working_space[shift + j] = 0; //xk[j]
4586 working_space[7 * i + 4] = working_space[shift + j]; //parameter[7*i+4]=xk[j]
4587 j += 1;
4588 }
4589 if (fFixPositionX1[i] == false) {
4590 if (working_space[shift + j] < fXmin) //xk[j]
4591 working_space[shift + j] = fXmin; //xk[j]
4592 if (working_space[shift + j] > fXmax) //xk[j]
4593 working_space[shift + j] = fXmax; //xk[j]
4594 working_space[7 * i + 5] = working_space[shift + j]; //parameter[7*i+5]=xk[j]
4595 j += 1;
4596 }
4597 if (fFixPositionY1[i] == false) {
4598 if (working_space[shift + j] < fYmin) //xk[j]
4599 working_space[shift + j] = fYmin; //xk[j]
4600 if (working_space[shift + j] > fYmax) //xk[j]
4601 working_space[shift + j] = fYmax; //xk[j]
4602 working_space[7 * i + 6] = working_space[shift + j]; //parameter[7*i+6]=xk[j]
4603 j += 1;
4604 }
4605 }
4606 if (fFixSigmaX == false) {
4607 if (working_space[shift + j] < 0.001) { //xk[j]
4608 working_space[shift + j] = 0.001; //xk[j]
4609 }
4610 working_space[peak_vel] = working_space[shift + j]; //parameter[peak_vel]=xk[j]
4611 j += 1;
4612 }
4613 if (fFixSigmaY == false) {
4614 if (working_space[shift + j] < 0.001) { //xk[j]
4615 working_space[shift + j] = 0.001; //xk[j]
4616 }
4617 working_space[peak_vel + 1] = working_space[shift + j]; //parameter[peak_vel+1]=xk[j]
4618 j += 1;
4619 }
4620 if (fFixRo == false) {
4621 if (working_space[shift + j] < -1) { //xk[j]
4622 working_space[shift + j] = -1; //xk[j]
4623 }
4624 if (working_space[shift + j] > 1) { //xk[j]
4625 working_space[shift + j] = 1; //xk[j]
4626 }
4627 working_space[peak_vel + 2] = working_space[shift + j]; //parameter[peak_vel+2]=xk[j]
4628 j += 1;
4629 }
4630 if (fFixA0 == false) {
4631 working_space[peak_vel + 3] = working_space[shift + j]; //parameter[peak_vel+3]=xk[j]
4632 j += 1;
4633 }
4634 if (fFixAx == false) {
4635 working_space[peak_vel + 4] = working_space[shift + j]; //parameter[peak_vel+4]=xk[j]
4636 j += 1;
4637 }
4638 if (fFixAy == false) {
4639 working_space[peak_vel + 5] = working_space[shift + j]; //parameter[peak_vel+5]=xk[j]
4640 j += 1;
4641 }
4642 if (fFixTxy == false) {
4643 working_space[peak_vel + 6] = working_space[shift + j]; //parameter[peak_vel+6]=xk[j]
4644 j += 1;
4645 }
4646 if (fFixSxy == false) {
4647 working_space[peak_vel + 7] = working_space[shift + j]; //parameter[peak_vel+7]=xk[j]
4648 j += 1;
4649 }
4650 if (fFixTx == false) {
4651 working_space[peak_vel + 8] = working_space[shift + j]; //parameter[peak_vel+8]=xk[j]
4652 j += 1;
4653 }
4654 if (fFixTy == false) {
4655 working_space[peak_vel + 9] = working_space[shift + j]; //parameter[peak_vel+9]=xk[j]
4656 j += 1;
4657 }
4658 if (fFixSx == false) {
4659 working_space[peak_vel + 10] = working_space[shift + j]; //parameter[peak_vel+10]=xk[j]
4660 j += 1;
4661 }
4662 if (fFixSy == false) {
4663 working_space[peak_vel + 11] = working_space[shift + j]; //parameter[peak_vel+11]=xk[j]
4664 j += 1;
4665 }
4666 if (fFixBx == false) {
4667 if (TMath::Abs(working_space[shift + j]) < 0.001) { //xk[j]
4668 if (working_space[shift + j] < 0) //xk[j]
4669 working_space[shift + j] = -0.001; //xk[j]
4670 else
4671 working_space[shift + j] = 0.001; //xk[j]
4672 }
4673 working_space[peak_vel + 12] = working_space[shift + j]; //parameter[peak_vel+12]=xk[j]
4674 j += 1;
4675 }
4676 if (fFixBy == false) {
4677 if (TMath::Abs(working_space[shift + j]) < 0.001) { //xk[j]
4678 if (working_space[shift + j] < 0) //xk[j]
4679 working_space[shift + j] = -0.001; //xk[j]
4680 else
4681 working_space[shift + j] = 0.001; //xk[j]
4682 }
4683 working_space[peak_vel + 13] = working_space[shift + j]; //parameter[peak_vel+13]=xk[j]
4684 j += 1;
4685 }
4686 chi = chi_min;
4687 }
4688 }
4689
4690 else {
4691 for (j = 0; j < size; j++) {
4692 working_space[shift + j] = working_space[4 * shift + j] + alpha * working_space[2 * shift + j]; //xk[j]=temp_xk[j]+pi*alpha*der[j]
4693 }
4694 for (i = 0, j = 0; i < fNPeaks; i++) {
4695 if (fFixAmp[i] == false) {
4696 if (working_space[shift + j] < 0) //xk[j]
4697 working_space[shift + j] = 0; //xk[j]
4698 working_space[7 * i] = working_space[shift + j]; //parameter[7*i]=xk[j]
4699 j += 1;
4700 }
4701 if (fFixPositionX[i] == false) {
4702 if (working_space[shift + j] < fXmin) //xk[j]
4703 working_space[shift + j] = fXmin; //xk[j]
4704 if (working_space[shift + j] > fXmax) //xk[j]
4705 working_space[shift + j] = fXmax; //xk[j]
4706 working_space[7 * i + 1] = working_space[shift + j]; //parameter[7*i+1]=xk[j]
4707 j += 1;
4708 }
4709 if (fFixPositionY[i] == false) {
4710 if (working_space[shift + j] < fYmin) //xk[j]
4711 working_space[shift + j] = fYmin; //xk[j]
4712 if (working_space[shift + j] > fYmax) //xk[j]
4713 working_space[shift + j] = fYmax; //xk[j]
4714 working_space[7 * i + 2] = working_space[shift + j]; //parameter[7*i+2]=xk[j]
4715 j += 1;
4716 }
4717 if (fFixAmpX1[i] == false) {
4718 if (working_space[shift + j] < 0) //xk[j]
4719 working_space[shift + j] = 0; //xk[j]
4720 working_space[7 * i + 3] = working_space[shift + j]; //parameter[7*i+3]=xk[j]
4721 j += 1;
4722 }
4723 if (fFixAmpY1[i] == false) {
4724 if (working_space[shift + j] < 0) //xk[j]
4725 working_space[shift + j] = 0; //xk[j]
4726 working_space[7 * i + 4] = working_space[shift + j]; //parameter[7*i+4]=xk[j]
4727 j += 1;
4728 }
4729 if (fFixPositionX1[i] == false) {
4730 if (working_space[shift + j] < fXmin) //xk[j]
4731 working_space[shift + j] = fXmin; //xk[j]
4732 if (working_space[shift + j] > fXmax) //xk[j]
4733 working_space[shift + j] = fXmax; //xk[j]
4734 working_space[7 * i + 5] = working_space[shift + j]; //parameter[7*i+5]=xk[j]
4735 j += 1;
4736 }
4737 if (fFixPositionY1[i] == false) {
4738 if (working_space[shift + j] < fYmin) //xk[j]
4739 working_space[shift + j] = fYmin; //xk[j]
4740 if (working_space[shift + j] > fYmax) //xk[j]
4741 working_space[shift + j] = fYmax; //xk[j]
4742 working_space[7 * i + 6] = working_space[shift + j]; //parameter[7*i+6]=xk[j]
4743 j += 1;
4744 }
4745 }
4746 if (fFixSigmaX == false) {
4747 if (working_space[shift + j] < 0.001) { //xk[j]
4748 working_space[shift + j] = 0.001; //xk[j]
4749 }
4750 working_space[peak_vel] = working_space[shift + j]; //parameter[peak_vel]=xk[j]
4751 j += 1;
4752 }
4753 if (fFixSigmaY == false) {
4754 if (working_space[shift + j] < 0.001) { //xk[j]
4755 working_space[shift + j] = 0.001; //xk[j]
4756 }
4757 working_space[peak_vel + 1] = working_space[shift + j]; //parameter[peak_vel+1]=xk[j]
4758 j += 1;
4759 }
4760 if (fFixRo == false) {
4761 if (working_space[shift + j] < -1) { //xk[j]
4762 working_space[shift + j] = -1; //xk[j]
4763 }
4764 if (working_space[shift + j] > 1) { //xk[j]
4765 working_space[shift + j] = 1; //xk[j]
4766 }
4767 working_space[peak_vel + 2] = working_space[shift + j]; //parameter[peak_vel+2]=xk[j]
4768 j += 1;
4769 }
4770 if (fFixA0 == false) {
4771 working_space[peak_vel + 3] = working_space[shift + j]; //parameter[peak_vel+3]=xk[j]
4772 j += 1;
4773 }
4774 if (fFixAx == false) {
4775 working_space[peak_vel + 4] = working_space[shift + j]; //parameter[peak_vel+4]=xk[j]
4776 j += 1;
4777 }
4778 if (fFixAy == false) {
4779 working_space[peak_vel + 5] = working_space[shift + j]; //parameter[peak_vel+5]=xk[j]
4780 j += 1;
4781 }
4782 if (fFixTxy == false) {
4783 working_space[peak_vel + 6] = working_space[shift + j]; //parameter[peak_vel+6]=xk[j]
4784 j += 1;
4785 }
4786 if (fFixSxy == false) {
4787 working_space[peak_vel + 7] = working_space[shift + j]; //parameter[peak_vel+7]=xk[j]
4788 j += 1;
4789 }
4790 if (fFixTx == false) {
4791 working_space[peak_vel + 8] = working_space[shift + j]; //parameter[peak_vel+8]=xk[j]
4792 j += 1;
4793 }
4794 if (fFixTy == false) {
4795 working_space[peak_vel + 9] = working_space[shift + j]; //parameter[peak_vel+9]=xk[j]
4796 j += 1;
4797 }
4798 if (fFixSx == false) {
4799 working_space[peak_vel + 10] = working_space[shift + j]; //parameter[peak_vel+10]=xk[j]
4800 j += 1;
4801 }
4802 if (fFixSy == false) {
4803 working_space[peak_vel + 11] = working_space[shift + j]; //parameter[peak_vel+11]=xk[j]
4804 j += 1;
4805 }
4806 if (fFixBx == false) {
4807 if (TMath::Abs(working_space[shift + j]) < 0.001) { //xk[j]
4808 if (working_space[shift + j] < 0) //xk[j]
4809 working_space[shift + j] = -0.001; //xk[j]
4810 else
4811 working_space[shift + j] = 0.001; //xk[j]
4812 }
4813 working_space[peak_vel + 12] = working_space[shift + j]; //parameter[peak_vel+12]=xk[j]
4814 j += 1;
4815 }
4816 if (fFixBy == false) {
4817 if (TMath::Abs(working_space[shift + j]) < 0.001) { //xk[j]
4818 if (working_space[shift + j] < 0) //xk[j]
4819 working_space[shift + j] = -0.001; //xk[j]
4820 else
4821 working_space[shift + j] = 0.001; //xk[j]
4822 }
4823 working_space[peak_vel + 13] = working_space[shift + j]; //parameter[peak_vel+13]=xk[j]
4824 j += 1;
4825 }
4826 chi = 0;
4827 for (i1 = fXmin; i1 <= fXmax; i1++) {
4828 for (i2 = fYmin; i2 <= fYmax; i2++) {
4829 yw = source[i1][i2];
4830 ywm = yw;
4831 f = Shape2(fNPeaks, i1, i2,
4842 working_space[peak_vel + 10],
4843 working_space[peak_vel + 11],
4844 working_space[peak_vel + 12],
4845 working_space[peak_vel + 13]);
4847 ywm = f;
4848 if (f < 0.00001)
4849 ywm = 0.00001;
4850 }
4852 if (f > 0.00001)
4853 chi += yw * TMath::Log(f) - f;
4854 }
4855
4856 else {
4857 if (ywm != 0)
4858 chi += (yw - f) * (yw - f) / ywm;
4859 }
4860 }
4861 }
4862 }
4863 chi2 = chi;
4865 if (fAlphaOptim == kFitAlphaHalving && chi > 1E-6)
4866 alpha = alpha * chi_opt / (2 * chi);
4867
4868 else if (fAlphaOptim == kFitAlphaOptimal)
4869 alpha = alpha / 10.0;
4870 iter += 1;
4871 regul_cycle += 1;
4872 } while (((chi > chi_opt
4874 || (chi < chi_opt
4877 for (j = 0; j < size; j++) {
4878 working_space[4 * shift + j] = 0; //temp_xk[j]
4879 working_space[2 * shift + j] = 0; //der[j]
4880 }
4881 for (i1 = fXmin, chi_cel = 0; i1 <= fXmax; i1++) {
4882 for (i2 = fYmin; i2 <= fYmax; i2++) {
4883 yw = source[i1][i2];
4884 if (yw == 0)
4885 yw = 1;
4886 f = Shape2(fNPeaks, i1, i2,
4897 working_space[peak_vel + 10],
4898 working_space[peak_vel + 11],
4899 working_space[peak_vel + 12],
4900 working_space[peak_vel + 13]);
4901 chi_opt = (yw - f) * (yw - f) / yw;
4902 chi_cel += (yw - f) * (yw - f) / yw;
4903
4904 //calculate gradient vector
4905 for (j = 0, k = 0; j < fNPeaks; j++) {
4906 if (fFixAmp[j] == false) {
4907 a = Deramp2(i1, i2,
4908 working_space[7 * j + 1],
4909 working_space[7 * j + 2],
4915 working_space[peak_vel + 12],
4916 working_space[peak_vel + 13]);
4917 if (yw != 0) {
4918 working_space[2 * shift + k] += chi_opt; //der[k]
4919 b = a * a / yw;
4920 working_space[4 * shift + k] += b; //temp_xk[k]
4921 }
4922 k += 1;
4923 }
4924 if (fFixPositionX[j] == false) {
4925 a = Deri02(i1, i2,
4926 working_space[7 * j],
4927 working_space[7 * j + 1],
4928 working_space[7 * j + 2],
4934 working_space[peak_vel + 12],
4935 working_space[peak_vel + 13]);
4936 if (yw != 0) {
4937 working_space[2 * shift + k] += chi_opt; //der[k]
4938 b = a * a / yw;
4939 working_space[4 * shift + k] += b; //temp_xk[k]
4940 }
4941 k += 1;
4942 }
4943 if (fFixPositionY[j] == false) {
4944 a = Derj02(i1, i2,
4945 working_space[7 * j],
4946 working_space[7 * j + 1],
4947 working_space[7 * j + 2],
4953 working_space[peak_vel + 12],
4954 working_space[peak_vel + 13]);
4955 if (yw != 0) {
4956 working_space[2 * shift + k] += chi_opt; //der[k]
4957 b = a * a / yw;
4958 working_space[4 * shift + k] += b; //temp_xk[k]
4959 }
4960 k += 1;
4961 }
4962 if (fFixAmpX1[j] == false) {
4963 a = Derampx(i1, working_space[7 * j + 5],
4966 working_space[peak_vel + 10],
4967 working_space[peak_vel + 12]);
4968 if (yw != 0) {
4969 working_space[2 * shift + k] += chi_opt; //der[k]
4970 b = a * a / yw;
4971 working_space[4 * shift + k] += b; //temp_xk[k]
4972 }
4973 k += 1;
4974 }
4975 if (fFixAmpY1[j] == false) {
4976 a = Derampx(i2, working_space[7 * j + 6],
4979 working_space[peak_vel + 11],
4980 working_space[peak_vel + 13]);
4981 if (yw != 0) {
4982 working_space[2 * shift + k] += chi_opt; //der[k]
4983 b = a * a / yw;
4984 working_space[4 * shift + k] += b; //temp_xk[k]
4985 }
4986 k += 1;
4987 }
4988 if (fFixPositionX1[j] == false) {
4989 a = Deri01(i1, working_space[7 * j + 3],
4990 working_space[7 * j + 5],
4993 working_space[peak_vel + 10],
4994 working_space[peak_vel + 12]);
4995 if (yw != 0) {
4996 working_space[2 * shift + k] += chi_opt; //der[k]
4997 b = a * a / yw;
4998 working_space[4 * shift + k] += b; //temp_xk[k]
4999 }
5000 k += 1;
5001 }
5002 if (fFixPositionY1[j] == false) {
5003 a = Deri01(i2, working_space[7 * j + 4],
5004 working_space[7 * j + 6],
5007 working_space[peak_vel + 11],
5008 working_space[peak_vel + 13]);
5009 if (yw != 0) {
5010 working_space[2 * shift + k] += chi_opt; //der[k]
5011 b = a * a / yw;
5012 working_space[4 * shift + k] += b; //temp_xk[k]
5013 }
5014 k += 1;
5015 }
5016 }
5017 if (fFixSigmaX == false) {
5018 a = Dersigmax(fNPeaks, i1, i2,
5025 working_space[peak_vel + 10],
5026 working_space[peak_vel + 12],
5027 working_space[peak_vel + 13]);
5028 if (yw != 0) {
5029 working_space[2 * shift + k] += chi_opt; //der[k]
5030 b = a * a / yw;
5031 working_space[4 * shift + k] += b; //temp_xk[k]
5032 }
5033 k += 1;
5034 }
5035 if (fFixSigmaY == false) {
5036 a = Dersigmay(fNPeaks, i1, i2,
5043 working_space[peak_vel + 11],
5044 working_space[peak_vel + 12],
5045 working_space[peak_vel + 13]);
5046 if (yw != 0) {
5047 working_space[2 * shift + k] += chi_opt; //der[k]
5048 b = a * a / yw;
5049 working_space[4 * shift + k] += b; //temp_xk[k]
5050 }
5051 k += 1;
5052 }
5053 if (fFixRo == false) {
5054 a = Derro(fNPeaks, i1, i2,
5057 working_space[peak_vel + 2]);
5058 if (yw != 0) {
5059 working_space[2 * shift + k] += chi_opt; //der[k]
5060 b = a * a / yw;
5061 working_space[4 * shift + k] += b; //temp_xk[k]
5062 }
5063 k += 1;
5064 }
5065 if (fFixA0 == false) {
5066 a = 1.;
5067 if (yw != 0) {
5068 working_space[2 * shift + k] += chi_opt; //der[k]
5069 b = a * a / yw;
5070 working_space[4 * shift + k] += b; //temp_xk[k]
5071 }
5072 k += 1;
5073 }
5074 if (fFixAx == false) {
5075 a = i1;
5076 if (yw != 0) {
5077 working_space[2 * shift + k] += chi_opt; //der[k]
5078 b = a * a / yw;
5079 working_space[4 * shift + k] += b; //temp_xk[k]
5080 }
5081 k += 1;
5082 }
5083 if (fFixAy == false) {
5084 a = i2;
5085 if (yw != 0) {
5086 working_space[2 * shift + k] += chi_opt; //der[k]
5087 b = a * a / yw;
5088 working_space[4 * shift + k] += b; //temp_xk[k]
5089 }
5090 k += 1;
5091 }
5092 if (fFixTxy == false) {
5093 a = Dertxy(fNPeaks, i1, i2,
5096 working_space[peak_vel + 12],
5097 working_space[peak_vel + 13]);
5098 if (yw != 0) {
5099 working_space[2 * shift + k] += chi_opt; //der[k]
5100 b = a * a / yw;
5101 working_space[4 * shift + k] += b; //temp_xk[k]
5102 }
5103 k += 1;
5104 }
5105 if (fFixSxy == false) {
5106 a = Dersxy(fNPeaks, i1, i2,
5108 working_space[peak_vel + 1]);
5109 if (yw != 0) {
5110 working_space[2 * shift + k] += chi_opt; //der[k]
5111 b = a * a / yw;
5112 working_space[4 * shift + k] += b; //temp_xk[k]
5113 }
5114 k += 1;
5115 }
5116 if (fFixTx == false) {
5119 working_space[peak_vel + 12]);
5120 if (yw != 0) {
5121 working_space[2 * shift + k] += chi_opt; //der[k]
5122 b = a * a / yw;
5123 working_space[4 * shift + k] += b; //temp_xk[k]
5124 }
5125 k += 1;
5126 }
5127 if (fFixTy == false) {
5130 working_space[peak_vel + 13]);
5131 if (yw != 0) {
5132 working_space[2 * shift + k] += chi_opt; //der[k]
5133 b = a * a / yw;
5134 working_space[4 * shift + k] += b; //temp_xk[k]
5135 }
5136 k += 1;
5137 }
5138 if (fFixSx == false) {
5141 if (yw != 0) {
5142 working_space[2 * shift + k] += chi_opt; //der[k]
5143 b = a * a / yw;
5144 working_space[4 * shift + k] += b; //temp_xk[k]
5145 }
5146 k += 1;
5147 }
5148 if (fFixSy == false) {
5150 working_space[peak_vel + 1]);
5151 if (yw != 0) {
5152 working_space[2 * shift + k] += chi_opt; //der[k]
5153 b = a * a / yw;
5154 working_space[4 * shift + k] += b; //temp_xk[k]
5155 }
5156 k += 1;
5157 }
5158 if (fFixBx == false) {
5159 a = Derbx(fNPeaks, i1, i2,
5164 working_space[peak_vel + 12],
5165 working_space[peak_vel + 13]);
5166 if (yw != 0) {
5167 working_space[2 * shift + k] += chi_opt; //der[k]
5168 b = a * a / yw;
5169 working_space[4 * shift + k] += b; //temp_xk[k]
5170 }
5171 k += 1;
5172 }
5173 if (fFixBy == false) {
5174 a = Derby(fNPeaks, i1, i2,
5179 working_space[peak_vel + 12],
5180 working_space[peak_vel + 13]);
5181 if (yw != 0) {
5182 working_space[2 * shift + k] += chi_opt; //der[k]
5183 b = a * a / yw;
5184 working_space[4 * shift + k] += b; //temp_xk[k]
5185 }
5186 k += 1;
5187 }
5188 }
5189 }
5190 }
5191 b = (fXmax - fXmin + 1) * (fYmax - fYmin + 1) - size;
5192 chi_er = chi_cel / b;
5193 for (i = 0, j = 0; i < fNPeaks; i++) {
5194 fVolume[i] =
5197 if (fVolume[i] > 0) {
5198 c = 0;
5199 if (fFixAmp[i] == false) {
5202 working_space[peak_vel + 2]);
5203 b = working_space[4 * shift + j]; //temp_xk[j]
5204 if (b == 0)
5205 b = 1;
5206
5207 else
5208 b = 1 / b;
5209 c = c + a * a * b;
5210 }
5211 if (fFixSigmaX == false) {
5212 a = Derpsigmax(working_space[shift + j],
5214 working_space[peak_vel + 2]);
5215 b = working_space[4 * shift + peak_vel]; //temp_xk[j]
5216 if (b == 0)
5217 b = 1;
5218
5219 else
5220 b = 1 / b;
5221 c = c + a * a * b;
5222 }
5223 if (fFixSigmaY == false) {
5224 a = Derpsigmay(working_space[shift + j],
5226 working_space[peak_vel + 2]);
5227 b = working_space[4 * shift + peak_vel + 1]; //temp_xk[j]
5228 if (b == 0)
5229 b = 1;
5230
5231 else
5232 b = 1 / b;
5233 c = c + a * a * b;
5234 }
5235 if (fFixRo == false) {
5238 working_space[peak_vel + 2]);
5239 b = working_space[4 * shift + peak_vel + 2]; //temp_xk[j]
5240 if (b == 0)
5241 b = 1;
5242
5243 else
5244 b = 1 / b;
5245 c = c + a * a * b;
5246 }
5248 }
5249
5250 else {
5251 fVolumeErr[i] = 0;
5252 }
5253 if (fFixAmp[i] == false) {
5254 fAmpCalc[i] = working_space[shift + j]; //xk[j]
5255 if (working_space[3 * shift + j] != 0)
5256 fAmpErr[i] = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
5257 j += 1;
5258 }
5259
5260 else {
5261 fAmpCalc[i] = fAmpInit[i];
5262 fAmpErr[i] = 0;
5263 }
5264 if (fFixPositionX[i] == false) {
5265 fPositionCalcX[i] = working_space[shift + j]; //xk[j]
5266 if (working_space[3 * shift + j] != 0)
5267 fPositionErrX[i] = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
5268 j += 1;
5269 }
5270
5271 else {
5273 fPositionErrX[i] = 0;
5274 }
5275 if (fFixPositionY[i] == false) {
5276 fPositionCalcY[i] = working_space[shift + j]; //xk[j]
5277 if (working_space[3 * shift + j] != 0)
5278 fPositionErrY[i] = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
5279 j += 1;
5280 }
5281
5282 else {
5284 fPositionErrY[i] = 0;
5285 }
5286 if (fFixAmpX1[i] == false) {
5287 fAmpCalcX1[i] = working_space[shift + j]; //xk[j]
5288 if (working_space[3 * shift + j] != 0)
5289 fAmpErrX1[i] = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
5290 j += 1;
5291 }
5292
5293 else {
5294 fAmpCalcX1[i] = fAmpInitX1[i];
5295 fAmpErrX1[i] = 0;
5296 }
5297 if (fFixAmpY1[i] == false) {
5298 fAmpCalcY1[i] = working_space[shift + j]; //xk[j]
5299 if (working_space[3 * shift + j] != 0)
5300 fAmpErrY1[i] = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
5301 j += 1;
5302 }
5303
5304 else {
5305 fAmpCalcY1[i] = fAmpInitY1[i];
5306 fAmpErrY1[i] = 0;
5307 }
5308 if (fFixPositionX1[i] == false) {
5309 fPositionCalcX1[i] = working_space[shift + j]; //xk[j]
5310 if (working_space[3 * shift + j] != 0)
5311 fPositionErrX1[i] = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
5312 j += 1;
5313 }
5314
5315 else {
5317 fPositionErrX1[i] = 0;
5318 }
5319 if (fFixPositionY1[i] == false) {
5320 fPositionCalcY1[i] = working_space[shift + j]; //xk[j]
5321 if (working_space[3 * shift + j] != 0)
5322 fPositionErrY1[i] = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
5323 j += 1;
5324 }
5325
5326 else {
5328 fPositionErrY1[i] = 0;
5329 }
5330 }
5331 if (fFixSigmaX == false) {
5332 fSigmaCalcX = working_space[shift + j]; //xk[j]
5333 if (working_space[3 * shift + j] != 0) //temp[j]
5334 fSigmaErrX = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
5335 j += 1;
5336 }
5337
5338 else {
5340 fSigmaErrX = 0;
5341 }
5342 if (fFixSigmaY == false) {
5343 fSigmaCalcY = working_space[shift + j]; //xk[j]
5344 if (working_space[3 * shift + j] != 0) //temp[j]
5345 fSigmaErrY = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
5346 j += 1;
5347 }
5348
5349 else {
5351 fSigmaErrY = 0;
5352 }
5353 if (fFixRo == false) {
5354 fRoCalc = working_space[shift + j]; //xk[j]
5355 if (working_space[3 * shift + j] != 0) //temp[j]
5356 fRoErr = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
5357 j += 1;
5358 }
5359
5360 else {
5361 fRoCalc = fRoInit;
5362 fRoErr = 0;
5363 }
5364 if (fFixA0 == false) {
5365 fA0Calc = working_space[shift + j]; //xk[j]
5366 if (working_space[3 * shift + j] != 0) //temp[j]
5367 fA0Err = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
5368 j += 1;
5369 }
5370
5371 else {
5372 fA0Calc = fA0Init;
5373 fA0Err = 0;
5374 }
5375 if (fFixAx == false) {
5376 fAxCalc = working_space[shift + j]; //xk[j]
5377 if (working_space[3 * shift + j] != 0) //temp[j]
5378 fAxErr = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
5379 j += 1;
5380 }
5381
5382 else {
5383 fAxCalc = fAxInit;
5384 fAxErr = 0;
5385 }
5386 if (fFixAy == false) {
5387 fAyCalc = working_space[shift + j]; //xk[j]
5388 if (working_space[3 * shift + j] != 0) //temp[j]
5389 fAyErr = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
5390 j += 1;
5391 }
5392
5393 else {
5394 fAyCalc = fAyInit;
5395 fAyErr = 0;
5396 }
5397 if (fFixTxy == false) {
5398 fTxyCalc = working_space[shift + j]; //xk[j]
5399 if (working_space[3 * shift + j] != 0) //temp[j]
5400 fTxyErr = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
5401 j += 1;
5402 }
5403
5404 else {
5406 fTxyErr = 0;
5407 }
5408 if (fFixSxy == false) {
5409 fSxyCalc = working_space[shift + j]; //xk[j]
5410 if (working_space[3 * shift + j] != 0) //temp[j]
5411 fSxyErr = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
5412 j += 1;
5413 }
5414
5415 else {
5417 fSxyErr = 0;
5418 }
5419 if (fFixTx == false) {
5420 fTxCalc = working_space[shift + j]; //xk[j]
5421 if (working_space[3 * shift + j] != 0) //temp[j]
5422 fTxErr = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
5423 j += 1;
5424 }
5425
5426 else {
5427 fTxCalc = fTxInit;
5428 fTxErr = 0;
5429 }
5430 if (fFixTy == false) {
5431 fTyCalc = working_space[shift + j]; //xk[j]
5432 if (working_space[3 * shift + j] != 0) //temp[j]
5433 fTyErr = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
5434 j += 1;
5435 }
5436
5437 else {
5438 fTyCalc = fTyInit;
5439 fTyErr = 0;
5440 }
5441 if (fFixSx == false) {
5442 fSxCalc = working_space[shift + j]; //xk[j]
5443 if (working_space[3 * shift + j] != 0) //temp[j]
5444 fSxErr = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
5445 j += 1;
5446 }
5447
5448 else {
5449 fSxCalc = fSxInit;
5450 fSxErr = 0;
5451 }
5452 if (fFixSy == false) {
5453 fSyCalc = working_space[shift + j]; //xk[j]
5454 if (working_space[3 * shift + j] != 0) //temp[j]
5455 fSyErr = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
5456 j += 1;
5457 }
5458
5459 else {
5460 fSyCalc = fSyInit;
5461 fSyErr = 0;
5462 }
5463 if (fFixBx == false) {
5464 fBxCalc = working_space[shift + j]; //xk[j]
5465 if (working_space[3 * shift + j] != 0) //temp[j]
5466 fBxErr = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
5467 j += 1;
5468 }
5469
5470 else {
5471 fBxCalc = fBxInit;
5472 fBxErr = 0;
5473 }
5474 if (fFixBy == false) {
5475 fByCalc = working_space[shift + j]; //xk[j]
5476 if (working_space[3 * shift + j] != 0) //temp[j]
5477 fByErr = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j])); //der[j]/temp[j]
5478 j += 1;
5479 }
5480
5481 else {
5482 fByCalc = fByInit;
5483 fByErr = 0;
5484 }
5485 b = (fXmax - fXmin + 1) * (fYmax - fYmin + 1) - size;
5486 fChi = chi_cel / b;
5487 for (i1 = fXmin; i1 <= fXmax; i1++) {
5488 for (i2 = fYmin; i2 <= fYmax; i2++) {
5489 f = Shape2(fNPeaks, i1, i2,
5500 working_space[peak_vel + 10],
5501 working_space[peak_vel + 11],
5502 working_space[peak_vel + 12],
5503 working_space[peak_vel + 13]);
5504 source[i1][i2] = f;
5505
5506 }
5507 }
5508 for (i = 0; i < size; i++) delete [] working_matrix[i];
5509 delete [] working_matrix;
5510 delete [] working_space;
5511 return;
5512}
5513
5514////////////////////////////////////////////////////////////////////////////////
5515/// This function sets the following fitting parameters:
5516/// - xmin, xmax, ymin, ymax - fitting region
5517/// - numberIterations - # of desired iterations in the fit
5518/// - alpha - convergence coefficient, it should be positive number and <=1, for details see references
5519/// - statisticType - type of statistics, possible values kFitOptimChiCounts (chi square statistics with counts as weighting coefficients), kFitOptimChiFuncValues (chi square statistics with function values as weighting coefficients),kFitOptimMaxLikelihood
5520/// - alphaOptim - optimization of convergence algorithm, possible values kFitAlphaHalving, kFitAlphaOptimal
5521/// - power - possible values kFitPower2,4,6,8,10,12, for details see references. It applies only for Awmi fitting function.
5522/// - fitTaylor - order of Taylor expansion, possible values kFitTaylorOrderFirst, kFitTaylorOrderSecond. It applies only for Awmi fitting function.
5523
5525{
5526 if(xmin<0 || xmax <= xmin || ymin<0 || ymax <= ymin){
5527 Error("SetFitParameters", "Wrong range");
5528 return;
5529 }
5530 if (numberIterations <= 0){
5531 Error("SetFitParameters","Invalid number of iterations, must be positive");
5532 return;
5533 }
5534 if (alpha <= 0 || alpha > 1){
5535 Error ("SetFitParameters","Invalid step coefficient alpha, must be > than 0 and <=1");
5536 return;
5537 }
5541 Error("SetFitParameters","Wrong type of statistic");
5542 return;
5543 }
5546 Error("SetFitParameters","Wrong optimization algorithm");
5547 return;
5548 }
5549 if (power != kFitPower2 && power != kFitPower4
5550 && power != kFitPower6 && power != kFitPower8
5551 && power != kFitPower10 && power != kFitPower12){
5552 Error("SetFitParameters","Wrong power");
5553 return;
5554 }
5557 Error("SetFitParameters","Wrong order of Taylor development");
5558 return;
5559 }
5561}
5562
5563////////////////////////////////////////////////////////////////////////////////
5564/// This function sets the following fitting parameters of peaks:
5565/// - sigmaX - initial value of sigma x parameter
5566/// - fixSigmaX - logical value of sigma x parameter, which allows to fix the parameter (not to fit)
5567/// - sigmaY - initial value of sigma y parameter
5568/// - fixSigmaY - logical value of sigma y parameter, which allows to fix the parameter (not to fit)
5569/// - ro - initial value of ro parameter (correlation coefficient)
5570/// - fixRo - logical value of ro parameter, which allows to fix the parameter (not to fit)
5571/// - positionInitX - array of initial values of peaks x positions
5572/// - fixPositionX - array of logical values which allow to fix appropriate x positions (not fit). However they are present in the estimated functional.
5573/// - positionInitY - array of initial values of peaks y positions
5574/// - fixPositionY - array of logical values which allow to fix appropriate y positions (not fit). However they are present in the estimated functional.
5575/// - ampInit - array of initial values of 2D peaks amplitudes
5576/// - fixAmp - array of logical values which allow to fix appropriate amplitudes of 2D peaks (not fit). However they are present in the estimated functional
5577/// - ampInitX1 - array of initial values of amplitudes of 1D ridges in x direction
5578/// - fixAmpX1 - array of logical values which allow to fix appropriate amplitudes of 1D ridges in x direction (not fit). However they are present in the estimated functional
5579/// - ampInitY1 - array of initial values of amplitudes of 1D ridges in y direction
5580/// - fixAmpY1 - array of logical values which allow to fix appropriate amplitudes of 1D ridges in y direction (not fit). However they are present in the estimated functional
5581
5583{
5584 if (sigmaX <= 0 || sigmaY <= 0){
5585 Error ("SetPeakParameters","Invalid sigma, must be > than 0");
5586 return;
5587 }
5588 if (ro < -1 || ro > 1){
5589 Error ("SetPeakParameters","Invalid ro, must be from region <-1,1>");
5590 return;
5591 }
5592 Int_t i;
5593 for(i=0; i < fNPeaks; i++){
5594 if(positionInitX[i] < fXmin || positionInitX[i] > fXmax){
5595 Error ("SetPeakParameters","Invalid peak position, must be in the range fXmin, fXmax");
5596 return;
5597 }
5598 if(positionInitY[i] < fYmin || positionInitY[i] > fYmax){
5599 Error ("SetPeakParameters","Invalid peak position, must be in the range fYmin, fYmax");
5600 return;
5601 }
5602 if(positionInitX1[i] < fXmin || positionInitX1[i] > fXmax){
5603 Error ("SetPeakParameters","Invalid ridge position, must be in the range fXmin, fXmax");
5604 return;
5605 }
5606 if(positionInitY1[i] < fYmin || positionInitY1[i] > fYmax){
5607 Error ("SetPeakParameters","Invalid ridge position, must be in the range fYmin, fYmax");
5608 return;
5609 }
5610 if(ampInit[i] < 0){
5611 Error ("SetPeakParameters","Invalid peak amplitude, must be > than 0");
5612 return;
5613 }
5614 if(ampInitX1[i] < 0){
5615 Error ("SetPeakParameters","Invalid x ridge amplitude, must be > than 0");
5616 return;
5617 }
5618 if(ampInitY1[i] < 0){
5619 Error ("SetPeakParameters","Invalid y ridge amplitude, must be > than 0");
5620 return;
5621 }
5622 }
5624 for(i=0; i < fNPeaks; i++){
5633 fAmpInit[i] = ampInit[i];
5634 fFixAmp[i] = fixAmp[i];
5635 fAmpInitX1[i] = ampInitX1[i];
5636 fFixAmpX1[i] = fixAmpX1[i];
5637 fAmpInitY1[i] = ampInitY1[i];
5638 fFixAmpY1[i] = fixAmpY1[i];
5639 }
5640}
5641
5642////////////////////////////////////////////////////////////////////////////////
5643/// This function sets the following fitting parameters of background:
5644/// - a0Init - initial value of a0 parameter (background is estimated as a0+ax*x+ay*y)
5645/// - fixA0 - logical value of a0 parameter, which allows to fix the parameter (not to fit)
5646/// - axInit - initial value of ax parameter
5647/// - fixAx - logical value of ax parameter, which allows to fix the parameter (not to fit)
5648/// - ayInit - initial value of ay parameter
5649/// - fixAy - logical value of ay parameter, which allows to fix the parameter (not to fit)
5650
5660
5661////////////////////////////////////////////////////////////////////////////////
5662/// This function sets the following fitting parameters of tails of peaks
5663/// - tInitXY - initial value of txy parameter
5664/// - fixTxy - logical value of txy parameter, which allows to fix the parameter (not to fit)
5665/// - tInitX - initial value of tx parameter
5666/// - fixTx - logical value of tx parameter, which allows to fix the parameter (not to fit)
5667/// - tInitY - initial value of ty parameter
5668/// - fixTy - logical value of ty parameter, which allows to fix the parameter (not to fit)
5669/// - bInitX - initial value of bx parameter
5670/// - fixBx - logical value of bx parameter, which allows to fix the parameter (not to fit)
5671/// - bInitY - initial value of by parameter
5672/// - fixBy - logical value of by parameter, which allows to fix the parameter (not to fit)
5673/// - sInitXY - initial value of sxy parameter
5674/// - fixSxy - logical value of sxy parameter, which allows to fix the parameter (not to fit)
5675/// - sInitX - initial value of sx parameter
5676/// - fixSx - logical value of sx parameter, which allows to fix the parameter (not to fit)
5677/// - sInitY - initial value of sy parameter
5678/// - fixSy - logical value of sy parameter, which allows to fix the parameter (not to fit)
5679
5699
5700////////////////////////////////////////////////////////////////////////////////
5701/// This function gets the positions of fitted 2D peaks and 1D ridges
5702/// - positionX - gets vector of x positions of 2D peaks
5703/// - positionY - gets vector of y positions of 2D peaks
5704/// - positionX1 - gets vector of x positions of 1D ridges
5705/// - positionY1 - gets vector of y positions of 1D ridges
5706
5716
5717////////////////////////////////////////////////////////////////////////////////
5718/// This function gets the errors of positions of fitted 2D peaks and 1D ridges
5719/// - positionErrorsX - gets vector of errors of x positions of 2D peaks
5720/// - positionErrorsY - gets vector of errors of y positions of 2D peaks
5721/// - positionErrorsX1 - gets vector of errors of x positions of 1D ridges
5722/// - positionErrorsY1 - gets vector of errors of y positions of 1D ridges
5723
5733
5734////////////////////////////////////////////////////////////////////////////////
5735/// This function gets the amplitudes of fitted 2D peaks and 1D ridges
5736/// - amplitudes - gets vector of amplitudes of 2D peaks
5737/// - amplitudesX1 - gets vector of amplitudes of 1D ridges in x direction
5738/// - amplitudesY1 - gets vector of amplitudes of 1D ridges in y direction
5739
5741{
5742 for( Int_t i=0; i < fNPeaks; i++){
5743 amplitudes[i] = fAmpCalc[i];
5744 amplitudesX1[i] = fAmpCalcX1[i];
5745 amplitudesY1[i] = fAmpCalcY1[i];
5746 }
5747}
5748
5749////////////////////////////////////////////////////////////////////////////////
5750/// This function gets the amplitudes of fitted 2D peaks and 1D ridges
5751/// - amplitudeErrors - gets vector of amplitudes errors of 2D peaks
5752/// - amplitudeErrorsX1 - gets vector of amplitudes errors of 1D ridges in x direction
5753/// - amplitudesErrorY1 - gets vector of amplitudes errors of 1D ridges in y direction
5754
5763
5764////////////////////////////////////////////////////////////////////////////////
5765/// This function gets the volumes of fitted 2D peaks
5766/// - volumes - gets vector of volumes of 2D peaks
5767
5769{
5770 for( Int_t i=0; i < fNPeaks; i++){
5771 volumes[i] = fVolume[i];
5772 }
5773}
5774
5775////////////////////////////////////////////////////////////////////////////////
5776/// This function gets errors of the volumes of fitted 2D peaks
5777/// - volumeErrors - gets vector of volumes errors of 2D peaks
5778
5780{
5781 for( Int_t i=0; i < fNPeaks; i++){
5782 volumeErrors[i] = fVolumeErr[i];
5783 }
5784}
5785
5786////////////////////////////////////////////////////////////////////////////////
5787/// This function gets the sigma x parameter and its error
5788/// - sigmaX - gets the fitted value of sigma x parameter
5789/// - sigmaErrX - gets error value of sigma x parameter
5790
5796
5797////////////////////////////////////////////////////////////////////////////////
5798/// This function gets the sigma y parameter and its error
5799/// - sigmaY - gets the fitted value of sigma y parameter
5800/// - sigmaErrY - gets error value of sigma y parameter
5801
5807
5808////////////////////////////////////////////////////////////////////////////////
5809/// This function gets the ro parameter and its error
5810/// - ro - gets the fitted value of ro parameter
5811/// - roErr - gets error value of ro parameter
5812
5818
5819////////////////////////////////////////////////////////////////////////////////
5820/// This function gets the background parameters and their errors
5821/// - a0 - gets the fitted value of a0 parameter
5822/// - a0Err - gets error value of a0 parameter
5823/// - ax - gets the fitted value of ax parameter
5824/// - axErr - gets error value of ax parameter
5825/// - ay - gets the fitted value of ay parameter
5826/// - ayErr - gets error value of ay parameter
5827
5837
5838////////////////////////////////////////////////////////////////////////////////
5839/// This function gets the tail parameters and their errors
5840/// - txy - gets the fitted value of txy parameter
5841/// - txyErr - gets error value of txy parameter
5842/// - tx - gets the fitted value of tx parameter
5843/// - txErr - gets error value of tx parameter
5844/// - ty - gets the fitted value of ty parameter
5845/// - tyErr - gets error value of ty parameter
5846/// - bx - gets the fitted value of bx parameter
5847/// - bxErr - gets error value of bx parameter
5848/// - by - gets the fitted value of by parameter
5849/// - byErr - gets error value of by parameter
5850/// - sxy - gets the fitted value of sxy parameter
5851/// - sxyErr - gets error value of sxy parameter
5852/// - sx - gets the fitted value of sx parameter
5853/// - sxErr - gets error value of sx parameter
5854/// - sy - gets the fitted value of sy parameter
5855/// - syErr - gets error value of sy parameter
5856
5876
#define d(i)
Definition RSha256.hxx:102
#define b(i)
Definition RSha256.hxx:100
#define f(i)
Definition RSha256.hxx:104
#define c(i)
Definition RSha256.hxx:101
#define a(i)
Definition RSha256.hxx:99
#define e(i)
Definition RSha256.hxx:103
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
winID h TVirtualViewer3D TVirtualGLPainter p
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t r
float xmin
float ymin
float xmax
float ymax
The TNamed class is the base class for all named ROOT classes.
Definition TNamed.h:29
virtual void Error(const char *method, const char *msgfmt,...) const
Issue error message.
Definition TObject.cxx:1071
Double_t Derbx(Int_t numOfFittedPeaks, Double_t x, Double_t y, const Double_t *parameter, Double_t sigmax, Double_t sigmay, Double_t txy, Double_t tx, Double_t bx, Double_t by)
This function calculates derivative of peaks shape function (see manual) according to slope bx.
Double_t Dersxy(Int_t numOfFittedPeaks, Double_t x, Double_t y, const Double_t *parameter, Double_t sigmax, Double_t sigmay)
This function calculates derivative of peaks shape function (see manual) according to relative amplit...
Bool_t fFixBx
logical value of b parameter for 1D ridges in x direction, which allows to fix the parameter (not to ...
Bool_t * fFixPositionY
[fNPeaks] array of logical values which allow to fix appropriate y positions of 2D peaks (not fit)....
Double_t fSigmaErrY
error value of sigma y parameter
Bool_t * fFixAmpY1
[fNPeaks] array of logical values which allow to fix appropriate amplitudes of 1D ridges in y directi...
Double_t * fAmpCalcX1
[fNPeaks] array of calculated values of amplitudes of 1D ridges in x direction, output parameters
Double_t Volume(Double_t a, Double_t sx, Double_t sy, Double_t ro)
This function calculates volume of a peak.
Bool_t fFixSxy
logical value of s parameter for 2D peaks, which allows to fix the parameter (not to fit).
Double_t fTxErr
error value of t parameter for 1D ridges in x direction
Double_t Deri01(Double_t x, Double_t ax, Double_t x0, Double_t sigmax, Double_t tx, Double_t sx, Double_t bx)
This function calculates derivative of 2D peaks shape function (see manual) according to x position o...
Double_t * fAmpErrY1
[fNPeaks] array of amplitudes errors of 1D ridges in y direction, output parameters
Double_t fBxInit
initial value of b parameter for 1D ridges in x direction (slope), for details see html manual and re...
Double_t Shape2(Int_t numOfFittedPeaks, Double_t x, Double_t y, const Double_t *parameter, Double_t sigmax, Double_t sigmay, Double_t ro, Double_t a0, Double_t ax, Double_t ay, Double_t txy, Double_t sxy, Double_t tx, Double_t ty, Double_t sx, Double_t sy, Double_t bx, Double_t by)
This function calculates 2D peaks shape function (see manual)
Double_t fA0Err
error value of background a0 parameter
void SetPeakParameters(Double_t sigmaX, Bool_t fixSigmaX, Double_t sigmaY, Bool_t fixSigmaY, Double_t ro, Bool_t fixRo, const Double_t *positionInitX, const Bool_t *fixPositionX, const Double_t *positionInitY, const Bool_t *fixPositionY, const Double_t *positionInitX1, const Bool_t *fixPositionX1, const Double_t *positionInitY1, const Bool_t *fixPositionY1, const Double_t *ampInit, const Bool_t *fixAmp, const Double_t *ampInitX1, const Bool_t *fixAmpX1, const Double_t *ampInitY1, const Bool_t *fixAmpY1)
This function sets the following fitting parameters of peaks:
Double_t fSigmaCalcX
calculated value of sigma x parameter
Bool_t * fFixAmpX1
[fNPeaks] array of logical values which allow to fix appropriate amplitudes of 1D ridges in x directi...
Double_t Derderi02(Double_t x, Double_t y, Double_t a, Double_t x0, Double_t y0, Double_t sigmax, Double_t sigmay, Double_t ro)
This function calculates second derivative of 2D peaks shape function (see manual) according to x pos...
Bool_t fFixRo
logical value of correlation coefficient, which allows to fix the parameter (not to fit).
Double_t * fAmpErr
[fNPeaks] array of amplitudes errors of 2D peaks, output parameters
Bool_t fFixSx
logical value of s parameter for 1D ridges in x direction, which allows to fix the parameter (not to ...
Double_t * fAmpInit
[fNPeaks] array of initial values of amplitudes of 2D peaks, input parameters
void GetTailParameters(Double_t &txy, Double_t &txyErr, Double_t &tx, Double_t &txErr, Double_t &ty, Double_t &tyErr, Double_t &bx, Double_t &bxErr, Double_t &by, Double_t &byErr, Double_t &sxy, Double_t &sxyErr, Double_t &sx, Double_t &sxErr, Double_t &sy, Double_t &syErr)
This function gets the tail parameters and their errors.
Double_t * fVolume
[fNPeaks] array of calculated volumes of 2D peaks, output parameters
Double_t Derdersigmax(Int_t numOfFittedPeaks, Double_t x, Double_t y, const Double_t *parameter, Double_t sigmax, Double_t sigmay, Double_t ro)
This function calculates second derivative of peaks shape function (see manual) according to sigmax o...
Double_t * fPositionCalcY
[fNPeaks] array of calculated values of y positions of 2D peaks, output parameters
Int_t fFitTaylor
order of Taylor expansion, possible values kFitTaylorOrderFirst, kFitTaylorOrderSecond....
Double_t fSxyErr
error value of s parameter for 2D peaks
Double_t * fPositionErrY1
[fNPeaks] array of y positions errors of 1D ridges, output parameters
Double_t fBxCalc
calculated value of b parameter for 1D ridges in x direction
Double_t fRoErr
error value of correlation coefficient
Double_t fTxCalc
calculated value of t parameter for 1D ridges in x direction
Double_t fRoCalc
calculated value of correlation coefficient
Bool_t fFixBy
logical value of b parameter for 1D ridges in y direction, which allows to fix the parameter (not to ...
Double_t Derby(Int_t numOfFittedPeaks, Double_t x, Double_t y, const Double_t *parameter, Double_t sigmax, Double_t sigmay, Double_t txy, Double_t ty, Double_t bx, Double_t by)
This function calculates derivative of peaks shape function (see manual) according to slope by.
Double_t fTxyInit
initial value of t parameter for 2D peaks (relative amplitude of tail), for details see html manual a...
Bool_t fFixSigmaY
logical value of sigma y parameter, which allows to fix the parameter (not to fit).
Double_t Deramp2(Double_t x, Double_t y, Double_t x0, Double_t y0, Double_t sigmax, Double_t sigmay, Double_t ro, Double_t txy, Double_t sxy, Double_t bx, Double_t by)
This function calculates derivative of 2D peaks shape function (see manual) according to amplitude of...
void GetRo(Double_t &ro, Double_t &roErr)
This function gets the ro parameter and its error.
Int_t fXmax
last fitted channel in x direction
Double_t fChi
here the fitting functions return resulting chi square
void GetVolumes(Double_t *volumes)
This function gets the volumes of fitted 2D peaks.
Double_t fByErr
error value of b parameter for 1D ridges in y direction
Double_t fA0Init
initial value of background a0 parameter(backgroud is estimated as a0+ax*x+ay*y)
Double_t fRoInit
initial value of correlation coefficient
Double_t Deri02(Double_t x, Double_t y, Double_t a, Double_t x0, Double_t y0, Double_t sigmax, Double_t sigmay, Double_t ro, Double_t txy, Double_t sxy, Double_t bx, Double_t by)
This function calculates derivative of 2D peaks shape function (see manual) according to x position o...
Double_t fSigmaInitX
initial value of sigma x parameter
void GetBackgroundParameters(Double_t &a0, Double_t &a0Err, Double_t &ax, Double_t &axErr, Double_t &ay, Double_t &ayErr)
This function gets the background parameters and their errors.
Double_t Derampx(Double_t x, Double_t x0, Double_t sigmax, Double_t tx, Double_t sx, Double_t bx)
This function calculates derivative of 2D peaks shape function (see manual) according to amplitude of...
Double_t * fPositionInitY1
[fNPeaks] array of initial y positions of 1D ridges, input parameters
Bool_t fFixSy
logical value of s parameter for 1D ridges in y direction, which allows to fix the parameter (not to ...
Bool_t * fFixAmp
[fNPeaks] array of logical values which allow to fix appropriate amplitudes of 2D peaks (not fit)....
Double_t Derderj02(Double_t x, Double_t y, Double_t a, Double_t x0, Double_t y0, Double_t sigmax, Double_t sigmay, Double_t ro)
This function calculates second derivative of 2D peaks shape function (see manual) according to y pos...
Double_t fAyErr
error value of background ay parameter
Double_t fSxyCalc
calculated value of s parameter for 2D peaks
Double_t * fPositionInitX1
[fNPeaks] array of initial x positions of 1D ridges, input parameters
Double_t fTyCalc
calculated value of t parameter for 1D ridges in y direction
Double_t * fPositionErrX1
[fNPeaks] array of x positions errors of 1D ridges, output parameters
Double_t Dertxy(Int_t numOfFittedPeaks, Double_t x, Double_t y, const Double_t *parameter, Double_t sigmax, Double_t sigmay, Double_t bx, Double_t by)
This function calculates derivative of peaks shape function (see manual) according to relative amplit...
Double_t Derj02(Double_t x, Double_t y, Double_t a, Double_t x0, Double_t y0, Double_t sigmax, Double_t sigmay, Double_t ro, Double_t txy, Double_t sxy, Double_t bx, Double_t by)
This function calculates derivative of 2D peaks shape function (see manual) according to y position o...
Double_t * fPositionInitY
[fNPeaks] array of initial values of y positions of 2D peaks, input parameters
Double_t fSxCalc
calculated value of s parameter for 1D ridges in x direction
void GetAmplitudeErrors(Double_t *amplitudeErrors, Double_t *amplitudeErrorsX1, Double_t *amplitudeErrorsY1)
This function gets the amplitudes of fitted 2D peaks and 1D ridges.
Double_t fAxCalc
calculated value of background ax parameter
Double_t fSyErr
error value of s parameter for 1D ridges in y direction
Int_t fStatisticType
type of statistics, possible values kFitOptimChiCounts (chi square statistics with counts as weightin...
Int_t fYmax
last fitted channel in y direction
Double_t * fPositionErrY
[fNPeaks] array of error values of y positions of 2D peaks, output parameters
Double_t Dersx(Int_t numOfFittedPeaks, Double_t x, const Double_t *parameter, Double_t sigmax)
This function calculates derivative of peaks shape function (see manual) according to relative amplit...
Double_t fByCalc
calculated value of b parameter for 1D ridges in y direction
Double_t fTyInit
initial value of t parameter for 1D ridges in y direction (relative amplitude of tail),...
Double_t fTxyCalc
calculated value of t parameter for 2D peaks
Double_t Derpa2(Double_t sx, Double_t sy, Double_t ro)
This function calculates derivative of the volume of a peak according to amplitude.
Double_t fByInit
initial value of b parameter for 1D ridges in y direction (slope), for details see html manual and re...
Double_t fSigmaCalcY
calculated value of sigma y parameter
Double_t * fAmpErrX1
[fNPeaks] array of amplitudes errors of 1D ridges in x direction, output parameters
Double_t Dertx(Int_t numOfFittedPeaks, Double_t x, const Double_t *parameter, Double_t sigmax, Double_t bx)
This function calculates derivative of peaks shape function (see manual) according to relative amplit...
Int_t fNumberIterations
number of iterations in fitting procedure, input parameter, it should be > 0
Bool_t fFixTx
logical value of t parameter for 1D ridges in x direction, which allows to fix the parameter (not to ...
Double_t * fPositionCalcY1
[fNPeaks] array of calculated y positions of 1D ridges, output parameters
Bool_t fFixTxy
logical value of t parameter for 2D peaks, which allows to fix the parameter (not to fit).
void FitAwmi(Double_t **source)
This function fits the source spectrum.
Bool_t fFixTy
logical value of t parameter for 1D ridges in y direction, which allows to fix the parameter (not to ...
Double_t fAlpha
convergence coefficient, input parameter, it should be positive number and <=1, for details see refer...
void GetPositions(Double_t *positionsX, Double_t *positionsY, Double_t *positionsX1, Double_t *positionsY1)
This function gets the positions of fitted 2D peaks and 1D ridges.
Bool_t fFixAx
logical value of ax parameter, which allows to fix the parameter (not to fit).
Double_t fTyErr
error value of t parameter for 1D ridges in y direction
Double_t fSyCalc
calculated value of s parameter for 1D ridges in y direction
Int_t fXmin
first fitted channel in x direction
Double_t fTxyErr
error value of t parameter for 2D peaks
void SetFitParameters(Int_t xmin, Int_t xmax, Int_t ymin, Int_t ymax, Int_t numberIterations, Double_t alpha, Int_t statisticType, Int_t alphaOptim, Int_t power, Int_t fitTaylor)
This function sets the following fitting parameters:
void GetSigmaX(Double_t &sigmaX, Double_t &sigmaErrX)
This function gets the sigma x parameter and its error.
Double_t Derderi01(Double_t x, Double_t ax, Double_t x0, Double_t sigmax)
This function calculates second derivative of 2D peaks shape function (see manual) according to x pos...
Double_t Erfc(Double_t x)
This function calculates error function of x.
Double_t Derro(Int_t numOfFittedPeaks, Double_t x, Double_t y, const Double_t *parameter, Double_t sx, Double_t sy, Double_t r)
This function calculates derivative of peaks shape function (see manual) according to correlation coe...
Bool_t * fFixPositionX1
[fNPeaks] array of logical values which allow to fix appropriate x positions of 1D ridges (not fit)....
Double_t Dersigmay(Int_t numOfFittedPeaks, Double_t x, Double_t y, const Double_t *parameter, Double_t sigmax, Double_t sigmay, Double_t ro, Double_t txy, Double_t sxy, Double_t ty, Double_t sy, Double_t bx, Double_t by)
This function calculates derivative of peaks shape function (see manual) according to sigmax of peaks...
Double_t Ourpowl(Double_t a, Int_t pw)
power function
Double_t * fAmpInitY1
[fNPeaks] array of initial values of amplitudes of 1D ridges in y direction, input parameters
Double_t fAxErr
error value of background ax parameter
Double_t Derdersigmay(Int_t numOfFittedPeaks, Double_t x, Double_t y, const Double_t *parameter, Double_t sigmax, Double_t sigmay, Double_t ro)
This function calculates second derivative of peaks shape function (see manual) according to sigmay o...
Double_t fAyCalc
calculated value of background ay parameter
Double_t fSigmaInitY
initial value of sigma y parameter
void SetTailParameters(Double_t tInitXY, Bool_t fixTxy, Double_t tInitX, Bool_t fixTx, Double_t tInitY, Bool_t fixTy, Double_t bInitX, Bool_t fixBx, Double_t bInitY, Bool_t fixBy, Double_t sInitXY, Bool_t fixSxy, Double_t sInitX, Bool_t fixSx, Double_t sInitY, Bool_t fixSy)
This function sets the following fitting parameters of tails of peaks.
Double_t * fPositionErrX
[fNPeaks] array of error values of x positions of 2D peaks, output parameters
Double_t * fAmpInitX1
[fNPeaks] array of initial values of amplitudes of 1D ridges in x direction, input parameters
Bool_t * fFixPositionY1
[fNPeaks] array of logical values which allow to fix appropriate y positions of 1D ridges (not fit)....
void GetVolumeErrors(Double_t *volumeErrors)
This function gets errors of the volumes of fitted 2D peaks.
Double_t Dersy(Int_t numOfFittedPeaks, Double_t x, const Double_t *parameter, Double_t sigmax)
This function calculates derivative of peaks shape function (see manual) according to relative amplit...
~TSpectrum2Fit() override
Destructor.
Double_t Derpsigmay(Double_t a, Double_t sx, Double_t ro)
This function calculates derivative of the volume of a peak according to sigmay.
Double_t Derty(Int_t numOfFittedPeaks, Double_t x, const Double_t *parameter, Double_t sigmax, Double_t bx)
This function calculates derivative of peaks shape function (see manual) according to relative amplit...
Double_t fTxInit
initial value of t parameter for 1D ridges in x direction (relative amplitude of tail),...
Double_t fSyInit
initial value of s parameter for 1D ridges in y direction (relative amplitude of step),...
Double_t Dersigmax(Int_t numOfFittedPeaks, Double_t x, Double_t y, const Double_t *parameter, Double_t sigmax, Double_t sigmay, Double_t ro, Double_t txy, Double_t sxy, Double_t tx, Double_t sx, Double_t bx, Double_t by)
This function calculates derivative of peaks shape function (see manual) according to sigmax of peaks...
Double_t * fAmpCalc
[fNPeaks] array of calculated values of amplitudes of 2D peaks, output parameters
void GetSigmaY(Double_t &sigmaY, Double_t &sigmaErrY)
This function gets the sigma y parameter and its error.
TSpectrum2Fit(void)
Default constructor.
Double_t fA0Calc
calculated value of background a0 parameter
Double_t * fPositionInitX
[fNPeaks] array of initial values of x positions of 2D peaks, input parameters
Int_t fAlphaOptim
optimization of convergence algorithm, possible values kFitAlphaHalving, kFitAlphaOptimal
Bool_t fFixSigmaX
logical value of sigma x parameter, which allows to fix the parameter (not to fit).
Double_t fSxErr
error value of s parameter for 1D ridges in x direction
Int_t fNPeaks
number of peaks present in fit, input parameter, it should be > 0
void SetBackgroundParameters(Double_t a0Init, Bool_t fixA0, Double_t axInit, Bool_t fixAx, Double_t ayInit, Bool_t fixAy)
This function sets the following fitting parameters of background:
Double_t Derpro(Double_t a, Double_t sx, Double_t sy, Double_t ro)
This function calculates derivative of the volume of a peak according to ro.
Double_t * fAmpCalcY1
[fNPeaks] array of calculated values of amplitudes of 1D ridges in y direction, output parameters
Bool_t fFixAy
logical value of ay parameter, which allows to fix the parameter (not to fit).
void FitStiefel(Double_t **source)
This function fits the source spectrum.
Double_t Derfc(Double_t x)
This function calculates derivative of error function of x.
Double_t fSxInit
initial value of s parameter for 1D ridges in x direction (relative amplitude of step),...
Double_t fSigmaErrX
error value of sigma x parameter
Int_t fYmin
first fitted channel in y direction
Double_t * fPositionCalcX1
[fNPeaks] array of calculated x positions of 1D ridges, output parameters
void GetAmplitudes(Double_t *amplitudes, Double_t *amplitudesX1, Double_t *amplitudesY1)
This function gets the amplitudes of fitted 2D peaks and 1D ridges.
Double_t fBxErr
error value of b parameter for 1D ridges in x direction
Double_t Derpsigmax(Double_t a, Double_t sy, Double_t ro)
This function calculates derivative of the volume of a peak according to sigmax.
Double_t * fPositionCalcX
[fNPeaks] array of calculated values of x positions of 2D peaks, output parameters
Double_t fAxInit
initial value of background ax parameter(backgroud is estimated as a0+ax*x+ay*y)
Bool_t * fFixPositionX
[fNPeaks] array of logical values which allow to fix appropriate x positions of 2D peaks (not fit)....
void GetPositionErrors(Double_t *positionErrorsX, Double_t *positionErrorsY, Double_t *positionErrorsX1, Double_t *positionErrorsY1)
This function gets the errors of positions of fitted 2D peaks and 1D ridges.
void StiefelInversion(Double_t **a, Int_t size)
This function calculates solution of the system of linear equations.
Double_t fSxyInit
initial value of s parameter for 2D peaks (relative amplitude of step), for details see html manual a...
Int_t fPower
possible values kFitPower2,4,6,8,10,12, for details see references. It applies only for Awmi fitting ...
Bool_t fFixA0
logical value of a0 parameter, which allows to fix the parameter (not to fit).
Double_t fAyInit
initial value of background ay parameter(backgroud is estimated as a0+ax*x+ay*y)
Double_t * fVolumeErr
[fNPeaks] array of volumes errors of 2D peaks, output parameters
Double_t y[n]
Definition legend1.C:17
Double_t x[n]
Definition legend1.C:17
Double_t ey[n]
Definition legend1.C:17
Double_t ex[n]
Definition legend1.C:17
Double_t Log(Double_t x)
Returns the natural logarithm of x.
Definition TMath.h:767
Double_t Sqrt(Double_t x)
Returns the square root of x.
Definition TMath.h:673
Short_t Abs(Short_t d)
Returns the absolute value of parameter Short_t d.
Definition TMathBase.h:124