OK here is as far as I’ve got so far. I think I’m stuck, I don’t know how to get further.
I generate a TH2F
with my pseudo-model P(A,X) which I then import as a RooDataHist
and then a RooHistPdf
(as far as I can tell, impossible to import it directly):
int bins_obs = 50;
int bins_par = 50;
auto h_mod = new TH2F("h_mod","Model",bins_par,0.,1.,bins_obs,-5.,5.);
auto mod_f2 = new TF2("mod_f2", [](double* x, double*p)
{
auto X=x[0];
auto Y=x[1];
return TMath::Gaus(Y,8.*X-4,(X+1)*.5);
}, 0., 1., -5., 5.);
auto N=500000;
h_mod->FillRandom("mod_f2",N);
h_mod->Draw("col");
new TCanvas;
// import model histogram
RooRealVar A("A", "parameter", 0., 1.);
RooRealVar X("X", "observable", -5., 5.);
RooDataHist rdh_model("rdh_model","rdh_model", RooArgList(A, X), Import(*h_mod));
RooHistPdf model("model","2D histo as PDF",RooArgList(A,X),rdh_model);
Then I use a gaussian distribution of the A parameter in order to generate some pseudo-data from the model, by doing \int P(X|A)P(A) dA:
// generate pseudo-data from gaussian distribution of A
RooRealVar mean("mean","mean",0.25);
RooRealVar sigma("sigma","sigma",.05);
RooGaussian gaussA("gaussA",
"Gaussian parameter distribution",
A, mean, sigma
);
RooProdPdf data_model("data_model", "Product PDF to make pseudo-data", gaussA, Conditional(model, X));
// Generate 1000 events in A and X from model
std::unique_ptr<RooDataSet> dati{data_model.generate({A, X}, 1000)};
RooPlot *xframe = X.frame();
dati->plotOn(xframe);
data_model.plotOn(xframe);
xframe->Draw();
Finally I try to retrieve the initial parameter distribution by doing the inverse projection using the pseudo-data histogram transformed into a RooHistPdf
as for the model:
RooDataHist dh("dh", "dh", X, *dati);
RooHistPdf data_pdf("data_pdf","data P(X) as PDF",X,dh);
RooProdPdf solution("solution", "Invert model using data", data_pdf, Conditional(model, A));
RooPlot *yframe = A.frame();
dati->plotOn(yframe);
data_model.plotOn(yframe);
solution.plotOn(yframe,LineColor(kRed));
new TCanvas;
yframe->Draw();
Amazingly, this sort of works… nearly:
The ‘solution’ has nearly the right mean value, but it’s width is far too large. Can anybody tell me what is wrong with what I’ve done (blindly fumbling around in the dark)?
Cheers
PS. Note that at the very beginning of my code I have to add
RooAbsPdf::defaultIntegratorConfig()->setEpsRel(1e-2);
RooAbsPdf::defaultIntegratorConfig()->setEpsAbs(1e-2);
otherwise the 2nd integration never converges.