Histogram parameters inside fit function

Hi,

I am using a fit function that requires knowing the bin width. I find the bin width by using a procedure I found in the root doucmentaion:

// Find Bin Width TVirtualFitter *fitter = TVirtualFitter::GetFitter(); //the current fitter TH1 *hist = (TH1*)fitter->GetObjectFit(); //the histogram being fitted Double_t bin_width = hist->GetBinWidth(1);

This works fine… except I am fitting many histograms with the same function, some with different bin widths, and displaying the results on the same canvas. After I fit a histogram with a new bin width, the functions on the previous histograms are updated, assuming the now wrong bin width. Is there any simple way to get around the problem other than passing the bin width as an additonal parameter to the fit?

Thanks,

Steve

If you fit via TH1::Fit, your problem should not happen.
TH1::Fit takes care of storing a copy of the original function in teh histogram list of functions and it draws this copy.
In case you draw the function yourself, you should call TF1::DrawCopy instead of Draw

Rene

Hi Rene,

Thanks for your reply. I am just using the TH1::Fit() member function. If I add a TH1::DrawCopy() after the fit, then all is well. But I still am not sure why that is necessary in this case. Perhaps I am doing something else wrong? Here is a simplified version of what I am trying to do (comment out the DrawCopy to see the problem).

Steve

(Also attached)

#include "TCanvas.h"
#include "TPad.h"
#include "TH1.h"
#include "TF1.h"
#include "TVirtualFitter.h"
#include "TMath.h"

Double_t fcn_gaussian_area(Double_t *x, Double_t *par ) {

  Double_t  area      = par[0];
  Double_t  mean      = par[1];
  Double_t  sigma     = par[2];

  // Find Bin Width
  TVirtualFitter *fitter = TVirtualFitter::GetFitter();  //the current fitter
  TH1 *hist = (TH1*)fitter->GetObjectFit(); //the histogram being fitted
  Double_t  bin_width = hist->GetBinWidth(1);

  Double_t y = (x[0] - mean)/sigma;

  const Double_t C = 1.0 / TMath::Sqrt( TMath::TwoPi() ); 
  Double_t amp = C * bin_width * area / sigma; 
  Double_t fitval = amp * TMath::Exp( -y*y/2.0 );
 
  return fitval;

}

void Fit( TH1 *h ) {

  // Generate unique name (necessary?)
  TString name = h->GetName();
  name += "Gaussian";

  TF1* gaussian = new TF1( name, fcn_gaussian_area, -5.0, 5.0, 3 );
  gaussian->SetParameters( 100, 0.0, 1.0 );
  h->Fit(name, "", "", -5.0, 5.0 );
  h->DrawCopy();  // Works!
}

void Fits() {

  gROOT->Reset();
  gDirectory->Delete("h1");
  gDirectory->Delete("h2");

  TH1F * h1 = new TH1F( "h1", "h1", 100, -5.0, 5.0 );
  TH1F * h2 = new TH1F( "h2", "h2",  50, -5.0, 5.0 );

  h1->FillRandom("gaus", 1000 );
  h2->FillRandom("gaus", 10000 );

  TCanvas* myCanvas = new TCanvas( "c1","c1", 20, 20, 400, 200 );
  myCanvas->Divide( 2, 1 );

  myCanvas->cd(1);
  Fit( h1 );

  myCanvas->cd(2);
  Fit( h2 );

}

test.C (1.4 KB)