RooFit doesn't properly normalize model w.r.t data

I am not sure whether this is a bug or I missed something. I tried creating a 2D (x,y) model, generate some data, fit to data with a fit range on y, then plot the data and model on x frame. The model does not normalize to the data correctly. I tested on 5.26 and 5.28, and they behave differently, but both have wrong normalization.

The test code is in the attached file and the problem is demonstrated by executing it.

fit_normalization.C :

// This shows that, the model-to-data normalization in x plot is wrong if a y fit range
// is applied in fit, regardless of the value of the range; is it a bug?
//
// In the plots, red line is with NormRange(), blue line is without.

using namespace RooFit;
RooWorkspace w("w",kTRUE);

void fit_normalization() {

  // Create 2D model with observables x and y. Apply a fit range "fit_range" on y.
  w.factory("x[0,10]");
  w.factory("y[1,9]");
  w::y.setRange("fit_range",5,6);  // setting any range is the same -- always wrong

  // Test model 1 : v5.28 cannot plot this model; v5.26 can if NormRange() is used.
  w.factory("Gaussian::model1(x,y,g_sigma[1,0.5,2])");
  plot(w::model1);

  // Test model 2 : G(x)*G(y) : both v5.28 and v5.26 cannot plot this
  w.factory("PROD::model2(Gaussian::g1(x,g1_mean[5],g1_sigma[1,0.5,2]),Gaussian::g2(y,g2_mean[5],g2_sigma[1,0.5,2]))");
  plot(w::model2);
}

void plot(RooAbsPdf& model) {

  TString model_name = model.GetName();

  data = model.generate(RooArgSet(w::x,w::y),50000);

  // Fit without fit_range
  model.fitTo(*data);

  x_frame = w::x.frame(Title(model_name+" full fit"));
  data->plotOn(x_frame);
  model.plotOn(x_frame);
  can=new TCanvas(); x_frame->Draw();

  // Fit with fit_range
  model.fitTo(*data, Range("fit_range"));

  // Not using ProjectionRange
  x_frame = w::x.frame(Title(model_name+" range fit without projection cut"));
  data->plotOn(x_frame);
  model.plotOn(x_frame);
  model.plotOn(x_frame,NormRange("fit_range"),LineColor(2));
  can=new TCanvas(); x_frame->Draw();

  // Use CutRange and ProjectionRange on fit_range
  x_frame = w::x.frame(Title(model_name+" range fit with CutRange() and ProjectionRange()"));
  data->plotOn(x_frame,CutRange("fit_range"));
  model.plotOn(x_frame,ProjectionRange("fit_range"));
  model.plotOn(x_frame,ProjectionRange("fit_range"),NormRange("fit_range"),LineColor(2));
  can=new TCanvas(); x_frame->Draw();

  // Try using Range() instead of ProjectionRange(); No use: Range() is only for the plot axis and has no effect on y axis.
//  x_frame = w::x.frame(Title(model_name+" range fit with CutRange() and Range()"));
//  data->plotOn(x_frame,CutRange("fit_range"));
//  model.plotOn(x_frame,Range("fit_range"));
//  model.plotOn(x_frame,Range("fit_range"),NormRange("fit_range"),LineColor(2));
//  can=new TCanvas(); x_frame->Draw();

}

fit_normalization.C (2.3 KB)