23 #ifndef GW_PEAKFITTER_H
26 #ifndef GW_CLICKCOLLECTOR_H
41 #ifndef ROOT_TCanvas_H
44 #ifndef ROOT_TVirtualFitter_H
45 #include "TVirtualFitter.h"
47 #ifndef ROOT_TObject_H
50 #ifndef ROOT_TQObject_H
65 return(par[0]*TMath::Exp(-0.5*TMath::Power(((x[0]-par[1])/par[2]),2)) +
66 par[3]*TMath::Exp((x[0]-par[1])/par[4])*TMath::Erfc(((x[0]-par[1])/(TMath::Sqrt(2.0)*par[2])) +
67 (par[2]/(TMath::Sqrt(2.0)*par[4]))) + par[5]*TMath::Erfc((x[0]-par[1])/(TMath::Sqrt(2.0)*par[2])));
70 PeakFitter::PeakFitter() : fPeaks(0), fType(kGauss)
80 fMainFrame =
new TGMainFrame(0,10,10,kMainFrame | kVerticalFrame);
128 fTextButtonDoFit->Connect(
"Clicked()",
"Gw::PeakFitter",
this,
"DoFit1(=1.0)");
138 fMainFrame->SetMWMHints(kMWMDecorAll,kMWMFuncAll,kMWMInputModeless);
156 if ( TVirtualPad::Pad() ) {
158 c->Connect(
"ProcessedEvent(Int_t,Int_t,Int_t,TObject*)",
"Gw::ClickCollector",thecollector,
"DoCollect(Int_t,Int_t,Int_t,TObject*)");
159 cout <<
" - Start collecting clicks in " << c->GetName() <<
endl ;
164 cout <<
" - Cannot collect clicks, there is no current pad !!! " <<
endl ;
170 if ( TVirtualPad::Pad() ) {
173 cout <<
" - Stop collecting clicks in " << c->GetName() <<
endl ;
180 TObject *obj;
if ( TVirtualPad::Pad() == NULL )
return;
182 TIter next(TVirtualPad::Pad()->GetListOfPrimitives());
183 while ( (obj = next()) ) {
184 if ( obj->InheritsFrom(
"TMarker") ) {
delete obj; }
186 TVirtualPad::Pad()->Update();
191 TObject *obj;
if ( TVirtualPad::Pad() == NULL )
return;
193 TIter next(TVirtualPad::Pad()->GetListOfPrimitives(),kIterBackward);
194 while ( (obj = next()) ) {
195 if ( obj->InheritsFrom(
"TMarker") ) {
delete obj;
break; }
197 TVirtualPad::Pad()->Update();
209 const Int_t MAXMARKERS = 50 ; TVirtualFitter::Fitter(0,3*MAXMARKERS);
211 Int_t i, nbmarkers, nbgauss, ind[MAXMARKERS];
212 Float_t x[MAXMARKERS], y[MAXMARKERS], xlow, xhigh; Double_t par[3*MAXMARKERS];
216 if ( TVirtualPad::Pad() == NULL )
return;
219 TIter next(TVirtualPad::Pad()->GetListOfPrimitives());
221 hist = NULL; nbmarkers = 0;
222 while ( (obj = next()) ) {
223 if ( obj->InheritsFrom(
"TMarker") ) {
224 x[nbmarkers] = ((TMarker *)obj)->GetX();
225 y[nbmarkers++] = ((TMarker *)obj)->GetY();
227 if ( obj->InheritsFrom(
"TH1") && !obj->InheritsFrom(
"TH2") ) { hist = (TH1 *)obj; }
229 if ( hist == NULL || nbmarkers < 3 ) {
230 printf(
"There is no histograms or enough clicks in the current pad to realise a graphical fit \n");
return; }
234 TMath::Sort(nbmarkers,x,ind,
false); xlow = x[ind[0]]; xhigh = x[ind[nbmarkers-1]];
237 TH1 *lochist = (TH1 *)hist->Clone(
"fitter"); lochist->Reset(
"ICE");
240 Int_t first_bin, last_bin; Stat_t first_bin_c, last_bin_c, bin_c;
242 first_bin = hist->FindBin( xlow );
243 last_bin = hist->FindBin( xhigh );
244 first_bin_c = hist->GetBinContent(first_bin); last_bin_c = hist->GetBinContent(last_bin);
248 if ( ( fbg = (TF1 *)gROOT->GetListOfFunctions()->FindObject(
"Background") ) ) {
delete fbg; }
250 fbg =
new TF1(
"Background",
"pol1",xlow,xhigh);
251 fbg->SetParameters(first_bin_c-xlow*(last_bin_c-first_bin_c)/(xhigh-xlow),(last_bin_c-first_bin_c)/(xhigh-xlow));
253 fbg->SetLineColor(30); fbg->SetLineWidth(3); fbg->SetLineStyle(1); fbg->Draw(
"same");
256 for ( i = first_bin; i < last_bin ; i++ ) {
257 bin_c = hist->GetBinContent(i) -
258 ( Float_t(i-first_bin)*(last_bin_c-first_bin_c)/(last_bin-first_bin) + first_bin_c ) ;
259 lochist->SetBinContent(i,bin_c);
262 char fname[500]; TString ffit, fdisplay =
"pol1(0)";
265 for ( i = 1; i < nbmarkers - 1; i++ ) {
267 if ( y[ind[i]] < fbg->Eval(x[ind[i]]) ) {
268 printf(
"background too high at position %.1f \n",x[ind[i]]);
continue;
273 par[3*nbgauss] = y[ind[i]] - fbg->Eval(x[ind[i]]);
274 par[3*nbgauss+1] = x[ind[i]];
275 par[3*nbgauss+2] = sigma;
276 sprintf(fname,
"gaus(%d)",nbgauss*3); ffit +=
"+"; ffit += fname;
277 sprintf(fname,
"gaus(%d)",2+nbgauss*3); fdisplay +=
"+"; fdisplay += fname;
282 par[6*nbgauss] = y[ind[i]] - fbg->Eval(x[ind[i]]);
283 par[6*nbgauss+1] = x[ind[i]];
284 par[6*nbgauss+2] = sigma;
285 par[6*nbgauss+3] = (y[ind[i]] - fbg->Eval(x[ind[i]]))/10.;
286 par[6*nbgauss+4] = beta;
287 par[6*nbgauss+5] = 0.;
289 sprintf(fname,
"[%d]*TMath::Exp(-0.5*TMath::Power(((x-[%d])/[%d]),2)) + [%d]*TMath::Exp((x-[%d])/[%d])*TMath::Erfc(((x-[%d])/(TMath::Sqrt(2.0)*[%d])) + ([%d]/(TMath::Sqrt(2.0)*[%d]))) + [%d]*TMath::Erfc((x-[%d])/(TMath::Sqrt(2.0)*[%d]))",6*nbgauss,6*nbgauss+1,6*nbgauss+2,6*nbgauss+3,6*nbgauss+1,6*nbgauss+4,6*nbgauss+1,6*nbgauss+2,6*nbgauss+2,6*nbgauss+4,6*nbgauss+5,6*nbgauss+1,6*nbgauss+2);
291 ffit +=
"+"; ffit += fname;
293 sprintf(fname,
"[%d]*TMath::Exp(-0.5*TMath::Power(((x-[%d])/[%d]),2)) + [%d]*TMath::Exp((x-[%d])/[%d])*TMath::Erfc(((x-[%d])/(TMath::Sqrt(2.0)*[%d])) + ([%d]/(TMath::Sqrt(2.0)*[%d]))) + [%d]*TMath::Erfc((x-[%d])/(TMath::Sqrt(2.0)*[%d]))",2+6*nbgauss,2+6*nbgauss+1,2+6*nbgauss+2,2+6*nbgauss+3,2+6*nbgauss+1,2+6*nbgauss+4,2+6*nbgauss+1,2+6*nbgauss+2,2+6*nbgauss+2,2+6*nbgauss+4,2+6*nbgauss+5,2+6*nbgauss+1,2+6*nbgauss+2);
294 fdisplay +=
"+"; fdisplay += fname;
301 TF1 *f;
if ( ( f = (TF1 *)gROOT->GetListOfFunctions()->FindObject(
"ResultFit") ) ) {
delete f; }
304 printf(
"%s \n",ffit.Data());
305 f =
new TF1(
"ResultFit",ffit.Data(),xlow,xhigh);
308 for ( i = 0; i < nbgauss; i++ ) {
309 if (
fType ==
kGauss) {f->SetParameter(3*i,par[3*i]); f->SetParameter(3*i+1,par[3*i+1]); f->SetParameter(3*i+2,par[3*i+2]);}
310 if (
fType ==
kSkewed) {f->SetParameter(6*i,par[6*i]); f->SetParameter(6*i+1,par[6*i+1]); f->SetParameter(6*i+2,par[6*i+2]); f->SetParameter(6*i+3,par[6*i+3]); f->SetParameter(6*i+4,par[6*i+4]); f->FixParameter(6*i+5,par[6*i+5]);}
317 lochist->Fit(f,
"VNR");
319 Stat_t intensity, intensity_err;
321 printf(
"******************* DOFIT1 RESULTS ******************* \n");
322 printf(
" Chi2 %.2f / %d = %.2f \n",f->GetChisquare(),f->GetNDF(),f->GetChisquare()/f->GetNDF());
326 for ( i = 0; i < nbgauss; i++ ) {
328 intensity = f->GetParameter(2+3*i)*f->GetParameter(3*i)*TMath::Sqrt(2*TMath::Pi());
329 intensity_err = intensity * (f->GetParError(1+3*i)/f->GetParameter(1+3*i) + f->GetParError(2+3*i)/f->GetParameter(2+3*i));
331 printf(
" Peak %d : Position %.2f +- %.3f, width %.3f +- %.3f, Height %.1f +- %.1f, \t Intensity %.1f +- %.1f\n",
332 i+1,f->GetParameter(1+3*i),f->GetParError(1+3*i),2*f->GetParameter(2+3*i),2*f->GetParError(2+3*i),
333 f->GetParameter(3*i),f->GetParError(3*i),intensity,intensity_err);
335 sprintf(fname,
"peak%d",i);
337 if ( ( fpeak = (TF1 *)gROOT->GetListOfFunctions()->FindObject(fname) ) ) {
delete fpeak; }
340 fpeak =
new TF1(fname,
"gaus",f->GetParameter(1+3*i)-10,f->GetParameter(1+3*i)+10);
341 fpeak->SetLineStyle(3); fpeak->SetLineColor(16);
343 fpeak->SetParameters(f->GetParameter(3*i),f->GetParameter(1+3*i),f->GetParameter(2+3*i));
347 fpeak =
new TF1(fname,
SkewedGaussian,f->GetParameter(1+6*i)-10,f->GetParameter(1+6*i)+10,6);
348 fpeak->SetLineStyle(3); fpeak->SetLineColor(16);
350 fpeak->SetParameters(f->GetParameter(6*i),f->GetParameter(1+6*i),f->GetParameter(2+6*i),f->GetParameter(3+6*i),f->GetParameter(4+6*i),f->GetParameter(5+6*i));
354 printf(
"****************************************************** \n");
357 par[0] = fbg->GetParameter(0);
358 par[1] = fbg->GetParameter(1); f->GetParameters(&par[2]);
360 if ( ( f = (TF1 *)gROOT->GetListOfFunctions()->FindObject(
"DisplayFit") ) ) {
delete f; }
362 f =
new TF1(
"DisplayFit",fdisplay.Data(),xlow,xhigh); f->SetParameters(par);
363 f->SetLineColor(6); f->SetLineWidth(3);
367 f->Draw(
"same"); TVirtualPad::Pad()->Update();
void SetFunctionType(const FunctionType type)
printf("******************************************************************** \n")
TGTextButton * fTextButtonDoFit
void DoFit1(Float_t sigma=1.0)
Function to fit gaussians or skewed gaussian.
PeakFitter is a tool class.
TGTextButton * fTextButtonClearMarkers
Double_t SkewedGaussian(Double_t *x, Double_t *par)
void SetMode(Bool_t mode=true)
static ClickCollector * TheCollector()
TGTextButton * fTextButtonClearLastMarker
TGTextButton * fTextButtonCollectOn
ADF::LogMessage & endl(ADF::LogMessage &log)
header file for the calibration facility
TGTextButton * fTextButtonCollectOff
TGGroupFrame * fGroupFrame1
TGComboBox * fComboBoxFunctionType