32 m_bValid = m_bFunct = m_bBckgr =
false;
33 m_bLine = m_bFlat = m_bSlope =
false;
34 m_bGauss = m_bExp = m_bSin =
false;
35 m_bStep = m_bTailL = m_bTailR =
false;
61 m_bValid = m_bFunct = m_bBckgr =
false;
62 m_bLine = m_bFlat = m_bSlope =
false;
63 m_bGauss = m_bExp = m_bSin =
false;
64 m_bStep = m_bTailL = m_bTailR =
false;
65 if(m_pRes) {
delete [] m_pRes; m_pRes = NULL;}
66 if(m_pErr) {
delete [] m_pErr; m_pErr = NULL;}
67 if(m_pPar) {
delete [] m_pPar; m_pPar = NULL;}
68 if(m_pDatVal) {
delete [] m_pDatVal; m_pDatVal = NULL;}
69 if(m_pDatErr) {
delete [] m_pDatErr; m_pDatErr = NULL;}
77 setUp.m_bB0 = m_pGFitPar[0]&1;
78 setUp.m_bB1 = m_pGFitPar[1]&1;
79 setUp.m_bAmpl = m_pGFitPar[2]&1;
80 setUp.m_bPosi = m_pGFitPar[3]&1;
81 setUp.m_bFWHM = m_pGFitPar[4]&1;
82 setUp.m_bStep = m_pGFitPar[5]&1;
83 setUp.m_bTailL = m_pGFitPar[6]&1;
84 setUp.m_bTailR = m_pGFitPar[7]&1;
85 setUp.m_bFWHMeq = m_pGFitPar[4]&2;
86 setUp.m_bTailLeq = m_pGFitPar[6]&2;
87 setUp.m_bTailReq = m_pGFitPar[7]&2;
89 if(setUp.DoModal() != IDOK)
92 m_pGFitPar[0] = setUp.m_bB0 ? 1 : 0;
93 m_pGFitPar[1] = setUp.m_bB1 ? 1 : 0;
94 m_pGFitPar[2] = setUp.m_bAmpl ? 1 : 0;
95 m_pGFitPar[3] = setUp.m_bPosi ? 1 : 0;
96 m_pGFitPar[4] = setUp.m_bFWHM ? 1 : 0;
97 m_pGFitPar[5] = setUp.m_bStep ? 1 : 0;
98 m_pGFitPar[6] = setUp.m_bTailL ? 1 : 0;
99 m_pGFitPar[7] = setUp.m_bTailR ? 1 : 0;
100 m_pGFitPar[4] |= setUp.m_bFWHMeq ? 2 : 0;
102 m_pGFitPar[6] |= setUp.m_bTailLeq ? 2 : 0;
103 m_pGFitPar[7] |= setUp.m_bTailReq ? 2 : 0;
127 m_nBgChanA = m_nChanA;
128 m_nBgChanB = m_nChanB;
129 m_nNdat = m_nChanB - m_nChanA + 1;
133 if(m_nNdat < 2)
return false;
135 double s1 = 0., sx = 0., sxx = 0., sy = 0., syx = 0.;
137 pd = pSpek + m_nChanA;
140 for(
int ii = 0; ii < m_nNdat; ii+=m_nNdat-1) {
154 for(
int ii = 0; ii < m_nNdat; ii++, x += 1.) {
164 double deter = s1*sxx-sx*sx;
166 m_dBack0 = (sxx*sy - sx*syx)/deter;
167 m_dBack1 = (-sx*sy + s1*syx)/deter;
168 m_dBack0Err = sqrt(sxx/deter);
169 m_dBack1Err = sqrt(s1 /deter);
176 pd = pSpek + m_nChanA;
177 for(
int ii = 0; ii < m_nNdat; ii++, x += 1.) {
178 double dy = *pd++ - (m_dBack0 + m_dBack1*x);
182 m_dBackL1 = sy1 / m_nNdat;
183 m_dBackL2 = sqrt(sy2 / m_nNdat);
190 pd = pSpek + m_nChanA;
193 for(
int ii = 0; ii < m_nNdat; ii+=m_nNdat-1)
199 for(
int ii = 0; ii < m_nNdat; ii++)
201 m_dBack0 = sy0 / m_nNdat;
205 pd = pSpek + m_nChanA;
206 for(
int ii = 0; ii < m_nNdat; ii++) {
207 double dy = *pd++ - m_dBack0;
211 m_dBackL1 = sy1 / m_nNdat;
212 m_dBackL2 = sqrt(sy2 / m_nNdat);
213 m_dBack1 = m_dBack1Err = 0.;
232 double CFitSpek::LineFunc(
double xx)
234 if(!m_bLine)
return 0.;
237 if(m_bFlat ) val += m_dBack0;
238 if(m_bSlope) val += m_dBack1*(xx-m_nChanA);
261 m_nBgChanA = m_nChanA;
262 m_nBgChanB = m_nChanB;
263 m_nNdat = m_nChanB - m_nChanA + 1;
265 int ndat = m_nNdat - 2 * nChanBack;
274 double s1 = 0., sx = 0., sxx = 0., sy = 0., syx = 0.;
276 for(
int ii = m_nChanA; ii <= m_nChanB; ii++) {
277 if(ii < m_nChanA+nChanBack || ii > m_nChanB-nChanBack) {
279 x = ii - m_nChanA + 0.5;
288 double deter = s1*sxx-sx*sx;
290 m_dBack0 = (sxx*sy - sx*syx)/deter;
291 m_dBack1 = (-sx*sy + s1*syx)/deter;
292 m_dBack0Err = sxx/deter;
293 m_dBack1Err = s1 /deter;
297 m_bFlat = m_dBack0 != 0;
298 m_bSlope = m_dBack1 != 0;
299 m_bBckgr = m_bFlat || m_bSlope;
303 double dKV2, dKV3, dKV4;
312 double xii, xyy, back;
313 for(
int ii = m_nChanA+nChanBack; ii <= m_nChanB-nChanBack; ii++) {
314 xii = ii + 0.5 - m_nChanA;
315 back = m_dBack0 + xii*m_dBack1;
327 dKV2 = dKV3 = dKV4 = 0;
329 for(
int ii = m_nChanA+nChanBack; ii <= m_nChanB-nChanBack; ii++) {
330 xii = ii + 0.5 - m_nChanA;
331 back = m_dBack0 + xii*m_dBack1;
336 dKV2 += (xny = xyy*xii*xii);
337 dKV3 += (xny *= xii);
338 dKV4 += (xny *= xii);
345 m_pRes =
new CFitRes [m_nNpeaks];
346 m_pErr =
new CFitRes [m_nNpeaks];
348 m_pRes[0].
Area = dMV0;
349 m_pRes[0].
Posi = dMV1 + m_nChanA;
350 m_pRes[0].
Sigma = m_pRes[0].
Area ? sqrt(dKV2) : 0.;
354 m_pRes[0].
W01L = sqrt(log(10.)/log(2.));
355 m_pRes[0].
W01R = sqrt(log(10.)/log(2.));
366 m_pErr[0].
Area = sqrt(dMV0);
367 m_pErr[0].
Posi = sqrt((dKV2 )/ dMV0);
368 m_pErr[0].
Sigma = sqrt((dKV4 - dKV2*dKV2)/ dMV0)/(2*sqrt(dKV2));
383 for(
int ii = m_nChanA+nChanBack; ii <= m_nChanB-nChanBack; ii++) {
384 double dy = pSpek[ii] -
FitFunc(ii+0.5);
386 dy /= pSpek[ii] ? pSpek[ii] : 1;
389 m_dChi2 /= m_nChanB-nChanBack - (m_nChanA+nChanBack);
451 m_nBgChanA = m_nChanA;
452 m_nBgChanB = m_nChanB;
456 for(ii = m_nChanA; ii <= m_nChanB; ii++) {
468 double *lPeaks =
new double[std::max(1,(
int)vPeaks.size())];
470 for(
size_t np = 0; np < vPeaks.size(); np++) {
471 if(vPeaks[np] > m_nChanA && vPeaks[np] < m_nChanB) {
472 lPeaks[nPeaks++] = vPeaks[np];
478 int pm = (m_nChanA+m_nChanB+1)/2;
479 float vm = pSpek[pm];
480 for(ii = m_nChanA+1; ii < m_nChanB-1; ii++) {
486 lPeaks[0] = pm + 0.5;
490 m_nNdat = m_nChanB - m_nChanA + 1;
492 m_nNpar = m_nOffB + m_nOffN * m_nNpeaks;
495 m_pPar =
new CFitPar [m_nNpar];
498 m_pDatVal =
new double [m_nNdat];
499 m_pDatErr =
new double [m_nNdat];
502 float *ps = pSpek + m_nChanA;
503 for(ii = 0; ii < m_nNdat; ii++) {
506 m_pDatErr[ii] = (yy) ? (1./fabs(yy)) : (1.);
514 double bgL = (m_pDatVal[0 ] + m_pDatVal[1 ])/2.;
515 double bgR = (m_pDatVal[m_nNdat-1] + m_pDatVal[m_nNdat-2])/2.;
520 if(m_pGFitPar[0]&1) bflag |= 1;
521 if(m_pGFitPar[1]&1) bflag |= 2;
526 m_pPar[0].
Value = 0.;
527 m_pPar[1].
Value = 0.;
532 m_pPar[0].
Value = (bgR+bgL)/2;
533 m_pPar[1].
Value = 0.;
538 m_pPar[0].
Value = 0.;
539 m_pPar[1].
Value = (bgR-bgL)/m_nNdat;
544 m_pPar[0].
Value = bgL;
545 m_pPar[1].
Value = (bgR-bgL)/m_nNdat;
555 bgL = m_pPar[0].
Value;
556 bgR = m_pPar[1].
Value;
566 for(
int np = 0, offs = m_nOffB; np < m_nNpeaks; np++, offs += m_nOffN) {
567 double ppos = lPeaks[np] - m_nChanA;
568 int ipos = int(ppos);
569 double ampl = m_pDatVal[ipos];
571 double back = bgL + ppos*bgR;
572 double ampl2 = (ampl+back)/2.;
574 for(
int iL = ipos-1; iL > 0; iL--) {
575 if(m_pDatVal[iL] < ampl2)
break;
578 for(
int iR = ipos+1; iR < m_nNdat-1; iR++) {
579 if(m_pDatVal[iR] < ampl2)
break;
582 m_pPar[offs+0].
Value = ampl - back;
583 m_pPar[offs+1].
Value = ppos;
585 m_pPar[offs+3].
Value = step;
586 m_pPar[offs+4].
Value = -100;
587 m_pPar[offs+5].
Value = 100;
593 for(
int np = 0, offs = m_nOffB; np < m_nNpeaks; np++, offs += m_nOffN) {
594 sigma += fabs(m_pPar[offs+0].Value)*m_pPar[offs+2].
Value;
595 total += fabs(m_pPar[offs+0].Value);
598 sigma = max(sigma, 1./sqrt(12.));
599 for(
int np = 0, offs = m_nOffB; np < m_nNpeaks; np++, offs += m_nOffN) {
600 m_pPar[offs+2].
Value = sigma;
604 for(
int np = 0, offs = m_nOffB; np < m_nNpeaks; np++, offs += m_nOffN) {
607 m_pPar[offs+0].
LinkTo = offs+0;
609 m_pPar[offs+0].
Valmin = 0.;
613 m_pPar[offs+1].
LinkTo = offs+1;
615 m_pPar[offs+1].
Valmin = 0.;
616 m_pPar[offs+1].
Valmax = m_nNdat-1.;
621 m_pPar[offs+2].
LinkTo = offs+2;
623 m_pPar[offs+2].
Valmin = 1./sqrt(12.);
628 m_pPar[offs+2].
LinkTo = m_nOffB+2;
646 for(
int np = 0; np < m_nNpar; np++) {
647 if(m_pPar[np].Status ==
p_Free) m_nFpar++;
655 if(m_nNdat - m_nFpar < 1) {
664 chi2 = Curfit(m_nNdat, m_nNpar, m_nFpar);
674 for(
int np = 0, offs = m_nOffB; np < m_nNpeaks; np++, offs += m_nOffN) {
678 m_pPar[offs+0].
LinkTo = offs+0;
680 m_pPar[offs+0].
Valmin = 0.;
684 m_pPar[offs+1].
LinkTo = offs+1;
686 m_pPar[offs+1].
Valmin = 1.;
687 m_pPar[offs+1].
Valmax = m_nNdat-2.;
690 if(np == 0 || !(m_pGFitPar[4]&2)) {
691 m_pPar[offs+2].
Value = fabs(m_pPar[offs+2].Value);
693 m_pPar[offs+2].
LinkTo = offs+2;
695 m_pPar[offs+2].
Valmin = 1./sqrt(12.);
699 m_pPar[offs+2].
Value = fabs(m_pPar[offs+2].Value);
701 m_pPar[offs+2].
LinkTo = m_nOffB+2;
705 if(m_pGFitPar[5]&1) {
707 if(np == 0 || !(m_pGFitPar[5]&2)) {
709 m_pPar[offs+3].
LinkTo = offs+3;
711 m_pPar[offs+3].
Valmin = 0;
712 m_pPar[offs+3].
Valmax = 1;
716 m_pPar[offs+3].
LinkTo = m_nOffB+3;
721 if(m_pGFitPar[6]&1) {
723 m_pPar[offs+4].
Value = -2.;
724 if(np == 0 || !(m_pGFitPar[6]&2)) {
726 m_pPar[offs+4].
LinkTo = offs+4;
728 m_pPar[offs+4].
Valmax = -0.1;
729 m_pPar[offs+4].
Valmin = -50.;
733 m_pPar[offs+4].
LinkTo = m_nOffB+4;
738 if(m_pGFitPar[7]&1) {
740 m_pPar[offs+5].
Value = 2.;
741 if(np == 0 || !(m_pGFitPar[7]&2)) {
743 m_pPar[offs+5].
LinkTo = offs+5;
745 m_pPar[offs+5].
Valmin = 0.1;
746 m_pPar[offs+5].
Valmax = 50.;
750 m_pPar[offs+5].
LinkTo = m_nOffB+5;
757 for(
int np = 0; np < m_nNpar; np++) {
758 if(m_pPar[np].Status ==
p_Free) m_nFpar++;
766 if(m_nNdat - m_nFpar < 1) {
771 chi2n = Curfit(m_nNdat, m_nNpar, m_nFpar);
780 m_dChi2 = chi2n/(m_nNdat-m_nFpar);
784 m_bLine = m_bFlat || m_bSlope;
797 delete [] m_pPar; m_pPar = NULL;
798 delete [] m_pDatVal; m_pDatVal = NULL;
799 delete [] m_pDatErr; m_pDatErr = NULL;
802 return (m_bValid) ? (m_nNpeaks) : (ierr);
807 std::vector<double> vPeaks;
809 std::swap(chanA, chanB);
810 vPeaks.push_back(chanA-1);
816 double CFitSpek::GFfunF(
double xx,
double *xpar)
840 double amp, pos, sig, yy, yl, yr, ex, f1, f2, ey, eyp1i;
844 for(np = 0, offs = m_nOffB; np < m_nNpeaks; np++, offs += m_nOffN) {
852 if(m_bTailL && yy < yl) {
853 ex = -0.5*yl*(2.*yy-yl);
855 else if(m_bTailR && yy > yr) {
856 ex = -0.5*yr*(2.*yy-yr);
867 f2 = xpar[offs+3]*eyp1i*eyp1i;
872 return xpar[0] + xpar[1]*xx + fsum;
877 void CFitSpek::GFderF(
int id,
double *xpar,
double *deriv,
double &deltay,
double &weight)
879 double amp, pos, sig, stp, f0, f1, f2, f3;
880 double yy, yl, yr, ex, ey, dd;
882 double xx =
id + 0.5;
884 deltay = m_pDatVal[id] - GFfunF(xx, xpar);
885 weight = m_pDatErr[id];
887 memset(deriv, 0, m_nNpar*
sizeof(
double));
893 for(np = 0, offs = m_nOffB; np < m_nNpeaks; np++, offs += m_nOffN) {
902 if(m_bTailL && yy < yl) {
903 ex = -0.5*yl*(2.*yy-yl);
906 deriv[offs+4] = amp*f1*(yl-yy);
908 else if(m_bTailR && yy > yr) {
909 ex = -0.5*yr*(2.*yy-yr);
912 deriv[offs+5] = amp*f1*(yr-yy);
926 deriv[offs+3] = amp*f2;
929 dd = amp*(f0*f1 + stp*f2*f3);
931 deriv[offs+0] = f1+stp*f2;
933 deriv[offs+2] = dd*yy;
940 void CFitSpek::GF_res()
942 m_dBack0 = m_pPar[0].
Value; m_dBack0Err = m_pPar[0].
Error;
943 m_dBack1 = m_pPar[1].
Value; m_dBack1Err = m_pPar[1].
Error;
945 m_pRes =
new CFitRes [m_nNpeaks];
946 m_pErr =
new CFitRes [m_nNpeaks];
949 for(np = 0, offs = m_nOffB; np < m_nNpeaks; np++, offs += m_nOffN) {
952 m_pRes[np].
Posi = m_pPar[offs+1].
Value+m_nChanA;
957 m_pRes[np].
W01L = sqrt(log(10.)/log(2.));
958 m_pRes[np].
W01R = sqrt(log(10.)/log(2.));
964 m_pErr[np].
Area = m_pRes[np].
Area*sqrt(pow(m_pPar[offs+0].Error/m_pPar[offs+0].Value,2.) +
965 pow(m_pPar[offs+2].Error/m_pPar[offs+2].Value,2.));
989 if(!m_bTailL && !m_bTailR)
993 for(np = 0, offs = m_nOffB; np < m_nNpeaks; np++, offs += m_nOffN) {
996 double L = fabs(m_pPar[offs+4].Value);
997 double a = exp(-0.5*L*L)/L;
1005 double R = fabs(m_pPar[offs+5].Value);
1006 double a = exp(-0.5*R*R)/R;
1013 area *= m_pPar[offs+0].
Value*m_pPar[offs+2].
Value;
1014 m_pErr[np].
Area *= area/m_pRes[np].
Area;
1015 m_pRes[np].
Area = area;
1018 for(np = 0; np < m_nNpeaks; np++) {
1019 m_pRes[np].
Fw05 = GF_y2w(np, 0.5);
1020 m_pRes[np].
Fw01 = GF_y2w(np, 0.1);
1021 m_pRes[np].
W01L = GF_y2w(np, 0.1, -1)/(m_pRes[np].
Fwhm/2);
1022 m_pRes[np].
W01R = GF_y2w(np, 0.1, +1)/(m_pRes[np].
Fwhm/2);
1034 double CFitSpek::GF_erf(
double x)
1039 ans=t*exp(-z*z-1.26551223+
1048 t* 0.17087277 )))))))) );
1050 return x >= 0.0 ? 1-ans : ans-1;
1054 double CFitSpek::GF_y2w(
int np,
double yval,
int side)
1056 const double precision = 1.e-6;
1058 if(!m_bGauss || np < 0 || np > m_nNpeaks)
return 0.;
1059 if(yval <=0 || yval >= 1.)
return 0.;
1061 CFitRes *pRes = m_pRes+ np;
1062 if(pRes->Ampli == 0)
return 0.;
1064 double ff = 1./pRes->
Ampli;
1065 double x0 = pRes->Posi;
1067 double dl = pRes->Sigma*sqrt(2.*log(1./yval));
1068 double xl = x0 - dl;
1069 double yl = GFitPeak(xl, np)*ff;
1071 while(fabs(yl/yval-1) > precision) {
1076 yl = GFitPeak(xl, np)*ff;
1082 yl = GFitPeak(xl, np)*ff;
1087 double dr = pRes->Sigma*sqrt(2.*log(1./yval));
1088 double xr = x0 + dr;
1089 double yr = GFitPeak(xr, np)*ff;
1091 while(fabs(yr/yval-1) > precision) {
1096 yr = GFitPeak(xr, np)*ff;
1102 yr = GFitPeak(xr, np)*ff;
1117 double CFitSpek::GFitFunc(
double xx)
1119 double yy, f1, f2, fsum, back, val;
1121 if(!m_bGauss)
return 0.;
1124 for(
int np = 0; np < m_nNpeaks; np++) {
1125 yy = (xx - m_pRes[np].
Posi) / m_pRes[np].
Sigma;
1128 if(m_bTailL && yy < m_pRes[np].TailL) {
1129 double yl = m_pRes[np].
TailL;
1130 f1 = exp(-0.5*yl*(2.*yy-yl));
1132 else if(m_bTailR && yy > m_pRes[np].TailR) {
1133 double yr = m_pRes[np].
TailR;
1134 f1 = exp(-0.5*yr*(2.*yy-yr));
1137 f1 = exp(-0.5*yy*yy);
1142 double ey = exp(yy);
1143 double ez = 1. / (1. + ey);
1144 f2 = m_pRes[np].
Step * ez * ez;
1147 fsum += m_pRes[np].
Ampli * (f1 + f2);
1151 if(m_bFlat ) back += m_dBack0;
1152 if(m_bSlope) back += m_dBack1*(xx-m_nChanA);
1161 double CFitSpek::GFitPeak(
double xx,
int np)
1165 if(!m_bGauss || np < 0 || np > m_nNpeaks)
return 0.;
1167 yy = (xx - m_pRes[np].
Posi) / m_pRes[np].
Sigma;
1170 if(m_bTailL && yy < m_pRes[np].TailL) {
1171 double yl = m_pRes[np].
TailL;
1172 f1 = exp(-0.5*yl*(2.*yy-yl));
1174 else if(m_bTailR && yy > m_pRes[np].TailR) {
1175 double yr = m_pRes[np].
TailR;
1176 f1 = exp(-0.5*yr*(2.*yy-yr));
1179 f1 = exp(-0.5*yy*yy);
1182 f1 *= m_pRes[np].
Ampli;
1190 double CFitSpek::GFitBack(
double xx)
1192 double yy, fsum, back, val;
1194 if(!m_bGauss)
return 0.;
1198 for(
int np = 0; np < m_nNpeaks; np++) {
1199 yy = (xx - m_pRes[np].
Posi) / m_pRes[np].
Sigma;
1200 double ey = exp(yy);
1201 double ez = 1. / (1. + ey);
1202 double f2 = m_pRes[np].
Step * ez * ez;
1203 fsum += m_pRes[np].
Ampli * f2;
1208 if(m_bFlat ) back += m_dBack0;
1209 if(m_bSlope) back += m_dBack1*(xx-m_nChanA);
1220 double CFitSpek::Curfit(
int ndat,
int npar,
int mpar)
1222 double *vvalue =
new double [npar];
1223 double *verror =
new double [npar];
1224 double *deriv =
new double [npar];
1226 double *beta =
new double [mpar];
1227 double *alpha =
new double [mpar*mpar];
1228 double *sqrp =
new double [mpar];
1229 double *array =
new double [mpar*mpar];
1232 double dyi,wwi, wwiderj;
1236 for(i = 0; i < npar; i++) vvalue[i] = m_pPar[i].Value;
1238 double chisqr = Chisqr(vvalue);
1239 double chisqt, chisq1, deter;
1240 double flamda = 0.001;
1246 for(
int iter = 0; iter < 20; iter++) {
1251 memset(beta, 0,
sizeof(
double)*mpar);
1252 memset(alpha, 0,
sizeof(
double)*mpar*mpar);
1253 for(i = 0; i < ndat; i++) {
1255 (this->*
m_pfDeriv)(i, vvalue, deriv, dyi, wwi);
1258 if(mpar < npar) Manage(deriv, 1);
1261 for(j = 0; j < mpar; j++) {
1263 wwiderj = wwi*deriv[j];
1264 beta[j] += dyi*wwiderj;
1265 for(k = 0; k <= j; k++) {
1266 alpha[
M12(j,k,mpar)] += deriv[k]*wwiderj;
1272 for(j=0; j < mpar; j++) {
1273 for(k=0; k < j; k++) {
1274 alpha[
M12(k,j,mpar)] = alpha[
M12(j,k,mpar)];
1281 for(j = 0; j < mpar; j++) {
1282 if(alpha[
M12(j,j,mpar)] < 1.e-15)
1283 alpha[
M12(j,j,mpar)] = 1.e-15;
1287 for(j = 0; j < mpar; j++) {
1288 sqrp[j] = sqrt(alpha[
M12(j,j,mpar)]);
1295 for(j = 0; j < mpar; j++) {
1296 for(k = 0; k < mpar; k++) {
1297 array[
M12(j,k,mpar)] = alpha[
M12(j,k,mpar)]/(sqrp[j]*sqrp[k]) ;
1299 array[
M12(j,j,mpar)] = 1. + flamda ;
1303 deter = Matinv(array, mpar, mpar);
1310 if(mpar < npar) Manage(vvalue, 2);
1313 for(j = 0; j < mpar; j++) {
1315 for(k = 0; k < mpar; k++) {
1316 dpar += array[
M12(j,k,mpar)]*beta[k]/(sqrp[j]*sqrp[k]);
1322 if(mpar < npar) Manage(vvalue, 3);
1328 chisq1 = Chisqr(vvalue);
1331 if(chisq1 < chisqr) {
1337 for(i = 0; i < npar; i++)
1338 vvalue[i] = m_pPar[i].Value;
1347 for(i = 0; i < npar; i++) m_pPar[i].Value = vvalue[i];
1351 for(j = 0; j < mpar; j++) {
1352 if(alpha[
M12(j,j,mpar)] == 0)
1355 verror[j] = sqrt(array[
M12(j,j,mpar)]/alpha[
M12(j,j,mpar)]);
1358 if(mpar < npar) Manage(verror, 5);
1360 if((chisqt-chisqr)/chisqr < 0.001)
1378 return (nsteps) ? (chisqr) : (-2);
1382 double CFitSpek::Chisqr(
double *xpar)
1386 for(
int ii = 0; ii < m_nNdat; ii++, xx += 1.) {
1387 double xval = (this->*
m_pfFunct)(xx, xpar);
1388 double dval = m_pDatVal[ii] - xval;
1389 chi += m_pDatErr[ii] * dval*dval;
1395 void CFitSpek::Manage(
double *xpar,
int flag)
1402 for(j = 0; j < m_nNpar; j++) {
1404 xpar[m_pPar[j].
LinkTo] += xpar[j];
1409 for(j = 0; j < m_nNpar; j++) {
1410 if(m_pPar[j].Status ==
p_Free) {
1419 for(j = 0; j < m_nNpar; j++) {
1420 if(m_pPar[j].Status ==
p_Free) {
1429 for(j = m_nNpar-1; j >=0; j--) {
1430 if(m_pPar[j].Status ==
p_Free)
1431 xpar[j] = xpar[m_pPar[j].
PackId];
1434 for(j = m_nNpar-1; j >=0; j--) {
1435 if(m_pPar[j].Status ==
p_Fixed)
1436 xpar[j] = m_pPar[j].
Value;
1437 else if(m_pPar[j].Status ==
p_Linked)
1438 xpar[j] = xpar[m_pPar[j].
LinkTo];
1443 for(j = 0; j < m_nNpar; j++) {
1444 if(m_pPar[j].Status ==
p_Free && m_pPar[j].Bounds !=
p_BNone) {
1445 if(m_pPar[j].Bounds &
p_BLow)
1446 xpar[j] = max(m_pPar[j].Valmin, xpar[j]);
1447 if(m_pPar[j].Bounds &
p_BHig)
1448 xpar[j] = min(m_pPar[j].Valmax, xpar[j]);
1453 for(j = 0; j < m_nNpar; j++) {
1455 xpar[j] = xpar[m_pPar[j].
LinkTo];
1461 for(j = m_nNpar-1; j >=0; j--) {
1462 if(m_pPar[j].Status ==
p_Free)
1465 m_pPar[j].Error = 0;
1467 for(j = 0; j < m_nNpar; j++) {
1468 if(m_pPar[j].Status ==
p_Fixed)
1469 m_pPar[j].
Error = 0.;
1470 else if(m_pPar[j].Status ==
p_Linked)
1484 double CFitSpek::Matinv(
double *array,
int mpar,
int npar)
1487 double det, amax, damax, dd;
1489 if(npar > mpar)
return 0.;
1490 if(npar < 1)
return 0.;
1493 if(amax == 0)
return 0.;
1498 int *iik =
new int[npar];
1499 int *jjk =
new int[npar];
1502 for(kk = 0; kk < npar; kk++) {
1505 for(ii = kk; ii < npar; ii++) {
1506 for(jj = kk; jj < npar; jj++) {
1507 dd = array[
M12(ii,jj,mpar)];
1508 if(fabs(dd) > fabs(amax)) {
1524 for(jj = 0; jj < npar; jj++) {
1525 dd = array[
M12(kk,jj,mpar)];
1526 array[
M12(kk,jj,mpar)] = array[
M12(ii,jj,mpar)];
1527 array[
M12(ii,jj,mpar)] = -dd;
1532 for(ii = 0; ii < npar; ii++) {
1533 dd = array[
M12(ii,kk,mpar)];
1534 array[
M12(ii,kk,mpar)] = array[
M12(ii,jj,mpar)];
1535 array[
M12(ii,jj,mpar)] = -dd;
1540 for(ii = 0; ii < npar; ii++) {
1542 array[
M12(ii,kk,mpar)] *= -damax;
1544 for(ii = 0; ii < npar; ii++) {
1545 if(ii == kk)
continue;
1546 for(jj = 0; jj < npar; jj++) {
1549 array[
M12(ii,jj,mpar)] += array[
M12(ii,kk,mpar)] * array[
M12(kk,jj,mpar)];
1552 for(jj = 0; jj < npar; jj++) {
1554 array[
M12(kk,jj,mpar)] *= damax;
1556 array[
M12(kk,kk,mpar)] = damax;
1561 for(kk = npar-1; kk >= 0; kk--) {
1564 for(ii = 0; ii < npar; ii++) {
1565 dd = array[
M12(ii,kk,mpar)];
1566 array[
M12(ii,kk,mpar)] = -array[
M12(ii,jj,mpar)];
1567 array[
M12(ii,jj,mpar)] = dd;
1572 for(jj = 0; jj < npar; jj++) {
1573 dd = array[
M12(kk,jj,mpar)];
1574 array[
M12(kk,jj,mpar)] = -array[
M12(ii,jj,mpar)];
1575 array[
M12(ii,jj,mpar)] = dd;
1603 if(bgA >-1 && bgB > -1) {
1604 if(bgA > bgB) {
int tmp = bgA; bgA = bgB; bgB =
tmp;}
1606 for(
int nn = bgA; nn <= bgB; nn++)
1607 m_dBack0 += pSpek[nn];
1613 if(chA > chB) {
int tmp = chA; chA = chB; chB =
tmp;}
1618 double s1 = 0., sx = 0., sxx = 0., sy = 0., syx = 0.;
1621 float * pd = pSpek + chA;
1622 for(
int ii = chA; ii <= chB; ii++, x += 1.) {
1623 y = *pd++ - m_dBack0;
1634 double deter = s1*sxx-sx*sx;
1640 m_bBckgr = m_bFlat || m_bSlope;
1650 m_dExpAmpli = (sxx*sy - sx*syx)/deter;
1651 m_dExpDecay = (-sx*sy + s1*syx)/deter;
1652 m_dExpAmpli = exp(m_dExpAmpli);
1653 m_dExpDecay = -1./m_dExpDecay;
1666 double CFitSpek::ExpFunc(
double xx)
1668 if(!m_bExp)
return 0.;
1672 val = m_dExpAmpli * exp(-xx/m_dExpDecay);
1682 double CFitSpek::ExpPeak(
double xx,
int )
1684 if(!m_bExp)
return 0.;
1688 val = m_dExpAmpli * exp(-xx/m_dExpDecay);
1737 m_nBgChanA = m_nChanA;
1738 m_nBgChanB = m_nChanB;
1742 for(ii = m_nChanA; ii <= m_nChanB; ii++) {
1759 m_nNdat = m_nChanB - m_nChanA + 1;
1761 m_nNpar = m_nOffB + m_nOffN * m_nNpeaks;
1764 m_pPar =
new CFitPar [m_nNpar];
1767 m_pDatErr =
new double [m_nNdat];
1768 m_pDatVal =
new double [m_nNdat];
1771 float *ps = pSpek + m_nChanA;
1772 for(ii = 0; ii < m_nNdat; ii++) {
1784 double vmin = m_pDatVal[0];
1785 double vmax = m_pDatVal[0];
1786 for(ii = 0; ii < m_nNdat; ii++) {
1787 double dd = m_pDatVal[ii];
1789 vmin = min(vmin, dd);
1790 vmax = max(vmax, dd);
1792 double bg0 = vsum / m_nNdat;
1800 m_pPar[0].
Value = bg0;
1804 m_pPar[0].
Value = 0;
1811 m_pPar[1].
Value = 0.;
1814 bg0 = m_pPar[0].
Value;
1815 bg1 = m_pPar[1].
Value;
1818 for(np = 0, offs = m_nOffB; np < m_nNpeaks; np++, offs += m_nOffN) {
1820 m_pPar[offs+0].
Value = (vmax - vmin)/ 2;;
1826 m_pPar[offs+2].
Value = 0;
1832 for(np = 0; np < m_nNpar; np++) {
1833 if(m_pPar[np].Status ==
p_Free) m_nFpar++;
1841 if(m_nNdat - m_nFpar < 1) {
1850 chi2 = Curfit(m_nNdat, m_nNpar, m_nFpar);
1867 for(np = 0, offs = m_nOffB; np < m_nNpeaks; np++, offs += m_nOffN) {
1878 for(np = 0; np < m_nNpar; np++) {
1879 if(m_pPar[np].Status ==
p_Free) m_nFpar++;
1887 if(m_nNdat - m_nFpar < 1) {
1892 chi2n = Curfit(m_nNdat, m_nNpar, m_nFpar);
1901 m_dChi2 = chi2n/(m_nNdat-m_nFpar);
1904 m_bBckgr = m_bFlat || m_bSlope;
1909 m_dBack0 = m_pPar[0].
Value; m_dBack0Err = m_pPar[0].
Error;
1910 m_dBack1 = m_pPar[1].
Value; m_dBack1Err = m_pPar[1].
Error;
1912 m_pRes =
new CFitRes [m_nNpeaks];
1913 m_pErr =
new CFitRes [m_nNpeaks];
1915 for(np = 0, offs = m_nOffB; np < m_nNpeaks; np++, offs += m_nOffN) {
1931 delete [] m_pPar; m_pPar = NULL;
1932 delete [] m_pDatVal; m_pDatVal = NULL;
1933 delete [] m_pDatErr; m_pDatErr = NULL;
1935 return (m_bValid) ? (m_nNpeaks) : (ierr);
1940 double CFitSpek::SFfunF(
double xx,
double *xpar)
1953 double ampli, omega, phase, f1;
1957 for(np = 0, offs = m_nOffB; np < m_nNpeaks; np++, offs += m_nOffN) {
1958 ampli = xpar[offs+0];
1959 omega = xpar[offs+1];
1960 phase = xpar[offs+2];
1961 f1 = ampli*sin(omega*xx+phase);
1964 return xpar[0] + xpar[1]*xx + fsum;
1968 void CFitSpek::SFderF(
int id,
double *xpar,
double *deriv,
double &deltay,
double &weight)
1970 double ampli, omega, phase, angle, cosvv;
1972 double xx =
id + 0.5;
1974 deltay = m_pDatVal[id] - SFfunF(xx, xpar);
1977 memset(deriv, 0, m_nNpar*
sizeof(
double));
1983 for(np = 0, offs = m_nOffB; np < m_nNpeaks; np++, offs += m_nOffN) {
1984 ampli = xpar[offs+0];
1985 omega = xpar[offs+1];
1986 phase = xpar[offs+2];
1987 angle = omega*xx+phase;
1988 cosvv = cos(angle) * ampli;
1990 deriv[offs+0] = sin(angle);
1991 deriv[offs+1] = cosvv * xx ;
1992 deriv[offs+2] = cosvv;
2000 double CFitSpek::SFitFunc(
double xx)
2002 double yy, f1, fsum, back, val;
2004 if(!m_bSin)
return 0.;
2008 for(
int np = 0; np < m_nNpeaks; np++) {
2009 f1 = m_pRes[np].
Ampli * sin( m_pRes[np].Omega * yy + m_pRes[np].Phase);
2014 if(m_bFlat ) back += m_dBack0;
2015 if(m_bSlope) back += m_dBack1*(xx-m_nChanA);
2024 double CFitSpek::SFitWave(
double xx,
int np)
2028 if(!m_bValid || np < 0 || np > m_nNpeaks)
return 0.;
2031 f1 = m_pRes[np].
Ampli * sin( m_pRes[np].Omega * yy + m_pRes[np].Phase);
double(CFitSpek::* m_pfFunct)(double, double *)
double(CFitSpek::* m_pfFitFunc)(double)
double(CFitSpek::* m_pfFitBack)(double)
int CalcGaussianFit(float *pSpek, int chanA, int chanB, std::vector< double > &vPeaks)
bool CalcStrightLine(float *pSpek, int chanA, int chanB, int doSlope)
int CalcSinusoid(float *pSpek, int chanA, int chanB, double period, bool bFlat, bool bSlope)
void(CFitSpek::* m_pfDeriv)(int, double *, double *, double &, double &)
bool CalcPeakMoments(float *pSpek, int chanA, int chanB, int nChanBack)
double(CFitSpek::* m_pfFitPeak)(double, int)
bool CalcExponential(float *pSpek, int chanA, int chanB, int bgA=-1, int bgB=-1)