Hi.
I'm trying to use a fit within a fit: the minimization function
of my fit involves another fit to a histogram, but I get a segmentation
violation using ROOT 2.23/11 on Linux.
Here is an example session followed by my code. Am I doing something
wrong or is this a bug? Is there a solution or workaround? Thanks.
Stephen
root [0] .L otto.cc
root [1] initOtto();
root [2] otto();
FCN=34.3176 FROM MIGRAD STATUS=CONVERGED 165 CALLS 166
TOTAL
EDM=1.31629e-05 STRATEGY= 1 ERROR MATRIX
ACCURATE
EXT PARAMETER STEP FIRST
NO. NAME VALUE ERROR SIZE DERIVATIVE
1 p0 7.29523e+01 3.36079e+00 8.08107e-03 -3.91228e-04
2 p1 -6.99217e-02 4.98261e-02 1.51244e-04 -3.12920e-02
3 p2 1.05729e+00 3.89826e-02 9.41497e-05 -5.54527e-02
4 p3 1.72997e+01 8.81791e-01 2.06990e-03 2.13463e-03
5 p4 -3.70281e-01 2.21413e-01 6.13668e-04 -1.58787e-02
<TCanvas::MakeDefCanvas>: created default TCanvas with name c1
*** Break *** segmentation violation
Root > Function otto() busy flag cleared
// Toy example of fit within a fit.
// The TNtuple nt contains a Gaussian mass (m) distribution with an
// exponential lifetime (t). It is on top of a background with a
// random mass and a shorter exponential lifetime distribution.
// The function otto() trys to maximize the statistical power S^2/(S+B)
// with a lifetime cut. The minimization function projects the ntuple
// into a histogram and fits the histogram, extracting S and B and
// returns -S*S/(S+B);
// But apparently fitting the histogram within the running fit causes
// the fitter to crash with a segmentation violation
TNtuple* nt;
void initOtto(void) {
nt = new TNtuple("nt", "Test Ntuple", "m:t");
TRandom rand;
// Fill with the signal and background
for(int i = 0; i < 1000; i++) {
nt.Fill( rand.Gaus(), rand.Exp(2) );
nt.Fill( rand.Rndm() * 10 - 5, rand.Exp(1) );
}
}
void otto(void) {
// Create and set up the fitter
TFitter *fitter = new TFitter(1);
fitter->SetFCN(fcn);
Double_t arg[5];
// Quiet it down a bit
arg[0] = -1; fitter->ExecuteCommand("SET PRI", arg, 1);
fitter->SetParameter(0, "t cut", 0.1, 0.01, 0, 0);
// Now ready for minimization step
arg[0] = 500;
arg[1] = 1.0;
fitter->ExecuteCommand("MIGRAD", arg, 2);
// Print results
Double_t amin;
fitter->PrintResults(1, amin);
} // end otto()
void fcn(Int_t &npar, Double_t *gin, Double_t &r, Double_t *par, Int_t flag)
{
TH1S h1("h1", "Test Histogram", 50, -5, 5);
TF1 f1("f1", "gaus(0)+pol1(3)", -5, 5);
f1.SetParameters(40, 0, 1, 2, 0);
char cut[50];
sprintf(cut, "t>%g", par[0]);
h1.Clear();
nt->Project("h1", "m", cut);
h1.Fit("f1");
// Normalization here is probably off, but that isn't the point.
Double_t s = f1->GetParameter(0) * 2.507 * f1->GetParameter(2);
Double_t b = f1->GetParameter(3);
r = -(s*s)/(s+b);
} // end fcn()
This archive was generated by hypermail 2b29 : Tue Jan 02 2001 - 11:50:21 MET