Hello,
I have previously posted a question/bug report on RooProdPdf changing behaviour depending on whether Print() is called on it. The short snippet I added in that question seems to have been fixed in ROOT 6.14.04/RooFit 3.60, however the problem is still there in my analysis code.
Therefore, I have made a more elaborate example, reproducing the bug below.
It has to do with using a RooProdPdf as a constrain in a simulateneous fit - depending on whether I include the getVal() flagged with “XXX” below, the constrain is or is not applied. Here is the code
void test2() {
// Two categories
RooCategory * cat = new RooCategory("cat", "cat");
cat->defineType("c1");
cat->defineType("c2");
// Our measured variable
RooRealVar * x = new RooRealVar("m1","m1", 2, 0, 4);
// Distribution functions
RooRealVar * mu1 = new RooRealVar("mu1","mu1", 2, 1, 3);
RooRealVar * mu2 = new RooRealVar("mu2","mu2", 2.2, 1, 3);
RooRealVar * s1 = new RooRealVar("s1","s1", 1, 0.1, 2);
RooRealVar * s2 = new RooRealVar("s2","s2", 1.2, 0.1, 2);
RooGaussian * g1 = new RooGaussian("g1","g1", *x, *mu1, *s1);
RooGaussian * g2 = new RooGaussian("g2","g2", *x, *mu2, *s2);
// Yields for extended fits
double multiplier = 1; // 'stats' multiplier
RooRealVar * n1 = new RooRealVar("n1","n1", 22*multiplier, 0, 50*multiplier);
RooRealVar * n2 = new RooRealVar("n2","n2", 11*multiplier, 0, 50*multiplier);
// Full Signal
RooAddPdf * sig1 = new RooAddPdf("sig1", "sig1", RooArgList(*g1), RooArgList(*n1));
RooAddPdf * sig2 = new RooAddPdf("sig2", "sig2", RooArgList(*g2), RooArgList(*n2));
// Constraints on mean, one for each mean
RooRealVar * mu1_const_mu = new RooRealVar("mu1_const_mu","mu1_const_mu", 2);
RooRealVar * mu2_const_mu = new RooRealVar("mu2_const_mu","mu2_const_mu", 2.2);
RooRealVar * mu1_const_sig = new RooRealVar("mu1_const_sig","mu1_const_sig", 0.05);
RooRealVar * mu2_const_sig = new RooRealVar("mu2_const_sig","mu2_const_sig", 0.05);
RooGaussian * const1 = new RooGaussian("const1","g1", *mu1, *mu1_const_mu, *mu1_const_sig);
RooGaussian * const2 = new RooGaussian("const2","g2", *mu2, *mu2_const_mu, *mu2_const_sig);
// Full constaint
RooProdPdf * const_pdf = new RooProdPdf("const", "", RooArgSet(*const1, *const2));
// XXX: if the function call is made, the constraint works
// XXX: if it left out, or moved below the mc_study definition, the constrain is not applied
const_pdf->getVal();
// Constrained signal pdf's
RooProdPdf * const_sig1 = new RooProdPdf("const_sig1", "", RooArgSet(*sig1, *const_pdf));
RooProdPdf * const_sig2 = new RooProdPdf("const_sig2", "", RooArgSet(*sig2, *const_pdf));
// Full sim
RooSimultaneous * sim = new RooSimultaneous("sim", "sim", *cat);
sim->addPdf(*const_sig1, "c1");
sim->addPdf(*const_sig2, "c2");
// Generate data
auto mc_study = new RooMCStudy(
*sim, RooArgSet(*x, *cat),
RooFit::Extended(true));
int n_events_per_sample = sim->expectedEvents(*cat);
mc_study->generate(5, n_events_per_sample, true);
auto data = mc_study->genData(2);
sim->fitTo(*data, RooFit::Constrain(RooArgSet(*mu1, *mu2)));
}
I find that
- If I use RooFit::ExternalConstraints(…), the constraint works irrespectively of the getVal() call
- If I include the getVal() call below the
mc_study
definition, the constraint is not applied, even if it is included
I can of course just switch to ExternalConstraints (is this more/less correct?), but still, this behaviour points to something weird in RooProdPdf I think. getVal() calls should definitely not change subsequent behaviour.
Thanks,
Mikkel