#include "TSpectrumFit.h"
#include "TMath.h"
ClassImp(TSpectrumFit)
TSpectrumFit::TSpectrumFit() :TNamed("SpectrumFit", "Miroslav Morhac peak fitter")
{
fNPeaks = 0;
fPositionInit = 0;
fPositionCalc = 0;
fPositionErr = 0;
fFixPosition = 0;
fAmpInit = 0;
fAmpCalc = 0;
fAmpErr = 0;
fFixAmp = 0;
fArea = 0;
fAreaErr = 0;
}
TSpectrumFit::TSpectrumFit(Int_t numberPeaks) :TNamed("SpectrumFit", "Miroslav Morhac peak fitter")
{
/* -->
<div class=Section1>
<p class=MsoNormal style='text-align:justify'>Shape function of the fitted
peaks is </p>
<p class=MsoNormal style='text-align:justify'>
<table cellpadding=0 cellspacing=0 align=left>
<tr>
<td width=68 height=6></td>
</tr>
<tr>
<td></td>
<td><img width=388 height=132 src="gif/spectrumfit_constructor_image001.gif"></td>
</tr>
</table>
<span style='font-family:Arial'> </span></p>
<p class=MsoNormal style='text-align:justify'> </p>
<p class=MsoNormal style='text-align:justify'> </p>
<p class=MsoNormal style='text-align:justify'> </p>
<p class=MsoNormal style='text-align:justify'> </p>
<p class=MsoNormal><i> </i></p>
<p class=MsoNormal><i> </i></p>
<p class=MsoNormal><i> </i></p>
<br clear=ALL>
<p class=MsoNormal style='text-align:justify'>where a represents vector of
fitted parameters (positions p(j), amplitudes A(j), sigma, relative amplitudes
T, S and slope B).</p>
<p class=MsoNormal><span style='font-size:16.0pt'> </span></p>
</div>
<!-- */
// --> End_Html
if (numberPeaks <= 0){
Error ("TSpectrumFit","Invalid number of peaks, must be > than 0");
return;
}
fNPeaks = numberPeaks;
fPositionInit = new Double_t[numberPeaks];
fPositionCalc = new Double_t[numberPeaks];
fPositionErr = new Double_t[numberPeaks];
fFixPosition = new Bool_t[numberPeaks];
fAmpInit = new Double_t[numberPeaks];
fAmpCalc = new Double_t[numberPeaks];
fAmpErr = new Double_t[numberPeaks];
fFixAmp = new Bool_t[numberPeaks];
fArea = new Double_t[numberPeaks];
fAreaErr = new Double_t[numberPeaks];
fXmin=0,fXmax=100,fSigmaInit = 2,fFixSigma = false;
fAlpha =1;
fStatisticType = kFitOptimChiCounts;
fAlphaOptim = kFitAlphaHalving;
fPower = kFitPower2;
fFitTaylor = kFitTaylorOrderFirst;
fTInit = 0;
fFixT = true;
fBInit = 1;
fFixB = true;
fSInit = 0;
fFixS = true;
fA0Init = 0;
fFixA0 = true;
fA1Init = 0;
fFixA1 = true;
fA2Init = 0;
fFixA2 = true;
}
TSpectrumFit::~TSpectrumFit()
{
delete [] fPositionInit;
delete [] fPositionCalc;
delete [] fPositionErr;
delete [] fFixPosition;
delete [] fAmpInit;
delete [] fAmpCalc;
delete [] fAmpErr;
delete [] fFixAmp;
delete [] fArea;
delete [] fAreaErr;
}
Double_t TSpectrumFit::Erfc(Double_t x)
{
Double_t da1 = 0.1740121, da2 = -0.0479399, da3 = 0.3739278, dap = 0.47047;
Double_t a, t, c, w;
a = TMath::Abs(x);
w = 1. + dap * a;
t = 1. / w;
w = a * a;
if (w < 700)
c = exp(-w);
else {
c = 0;
}
c = c * t * (da1 + t * (da2 + t * da3));
if (x < 0)
c = 1. - c;
return (c);
}
Double_t TSpectrumFit::Derfc(Double_t x)
{
Double_t a, t, c, w;
Double_t da1 = 0.1740121, da2 = -0.0479399, da3 = 0.3739278, dap = 0.47047;
a = TMath::Abs(x);
w = 1. + dap * a;
t = 1. / w;
w = a * a;
if (w < 700)
c = exp(-w);
else {
c = 0;
}
c = (-1.) * dap * c * t * t * (da1 + t * (2. * da2 + t * 3. * da3)) -
2. * a * Erfc(a);
return (c);
}
Double_t TSpectrumFit::Deramp(Double_t i, Double_t i0, Double_t sigma, Double_t t,
Double_t s, Double_t b)
{
Double_t p, q, r, a;
p = (i - i0) / sigma;
if ((p * p) < 700)
q = exp(-p * p);
else {
q = 0;
}
r = 0;
if (t != 0) {
a = p / b;
if (a > 700)
a = 700;
r = t * exp(a) / 2.;
}
if (r != 0)
r = r * Erfc(p + 1. / (2. * b));
q = q + r;
if (s != 0)
q = q + s * Erfc(p) / 2.;
return (q);
}
Double_t TSpectrumFit::Deri0(Double_t i, Double_t amp, Double_t i0, Double_t sigma,
Double_t t, Double_t s, Double_t b)
{
Double_t p, r1, r2, r3, r4, c, d, e;
p = (i - i0) / sigma;
d = 2. * sigma;
if ((p * p) < 700)
r1 = 2. * p * exp(-p * p) / sigma;
else {
r1 = 0;
}
r2 = 0, r3 = 0;
if (t != 0) {
c = p + 1. / (2. * b);
e = p / b;
if (e > 700)
e = 700;
r2 = -t * exp(e) * Erfc(c) / (d * b);
r3 = -t * exp(e) * Derfc(c) / d;
}
r4 = 0;
if (s != 0)
r4 = -s * Derfc(p) / d;
r1 = amp * (r1 + r2 + r3 + r4);
return (r1);
}
Double_t TSpectrumFit::Derderi0(Double_t i, Double_t amp, Double_t i0,
Double_t sigma)
{
Double_t p, r1, r2, r3, r4;
p = (i - i0) / sigma;
if ((p * p) < 700)
r1 = exp(-p * p);
else {
r1 = 0;
}
r1 = r1 * (4 * p * p - 2) / (sigma * sigma);
r2 = 0, r3 = 0, r4 = 0;
r1 = amp * (r1 + r2 + r3 + r4);
return (r1);
}
Double_t TSpectrumFit::Dersigma(Int_t num_of_fitted_peaks, Double_t i,
const Double_t *parameter, Double_t sigma,
Double_t t, Double_t s, Double_t b)
{
Int_t j;
Double_t r, p, r1, r2, r3, r4, c, d, e;
r = 0;
d = 2. * sigma;
for (j = 0; j < num_of_fitted_peaks; j++) {
p = (i - parameter[2 * j + 1]) / sigma;
r1 = 0;
if (TMath::Abs(p) < 3) {
if ((p * p) < 700)
r1 = 2. * p * p * exp(-p * p) / sigma;
else {
r1 = 0;
}
}
r2 = 0, r3 = 0;
if (t != 0) {
c = p + 1. / (2. * b);
e = p / b;
if (e > 700)
e = 700;
r2 = -t * p * exp(e) * Erfc(c) / (d * b);
r3 = -t * p * exp(e) * Derfc(c) / d;
}
r4 = 0;
if (s != 0)
r4 = -s * p * Derfc(p) / d;
r = r + parameter[2 * j] * (r1 + r2 + r3 + r4);
}
return (r);
}
Double_t TSpectrumFit::Derdersigma(Int_t num_of_fitted_peaks, Double_t i,
const Double_t *parameter, Double_t sigma)
{
Int_t j;
Double_t r, p, r1, r2, r3, r4;
r = 0;
for (j = 0; j < num_of_fitted_peaks; j++) {
p = (i - parameter[2 * j + 1]) / sigma;
r1 = 0;
if (TMath::Abs(p) < 3) {
if ((p * p) < 700)
r1 = exp(-p * p) * p * p * (4. * p * p - 6) / (sigma * sigma);
else {
r1 = 0;
}
}
r2 = 0, r3 = 0, r4 = 0;
r = r + parameter[2 * j] * (r1 + r2 + r3 + r4);
}
return (r);
}
Double_t TSpectrumFit::Dert(Int_t num_of_fitted_peaks, Double_t i,
const Double_t *parameter, Double_t sigma, Double_t b)
{
Int_t j;
Double_t r, p, r1, c, e;
r = 0;
for (j = 0; j < num_of_fitted_peaks; j++) {
p = (i - parameter[2 * j + 1]) / sigma;
c = p + 1. / (2. * b);
e = p / b;
if (e > 700)
e = 700;
r1 = exp(e) * Erfc(c);
r = r + parameter[2 * j] * r1;
}
r = r / 2.;
return (r);
}
Double_t TSpectrumFit::Ders(Int_t num_of_fitted_peaks, Double_t i,
const Double_t *parameter, Double_t sigma)
{
Int_t j;
Double_t r, p, r1;
r = 0;
for (j = 0; j < num_of_fitted_peaks; j++) {
p = (i - parameter[2 * j + 1]) / sigma;
r1 = Erfc(p);
r = r + parameter[2 * j] * r1;
}
r = r / 2.;
return (r);
}
Double_t TSpectrumFit::Derb(Int_t num_of_fitted_peaks, Double_t i,
const Double_t *parameter, Double_t sigma, Double_t t,
Double_t b)
{
Int_t j;
Double_t r, p, r1, c, e;
r = 0;
for (j = 0; j < num_of_fitted_peaks && t != 0; j++) {
p = (i - parameter[2 * j + 1]) / sigma;
c = p + 1. / (2. * b);
e = p / b;
r1 = p * Erfc(c);
r1 = r1 + Derfc(c) / 2.;
if (e > 700)
e = 700;
if (e < -700)
r1 = 0;
else
r1 = r1 * exp(e);
r = r + parameter[2 * j] * r1;
}
r = -r * t / (2. * b * b);
return (r);
}
Double_t TSpectrumFit::Dera1(Double_t i)
{
return (i);
}
Double_t TSpectrumFit::Dera2(Double_t i)
{
return (i * i);
}
Double_t TSpectrumFit::Shape(Int_t num_of_fitted_peaks, Double_t i,
const Double_t *parameter, Double_t sigma, Double_t t,
Double_t s, Double_t b, Double_t a0, Double_t a1,
Double_t a2)
{
Int_t j;
Double_t r, p, r1, r2, r3, c, e;
r = 0;
for (j = 0; j < num_of_fitted_peaks; j++) {
if (sigma > 0.0001)
p = (i - parameter[2 * j + 1]) / sigma;
else {
if (i == parameter[2 * j + 1])
p = 0;
else
p = 10;
}
r1 = 0;
if (TMath::Abs(p) < 3) {
if ((p * p) < 700)
r1 = exp(-p * p);
else {
r1 = 0;
}
}
r2 = 0;
if (t != 0) {
c = p + 1. / (2. * b);
e = p / b;
if (e > 700)
e = 700;
r2 = t * exp(e) * Erfc(c) / 2.;
}
r3 = 0;
if (s != 0)
r3 = s * Erfc(p) / 2.;
r = r + parameter[2 * j] * (r1 + r2 + r3);
}
r = r + a0 + a1 * i + a2 * i * i;
return (r);
}
Double_t TSpectrumFit::Area(Double_t a, Double_t sigma, Double_t t, Double_t b)
{
Double_t odm_pi = 1.7724538, r = 0;
if (b != 0)
r = 0.5 / b;
r = (-1.) * r * r;
if (TMath::Abs(r) < 700)
r = a * sigma * (odm_pi + t * b * exp(r));
else {
r = a * sigma * odm_pi;
}
return (r);
}
Double_t TSpectrumFit::Derpa(Double_t sigma, Double_t t, Double_t b)
{
Double_t odm_pi = 1.7724538, r;
r = 0.5 / b;
r = (-1.) * r * r;
if (TMath::Abs(r) < 700)
r = sigma * (odm_pi + t * b * exp(r));
else {
r = sigma * odm_pi;
}
return (r);
}
Double_t TSpectrumFit::Derpsigma(Double_t a, Double_t t, Double_t b)
{
Double_t odm_pi = 1.7724538, r;
r = 0.5 / b;
r = (-1.) * r * r;
if (TMath::Abs(r) < 700)
r = a * (odm_pi + t * b * exp(r));
else {
r = a * odm_pi;
}
return (r);
}
Double_t TSpectrumFit::Derpt(Double_t a, Double_t sigma, Double_t b)
{
Double_t r;
r = 0.5 / b;
r = (-1.) * r * r;
if (TMath::Abs(r) < 700)
r = a * sigma * b * exp(r);
else {
r = 0;
}
return (r);
}
Double_t TSpectrumFit::Derpb(Double_t a, Double_t sigma, Double_t t, Double_t b)
{
Double_t r;
r = (-1) * 0.25 / (b * b);
if (TMath::Abs(r) < 700)
r = a * sigma * t * exp(r) * (1 - 2 * r);
else {
r = 0;
}
return (r);
}
Double_t TSpectrumFit::Ourpowl(Double_t a, Int_t pw)
{
Double_t c;
c = 1;
if (pw > 0)
c = c * a * a;
else if (pw > 2)
c = c * a * a;
else if (pw > 4)
c = c * a * a;
else if (pw > 6)
c = c * a * a;
else if (pw > 8)
c = c * a * a;
else if (pw > 10)
c = c * a * a;
else if (pw > 12)
c = c * a * a;
return (c);
}
void TSpectrumFit::FitAwmi(Float_t *source)
{
/* -->
<div class=Section2>
<p class=MsoNormal><b><span style='font-size:14.0pt'>Fitting</span></b></p>
<p class=MsoNormal style='text-align:justify'><i>Goal: to estimate
simultaneously peak shape parameters in spectra with large number of peaks</i></p>
<p class=MsoNormal style='margin-left:36.0pt;text-align:justify;text-indent:
-18.0pt'>•<span style='font:7.0pt "Times New Roman"'>
</span>peaks can be fitted separately, each peak (or multiplets) in a region or
together all peaks in a spectrum. To fit separately each peak one needs to
determine the fitted region. However it can happen that the regions of
neighboring peaks are overlapping. Then the results of fitting are very poor.
On the other hand, when fitting together all peaks found in a spectrum, one
needs to have a method that is stable (converges) and fast enough to carry out
fitting in reasonable time </p>
<p class=MsoNormal style='margin-left:36.0pt;text-align:justify;text-indent:
-18.0pt'>•<span style='font:7.0pt "Times New Roman"'>
</span>we have implemented the nonsymmetrical semiempirical peak shape function
[1]</p>
<p class=MsoNormal style='margin-left:36.0pt;text-align:justify;text-indent:
-18.0pt'>•<span style='font:7.0pt "Times New Roman"'>
</span>it contains the symmetrical Gaussian as well as nonsymmetrical terms.</p>
<p class=MsoNormal style='text-align:justify'>
<table cellpadding=0 cellspacing=0 align=left>
<tr>
<td width=84 height=18></td>
</tr>
<tr>
<td></td>
<td><img width=372 height=127 src="gif/spectrumfit_awni_image001.gif"></td>
</tr>
</table>
<span style='font-size:16.0pt'> </span></p>
<p class=MsoNormal style='text-align:justify'><span style='font-size:16.0pt'> </span></p>
<p class=MsoNormal style='text-align:justify'><span style='font-size:16.0pt'> </span></p>
<p class=MsoNormal style='text-align:justify'><span style='font-size:16.0pt'> </span></p>
<p class=MsoNormal style='text-align:justify'><span style='font-size:16.0pt'> </span></p>
<br clear=ALL>
<p class=MsoNormal style='text-indent:34.2pt'>where T and S are relative amplitudes
and B is slope.</p>
<p class=MsoNormal> </p>
<p class=MsoNormal style='margin-left:36.0pt;text-align:justify;text-indent:
-18.0pt'>•<span style='font:7.0pt "Times New Roman"'>
</span>algorithm without matrix inversion (AWMI) allows fitting tens, hundreds
of peaks simultaneously that represent sometimes thousands of parameters [2],
[5]. </p>
<p class=MsoNormal><i>Function:</i></p>
<p class=MsoNormal style='text-align:justify'>void <a
href="http://root.cern.ch/root/html/TSpectrum.html#TSpectrum:Fit1Awmi"><b>TSpectrumFit::FitAwmi</b></a>(<a
href="http://root.cern.ch/root/html/ListOfTypes.html#float"><b>float</b></a> *fSource)
</p>
<p class=MsoNormal style='text-align:justify'>This function fits the source
spectrum using AWMI algorithm. The calling program should fill in input fitting
parameters of the TSpectrumFit class using a set of TSpectrumFit setters. The
fitted parameters are written into the class and the fitted data are written
into source spectrum. </p>
<p class=MsoNormal> </p>
<p class=MsoNormal><i><span style='color:red'>Parameter:</span></i></p>
<p class=MsoNormal style='text-align:justify'> <b>fSource</b>-pointer to
the vector of source spectrum </p>
<p class=MsoNormal style='text-align:justify'> </p>
<p class=MsoNormal><i><span style='color:red'>Member variables of the
TSpectrumFit class:</span></i></p>
<p class=MsoNormal style='text-align:justify'><span style='font-size:10.0pt'>
Int_t fNPeaks; //number of peaks present in fit, input
parameter, it should be > 0</span></p>
<p class=MsoNormal style='text-align:justify'><span style='font-size:10.0pt'>
Int_t fNumberIterations; //number of iterations in fitting
procedure, input parameter, it should be > 0</span></p>
<p class=MsoNormal style='text-align:justify'><span style='font-size:10.0pt'>
Int_t fXmin; //first fitted channel</span></p>
<p class=MsoNormal style='text-align:justify'><span style='font-size:10.0pt'>
Int_t fXmax; //last fitted channel</span></p>
<p class=MsoNormal style='text-align:justify'><span style='font-size:10.0pt'>
Int_t fStatisticType; //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</span></p>
<p class=MsoNormal style='text-align:justify'><span style='font-size:10.0pt'>
Int_t fAlphaOptim; //optimization of convergence algorithm, possible
values kFitAlphaHalving, kFitAlphaOptimal</span></p>
<p class=MsoNormal style='text-align:justify'><span style='font-size:10.0pt'>
Int_t fPower; //possible values kFitPower2,4,6,8,10,12,
for details see references. It applies only for Awmi fitting function.</span></p>
<p class=MsoNormal style='text-align:justify'><span style='font-size:10.0pt'>
Int_t fFitTaylor; //order of Taylor expansion, possible
values kFitTaylorOrderFirst, kFitTaylorOrderSecond. It applies only for Awmi
fitting function.</span></p>
<p class=MsoNormal style='text-align:justify'><span style='font-size:10.0pt'>
Double_t fAlpha; //convergence coefficient, input
parameter, it should be positive number and <=1, for details see references</span></p>
<p class=MsoNormal style='text-align:justify'><span style='font-size:10.0pt'>
Double_t fChi; //here the fitting functions return
resulting chi square </span></p>
<p class=MsoNormal style='text-align:justify'><span style='font-size:10.0pt'>
Double_t *fPositionInit; //[fNPeaks] array of initial values of
peaks positions, input parameters</span></p>
<p class=MsoNormal style='text-align:justify'><span style='font-size:10.0pt'>
Double_t *fPositionCalc; //[fNPeaks] array of calculated values of
fitted positions, output parameters</span></p>
<p class=MsoNormal style='text-align:justify'><span style='font-size:10.0pt'>
Double_t *fPositionErr; //[fNPeaks] array of position errors</span></p>
<p class=MsoNormal style='text-align:justify'><span style='font-size:10.0pt'>
Double_t *fAmpInit; //[fNPeaks] array of initial values of
peaks amplitudes, input parameters</span></p>
<p class=MsoNormal style='text-align:justify'><span style='font-size:10.0pt'>
Double_t *fAmpCalc; //[fNPeaks] array of calculated values of
fitted amplitudes, output parameters</span></p>
<p class=MsoNormal style='text-align:justify'><span style='font-size:10.0pt'>
Double_t *fAmpErr; //[fNPeaks] array of amplitude errors</span></p>
<p class=MsoNormal style='text-align:justify'><span style='font-size:10.0pt'>
Double_t *fArea; //[fNPeaks] array of calculated areas of
peaks</span></p>
<p class=MsoNormal style='text-align:justify'><span style='font-size:10.0pt'>
Double_t *fAreaErr; //[fNPeaks] array of errors of peak areas</span></p>
<p class=MsoNormal style='text-align:justify'><span style='font-size:10.0pt'>
Double_t fSigmaInit; //initial value of sigma parameter</span></p>
<p class=MsoNormal style='text-align:justify'><span style='font-size:10.0pt'>
Double_t fSigmaCalc; //calculated value of sigma parameter</span></p>
<p class=MsoNormal style='text-align:justify'><span style='font-size:10.0pt'>
Double_t fSigmaErr; //error value of sigma parameter</span></p>
<p class=MsoNormal style='text-align:justify'><span style='font-size:10.0pt'>
Double_t fTInit; //initial value of t parameter (relative
amplitude of tail), for details see html manual and references</span></p>
<p class=MsoNormal style='text-align:justify'><span style='font-size:10.0pt'>
Double_t fTCalc; //calculated value of t parameter</span></p>
<p class=MsoNormal style='text-align:justify'><span style='font-size:10.0pt'>
Double_t fTErr; //error value of t parameter</span></p>
<p class=MsoNormal style='text-align:justify'><span style='font-size:10.0pt'>
Double_t fBInit; //initial value of b parameter (slope),
for details see html manual and references</span></p>
<p class=MsoNormal style='text-align:justify'><span style='font-size:10.0pt'>
Double_t fBCalc; //calculated value of b parameter</span></p>
<p class=MsoNormal style='text-align:justify'><span style='font-size:10.0pt'>
Double_t fBErr; //error value of b parameter</span></p>
<p class=MsoNormal style='text-align:justify'><span style='font-size:10.0pt'>
Double_t fSInit; //initial value of s parameter (relative
amplitude of step), for details see html manual and references</span></p>
<p class=MsoNormal style='text-align:justify'><span style='font-size:10.0pt'>
Double_t fSCalc; //calculated value of s parameter</span></p>
<p class=MsoNormal style='text-align:justify'><span style='font-size:10.0pt'>
Double_t fSErr; //error value of s parameter</span></p>
<p class=MsoNormal style='text-align:justify'><span style='font-size:10.0pt'>
Double_t fA0Init; //initial value of background a0
parameter(backgroud is estimated as a0+a1*x+a2*x*x)</span></p>
<p class=MsoNormal style='text-align:justify'><span style='font-size:10.0pt'>
Double_t fA0Calc; //calculated value of background a0
parameter</span></p>
<p class=MsoNormal style='text-align:justify'><span style='font-size:10.0pt'>
Double_t fA0Err; //error value of background a0 parameter</span></p>
<p class=MsoNormal style='text-align:justify'><span style='font-size:10.0pt'>
Double_t fA1Init; //initial value of background a1
parameter(backgroud is estimated as a0+a1*x+a2*x*x)</span></p>
<p class=MsoNormal style='text-align:justify'><span style='font-size:10.0pt'>
Double_t fA1Calc; //calculated value of background a1
parameter</span></p>
<p class=MsoNormal style='text-align:justify'><span style='font-size:10.0pt'>
Double_t fA1Err; //error value of background a1 parameter</span></p>
<p class=MsoNormal style='text-align:justify'><span style='font-size:10.0pt'>
Double_t fA2Init; //initial value of background a2
parameter(backgroud is estimated as a0+a1*x+a2*x*x)</span></p>
<p class=MsoNormal style='text-align:justify'><span style='font-size:10.0pt'>
Double_t fA2Calc; //calculated value of background a2
parameter</span></p>
<p class=MsoNormal style='text-align:justify'><span style='font-size:10.0pt'>
Double_t fA2Err; //error value of background a2 parameter</span></p>
<p class=MsoNormal style='text-align:justify'><span style='font-size:10.0pt'>
Bool_t *fFixPosition; //[fNPeaks] array of logical values which
allow to fix appropriate positions (not fit). However they are present in the
estimated functional </span></p>
<p class=MsoNormal style='text-align:justify'><span style='font-size:10.0pt'>
Bool_t *fFixAmp; //[fNPeaks] array of logical values which
allow to fix appropriate amplitudes (not fit). However they are present in the
estimated functional </span></p>
<p class=MsoNormal style='text-align:justify'><span style='font-size:10.0pt'>
Bool_t fFixSigma; //logical value of sigma parameter, which
allows to fix the parameter (not to fit). </span></p>
<p class=MsoNormal style='text-align:justify'><span style='font-size:10.0pt'>
Bool_t fFixT; //logical value of t parameter, which
allows to fix the parameter (not to fit). </span></p>
<p class=MsoNormal style='text-align:justify'><span style='font-size:10.0pt'>
Bool_t fFixB; //logical value of b parameter, which
allows to fix the parameter (not to fit). </span></p>
<p class=MsoNormal style='text-align:justify'><span style='font-size:10.0pt'>
Bool_t fFixS; //logical value of s parameter, which
allows to fix the parameter (not to fit). </span></p>
<p class=MsoNormal style='text-align:justify'><span style='font-size:10.0pt'>
Bool_t fFixA0; //logical value of a0 parameter, which
allows to fix the parameter (not to fit).</span></p>
<p class=MsoNormal style='text-align:justify'><span style='font-size:10.0pt'>
Bool_t fFixA1; //logical value of a1 parameter, which
allows to fix the parameter (not to fit). </span></p>
<p class=MsoNormal style='text-align:justify'><span style='font-size:10.0pt'>
Bool_t fFixA2; //logical value of a2 parameter, which
allows to fix the parameter (not to fit).</span></p>
<p class=MsoNormal style='text-align:justify'><b><i> </i></b></p>
<p class=MsoNormal style='text-align:justify'><b><i>References:</i></b></p>
<p class=MsoNormal style='text-align:justify'>[1] Phillps G.W., Marlow K.W.,
NIM 137 (1976) 525.</p>
<p class=MsoNormal style='text-align:justify'>[2] I. A. Slavic: Nonlinear
least-squares fitting without matrix inversion applied to complex Gaussian
spectra analysis. NIM 134 (1976) 285-289.</p>
<p class=MsoNormal style='text-align:justify'>[3] T. Awaya: A new method for
curve fitting to the data with low statistics not using chi-square method. NIM
165 (1979) 317-323.</p>
<p class=MsoNormal style='text-align:justify'>[4] T. Hauschild, M. Jentschel:
Comparison of maximum likelihood estimation and chi-square statistics applied
to counting experiments. NIM A 457 (2001) 384-401.</p>
<p class=MsoNormal style='text-align:justify'> [5] M. Morháč, J.
Kliman, M. Jandel, Ľ. Krupa, V. Matoušek: Study of fitting algorithms
applied to simultaneous analysis of large number of peaks in -ray spectra. <span
lang=EN-GB>Applied Spectroscopy, Vol. 57, No. 7, pp. 753-760, 2003</span></p>
<p class=MsoNormal style='text-align:justify'> </p>
<p class=MsoNormal style='text-align:justify'><i>Example – script FitAwmi.c:</i></p>
<p class=MsoNormal style='text-align:justify'><i><span style='font-size:16.0pt'><img
border=0 width=601 height=402 src="gif/spectrumfit_awni_image002.jpg"></span></i></p>
<p class=MsoNormal style='text-align:justify'><b>Fig. 1 Original spectrum
(black line) and fitted spectrum using AWMI algorithm (red line) and number of
iteration steps = 1000. Positions of fitted peaks are denoted by markers</b></p>
<p class=MsoNormal><b><span style='color:#339966'>Script:</span></b></p>
<p class=MsoNormal><span style='font-size:10.0pt'>// Example to illustrate
fitting function using AWMI algorithm.</span></p>
<p class=MsoNormal><span style='font-size:10.0pt'>// To execute this example,
do</span></p>
<p class=MsoNormal><span style='font-size:10.0pt'>// root > .x FitAwmi.C</span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'> </span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'>void FitAwmi() {</span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'> Double_t a;</span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'> Int_t
i,nfound=0,bin;</span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'> Int_t nbins = 256;</span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'> Int_t xmin = 0;</span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'> Int_t xmax =
nbins;</span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'> Float_t * source =
new float[nbins];</span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'> Float_t * dest =
new float[nbins]; </span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'> TH1F *h = new
TH1F("h","Fitting using AWMI algorithm",nbins,xmin,xmax);</span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'> TH1F *d = new
TH1F("d","",nbins,xmin,xmax); </span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'> TFile *f = new
TFile("TSpectrum.root");</span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'> h=(TH1F*)
f->Get("fit;1"); </span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'> for (i = 0; i <
nbins; i++) source[i]=h->GetBinContent(i + 1); </span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'> TCanvas *Fit1 =
gROOT->GetListOfCanvases()->FindObject("Fit1");</span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'> if (!Fit1) Fit1 =
new TCanvas("Fit1","Fit1",10,10,1000,700);</span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'>
h->Draw("L");</span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'> TSpectrum *s = new
TSpectrum();</span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'> //searching for
candidate peaks positions</span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'> nfound =
s->SearchHighRes(source, dest, nbins, 2, 0.1, kFALSE, 10000, kFALSE, 0);</span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'> Bool_t *FixPos =
new Bool_t[nfound];</span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'> Bool_t *FixAmp =
new Bool_t[nfound]; </span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'> for(i = 0; i<
nfound ; i++){</span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'> FixPos[i] =
kFALSE;</span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'> FixAmp[i] =
kFALSE; </span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'> }</span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'> //filling in the
initial estimates of the input parameters</span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'> Float_t *PosX =
new Float_t[nfound]; </span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'> Float_t *PosY =
new Float_t[nfound];</span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'> PosX =
s->GetPositionX();</span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'> for (i = 0; i <
nfound; i++) {</span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'> a=PosX[i];</span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'> bin = 1 +
Int_t(a + 0.5);</span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'> PosY[i] =
h->GetBinContent(bin);</span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'> } </span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'> TSpectrumFit
*pfit=new TSpectrumFit(nfound);</span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'>
pfit->SetFitParameters(xmin, xmax-1, 1000, 0.1, pfit->kFitOptimChiCounts,
pfit->kFitAlphaHalving, pfit->kFitPower2,
pfit->kFitTaylorOrderFirst); </span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'> pfit->SetPeakParameters(2,
kFALSE, PosX, (Bool_t *) FixPos, PosY, (Bool_t *) FixAmp); </span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'>
pfit->FitAwmi(source);</span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'> Double_t
*CalcPositions = new Double_t[nfound]; </span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'> Double_t
*CalcAmplitudes = new Double_t[nfound]; </span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'>
CalcPositions=pfit->GetPositions();</span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'>
CalcAmplitudes=pfit->GetAmplitudes(); </span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'> for (i = 0; i <
nbins; i++) d->SetBinContent(i + 1,source[i]);</span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'>
d->SetLineColor(kRed); </span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'>
d->Draw("SAME L"); </span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'> for (i = 0; i <
nfound; i++) {</span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'> a=CalcPositions[i];</span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'> bin = 1 +
Int_t(a + 0.5); </span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'> PosX[i] =
d->GetBinCenter(bin);</span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'> PosY[i] =
d->GetBinContent(bin);</span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'> }</span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'> TPolyMarker * pm =
(TPolyMarker*)h->GetListOfFunctions()->FindObject("TPolyMarker");</span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'> if (pm) {</span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'>
h->GetListOfFunctions()->Remove(pm);</span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'> delete pm;</span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'> }</span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'> pm = new
TPolyMarker(nfound, PosX, PosY);</span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'>
h->GetListOfFunctions()->Add(pm);</span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'>
pm->SetMarkerStyle(23);</span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'>
pm->SetMarkerColor(kRed);</span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'>
pm->SetMarkerSize(1); </span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'>}</span></p>
</div>
<!-- */
// --> End_Html
Int_t i, j, k, shift =
2 * fNPeaks + 7, peak_vel, rozmer, iter, pw, regul_cycle,
flag;
Double_t a, b, c, d = 0, alpha, chi_opt, yw, ywm, f, chi2, chi_min, chi =
0, pi, pmin = 0, chi_cel = 0, chi_er;
Double_t *working_space = new Double_t[5 * (2 * fNPeaks + 7)];
for (i = 0, j = 0; i < fNPeaks; i++) {
working_space[2 * i] = fAmpInit[i];
if (fFixAmp[i] == false) {
working_space[shift + j] = fAmpInit[i];
j += 1;
}
working_space[2 * i + 1] = fPositionInit[i];
if (fFixPosition[i] == false) {
working_space[shift + j] = fPositionInit[i];
j += 1;
}
}
peak_vel = 2 * i;
working_space[2 * i] = fSigmaInit;
if (fFixSigma == false) {
working_space[shift + j] = fSigmaInit;
j += 1;
}
working_space[2 * i + 1] = fTInit;
if (fFixT == false) {
working_space[shift + j] = fTInit;
j += 1;
}
working_space[2 * i + 2] = fBInit;
if (fFixB == false) {
working_space[shift + j] = fBInit;
j += 1;
}
working_space[2 * i + 3] = fSInit;
if (fFixS == false) {
working_space[shift + j] = fSInit;
j += 1;
}
working_space[2 * i + 4] = fA0Init;
if (fFixA0 == false) {
working_space[shift + j] = fA0Init;
j += 1;
}
working_space[2 * i + 5] = fA1Init;
if (fFixA1 == false) {
working_space[shift + j] = fA1Init;
j += 1;
}
working_space[2 * i + 6] = fA2Init;
if (fFixA2 == false) {
working_space[shift + j] = fA2Init;
j += 1;
}
rozmer = j;
if (rozmer == 0){
Error ("FitAwmi","All parameters are fixed");
return;
}
if (rozmer >= fXmax - fXmin + 1){
Error ("FitAwmi","Number of fitted parameters is larger than # of fitted points");
return;
}
for (iter = 0; iter < fNumberIterations; iter++) {
for (j = 0; j < rozmer; j++) {
working_space[2 * shift + j] = 0, working_space[3 * shift + j] = 0;
}
alpha = fAlpha;
chi_opt = 0, pw = fPower - 2;
for (i = fXmin; i <= fXmax; i++) {
yw = source[i];
ywm = yw;
f = Shape(fNPeaks, (Double_t) i, working_space,
working_space[peak_vel], working_space[peak_vel + 1],
working_space[peak_vel + 3],
working_space[peak_vel + 2],
working_space[peak_vel + 4],
working_space[peak_vel + 5],
working_space[peak_vel + 6]);
if (fStatisticType == kFitOptimMaxLikelihood) {
if (f > 0.00001)
chi_opt += yw * TMath::Log(f) - f;
}
else {
if (ywm != 0)
chi_opt += (yw - f) * (yw - f) / ywm;
}
if (fStatisticType == kFitOptimChiFuncValues) {
ywm = f;
if (f < 0.00001)
ywm = 0.00001;
}
else if (fStatisticType == kFitOptimMaxLikelihood) {
ywm = f;
if (f < 0.001)
ywm = 0.001;
}
else {
if (ywm == 0)
ywm = 1;
}
for (j = 0, k = 0; j < fNPeaks; j++) {
if (fFixAmp[j] == false) {
a = Deramp((Double_t) i, working_space[2 * j + 1],
working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 3],
working_space[peak_vel + 2]);
if (ywm != 0) {
c = Ourpowl(a, pw);
if (fStatisticType == kFitOptimChiFuncValues) {
b = a * (yw * yw - f * f) / (ywm * ywm);
working_space[2 * shift + k] += b * c;
b = a * a * (4 * yw - 2 * f) / (ywm * ywm);
working_space[3 * shift + k] += b * c;
}
else {
b = a * (yw - f) / ywm;
working_space[2 * shift + k] += b * c;
b = a * a / ywm;
working_space[3 * shift + k] += b * c;
}
}
k += 1;
}
if (fFixPosition[j] == false) {
a = Deri0((Double_t) i, working_space[2 * j],
working_space[2 * j + 1],
working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 3],
working_space[peak_vel + 2]);
if (fFitTaylor == kFitTaylorOrderSecond)
d = Derderi0((Double_t) i, working_space[2 * j],
working_space[2 * j + 1],
working_space[peak_vel]);
if (ywm != 0) {
c = Ourpowl(a, pw);
if (TMath::Abs(a) > 0.00000001
&& fFitTaylor == kFitTaylorOrderSecond) {
d = d * TMath::Abs(yw - f) / (2 * a * ywm);
if (((a + d) <= 0 && a >= 0) || ((a + d) >= 0 && a <= 0))
d = 0;
}
else
d = 0;
a = a + d;
if (fStatisticType == kFitOptimChiFuncValues) {
b = a * (yw * yw - f * f) / (ywm * ywm);
working_space[2 * shift + k] += b * c;
b = a * a * (4 * yw - 2 * f) / (ywm * ywm);
working_space[3 * shift + k] += b * c;
}
else {
b = a * (yw - f) / ywm;
working_space[2 * shift + k] += b * c;
b = a * a / ywm;
working_space[3 * shift + k] += b * c;
}
}
k += 1;
}
}
if (fFixSigma == false) {
a = Dersigma(fNPeaks, (Double_t) i, working_space,
working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 3],
working_space[peak_vel + 2]);
if (fFitTaylor == kFitTaylorOrderSecond)
d = Derdersigma(fNPeaks, (Double_t) i,
working_space, working_space[peak_vel]);
if (ywm != 0) {
c = Ourpowl(a, pw);
if (TMath::Abs(a) > 0.00000001
&& fFitTaylor == kFitTaylorOrderSecond) {
d = d * TMath::Abs(yw - f) / (2 * a * ywm);
if (((a + d) <= 0 && a >= 0) || ((a + d) >= 0 && a <= 0))
d = 0;
}
else
d = 0;
a = a + d;
if (fStatisticType == kFitOptimChiFuncValues) {
b = a * (yw * yw - f * f) / (ywm * ywm);
working_space[2 * shift + k] += b * c;
b = a * a * (4 * yw - 2 * f) / (ywm * ywm);
working_space[3 * shift + k] += b * c;
}
else {
b = a * (yw - f) / ywm;
working_space[2 * shift + k] += b * c;
b = a * a / ywm;
working_space[3 * shift + k] += b * c;
}
}
k += 1;
}
if (fFixT == false) {
a = Dert(fNPeaks, (Double_t) i, working_space,
working_space[peak_vel],
working_space[peak_vel + 2]);
if (ywm != 0) {
c = Ourpowl(a, pw);
if (fStatisticType == kFitOptimChiFuncValues) {
b = a * (yw * yw - f * f) / (ywm * ywm);
working_space[2 * shift + k] += b * c;
b = a * a * (4 * yw - 2 * f) / (ywm * ywm);
working_space[3 * shift + k] += b * c;
}
else {
b = a * (yw - f) / ywm;
working_space[2 * shift + k] += b * c;
b = a * a / ywm;
working_space[3 * shift + k] += b * c;
}
}
k += 1;
}
if (fFixB == false) {
a = Derb(fNPeaks, (Double_t) i, working_space,
working_space[peak_vel], working_space[peak_vel + 1],
working_space[peak_vel + 2]);
if (ywm != 0) {
c = Ourpowl(a, pw);
if (fStatisticType == kFitOptimChiFuncValues) {
b = a * (yw * yw - f * f) / (ywm * ywm);
working_space[2 * shift + k] += b * c;
b = a * a * (4 * yw - 2 * f) / (ywm * ywm);
working_space[3 * shift + k] += b * c;
}
else {
b = a * (yw - f) / ywm;
working_space[2 * shift + k] += b * c;
b = a * a / ywm;
working_space[3 * shift + k] += b * c;
}
}
k += 1;
}
if (fFixS == false) {
a = Ders(fNPeaks, (Double_t) i, working_space,
working_space[peak_vel]);
if (ywm != 0) {
c = Ourpowl(a, pw);
if (fStatisticType == kFitOptimChiFuncValues) {
b = a * (yw * yw - f * f) / (ywm * ywm);
working_space[2 * shift + k] += b * c;
b = a * a * (4 * yw - 2 * f) / (ywm * ywm);
working_space[3 * shift + k] += b * c;
}
else {
b = a * (yw - f) / ywm;
working_space[2 * shift + k] += b * c;
b = a * a / ywm;
working_space[3 * shift + k] += b * c;
}
}
k += 1;
}
if (fFixA0 == false) {
a = 1.;
if (ywm != 0) {
c = Ourpowl(a, pw);
if (fStatisticType == kFitOptimChiFuncValues) {
b = a * (yw * yw - f * f) / (ywm * ywm);
working_space[2 * shift + k] += b * c;
b = a * a * (4 * yw - 2 * f) / (ywm * ywm);
working_space[3 * shift + k] += b * c;
}
else {
b = a * (yw - f) / ywm;
working_space[2 * shift + k] += b * c;
b = a * a / ywm;
working_space[3 * shift + k] += b * c;
}
}
k += 1;
}
if (fFixA1 == false) {
a = Dera1((Double_t) i);
if (ywm != 0) {
c = Ourpowl(a, pw);
if (fStatisticType == kFitOptimChiFuncValues) {
b = a * (yw * yw - f * f) / (ywm * ywm);
working_space[2 * shift + k] += b * c;
b = a * a * (4 * yw - 2 * f) / (ywm * ywm);
working_space[3 * shift + k] += b * c;
}
else {
b = a * (yw - f) / ywm;
working_space[2 * shift + k] += b * c;
b = a * a / ywm;
working_space[3 * shift + k] += b * c;
}
}
k += 1;
}
if (fFixA2 == false) {
a = Dera2((Double_t) i);
if (ywm != 0) {
c = Ourpowl(a, pw);
if (fStatisticType == kFitOptimChiFuncValues) {
b = a * (yw * yw - f * f) / (ywm * ywm);
working_space[2 * shift + k] += b * c;
b = a * a * (4 * yw - 2 * f) / (ywm * ywm);
working_space[3 * shift + k] += b * c;
}
else {
b = a * (yw - f) / ywm;
working_space[2 * shift + k] += b * c;
b = a * a / ywm;
working_space[3 * shift + k] += b * c;
}
}
k += 1;
}
}
for (j = 0; j < rozmer; j++) {
if (TMath::Abs(working_space[3 * shift + j]) > 0.000001)
working_space[2 * shift + j] = working_space[2 * shift + j] / TMath::Abs(working_space[3 * shift + j]);
else
working_space[2 * shift + j] = 0;
}
chi2 = chi_opt;
chi_opt = TMath::Sqrt(TMath::Abs(chi_opt));
regul_cycle = 0;
for (j = 0; j < rozmer; j++) {
working_space[4 * shift + j] = working_space[shift + j];
}
do {
if (fAlphaOptim == kFitAlphaOptimal) {
if (fStatisticType != kFitOptimMaxLikelihood)
chi_min = 10000 * chi2;
else
chi_min = 0.1 * chi2;
flag = 0;
for (pi = 0.1; flag == 0 && pi <= 100; pi += 0.1) {
for (j = 0; j < rozmer; j++) {
working_space[shift + j] = working_space[4 * shift + j] + pi * alpha * working_space[2 * shift + j];
}
for (i = 0, j = 0; i < fNPeaks; i++) {
if (fFixAmp[i] == false) {
if (working_space[shift + j] < 0)
working_space[shift + j] = 0;
working_space[2 * i] = working_space[shift + j];
j += 1;
}
if (fFixPosition[i] == false) {
if (working_space[shift + j] < fXmin)
working_space[shift + j] = fXmin;
if (working_space[shift + j] > fXmax)
working_space[shift + j] = fXmax;
working_space[2 * i + 1] = working_space[shift + j];
j += 1;
}
}
if (fFixSigma == false) {
if (working_space[shift + j] < 0.001) {
working_space[shift + j] = 0.001;
}
working_space[peak_vel] = working_space[shift + j];
j += 1;
}
if (fFixT == false) {
working_space[peak_vel + 1] = working_space[shift + j];
j += 1;
}
if (fFixB == false) {
if (TMath::Abs(working_space[shift + j]) < 0.001) {
if (working_space[shift + j] < 0)
working_space[shift + j] = -0.001;
else
working_space[shift + j] = 0.001;
}
working_space[peak_vel + 2] = working_space[shift + j];
j += 1;
}
if (fFixS == false) {
working_space[peak_vel + 3] = working_space[shift + j];
j += 1;
}
if (fFixA0 == false) {
working_space[peak_vel + 4] = working_space[shift + j];
j += 1;
}
if (fFixA1 == false) {
working_space[peak_vel + 5] = working_space[shift + j];
j += 1;
}
if (fFixA2 == false) {
working_space[peak_vel + 6] = working_space[shift + j];
j += 1;
}
chi2 = 0;
for (i = fXmin; i <= fXmax; i++) {
yw = source[i];
ywm = yw;
f = Shape(fNPeaks, (Double_t) i, working_space,
working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 3],
working_space[peak_vel + 2],
working_space[peak_vel + 4],
working_space[peak_vel + 5],
working_space[peak_vel + 6]);
if (fStatisticType == kFitOptimChiFuncValues) {
ywm = f;
if (f < 0.00001)
ywm = 0.00001;
}
if (fStatisticType == kFitOptimMaxLikelihood) {
if (f > 0.00001)
chi2 += yw * TMath::Log(f) - f;
}
else {
if (ywm != 0)
chi2 += (yw - f) * (yw - f) / ywm;
}
}
if ((chi2 < chi_min
&& fStatisticType != kFitOptimMaxLikelihood)
|| (chi2 > chi_min
&& fStatisticType == kFitOptimMaxLikelihood)) {
pmin = pi, chi_min = chi2;
}
else
flag = 1;
if (pi == 0.1)
chi_min = chi2;
chi = chi_min;
}
if (pmin != 0.1) {
for (j = 0; j < rozmer; j++) {
working_space[shift + j] = working_space[4 * shift + j] + pmin * alpha * working_space[2 * shift + j];
}
for (i = 0, j = 0; i < fNPeaks; i++) {
if (fFixAmp[i] == false) {
if (working_space[shift + j] < 0)
working_space[shift + j] = 0;
working_space[2 * i] = working_space[shift + j];
j += 1;
}
if (fFixPosition[i] == false) {
if (working_space[shift + j] < fXmin)
working_space[shift + j] = fXmin;
if (working_space[shift + j] > fXmax)
working_space[shift + j] = fXmax;
working_space[2 * i + 1] = working_space[shift + j];
j += 1;
}
}
if (fFixSigma == false) {
if (working_space[shift + j] < 0.001) {
working_space[shift + j] = 0.001;
}
working_space[peak_vel] = working_space[shift + j];
j += 1;
}
if (fFixT == false) {
working_space[peak_vel + 1] = working_space[shift + j];
j += 1;
}
if (fFixB == false) {
if (TMath::Abs(working_space[shift + j]) < 0.001) {
if (working_space[shift + j] < 0)
working_space[shift + j] = -0.001;
else
working_space[shift + j] = 0.001;
}
working_space[peak_vel + 2] = working_space[shift + j];
j += 1;
}
if (fFixS == false) {
working_space[peak_vel + 3] = working_space[shift + j];
j += 1;
}
if (fFixA0 == false) {
working_space[peak_vel + 4] = working_space[shift + j];
j += 1;
}
if (fFixA1 == false) {
working_space[peak_vel + 5] = working_space[shift + j];
j += 1;
}
if (fFixA2 == false) {
working_space[peak_vel + 6] = working_space[shift + j];
j += 1;
}
chi = chi_min;
}
}
else {
for (j = 0; j < rozmer; j++) {
working_space[shift + j] = working_space[4 * shift + j] + alpha * working_space[2 * shift + j];
}
for (i = 0, j = 0; i < fNPeaks; i++) {
if (fFixAmp[i] == false) {
if (working_space[shift + j] < 0)
working_space[shift + j] = 0;
working_space[2 * i] = working_space[shift + j];
j += 1;
}
if (fFixPosition[i] == false) {
if (working_space[shift + j] < fXmin)
working_space[shift + j] = fXmin;
if (working_space[shift + j] > fXmax)
working_space[shift + j] = fXmax;
working_space[2 * i + 1] = working_space[shift + j];
j += 1;
}
}
if (fFixSigma == false) {
if (working_space[shift + j] < 0.001) {
working_space[shift + j] = 0.001;
}
working_space[peak_vel] = working_space[shift + j];
j += 1;
}
if (fFixT == false) {
working_space[peak_vel + 1] = working_space[shift + j];
j += 1;
}
if (fFixB == false) {
if (TMath::Abs(working_space[shift + j]) < 0.001) {
if (working_space[shift + j] < 0)
working_space[shift + j] = -0.001;
else
working_space[shift + j] = 0.001;
}
working_space[peak_vel + 2] = working_space[shift + j];
j += 1;
}
if (fFixS == false) {
working_space[peak_vel + 3] = working_space[shift + j];
j += 1;
}
if (fFixA0 == false) {
working_space[peak_vel + 4] = working_space[shift + j];
j += 1;
}
if (fFixA1 == false) {
working_space[peak_vel + 5] = working_space[shift + j];
j += 1;
}
if (fFixA2 == false) {
working_space[peak_vel + 6] = working_space[shift + j];
j += 1;
}
chi = 0;
for (i = fXmin; i <= fXmax; i++) {
yw = source[i];
ywm = yw;
f = Shape(fNPeaks, (Double_t) i, working_space,
working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 3],
working_space[peak_vel + 2],
working_space[peak_vel + 4],
working_space[peak_vel + 5],
working_space[peak_vel + 6]);
if (fStatisticType == kFitOptimChiFuncValues) {
ywm = f;
if (f < 0.00001)
ywm = 0.00001;
}
if (fStatisticType == kFitOptimMaxLikelihood) {
if (f > 0.00001)
chi += yw * TMath::Log(f) - f;
}
else {
if (ywm != 0)
chi += (yw - f) * (yw - f) / ywm;
}
}
}
chi2 = chi;
chi = TMath::Sqrt(TMath::Abs(chi));
if (fAlphaOptim == kFitAlphaHalving && chi > 1E-6)
alpha = alpha * chi_opt / (2 * chi);
else if (fAlphaOptim == kFitAlphaOptimal)
alpha = alpha / 10.0;
iter += 1;
regul_cycle += 1;
} while (((chi > chi_opt
&& fStatisticType != kFitOptimMaxLikelihood)
|| (chi < chi_opt
&& fStatisticType == kFitOptimMaxLikelihood))
&& regul_cycle < kFitNumRegulCycles);
for (j = 0; j < rozmer; j++) {
working_space[4 * shift + j] = 0;
working_space[2 * shift + j] = 0;
}
for (i = fXmin, chi_cel = 0; i <= fXmax; i++) {
yw = source[i];
if (yw == 0)
yw = 1;
f = Shape(fNPeaks, (Double_t) i, working_space,
working_space[peak_vel], working_space[peak_vel + 1],
working_space[peak_vel + 3],
working_space[peak_vel + 2],
working_space[peak_vel + 4],
working_space[peak_vel + 5],
working_space[peak_vel + 6]);
chi_opt = (yw - f) * (yw - f) / yw;
chi_cel += (yw - f) * (yw - f) / yw;
for (j = 0, k = 0; j < fNPeaks; j++) {
if (fFixAmp[j] == false) {
a = Deramp((Double_t) i, working_space[2 * j + 1],
working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 3],
working_space[peak_vel + 2]);
if (yw != 0) {
c = Ourpowl(a, pw);
working_space[2 * shift + k] += chi_opt * c;
b = a * a / yw;
working_space[4 * shift + k] += b * c;
}
k += 1;
}
if (fFixPosition[j] == false) {
a = Deri0((Double_t) i, working_space[2 * j],
working_space[2 * j + 1],
working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 3],
working_space[peak_vel + 2]);
if (yw != 0) {
c = Ourpowl(a, pw);
working_space[2 * shift + k] += chi_opt * c;
b = a * a / yw;
working_space[4 * shift + k] += b * c;
}
k += 1;
}
}
if (fFixSigma == false) {
a = Dersigma(fNPeaks, (Double_t) i, working_space,
working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 3],
working_space[peak_vel + 2]);
if (yw != 0) {
c = Ourpowl(a, pw);
working_space[2 * shift + k] += chi_opt * c;
b = a * a / yw;
working_space[4 * shift + k] += b * c;
}
k += 1;
}
if (fFixT == false) {
a = Dert(fNPeaks, (Double_t) i, working_space,
working_space[peak_vel],
working_space[peak_vel + 2]);
if (yw != 0) {
c = Ourpowl(a, pw);
working_space[2 * shift + k] += chi_opt * c;
b = a * a / yw;
working_space[4 * shift + k] += b * c;
}
k += 1;
}
if (fFixB == false) {
a = Derb(fNPeaks, (Double_t) i, working_space,
working_space[peak_vel], working_space[peak_vel + 1],
working_space[peak_vel + 2]);
if (yw != 0) {
c = Ourpowl(a, pw);
working_space[2 * shift + k] += chi_opt * c;
b = a * a / yw;
working_space[4 * shift + k] += b * c;
}
k += 1;
}
if (fFixS == false) {
a = Ders(fNPeaks, (Double_t) i, working_space,
working_space[peak_vel]);
if (yw != 0) {
c = Ourpowl(a, pw);
working_space[2 * shift + k] += chi_opt * c;
b = a * a / yw;
working_space[4 * shift + k] += b * c;
}
k += 1;
}
if (fFixA0 == false) {
a = 1.0;
if (yw != 0) {
c = Ourpowl(a, pw);
working_space[2 * shift + k] += chi_opt * c;
b = a * a / yw;
working_space[4 * shift + k] += b * c;
}
k += 1;
}
if (fFixA1 == false) {
a = Dera1((Double_t) i);
if (yw != 0) {
c = Ourpowl(a, pw);
working_space[2 * shift + k] += chi_opt * c;
b = a * a / yw;
working_space[4 * shift + k] += b * c;
}
k += 1;
}
if (fFixA2 == false) {
a = Dera2((Double_t) i);
if (yw != 0) {
c = Ourpowl(a, pw);
working_space[2 * shift + k] += chi_opt * c;
b = a * a / yw;
working_space[4 * shift + k] += b * c;
}
k += 1;
}
}
}
b = fXmax - fXmin + 1 - rozmer;
chi_er = chi_cel / b;
for (i = 0, j = 0; i < fNPeaks; i++) {
fArea[i] =
Area(working_space[2 * i], working_space[peak_vel],
working_space[peak_vel + 1], working_space[peak_vel + 2]);
if (fFixAmp[i] == false) {
fAmpCalc[i] = working_space[shift + j];
if (working_space[3 * shift + j] != 0)
fAmpErr[i] = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j]));
if (fArea[i] > 0) {
a = Derpa(working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 2]);
b = working_space[4 * shift + j];
if (b == 0)
b = 1;
else
b = 1 / b;
fAreaErr[i] = TMath::Sqrt(TMath::Abs(a * a * b * chi_er));
}
else
fAreaErr[i] = 0;
j += 1;
}
else {
fAmpCalc[i] = fAmpInit[i];
fAmpErr[i] = 0;
fAreaErr[i] = 0;
}
if (fFixPosition[i] == false) {
fPositionCalc[i] = working_space[shift + j];
if (working_space[3 * shift + j] != 0)
fPositionErr[i] = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j]));
j += 1;
}
else {
fPositionCalc[i] = fPositionInit[i];
fPositionErr[i] = 0;
}
}
if (fFixSigma == false) {
fSigmaCalc = working_space[shift + j];
if (working_space[3 * shift + j] != 0)
fSigmaErr = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j]));
j += 1;
}
else {
fSigmaCalc = fSigmaInit;
fSigmaErr = 0;
}
if (fFixT == false) {
fTCalc = working_space[shift + j];
if (working_space[3 * shift + j] != 0)
fTErr = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j]));
j += 1;
}
else {
fTCalc = fTInit;
fTErr = 0;
}
if (fFixB == false) {
fBCalc = working_space[shift + j];
if (working_space[3 * shift + j] != 0)
fBErr = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j]));
j += 1;
}
else {
fBCalc = fBInit;
fBErr = 0;
}
if (fFixS == false) {
fSCalc = working_space[shift + j];
if (working_space[3 * shift + j] != 0)
fSErr = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j]));
j += 1;
}
else {
fSCalc = fSInit;
fSErr = 0;
}
if (fFixA0 == false) {
fA0Calc = working_space[shift + j];
if (working_space[3 * shift + j] != 0)
fA0Err = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j]));
j += 1;
}
else {
fA0Calc = fA0Init;
fA0Err = 0;
}
if (fFixA1 == false) {
fA1Calc = working_space[shift + j];
if (working_space[3 * shift + j] != 0)
fA1Err = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j]));
j += 1;
}
else {
fA1Calc = fA1Init;
fA1Err = 0;
}
if (fFixA2 == false) {
fA2Calc = working_space[shift + j];
if (working_space[3 * shift + j] != 0)
fA2Err = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j]));
j += 1;
}
else {
fA2Calc = fA2Init;
fA2Err = 0;
}
b = fXmax - fXmin + 1 - rozmer;
fChi = chi_cel / b;
for (i = fXmin; i <= fXmax; i++) {
f = Shape(fNPeaks, (Double_t) i, working_space,
working_space[peak_vel], working_space[peak_vel + 1],
working_space[peak_vel + 3], working_space[peak_vel + 2],
working_space[peak_vel + 4], working_space[peak_vel + 5],
working_space[peak_vel + 6]);
source[i] = f;
}
delete[]working_space;
return;
}
void TSpectrumFit::StiefelInversion(Double_t **a, Int_t size)
{
Int_t i, j, k = 0;
Double_t sk = 0, b, lambdak, normk, normk_old = 0;
do {
normk = 0;
for (i = 0; i < size; i++) {
a[i][size + 2] = -a[i][size];
for (j = 0; j < size; j++) {
a[i][size + 2] += a[i][j] * a[j][size + 1];
}
normk += a[i][size + 2] * a[i][size + 2];
}
if (k != 0) {
sk = normk / normk_old;
}
for (i = 0; i < size; i++) {
a[i][size + 3] = -a[i][size + 2] + sk * a[i][size + 3];
}
lambdak = 0;
for (i = 0; i < size; i++) {
for (j = 0, b = 0; j < size; j++) {
b += a[i][j] * a[j][size + 3];
}
lambdak += b * a[i][size + 3];
}
if (TMath::Abs(lambdak) > 1e-50)
lambdak = normk / lambdak;
else
lambdak = 0;
for (i = 0; i < size; i++)
a[i][size + 1] += lambdak * a[i][size + 3];
normk_old = normk;
k += 1;
} while (k < size && TMath::Abs(normk) > 1e-50);
return;
}
void TSpectrumFit::FitStiefel(Float_t *source)
{
/* -->
<div class=Section3>
<p class=MsoNormal><b><span style='font-size:14.0pt'>Stiefel fitting algorithm</span></b></p>
<p class=MsoNormal style='text-align:justify'><i><span style='font-size:18.0pt'> </span></i></p>
<p class=MsoNormal><i>Function:</i></p>
<p class=MsoNormal style='text-align:justify'>void <a
href="http://root.cern.ch/root/html/TSpectrum.html#TSpectrum:Fit1Awmi"><b>TSpectrumFit::</b></a>FitStiefel(<a
href="http://root.cern.ch/root/html/ListOfTypes.html#float"><b>float</b></a> *fSource)
</p>
<p class=MsoNormal style='text-align:justify'> </p>
<p class=MsoNormal style='text-align:justify'>This function fits the source
spectrum using Stiefel-Hestens method [1] (see Awmi function). The calling
program should fill in input fitting parameters of the TSpectrumFit class using
a set of TSpectrumFit setters. The fitted parameters are written into the class
and the fitted data are written into source spectrum. It converges faster than
Awmi method.</p>
<p class=MsoNormal> </p>
<p class=MsoNormal><i><span style='color:red'>Parameter:</span></i></p>
<p class=MsoNormal style='text-align:justify'> <b>fSource</b>-pointer to
the vector of source spectrum </p>
<p class=MsoNormal style='text-align:justify'> </p>
<p class=MsoNormal style='text-align:justify'><i>Example – script FitStiefel.c:</i></p>
<p class=MsoNormal style='text-align:justify'><i><span style='font-size:16.0pt'><img
border=0 width=601 height=402 src="gif/spectrumfit_stiefel_image001.jpg"></span></i></p>
<p class=MsoNormal style='text-align:justify'><b>Fig. 2 Original spectrum
(black line) and fitted spectrum using Stiefel-Hestens method (red line) and
number of iteration steps = 100. Positions of fitted peaks are denoted by
markers</b></p>
<p class=MsoNormal><b><span style='color:#339966'> </span></b></p>
<p class=MsoNormal><b><span style='color:#339966'>Script:</span></b></p>
<p class=MsoNormal><span style='font-size:10.0pt'>// Example to illustrate
fitting function using Stiefel-Hestens method.</span></p>
<p class=MsoNormal><span style='font-size:10.0pt'>// To execute this example, do</span></p>
<p class=MsoNormal><span style='font-size:10.0pt'>// root > .x FitStiefel.C</span></p>
<p class=MsoNormal><span style='font-size:10.0pt'> </span></p>
<p class=MsoNormal><span style='font-size:10.0pt'>void FitStiefel() {</span></p>
<p class=MsoNormal><span style='font-size:10.0pt'> Double_t a;</span></p>
<p class=MsoNormal><span style='font-size:10.0pt'> Int_t i,nfound=0,bin;</span></p>
<p class=MsoNormal><span style='font-size:10.0pt'> Int_t nbins = 256;</span></p>
<p class=MsoNormal><span style='font-size:10.0pt'> </span><span lang=FR
style='font-size:10.0pt'>Int_t xmin = 0;</span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'> Int_t xmax =
nbins;</span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'> </span><span
style='font-size:10.0pt'>Float_t * source = new float[nbins];</span></p>
<p class=MsoNormal><span style='font-size:10.0pt'> Float_t * dest = new
float[nbins]; </span></p>
<p class=MsoNormal><span style='font-size:10.0pt'> TH1F *h = new TH1F("h","Fitting
using AWMI algorithm",nbins,xmin,xmax);</span></p>
<p class=MsoNormal><span style='font-size:10.0pt'> TH1F *d = new
TH1F("d","",nbins,xmin,xmax); </span></p>
<p class=MsoNormal><span style='font-size:10.0pt'> TFile *f = new
TFile("TSpectrum.root");</span></p>
<p class=MsoNormal><span style='font-size:10.0pt'> h=(TH1F*)
f->Get("fit;1"); </span></p>
<p class=MsoNormal><span style='font-size:10.0pt'> for (i = 0; i < nbins;
i++) source[i]=h->GetBinContent(i + 1); </span></p>
<p class=MsoNormal><span style='font-size:10.0pt'> TCanvas *Fit1 =
gROOT->GetListOfCanvases()->FindObject("Fit1");</span></p>
<p class=MsoNormal><span style='font-size:10.0pt'> if (!Fit1) Fit1 = new
TCanvas("Fit1","Fit1",10,10,1000,700);</span></p>
<p class=MsoNormal><span style='font-size:10.0pt'> h->Draw("L");</span></p>
<p class=MsoNormal><span style='font-size:10.0pt'> TSpectrum *s = new
TSpectrum();</span></p>
<p class=MsoNormal><span style='font-size:10.0pt'> //searching for candidate
peaks positions</span></p>
<p class=MsoNormal><span style='font-size:10.0pt'> nfound =
s->SearchHighRes(source, dest, nbins, 2, 0.1, kFALSE, 10000, kFALSE, 0);</span></p>
<p class=MsoNormal><span style='font-size:10.0pt'> Bool_t *FixPos = new
Bool_t[nfound];</span></p>
<p class=MsoNormal><span style='font-size:10.0pt'> Bool_t *FixAmp = new
Bool_t[nfound]; </span></p>
<p class=MsoNormal><span style='font-size:10.0pt'> for(i = 0; i< nfound ;
i++){</span></p>
<p class=MsoNormal><span style='font-size:10.0pt'> FixPos[i] = kFALSE;</span></p>
<p class=MsoNormal><span style='font-size:10.0pt'> FixAmp[i] = kFALSE; </span></p>
<p class=MsoNormal><span style='font-size:10.0pt'> }</span></p>
<p class=MsoNormal><span style='font-size:10.0pt'> //filling in the initial
estimates of the input parameters</span></p>
<p class=MsoNormal><span style='font-size:10.0pt'> Float_t *PosX = new
Float_t[nfound]; </span></p>
<p class=MsoNormal><span style='font-size:10.0pt'> Float_t *PosY = new
Float_t[nfound];</span></p>
<p class=MsoNormal><span style='font-size:10.0pt'> PosX =
s->GetPositionX();</span></p>
<p class=MsoNormal><span style='font-size:10.0pt'> for (i = 0; i < nfound;
i++) {</span></p>
<p class=MsoNormal><span style='font-size:10.0pt'> a=PosX[i];</span></p>
<p class=MsoNormal><span style='font-size:10.0pt'> bin = 1 + Int_t(a +
0.5);</span></p>
<p class=MsoNormal><span style='font-size:10.0pt'> PosY[i] =
h->GetBinContent(bin);</span></p>
<p class=MsoNormal><span style='font-size:10.0pt'> } </span></p>
<p class=MsoNormal><span style='font-size:10.0pt'> TSpectrumFit *pfit=new
TSpectrumFit(nfound);</span></p>
<p class=MsoNormal><span style='font-size:10.0pt'>
pfit->SetFitParameters(xmin, xmax-1, 1000, 0.1, pfit->kFitOptimChiCounts,
pfit->kFitAlphaHalving, pfit->kFitPower2,
pfit->kFitTaylorOrderFirst); </span></p>
<p class=MsoNormal><span style='font-size:10.0pt'> pfit->SetPeakParameters(2,
kFALSE, PosX, (Bool_t *) FixPos, PosY, (Bool_t *) FixAmp); </span></p>
<p class=MsoNormal><span style='font-size:10.0pt'>
pfit->FitStiefel(source);</span></p>
<p class=MsoNormal><span style='font-size:10.0pt'> Double_t *CalcPositions =
new Double_t[nfound]; </span></p>
<p class=MsoNormal><span style='font-size:10.0pt'> </span><span lang=FR
style='font-size:10.0pt'>Double_t *CalcAmplitudes = new
Double_t[nfound]; </span></p>
<p class=MsoNormal><span lang=FR style='font-size:10.0pt'> </span><span
style='font-size:10.0pt'>CalcPositions=pfit->GetPositions();</span></p>
<p class=MsoNormal><span style='font-size:10.0pt'>
CalcAmplitudes=pfit->GetAmplitudes(); </span></p>
<p class=MsoNormal><span style='font-size:10.0pt'> for (i = 0; i < nbins;
i++) d->SetBinContent(i + 1,source[i]);</span></p>
<p class=MsoNormal><span style='font-size:10.0pt'>
d->SetLineColor(kRed); </span></p>
<p class=MsoNormal><span style='font-size:10.0pt'> d->Draw("SAME
L"); </span></p>
<p class=MsoNormal><span style='font-size:10.0pt'> for (i = 0; i < nfound;
i++) {</span></p>
<p class=MsoNormal><span style='font-size:10.0pt'> a=CalcPositions[i];</span></p>
<p class=MsoNormal><span style='font-size:10.0pt'> bin = 1 + Int_t(a +
0.5); </span></p>
<p class=MsoNormal><span style='font-size:10.0pt'> PosX[i] =
d->GetBinCenter(bin);</span></p>
<p class=MsoNormal><span style='font-size:10.0pt'> PosY[i] =
d->GetBinContent(bin);</span></p>
<p class=MsoNormal><span style='font-size:10.0pt'> }</span></p>
<p class=MsoNormal><span style='font-size:10.0pt'> TPolyMarker * pm =
(TPolyMarker*)h->GetListOfFunctions()->FindObject("TPolyMarker");</span></p>
<p class=MsoNormal><span style='font-size:10.0pt'> if (pm) {</span></p>
<p class=MsoNormal><span style='font-size:10.0pt'>
h->GetListOfFunctions()->Remove(pm);</span></p>
<p class=MsoNormal><span style='font-size:10.0pt'> delete pm;</span></p>
<p class=MsoNormal><span style='font-size:10.0pt'> }</span></p>
<p class=MsoNormal><span style='font-size:10.0pt'> pm = new
TPolyMarker(nfound, PosX, PosY);</span></p>
<p class=MsoNormal><span style='font-size:10.0pt'>
h->GetListOfFunctions()->Add(pm);</span></p>
<p class=MsoNormal><span style='font-size:10.0pt'> pm->SetMarkerStyle(23);</span></p>
<p class=MsoNormal><span style='font-size:10.0pt'>
pm->SetMarkerColor(kRed);</span></p>
<p class=MsoNormal><span style='font-size:10.0pt'> pm->SetMarkerSize(1);
</span></p>
<p class=MsoNormal><span style='font-size:10.0pt'>}</span></p>
</div>
<!-- */
// --> End_Html
Int_t i, j, k, shift =
2 * fNPeaks + 7, peak_vel, rozmer, iter, regul_cycle,
flag;
Double_t a, b, alpha, chi_opt, yw, ywm, f, chi2, chi_min, chi =
0, pi, pmin = 0, chi_cel = 0, chi_er;
Double_t *working_space = new Double_t[5 * (2 * fNPeaks + 7)];
for (i = 0, j = 0; i < fNPeaks; i++) {
working_space[2 * i] = fAmpInit[i];
if (fFixAmp[i] == false) {
working_space[shift + j] = fAmpInit[i];
j += 1;
}
working_space[2 * i + 1] = fPositionInit[i];
if (fFixPosition[i] == false) {
working_space[shift + j] = fPositionInit[i];
j += 1;
}
}
peak_vel = 2 * i;
working_space[2 * i] = fSigmaInit;
if (fFixSigma == false) {
working_space[shift + j] = fSigmaInit;
j += 1;
}
working_space[2 * i + 1] = fTInit;
if (fFixT == false) {
working_space[shift + j] = fTInit;
j += 1;
}
working_space[2 * i + 2] = fBInit;
if (fFixB == false) {
working_space[shift + j] = fBInit;
j += 1;
}
working_space[2 * i + 3] = fSInit;
if (fFixS == false) {
working_space[shift + j] = fSInit;
j += 1;
}
working_space[2 * i + 4] = fA0Init;
if (fFixA0 == false) {
working_space[shift + j] = fA0Init;
j += 1;
}
working_space[2 * i + 5] = fA1Init;
if (fFixA1 == false) {
working_space[shift + j] = fA1Init;
j += 1;
}
working_space[2 * i + 6] = fA2Init;
if (fFixA2 == false) {
working_space[shift + j] = fA2Init;
j += 1;
}
rozmer = j;
if (rozmer == 0){
Error ("FitAwmi","All parameters are fixed");
return;
}
if (rozmer >= fXmax - fXmin + 1){
Error ("FitAwmi","Number of fitted parameters is larger than # of fitted points");
return;
}
Double_t **working_matrix = new Double_t *[rozmer];
for (i = 0; i < rozmer; i++)
working_matrix[i] = new Double_t[rozmer + 4];
for (iter = 0; iter < fNumberIterations; iter++) {
for (j = 0; j < rozmer; j++) {
working_space[3 * shift + j] = 0;
for (k = 0; k <= rozmer; k++) {
working_matrix[j][k] = 0;
}
}
alpha = fAlpha;
chi_opt = 0;
for (i = fXmin; i <= fXmax; i++) {
for (j = 0, k = 0; j < fNPeaks; j++) {
if (fFixAmp[j] == false) {
working_space[2 * shift + k] =
Deramp((Double_t) i, working_space[2 * j + 1],
working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 3],
working_space[peak_vel + 2]);
k += 1;
}
if (fFixPosition[j] == false) {
working_space[2 * shift + k] =
Deri0((Double_t) i, working_space[2 * j],
working_space[2 * j + 1], working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 3],
working_space[peak_vel + 2]);
k += 1;
}
} if (fFixSigma == false) {
working_space[2 * shift + k] =
Dersigma(fNPeaks, (Double_t) i, working_space,
working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 3],
working_space[peak_vel + 2]);
k += 1;
}
if (fFixT == false) {
working_space[2 * shift + k] =
Dert(fNPeaks, (Double_t) i, working_space,
working_space[peak_vel], working_space[peak_vel + 2]);
k += 1;
}
if (fFixB == false) {
working_space[2 * shift + k] =
Derb(fNPeaks, (Double_t) i, working_space,
working_space[peak_vel], working_space[peak_vel + 1],
working_space[peak_vel + 2]);
k += 1;
}
if (fFixS == false) {
working_space[2 * shift + k] =
Ders(fNPeaks, (Double_t) i, working_space,
working_space[peak_vel]);
k += 1;
}
if (fFixA0 == false) {
working_space[2 * shift + k] = 1.;
k += 1;
}
if (fFixA1 == false) {
working_space[2 * shift + k] = Dera1((Double_t) i);
k += 1;
}
if (fFixA2 == false) {
working_space[2 * shift + k] = Dera2((Double_t) i);
k += 1;
}
yw = source[i];
ywm = yw;
f = Shape(fNPeaks, (Double_t) i, working_space,
working_space[peak_vel], working_space[peak_vel + 1],
working_space[peak_vel + 3],
working_space[peak_vel + 2],
working_space[peak_vel + 4],
working_space[peak_vel + 5],
working_space[peak_vel + 6]);
if (fStatisticType == kFitOptimMaxLikelihood) {
if (f > 0.00001)
chi_opt += yw * TMath::Log(f) - f;
}
else {
if (ywm != 0)
chi_opt += (yw - f) * (yw - f) / ywm;
}
if (fStatisticType == kFitOptimChiFuncValues) {
ywm = f;
if (f < 0.00001)
ywm = 0.00001;
}
else if (fStatisticType == kFitOptimMaxLikelihood) {
ywm = f;
if (f < 0.00001)
ywm = 0.00001;
}
else {
if (ywm == 0)
ywm = 1;
}
for (j = 0; j < rozmer; j++) {
for (k = 0; k < rozmer; k++) {
b = working_space[2 * shift +
j] * working_space[2 * shift + k] / ywm;
if (fStatisticType == kFitOptimChiFuncValues)
b = b * (4 * yw - 2 * f) / ywm;
working_matrix[j][k] += b;
if (j == k)
working_space[3 * shift + j] += b;
}
}
if (fStatisticType == kFitOptimChiFuncValues)
b = (f * f - yw * yw) / (ywm * ywm);
else
b = (f - yw) / ywm;
for (j = 0; j < rozmer; j++) {
working_matrix[j][rozmer] -= b * working_space[2 * shift + j];
}
}
for (i = 0; i < rozmer; i++) {
working_matrix[i][rozmer + 1] = 0;
}
StiefelInversion(working_matrix, rozmer);
for (i = 0; i < rozmer; i++) {
working_space[2 * shift + i] = working_matrix[i][rozmer + 1];
}
chi2 = chi_opt;
chi_opt = TMath::Sqrt(TMath::Abs(chi_opt));
regul_cycle = 0;
for (j = 0; j < rozmer; j++) {
working_space[4 * shift + j] = working_space[shift + j];
}
do {
if (fAlphaOptim == kFitAlphaOptimal) {
if (fStatisticType != kFitOptimMaxLikelihood)
chi_min = 10000 * chi2;
else
chi_min = 0.1 * chi2;
flag = 0;
for (pi = 0.1; flag == 0 && pi <= 100; pi += 0.1) {
for (j = 0; j < rozmer; j++) {
working_space[shift + j] = working_space[4 * shift + j] + pi * alpha * working_space[2 * shift + j];
}
for (i = 0, j = 0; i < fNPeaks; i++) {
if (fFixAmp[i] == false) {
if (working_space[shift + j] < 0)
working_space[shift + j] = 0;
working_space[2 * i] = working_space[shift + j];
j += 1;
}
if (fFixPosition[i] == false) {
if (working_space[shift + j] < fXmin)
working_space[shift + j] = fXmin;
if (working_space[shift + j] > fXmax)
working_space[shift + j] = fXmax;
working_space[2 * i + 1] = working_space[shift + j];
j += 1;
}
}
if (fFixSigma == false) {
if (working_space[shift + j] < 0.001) {
working_space[shift + j] = 0.001;
}
working_space[peak_vel] = working_space[shift + j];
j += 1;
}
if (fFixT == false) {
working_space[peak_vel + 1] = working_space[shift + j];
j += 1;
}
if (fFixB == false) {
if (TMath::Abs(working_space[shift + j]) < 0.001) {
if (working_space[shift + j] < 0)
working_space[shift + j] = -0.001;
else
working_space[shift + j] = 0.001;
}
working_space[peak_vel + 2] = working_space[shift + j];
j += 1;
}
if (fFixS == false) {
working_space[peak_vel + 3] = working_space[shift + j];
j += 1;
}
if (fFixA0 == false) {
working_space[peak_vel + 4] = working_space[shift + j];
j += 1;
}
if (fFixA1 == false) {
working_space[peak_vel + 5] = working_space[shift + j];
j += 1;
}
if (fFixA2 == false) {
working_space[peak_vel + 6] = working_space[shift + j];
j += 1;
}
chi2 = 0;
for (i = fXmin; i <= fXmax; i++) {
yw = source[i];
ywm = yw;
f = Shape(fNPeaks, (Double_t) i, working_space,
working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 3],
working_space[peak_vel + 2],
working_space[peak_vel + 4],
working_space[peak_vel + 5],
working_space[peak_vel + 6]);
if (fStatisticType == kFitOptimChiFuncValues) {
ywm = f;
if (f < 0.00001)
ywm = 0.00001;
}
if (fStatisticType == kFitOptimMaxLikelihood) {
if (f > 0.00001)
chi2 += yw * TMath::Log(f) - f;
}
else {
if (ywm != 0)
chi2 += (yw - f) * (yw - f) / ywm;
}
}
if ((chi2 < chi_min
&& fStatisticType != kFitOptimMaxLikelihood)
|| (chi2 > chi_min
&& fStatisticType == kFitOptimMaxLikelihood)) {
pmin = pi, chi_min = chi2;
}
else
flag = 1;
if (pi == 0.1)
chi_min = chi2;
chi = chi_min;
}
if (pmin != 0.1) {
for (j = 0; j < rozmer; j++) {
working_space[shift + j] = working_space[4 * shift + j] + pmin * alpha * working_space[2 * shift + j];
}
for (i = 0, j = 0; i < fNPeaks; i++) {
if (fFixAmp[i] == false) {
if (working_space[shift + j] < 0)
working_space[shift + j] = 0;
working_space[2 * i] = working_space[shift + j];
j += 1;
}
if (fFixPosition[i] == false) {
if (working_space[shift + j] < fXmin)
working_space[shift + j] = fXmin;
if (working_space[shift + j] > fXmax)
working_space[shift + j] = fXmax;
working_space[2 * i + 1] = working_space[shift + j];
j += 1;
}
}
if (fFixSigma == false) {
if (working_space[shift + j] < 0.001) {
working_space[shift + j] = 0.001;
}
working_space[peak_vel] = working_space[shift + j];
j += 1;
}
if (fFixT == false) {
working_space[peak_vel + 1] = working_space[shift + j];
j += 1;
}
if (fFixB == false) {
if (TMath::Abs(working_space[shift + j]) < 0.001) {
if (working_space[shift + j] < 0)
working_space[shift + j] = -0.001;
else
working_space[shift + j] = 0.001;
}
working_space[peak_vel + 2] = working_space[shift + j];
j += 1;
}
if (fFixS == false) {
working_space[peak_vel + 3] = working_space[shift + j];
j += 1;
}
if (fFixA0 == false) {
working_space[peak_vel + 4] = working_space[shift + j];
j += 1;
}
if (fFixA1 == false) {
working_space[peak_vel + 5] = working_space[shift + j];
j += 1;
}
if (fFixA2 == false) {
working_space[peak_vel + 6] = working_space[shift + j];
j += 1;
}
chi = chi_min;
}
}
else {
for (j = 0; j < rozmer; j++) {
working_space[shift + j] = working_space[4 * shift + j] + alpha * working_space[2 * shift + j];
}
for (i = 0, j = 0; i < fNPeaks; i++) {
if (fFixAmp[i] == false) {
if (working_space[shift + j] < 0)
working_space[shift + j] = 0;
working_space[2 * i] = working_space[shift + j];
j += 1;
}
if (fFixPosition[i] == false) {
if (working_space[shift + j] < fXmin)
working_space[shift + j] = fXmin;
if (working_space[shift + j] > fXmax)
working_space[shift + j] = fXmax;
working_space[2 * i + 1] = working_space[shift + j];
j += 1;
}
}
if (fFixSigma == false) {
if (working_space[shift + j] < 0.001) {
working_space[shift + j] = 0.001;
}
working_space[peak_vel] = working_space[shift + j];
j += 1;
}
if (fFixT == false) {
working_space[peak_vel + 1] = working_space[shift + j];
j += 1;
}
if (fFixB == false) {
if (TMath::Abs(working_space[shift + j]) < 0.001) {
if (working_space[shift + j] < 0)
working_space[shift + j] = -0.001;
else
working_space[shift + j] = 0.001;
}
working_space[peak_vel + 2] = working_space[shift + j];
j += 1;
}
if (fFixS == false) {
working_space[peak_vel + 3] = working_space[shift + j];
j += 1;
}
if (fFixA0 == false) {
working_space[peak_vel + 4] = working_space[shift + j];
j += 1;
}
if (fFixA1 == false) {
working_space[peak_vel + 5] = working_space[shift + j];
j += 1;
}
if (fFixA2 == false) {
working_space[peak_vel + 6] = working_space[shift + j];
j += 1;
}
chi = 0;
for (i = fXmin; i <= fXmax; i++) {
yw = source[i];
ywm = yw;
f = Shape(fNPeaks, (Double_t) i, working_space,
working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 3],
working_space[peak_vel + 2],
working_space[peak_vel + 4],
working_space[peak_vel + 5],
working_space[peak_vel + 6]);
if (fStatisticType == kFitOptimChiFuncValues) {
ywm = f;
if (f < 0.00001)
ywm = 0.00001;
}
if (fStatisticType == kFitOptimMaxLikelihood) {
if (f > 0.00001)
chi += yw * TMath::Log(f) - f;
}
else {
if (ywm != 0)
chi += (yw - f) * (yw - f) / ywm;
}
}
}
chi2 = chi;
chi = TMath::Sqrt(TMath::Abs(chi));
if (fAlphaOptim == kFitAlphaHalving && chi > 1E-6)
alpha = alpha * chi_opt / (2 * chi);
else if (fAlphaOptim == kFitAlphaOptimal)
alpha = alpha / 10.0;
iter += 1;
regul_cycle += 1;
} while (((chi > chi_opt
&& fStatisticType != kFitOptimMaxLikelihood)
|| (chi < chi_opt
&& fStatisticType == kFitOptimMaxLikelihood))
&& regul_cycle < kFitNumRegulCycles);
for (j = 0; j < rozmer; j++) {
working_space[4 * shift + j] = 0;
working_space[2 * shift + j] = 0;
}
for (i = fXmin, chi_cel = 0; i <= fXmax; i++) {
yw = source[i];
if (yw == 0)
yw = 1;
f = Shape(fNPeaks, (Double_t) i, working_space,
working_space[peak_vel], working_space[peak_vel + 1],
working_space[peak_vel + 3],
working_space[peak_vel + 2],
working_space[peak_vel + 4],
working_space[peak_vel + 5],
working_space[peak_vel + 6]);
chi_opt = (yw - f) * (yw - f) / yw;
chi_cel += (yw - f) * (yw - f) / yw;
for (j = 0, k = 0; j < fNPeaks; j++) {
if (fFixAmp[j] == false) {
a = Deramp((Double_t) i, working_space[2 * j + 1],
working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 3],
working_space[peak_vel + 2]);
if (yw != 0) {
working_space[2 * shift + k] += chi_opt;
b = a * a / yw;
working_space[4 * shift + k] += b;
}
k += 1;
}
if (fFixPosition[j] == false) {
a = Deri0((Double_t) i, working_space[2 * j],
working_space[2 * j + 1],
working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 3],
working_space[peak_vel + 2]);
if (yw != 0) {
working_space[2 * shift + k] += chi_opt;
b = a * a / yw;
working_space[4 * shift + k] += b;
}
k += 1;
}
}
if (fFixSigma == false) {
a = Dersigma(fNPeaks, (Double_t) i, working_space,
working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 3],
working_space[peak_vel + 2]);
if (yw != 0) {
working_space[2 * shift + k] += chi_opt;
b = a * a / yw;
working_space[4 * shift + k] += b;
}
k += 1;
}
if (fFixT == false) {
a = Dert(fNPeaks, (Double_t) i, working_space,
working_space[peak_vel],
working_space[peak_vel + 2]);
if (yw != 0) {
working_space[2 * shift + k] += chi_opt;
b = a * a / yw;
working_space[4 * shift + k] += b;
}
k += 1;
}
if (fFixB == false) {
a = Derb(fNPeaks, (Double_t) i, working_space,
working_space[peak_vel], working_space[peak_vel + 1],
working_space[peak_vel + 2]);
if (yw != 0) {
working_space[2 * shift + k] += chi_opt;
b = a * a / yw;
working_space[4 * shift + k] += b;
}
k += 1;
}
if (fFixS == false) {
a = Ders(fNPeaks, (Double_t) i, working_space,
working_space[peak_vel]);
if (yw != 0) {
working_space[2 * shift + k] += chi_opt;
b = a * a / yw;
working_space[4 * shift + k] += b;
}
k += 1;
}
if (fFixA0 == false) {
a = 1.0;
if (yw != 0) {
working_space[2 * shift + k] += chi_opt;
b = a * a / yw;
working_space[4 * shift + k] += b;
}
k += 1;
}
if (fFixA1 == false) {
a = Dera1((Double_t) i);
if (yw != 0) {
working_space[2 * shift + k] += chi_opt;
b = a * a / yw;
working_space[4 * shift + k] += b;
}
k += 1;
}
if (fFixA2 == false) {
a = Dera2((Double_t) i);
if (yw != 0) {
working_space[2 * shift + k] += chi_opt;
b = a * a / yw;
working_space[4 * shift + k] += b;
}
k += 1;
}
}
}
b = fXmax - fXmin + 1 - rozmer;
chi_er = chi_cel / b;
for (i = 0, j = 0; i < fNPeaks; i++) {
fArea[i] =
Area(working_space[2 * i], working_space[peak_vel],
working_space[peak_vel + 1], working_space[peak_vel + 2]);
if (fFixAmp[i] == false) {
fAmpCalc[i] = working_space[shift + j];
if (working_space[3 * shift + j] != 0)
fAmpErr[i] = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j]));
if (fArea[i] > 0) {
a = Derpa(working_space[peak_vel],
working_space[peak_vel + 1],
working_space[peak_vel + 2]);
b = working_space[4 * shift + j];
if (b == 0)
b = 1;
else
b = 1 / b;
fAreaErr[i] = TMath::Sqrt(TMath::Abs(a * a * b * chi_er));
}
else
fAreaErr[i] = 0;
j += 1;
}
else {
fAmpCalc[i] = fAmpInit[i];
fAmpErr[i] = 0;
fAreaErr[i] = 0;
}
if (fFixPosition[i] == false) {
fPositionCalc[i] = working_space[shift + j];
if (working_space[3 * shift + j] != 0)
fPositionErr[i] = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j]));
j += 1;
}
else {
fPositionCalc[i] = fPositionInit[i];
fPositionErr[i] = 0;
}
}
if (fFixSigma == false) {
fSigmaCalc = working_space[shift + j];
if (working_space[3 * shift + j] != 0)
fSigmaErr = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j]));
j += 1;
}
else {
fSigmaCalc = fSigmaInit;
fSigmaErr = 0;
}
if (fFixT == false) {
fTCalc = working_space[shift + j];
if (working_space[3 * shift + j] != 0)
fTErr = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j]));
j += 1;
}
else {
fTCalc = fTInit;
fTErr = 0;
}
if (fFixB == false) {
fBCalc = working_space[shift + j];
if (working_space[3 * shift + j] != 0)
fBErr = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j]));
j += 1;
}
else {
fBCalc = fBInit;
fBErr = 0;
}
if (fFixS == false) {
fSCalc = working_space[shift + j];
if (working_space[3 * shift + j] != 0)
fSErr = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j]));
j += 1;
}
else {
fSCalc = fSInit;
fSErr = 0;
}
if (fFixA0 == false) {
fA0Calc = working_space[shift + j];
if (working_space[3 * shift + j] != 0)
fA0Err = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j]));
j += 1;
}
else {
fA0Calc = fA0Init;
fA0Err = 0;
}
if (fFixA1 == false) {
fA1Calc = working_space[shift + j];
if (working_space[3 * shift + j] != 0)
fA1Err = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j]));
j += 1;
}
else {
fA1Calc = fA1Init;
fA1Err = 0;
}
if (fFixA2 == false) {
fA2Calc = working_space[shift + j];
if (working_space[3 * shift + j] != 0)
fA2Err = TMath::Sqrt(TMath::Abs(working_space[2 * shift + j])) / TMath::Sqrt(TMath::Abs(working_space[3 * shift + j]));
j += 1;
}
else {
fA2Calc = fA2Init;
fA2Err = 0;
}
b = fXmax - fXmin + 1 - rozmer;
fChi = chi_cel / b;
for (i = fXmin; i <= fXmax; i++) {
f = Shape(fNPeaks, (Double_t) i, working_space,
working_space[peak_vel], working_space[peak_vel + 1],
working_space[peak_vel + 3], working_space[peak_vel + 2],
working_space[peak_vel + 4], working_space[peak_vel + 5],
working_space[peak_vel + 6]);
source[i] = f;
}
for (i = 0; i < rozmer; i++)
delete [] working_matrix[i];
delete [] working_matrix;
delete [] working_space;
return;
}
void TSpectrumFit::SetFitParameters(Int_t xmin,Int_t xmax, Int_t numberIterations, Double_t alpha, Int_t statisticType, Int_t alphaOptim, Int_t power, Int_t fitTaylor)
{
if(xmin<0 || xmax <= xmin){
Error("SetFitParameters", "Wrong range");
return;
}
if (numberIterations <= 0){
Error("SetFitParameters","Invalid number of iterations, must be positive");
return;
}
if (alpha <= 0 || alpha > 1){
Error ("SetFitParameters","Invalid step coefficient alpha, must be > than 0 and <=1");
return;
}
if (statisticType != kFitOptimChiCounts
&& statisticType != kFitOptimChiFuncValues
&& statisticType != kFitOptimMaxLikelihood){
Error("SetFitParameters","Wrong type of statistic");
return;
}
if (alphaOptim != kFitAlphaHalving
&& alphaOptim != kFitAlphaOptimal){
Error("SetFitParameters","Wrong optimization algorithm");
return;
}
if (power != kFitPower2 && power != kFitPower4
&& power != kFitPower6 && power != kFitPower8
&& power != kFitPower10 && power != kFitPower12){
Error("SetFitParameters","Wrong power");
return;
}
if (fitTaylor != kFitTaylorOrderFirst
&& fitTaylor != kFitTaylorOrderSecond){
Error("SetFitParameters","Wrong order of Taylor development");
return;
}
fXmin=xmin,fXmax=xmax,fNumberIterations=numberIterations,fAlpha=alpha,fStatisticType=statisticType,fAlphaOptim=alphaOptim,fPower=power,fFitTaylor=fitTaylor;
}
void TSpectrumFit::SetPeakParameters(Double_t sigma, Bool_t fixSigma, const Float_t *positionInit, const Bool_t *fixPosition, const Float_t *ampInit, const Bool_t *fixAmp)
{
Int_t i;
if (sigma <= 0){
Error ("SetPeakParameters","Invalid sigma, must be > than 0");
return;
}
for(i=0; i < fNPeaks; i++){
if((Int_t) positionInit[i] < fXmin || (Int_t) positionInit[i] > fXmax){
Error ("SetPeakParameters","Invalid peak position, must be in the range fXmin, fXmax");
return;
}
if(ampInit[i] < 0){
Error ("SetPeakParameters","Invalid peak amplitude, must be > than 0");
return;
}
}
fSigmaInit = sigma,fFixSigma = fixSigma;
for(i=0; i < fNPeaks; i++){
fPositionInit[i] = (Double_t) positionInit[i];
fFixPosition[i] = fixPosition[i];
fAmpInit[i] = (Double_t) ampInit[i];
fFixAmp[i] = fixAmp[i];
}
}
void TSpectrumFit::SetBackgroundParameters(Double_t a0Init, Bool_t fixA0, Double_t a1Init, Bool_t fixA1, Double_t a2Init, Bool_t fixA2)
{
fA0Init = a0Init;
fFixA0 = fixA0;
fA1Init = a1Init;
fFixA1 = fixA1;
fA2Init = a2Init;
fFixA2 = fixA2;
}
void TSpectrumFit::SetTailParameters(Double_t tInit, Bool_t fixT, Double_t bInit, Bool_t fixB, Double_t sInit, Bool_t fixS)
{
fTInit = tInit;
fFixT = fixT;
fBInit = bInit;
fFixB = fixB;
fSInit = sInit;
fFixS = fixS;
}
void TSpectrumFit::GetSigma(Double_t &sigma, Double_t &sigmaErr)
{
sigma=fSigmaCalc;
sigmaErr=fSigmaErr;
}
void TSpectrumFit::GetBackgroundParameters(Double_t &a0, Double_t &a0Err, Double_t &a1, Double_t &a1Err, Double_t &a2, Double_t &a2Err)
{
a0 = fA0Calc;
a0Err = fA0Err;
a1 = fA1Calc;
a1Err = fA1Err;
a2 = fA2Calc;
a2Err = fA2Err;
}
void TSpectrumFit::GetTailParameters(Double_t &t, Double_t &tErr, Double_t &b, Double_t &bErr, Double_t &s, Double_t &sErr)
{
t = fTCalc;
tErr = fTErr;
b = fBCalc;
bErr = fBErr;
s = fSCalc;
sErr = fSErr;
}
Last change: Wed Jun 25 08:53:16 2008
Last generated: 2008-06-25 08:53
This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.