28 fDefinePersoBackground =
false;
34 InitSourceProperties();
45 fHistName = fHistToFit->GetName();
47 fDefinePersoBackground =
false;
50 fFitFctName =
"FitFct_" + (TString)fHistToFit->GetName();
51 fBackGroundName =
"BackGround_" + (TString)fHistToFit->GetName();
53 InitSourceProperties();
58 delete BackGroundHist;
64 if(fSourceName ==
"60Co")
66 fEPeaks.push_back(1173.238);
67 fEPeaks.push_back(1332.513);
69 else if(fSourceName ==
"22Na") {
70 fEPeaks.push_back( 511.006);
71 fEPeaks.push_back(1274.545);
73 else if(fSourceName ==
"152Eu") {
74 fEPeaks.push_back( 121.7793);
75 fEPeaks.push_back( 244.6927);
76 fEPeaks.push_back( 344.2724);
77 fEPeaks.push_back( 411.111);
78 fEPeaks.push_back( 443.979);
79 fEPeaks.push_back( 778.890);
80 fEPeaks.push_back( 867.388);
81 fEPeaks.push_back( 964.014);
82 fEPeaks.push_back(1085.793);
84 fEPeaks.push_back(1112.070);
85 fEPeaks.push_back(1212.95);
86 fEPeaks.push_back(1299.1);
87 fEPeaks.push_back(1407.993);
89 else if(fSourceName ==
"88Y") {
90 fEPeaks.push_back( 898.045);
91 fEPeaks.push_back(1836.062);
94 else if(fSourceName ==
"133Ba") {
95 fEPeaks.push_back( 53.156);
96 fEPeaks.push_back( 79.623);
97 fEPeaks.push_back( 80.999);
98 fEPeaks.push_back( 160.609);
99 fEPeaks.push_back( 223.116);
100 fEPeaks.push_back( 276.404);
101 fEPeaks.push_back( 302.858);
102 fEPeaks.push_back( 356.014);
103 fEPeaks.push_back( 383.859);
105 else if(fSourceName ==
"baseline") {
106 fEPeaks.push_back(4000.);
109 fNPeaksToFit = fEPeaks.size();
114 fSourceName = source;
115 InitSourceProperties();
121 fHistName = fHistToFit->GetName();
126 fHistToFit = (TH1*)gROOT->FindObject(HistName);
127 if(fHistToFit == 0x0)
128 Warning(
"FitSpectra::SetHistogram",
"Histogram with name %s not found",HistName.Data());
129 else fHistName = fHistToFit->GetName();
136 TList *ListOfPrimitives = (TList*) CurrentPad->GetListOfPrimitives();
138 if(ListOfPrimitives->GetSize())
140 TIter iter(ListOfPrimitives);
144 while( (o = iter()) )
146 if(o->InheritsFrom(
"TH1"))
153 fHistName = fHistToFit->GetName();
155 fFitFctName =
"FitFct_" + (TString)fHistToFit->GetName();
156 fBackGroundName =
"BackGround_" + (TString)fHistToFit->GetName();
165 if(fHistToFit==0x0 || fHistToFit->Integral(2,fHistToFit->GetNbinsX()) < 100)
171 CurrentPad->SetEditable(
true);
173 gErrorIgnoreLevel = kError;
177 if(fxmin==0. && fxmax == 0.) fHistToFit->SetAxisRange(0.,fHistToFit->GetXaxis()->GetXmax());
178 else fHistToFit->SetAxisRange(fxmin,fHistToFit->GetXaxis()->GetXmax());
181 if(fSourceName==
"baseline") peakfactor = 1;
183 TSpectrum *s =
new TSpectrum(peakfactor*fNPeaksToFit);
193 double FirstStep = fThreshold;
194 while(fNFound>(
int)fNPeaksToFit*3)
196 fNFound = s->Search(fHistToFit,fWidth,
"nodraw",FirstStep);
197 FirstStep += fThreshold;
209 for(
int i=0 ; i<fNFound ; i++)
211 fXPeaks.push_back(s->GetPositionX()[i]);
212 fYPeaks.push_back(s->GetPositionY()[i]);
216 for(
int t=1 ; t<fNFound ; t++)
217 for(
int i=0 ; i<fNFound-1 ; i++)
218 if(fXPeaks[i]>fXPeaks[i+1])
220 swap(fXPeaks[i],fXPeaks[i+1]);
221 swap(fYPeaks[i],fYPeaks[i+1]);
225 if(fNFound!=fNPeaksToFit)
232 double rapmaxmin = fEPeaks[fEPeaks.size()-1]/fEPeaks[0];
233 double rapmaxmin2 = fEPeaks[fEPeaks.size()-1]/964.014;
237 for(
int i=0 ; i<fNFound ; i++)
239 for(
int j=i+1 ; j<fNFound ; j++)
241 double rap = TMath::Abs((fXPeaks[j]/fXPeaks[i])/rapmaxmin-1);
243 if(rap<0.005 && fYPeaks[i]>0.9*fYPeaks[j] && rap<bestrap)
245 if(fSourceName.Contains(
"Eu"))
248 for(
int k=0 ; k<fNFound ; k++)
250 double rap2 = TMath::Abs((fXPeaks[j]/fXPeaks[k])/rapmaxmin2-1);
270 Error(
"FitSpectra::Fit()",
"First and last peak not found ==> Calibration not feasible, exit Fit() method.");
279 fXPeaks.erase(fXPeaks.begin()+max+1,fXPeaks.end());
280 fYPeaks.erase(fYPeaks.begin()+max+1,fYPeaks.end());
282 fXPeaks.erase(fXPeaks.begin(),fXPeaks.begin()+min);
283 fYPeaks.erase(fYPeaks.begin(),fYPeaks.begin()+min);
290 vector < int > BadPeaks;
291 vector < int > PeakNotFound;
295 for(
int i=1 ; i<fNPeaksToFit-1 ; i++)
298 bool peakfound =
false;
300 double rapE = fEPeaks[i]/fEPeaks[0];
302 for(
int j=lastgoodpeak+1 ; j<fNFound-1 ; j++)
304 double rap = TMath::Abs((fXPeaks[j]/fXPeaks[0])/rapE-1);
305 if(rap<0.007&&rap<bestrap)
307 for(
int k=lastgoodpeak+1 ; k<j ; k++) BadPeaks.push_back(k);
316 PeakNotFound.push_back(i);
324 fXPeaks.erase(fXPeaks.begin()+lastgoodpeak+1,fXPeaks.end()-1);
325 fYPeaks.erase(fYPeaks.begin()+lastgoodpeak+1,fYPeaks.end()-1);
327 for(
int i=BadPeaks.size()-1 ; i>=0 ; i--)
329 fXPeaks.erase(fXPeaks.begin()+BadPeaks[i]);
330 fYPeaks.erase(fYPeaks.begin()+BadPeaks[i]);
333 for(
int i=PeakNotFound.size()-1 ; i>=0 ; i--)
335 fEPeaks.erase(fEPeaks.begin()+PeakNotFound[i]);
340 double xmin = fXPeaks[0] - fXPeaks[fNPeaksToFit-1]*0.05;
341 double xmax = fXPeaks[fNPeaksToFit-1] + fXPeaks[fNPeaksToFit-1]*0.05;
342 fHistToFit->SetAxisRange(xmin,xmax);
349 if(fSourceName==
"baseline")
351 xmin = fXPeaks[0]*(1-0.1);
352 xmax = fXPeaks[fNFound-1]*(1+0.2);
355 int nbins = fHistToFit->FindBin(xmax)-fHistToFit->FindBin(xmin);
356 CurrentPad->SetLogy();
359 #if ROOT_VERSION_CODE >= ROOT_VERSION(6,0,0)
360 double * source =
new double[nbins];
362 float * source =
new float[nbins];
365 for(
int i=0 ; i< nbins ; i++) source[i] = fHistToFit->GetBinContent(fHistToFit->FindBin(xmin)+i+1);
367 if(fDefinePersoBackground)
369 s->Background(source,nbins,fNumberIterations,fDirection,fFilterOrder,fSmoothing,fsmoothingWindow,fCompton);
371 else if(fSourceName==
"152Eu")
373 s->Background(source,nbins,30,TSpectrum::kBackDecreasingWindow,TSpectrum::kBackOrder2,
true,TSpectrum::kBackSmoothing3,
false);
375 else if(fSourceName==
"baseline")
377 s->Background(source,nbins,20,TSpectrum::kBackDecreasingWindow,TSpectrum::kBackOrder2,
true,TSpectrum::kBackSmoothing3,
false);
379 else if(fHistName.Contains(
"36") || fHistName.Contains(
"37"))
381 s->Background(source,nbins,90,TSpectrum::kBackDecreasingWindow,TSpectrum::kBackOrder2,
true,TSpectrum::kBackSmoothing3,
false);
385 s->Background(source,nbins,300,TSpectrum::kBackDecreasingWindow,TSpectrum::kBackOrder8,
true,TSpectrum::kBackSmoothing3,
true);
388 if(gROOT->FindObject(fBackGroundName) != 0x0)
390 TH1 *h = (TH1*) gROOT->FindObject(fBackGroundName);
394 BackGroundHist =
new TH1F(fBackGroundName,fBackGroundName,nbins,xmin,xmax);
396 for (
int i = 0; i < nbins; i++) BackGroundHist->SetBinContent(i+1,source[i]);
398 if(gROOT->FindObject(fFitFctName) != 0x0)
400 TH1 *f = (TH1*) gROOT->FindObject(fFitFctName);
406 if(fFitType ==
"Gaus")
410 fFitFct =
new TF1(fFitFctName,
this,&
FitSpectra::BGPlusGaus,xmin,xmax,fNPeaksToFit*NPar,
"FitSpectra",
"BGPlusGaus");
411 fFitFct->SetNpx(nbins);
413 for(
int i=0 ; i<fNPeaksToFit ; i++)
415 fFitFct->SetParameter(0+NPar*i,fYPeaks[i]-BackGroundHist->GetBinContent(BackGroundHist->FindBin(fXPeaks[i])));
416 fFitFct->SetParLimits(0+NPar*i,fFitFct->GetParameter(0+NPar*i)/2.,fFitFct->GetParameter(0+NPar*i)*2.);
418 fFitFct->SetParameter(1+NPar*i,fXPeaks[i]);
419 fFitFct->SetParLimits(1+NPar*i,fXPeaks[i]*(1-2e-3),fXPeaks[i]*(1+2e-3));
421 fFitFct->SetParameter(2+NPar*i,fXPeaks[i]*5e-4);
422 fFitFct->SetParLimits(2+NPar*i,0.,20.);
425 else if(fFitType ==
"CBDS")
429 fFitFct =
new TF1(fFitFctName,
this,&
FitSpectra::BGPlusCBDS,xmin,xmax,fNPeaksToFit*NPar,
"FitSpectra",
"BGPlusCBDS");
430 fFitFct->SetNpx(nbins);
432 for(
int i=0 ; i<fNPeaksToFit ; i++)
434 fFitFct->SetParameter(0+NPar*i,fYPeaks[i]-BackGroundHist->GetBinContent(BackGroundHist->FindBin(fXPeaks[i])));
435 fFitFct->SetParLimits(0+NPar*i,fFitFct->GetParameter(0+NPar*i)*0.95,fFitFct->GetParameter(0+NPar*i)*1.05);
437 fFitFct->SetParameter(1+NPar*i,fXPeaks[i]);
438 fFitFct->SetParLimits(1+NPar*i,fXPeaks[i]*(1-0.001),fXPeaks[i]*(1+0.001));
440 fFitFct->SetParameter(2+NPar*i,fXPeaks[i]*5e-4);
443 fFitFct->SetParameter(3+NPar*i,2.);
444 fFitFct->SetParLimits(3+NPar*i,0.,5.);
446 fFitFct->SetParameter(4+NPar*i,5.);
447 fFitFct->SetParLimits(4+NPar*i,0.,25.);
449 fFitFct->SetParameter(5+NPar*i,2.);
450 fFitFct->SetParLimits(5+NPar*i,0.,5.);
452 fFitFct->SetParameter(6+NPar*i,5.);
453 fFitFct->SetParLimits(6+NPar*i,0.,25.);
456 else if(fFitType ==
"Dino")
460 double par[fNPeaksToFit*NPar];
462 for(
int i=0 ; i<fNPeaksToFit ; i++)
464 TF1 *Gaus =
new TF1(
"Gaus",
this,&
FitSpectra::BGPlusGaus,fXPeaks[i]-5.,fXPeaks[i]+10.,NPar,
"FitSpectra",
"BGPlusGaus");
466 Gaus->SetParameter(0,fYPeaks[i]-BackGroundHist->GetBinContent(BackGroundHist->FindBin(fXPeaks[i])));
468 Gaus->SetParameter(1,fXPeaks[i]);
469 Gaus->SetParLimits(1,fXPeaks[i]-1.,fXPeaks[i]+1.);
471 Gaus->SetParameter(2,fXPeaks[i]*1e-3);
472 Gaus->SetParLimits(2,0.,fXPeaks[i]*2e-3);
474 fHistToFit->Fit(Gaus,
"QRS0");
476 par[0+NPar*i] = Gaus->GetParameter(0);
477 par[1+NPar*i] = Gaus->GetParameter(1);
478 par[2+NPar*i] = Gaus->GetParameter(2);
485 fFitFct->SetNpx(nbins);
487 for(
int i=0 ; i<fNPeaksToFit ; i++)
489 fFitFct->FixParameter(0+NPar*i,par[0+3*i]);
491 fFitFct->FixParameter(1+NPar*i,par[1+3*i]);
493 fFitFct->SetParameter(2+NPar*i,par[2+3*i]);
494 fFitFct->SetParLimits(2+NPar*i,1./sqrt(12.),par[2+3*i]*2.35);
496 fFitFct->SetParameter(3+NPar*i,-2.);
497 fFitFct->SetParLimits(3+NPar*i,-50,-0.1);
499 fFitFct->SetParameter(4+NPar*i,2.);
500 fFitFct->SetParLimits(4+NPar*i,0.1,50.);
502 fFitFct->FixParameter(5+NPar*i,0.);
505 fHistToFit->Fit(fFitFct,
"QRS0+");
506 TF1 *FitFctClone = (TF1*)fFitFct->Clone();
510 for(
int i=0 ; i<fNPeaksToFit ; i++)
513 if(fFitType ==
"Gaus") FNoBG =
new TF1(
"FNoBG",
this,&
FitSpectra::MyGaus,xmin,xmax,NPar,
"FitSpectra",
"MyGaus");
514 else if(fFitType ==
"CBDS") FNoBG =
new TF1(
"FNoBG",
this,&
FitSpectra::fnc_dscb,xmin,xmax,NPar,
"FitSpectra",
"fnc_dscb");
515 else if(fFitType ==
"Dino") FNoBG =
new TF1(
"FNoBG",
this,&
FitSpectra::DinoFct,xmin,xmax,NPar,
"FitSpectra",
"DinoFct");
517 for(
int j=0 ; j<NPar ; j++) FNoBG->SetParameter(j,fFitFct->GetParameter(j+NPar*i));
519 double mean = FNoBG->GetParameter(1);
520 double sigma = FNoBG->GetParameter(2);
522 fMean.push_back(mean);
523 fSigma.push_back(sigma);
525 double N = FNoBG->GetParameter(0);
527 double fwhm = FNoBG->GetX(N/2.,mean,mean+5*sigma)-FNoBG->GetX(N/2.,mean-5*sigma,mean);
529 fFWHM.push_back(fwhm);
531 double fwhm_10 = FNoBG->GetX(N/10.,mean,mean+5*sigma)-FNoBG->GetX(N/10.,mean-5*sigma,mean);
533 fFWHM_10.push_back(fwhm_10);
535 double LTProp = (mean-FNoBG->GetX(N/10.,mean-5*sigma,mean))/(mean-FNoBG->GetX(N/2.,mean-5*sigma,mean));
537 fLeftTailProp.push_back(LTProp);
539 double RTProp = (mean-FNoBG->GetX(N/10.,mean,mean+5*sigma))/(mean-FNoBG->GetX(N/2.,mean,mean+5*sigma));
541 fRightTailProp.push_back(RTProp);
543 double area = FNoBG->Integral(mean-5*sigma,mean+5*sigma);
544 fArea.push_back(area);
557 FitFctClone->Draw(
"same");
559 TH1F *BackGroundHistClone = (TH1F*)BackGroundHist->Clone();
560 BackGroundHistClone->SetLineColor(kGreen);
561 BackGroundHistClone->SetLineStyle(7);
562 BackGroundHistClone->Draw(
"same");
564 fHistToFit->SetAxisRange(xmin,xmax);
566 CurrentPad->SetEditable(
true);
571 gErrorIgnoreLevel = kPrint;
579 const int n = fNPeaksToFit;
584 for(
int i=0 ; i<fNPeaksToFit ; i++)
590 TGraph *g =
new TGraph(fNPeaksToFit,Raw,E);
592 TF1 *fpol =
new TF1(
"f",
"[0]+[1]*x",0.,Raw[fNPeaksToFit-1]*1.2);
593 if(!fUseOffset) fpol->FixParameter(0,0.);
597 fCalibOffset = fpol->GetParameter(0);
598 fCalibSlope = fpol->GetParameter(1);
600 for(
int i=0 ; i<fNPeaksToFit ; i++)
602 fEcal.push_back(fpol->Eval(fMean[i]));
603 fFWHMCal.push_back(fCalibSlope*fFWHM[i]);
604 fFWHM_10Cal.push_back(fCalibSlope*fFWHM_10[i]);
623 double u = (x-mu)/sig;
624 double A1 = TMath::Power(p1/TMath::Abs(a1),p1)*TMath::Exp(-a1*a1/2);
625 double A2 = TMath::Power(p2/TMath::Abs(a2),p2)*TMath::Exp(-a2*a2/2);
626 double B1 = p1/TMath::Abs(a1) - TMath::Abs(a1);
627 double B2 = p2/TMath::Abs(a2) - TMath::Abs(a2);
630 if (u<-a1) result *= A1*TMath::Power(B1-u,-p1);
631 else if (u<a2) result *= TMath::Exp(-u*u/2);
632 else result *= A2*TMath::Power(B2+u,-p2);
642 double sigma = pp[2];
644 double lambda = pp[3];
648 double u = (x-P)/sigma;
650 double f_g = A*TMath::Exp(-u*u*0.5);
652 double f_lambda = A*TMath::Exp(-0.5*lambda*(2.*u-lambda));
654 double f_rho = A*TMath::Exp(-0.5*rho*(2.*u-rho));
656 double f_S = A*S*1./((1+TMath::Exp(u))*(1+TMath::Exp(u)));
660 if(u<lambda) f_tot += f_lambda;
661 else if(u>rho) f_tot += f_rho;
673 double mean = par[1];
674 double sigma = par[2];
676 double f = N*exp(-0.5*((x-mean)/sigma)*((x-mean)/sigma));
685 double f = BackGroundHist->GetBinContent(BackGroundHist->FindBin(x));
687 for(
int i=0 ; i<fNFound ; i++)
689 double *p =
new double[3];
706 double f = BackGroundHist->GetBinContent(BackGroundHist->FindBin(x));
708 for(
int i=0 ; i<fNFound ; i++)
712 double *p =
new double[
size];
714 p[0] = par[size*i+0];
715 p[1] = par[size*i+1];
716 p[2] = par[size*i+2];
717 p[3] = par[size*i+3];
718 p[4] = par[size*i+4];
719 p[5] = par[size*i+5];
720 p[6] = par[size*i+6];
733 double f = BackGroundHist->GetBinContent(BackGroundHist->FindBin(x));
735 for(
int i=0 ; i<fNFound ; i++)
739 double *p =
new double[
size];
741 p[0] = par[size*i+0];
742 p[1] = par[size*i+1];
743 p[2] = par[size*i+2];
744 p[3] = par[size*i+3];
745 p[4] = par[size*i+4];
746 p[5] = par[size*i+5];
757 fDefinePersoBackground =
true;
758 fNumberIterations = NumberIterations;
759 fDirection = Direction;
760 fFilterOrder = FilterOrder;
761 fSmoothing = Smoothing;
762 fsmoothingWindow = smoothingWindow;
768 double FirstEToKeep = 344.272;
770 for(
int i=0 ; i<fNPeaksToFit ; i++)
772 if(fEPeaks[i] < FirstEToKeep) Pos = i;
775 fEPeaks.erase(fEPeaks.begin(),fEPeaks.begin()+Pos+1);
776 fNPeaksToFit = fEPeaks.size();
void SetHistogram(TH1 *h)
double BGPlusCBDS(double *xx, double *par)
void SetSource(TString source)
FitSpectra(TString type="Dino", TString source="60Co")
void InitSourceProperties()
double BGPlusDinoFct(double *xx, double *par)
double MyGaus(double *xx, double *par)
double BGPlusGaus(double *xx, double *par)
void SetPersoBackground(int NumberIterations=100, int Direction=TSpectrum::kBackDecreasingWindow, int FilterOrder=TSpectrum::kBackOrder8, bool Smoothing=true, int smoothingWindow=TSpectrum::kBackSmoothing3, bool Compton=false)
double fnc_dscb(double *xx, double *pp)
void GetCurrentHistogram()
double DinoFct(double *xx, double *pp)