Troubles w/ a fit using a user-defined function +a histogram

Dear Rene,

[quote=“brun”]Let me repeat my request;
Could you provide a simple script that can reproduce the problem in a short amount of time?[/quote]
Do you mean you couldn’t reproduce the problem with the previously attached script(manyfit.C)/class files? I often observe that TF1::EvalPar() yields nan or values greater than 1.0e10.

The version attached to this post should do better; I was not sure whether I should delete objects which were Clone()d or TSpectrum::Background().

One question: is it possible to use a functor or a member function with TF1 for histogram fitting? My understanding from the users’ guide is that we can’t. Of course I’d be happy if we can.

Kazuyoshi
TGTsBGFit.cxx (4.49 KB)

I can run your script with your latest class without any problem. The memory leaks are now gone and I do not see any reports about NaN.

Rene

Do you always see a thick blue line which represents results of the fits? What is your environmen?

On Fedora 10 (i386 as well as x86_64) I sometimes don’t get the line because the unused parameters have somehow large absolute values and EvalPar() evaluate to nan, inf, or a extremely large value…

By the way, how about functor/member function fitting?

Kazuyoshi

I suggest to write your test script in the following way to avoid double deletes.

[code]void manyfits(void) {
TString names[] = {“hH00”, “hH01”, “hH02”, “hH03”, “hH04”,
“hH05”, “hH06”, “hH07”, “hH08”, “hH09”,
“hH10”, “hH11”, “hH12”, “hH16”, “hH17”,
“hH18”, “hH19”, “hH24”, “hH25”, “hH26”,
“hH27”, “hH28”, “hH29”, “hH30”, “hH31”};
Float_t zeroth[] = {-0.822299, -0.650575, -1.004017, -1.015329, -1.078479 ,
-0.491117, -0.318672, -2.518277, 0.347851, -0.277543 ,
-1.567872, -0.589049, -0.139822, -1.085679, 0.86937 ,
-0.817956, -0.497455, -1.270019, -1.403638, -1.1102 ,
-0.794053, -1.702961, -1.554968, -0.91216, -2.094039};
Float_t first[] = {0.742309, 0.74639, 0.750189, 0.748014, 0.750298,
0.741829, 0.758071, 0.745851, 0.750407, 0.752432,
0.749916, 0.74413, 0.744559, 0.741616, 0.735589,
0.749916, 0.740764, 0.749481, 0.752981, 0.751446,
0.754302, 0.753421, 0.744452, 0.753366, 0.74959};

Int_t error;
//gROOT->ProcessLine(".L TGTsBGFit.cxx+", &error);
TH1D *h=0;
TGTsBGFit *t=0;
TFile *f = new TFile(“coin3953_sumprj.root”,“read”);
TCanvas c = new TCanvas();
for (Int_t times=0;times<20;times++) {
for (Int_t idx=0; idx<25; idx++) {
cout << “<< " << names[idx] << " >>” << endl;
delete t;
delete h;
c->Clear();
h = (TH1D
)f->Get(names[idx]);
t = new TGTsBGFit(h,481.,541.,zeroth[idx],first[idx],1,c);
t->FindPeaks();
t->FitThePeaks();
c->Update();
} // idx
} // times
f->Close();
delete c;
}
[/code]

Concerning the functors have a look at the TF1 doc and the tutorials.

Rene

It IS. The attached script WORKS. (Ah, but the one I wrote for the TGTsBGFit DOESN’T… sigh.)

Thanks. It works much better.

By the way, “Functional documentation” of the TF1 document http://root.cern.ch/root/html/TF1.html lists the following method twice:

TF1(const char* name, void* ptr, Double_t xmin, Double_t xmax, Int_t npar, const char* className)

Seems to me that one should be

TF1(const char *name, Double_t (*fcn)(Double_t *, Double_t *), Double_t xmin, Double_t xmax, Int_t npar)

and the other

TF1(const char *name, Double_t (*fcn)(const Double_t *, const Double_t *), Double_t xmin, Double_t xmax, Int_t npar)

according to the source http://root.cern.ch/root/html/src/TF1.cxx.html

Kazuyoshi
functorFit.C (1.43 KB)

Hi,

thanks for the report! THtml (the tool generating the doc) sees whatever ROOT tells it, and ROOT claims that these function pointers are void*. You can see that when you type TF1::TF1([tab] at the ROOT prompt: you get the same set of constructors as THtml claims:

TF1 TF1()
TF1 TF1(const char* name, const char* formula, Double_t xmin = 0, Double_t xmax = 1)
TF1 TF1(const char* name, Double_t xmin, Double_t xmax, Int_t npar)
TF1 TF1(const char* name, void* fcn, Double_t xmin, Double_t xmax, Int_t npar)
TF1 TF1(const char* name, ROOT::Math::ParamFunctor f, Double_t xmin = 0, Double_t xmax = 1, Int_t npar = 0)
TF1 TF1(const char* name, void* ptr, Double_t xmin, Double_t xmax, Int_t npar, const char* className)
TF1 TF1(const char* name, void* ptr, void*, Double_t xmin, Double_t xmax, Int_t npar, const char* className, const char* methodName = 0)
TF1 TF1(const TF1& f1)

Now that’s of course not a good reason, it should still be fixed - but it’s not just a simple change in THtml. In the meantime I will try to come up with a workaround; I’ll let you know.

Cheers, Axel.

Hi,

I do not quite see any duplicate. However, indeed the one entry that correspond to the constructor taking a pointer to a function as an argument is ‘not quite’ right. Technically this is due to the internal representation (or lack thereof) of function (pointers) in CINT v5. This can not be resolved until we migrate to an extended C++ reflection ‘database’ (I.e. when we can start using Reflex or LLVM).

Cheers,
Philippe.