Hi,
How can I pass TMinuit a user function for minimization when
fitting a histogram? I'm having difficulties adapting the
tutorial Ifit.C (MINUIT is called directly, rather than
fitting a histogram).
Below is a macro with a modified chi-square function. If I
run this program (RH 7.2, ROOT 3.05/05), I don't see a
difference if I comment out the SetFCN call. Also, I added
the printf statement and it never gets executed.
Thanks for any help,
Chris
void diffMiniFunc() {
TH1F *h = new TH1F("h","My histogram",100,-3,3);
h->FillRandom("gaus",6000);
h->Fit("gaus"); // fit first to get a gMinuit object
gMinuit->SetFCN( MyH1FitChisquare );
h->Fit("gaus");
}
void MyH1FitChisquare(Int_t &npar, Double_t *gin, Double_t &f, Double_t *u, Int_t flag)
{
// Minimization function for H1s using a Chisquare method
// ======================================================
printf("I've been called!!\n");
Double_t cu,eu,fu,fsum;
Double_t dersum[100], grad[100];
Double_t x[3];
Int_t bin,binx,biny,binz,k;
Axis_t binlow, binup, binsize;
Int_t npfits = 0;
TVirtualFitter *hFitter = TVirtualFitter::GetFitter();
TH1 *hfit = (TH1*)hFitter->GetObjectFit();
TF1 *f1 = (TF1*)hFitter->GetUserFunc();
Foption_t Foption = hFitter->GetFitOption();
f1->InitArgs(x,u);
npar = f1->GetNpar();
if (flag == 2) for (k=0;k<npar;k++) dersum[k] = gin[k] = 0;
f = 0;
Int_t hxfirst = hFitter->GetXfirst();
Int_t hxlast = hFitter->GetXlast();
Int_t hyfirst = hFitter->GetYfirst();
Int_t hylast = hFitter->GetYlast();
Int_t hzfirst = hFitter->GetZfirst();
Int_t hzlast = hFitter->GetZlast();
TAxis *xaxis = hfit->GetXaxis();
TAxis *yaxis = hfit->GetYaxis();
TAxis *zaxis = hfit->GetZaxis();
for (binz=hzfirst;binz<=hzlast;binz++) {
x[2] = zaxis->GetBinCenter(binz);
for (biny=hyfirst;biny<=hylast;biny++) {
x[1] = yaxis->GetBinCenter(biny);
for (binx=hxfirst;binx<=hxlast;binx++) {
x[0] = xaxis->GetBinCenter(binx);
if (!f1->IsInside(x)) continue;
bin = hfit->GetBin(binx,biny,binz);
cu = hfit->GetBinContent(bin);
TF1::RejectPoint(kFALSE);
if (Foption.Integral) {
binlow = xaxis->GetBinLowEdge(binx);
binsize = xaxis->GetBinWidth(binx);
binup = binlow + binsize;
fu = f1->Integral(binlow,binup,u)/binsize;
} else {
fu = f1->EvalPar(x,u);
}
if (TF1::RejectedPoint()) continue;
if (Foption.W1) {
eu = 1;
} else {
//eu = hfit->GetBinError(bin);
// take error from value of fit
eu = TMath::Sqrt(fu);
if (eu <= 0) continue;
}
if (flag == 2) {
for (k=0;k<npar;k++) dersum[k] += 1; //should be the derivative
}
npfits++;
if (flag == 2) {
for (k=0;k<npar;k++) grad[k] += dersum[k]*(fu-cu)/eu; dersum[k] = 0;
}
fsum = (cu-fu)/eu;
f += fsum*fsum;
}
}
}
f1->SetNumberFitPoints(npfits);
}
This archive was generated by hypermail 2b29 : Thu Jan 01 2004 - 17:50:13 MET