RooProdPdf (still) changes behaviour on Print()/getVal()


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");

  // 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

  // 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),

  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.


Dear Mikkel,

Perhaps @moneta can give you a hand with this,


This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.