Hi experts,
While calling Minuit, I would like to parametrize my data by an array of histograms stored in a file. This means the TF1 is not needed, and I want to make sure that it is not necessary for the minuit calls under the hood. The examples suggest that minuit does not need the TF1 to work, but I see no examples without a TF1…
I also want to try an unbinned parameter extraction. Can minuit handle this? I would simply define a global data TTree instead of TH2, and pass it to the fcn.
Specifically I have three questions:
- Should the code below work, without defining a TF1 and telling minuit about it?
- Should the code below work, defining a TTree as the global data set, and passing it around?
- What are the numbers I should multiply by to get the errors right? In the code above I multiply nll by -2. But I see some conflicting accounts, especially for the unbinned case.
Many thanks for your help!
TFile *expFile;
TFile *simFile;
TH2D *exp_hist;
TTree *exp_tree;
double binnedNLL(TH2F* h_meas, TH2F *h_sim){
double nll=0;
TAxis *xaxis = h_meas->GetXaxis();
TAxis *yaxis = h_meas->GetYaxis();
Double_t X,Y;
for (int i=1; i<=h_meas->GetNbinsX(); i++)for (int j=1; j<=h_meas->GetNbinsY(); j++){
X=xaxis->GetBinCenter(i);
Y=yaxis->GetBinCenter(j);
int n=(int)(h_meas->GetBinContent(i,j));
double mu;
mu=(double)h_sim->Interpolate(X,Y);
if (mu<1e-10) mu=1e-10; // avoid log(0) problems!
nll += n*TMath::Log(mu) + mu + TMath::LnGamma(n+1);
}
return -2*nll; // factor of -2 so minuit gets the errors right
}
double unbinnedNLL(TTree *t_meas, TH2D *h_sim){
double nll=0;
Double_t X,Y;
t_meas->SetBranchAddress("X",&X);
t_meas->SetBranchAddress("Y",&Y);
Long64_t nentries = t_meas->GetEntries();
for (Long64_t jentry=0; jentry<nentries; jentry++){
double mu;
mu=(double)h_sim->Interpolate(X,Y);
if (mu<1e-10) mu=1e-10; // avoid log(0) problems!
nll += TMath::Log(mu);
}
//nll+=h_sim->Integral(); //the extended likelihood needs the yield
return -2*nll; // factor of -2 so minuit gets the errors right
}
void fcn(int& npar, double* deriv, double& f, double par[], int flag){
TString hsim_name=Form(h2_%d_%d,par[0],par[1]);
TH2D *hsim=(TH2F*)simFile->Get(hsim_name.Data());
f = binnedNLL(exp_hist,hsim);
//f = unbinnedNLL(exp_tree,hsim);
} // end of fcn
int main(int argc, char **argv) {
TApplication theApp("App", &argc, argv);
TString expFilename="expfilename.root";
TString simFilename="simfilename.root";
expFile = new TFile(expFilename);
simFile = new TFile(simFilename);
cout << "Got files\n";
TFolder *histos = (TFolder*)expFile->FindObjectAny("histos2D");
TH2D *h_exp=(TH2D*)histos->FindObjectAny("observables_hist");
TTree *t_exp=(TTree*)expFile->Get("observables_tree");
TMinuit minuit(npar);
minuit.SetFCN(fcn);
exp_hist=h_exp;
exp_tree=t_exp;
etc.....