RooGenericPdf::generate missing data; setRange causes error

Hello,
Im using roofit v3.52. I am trying to fit data which falls within a circular region. The data basically forms a 2D Gaussian. When fitting to this distribution I seem to be having two issues with roofit. I’ll start with what’s probably the easier of the two problems

  1. To test my fit method I generate a generic 2D gaussian pdf using RooGenericPdf. I then generate a RooDataSet from this as follows:
   TString generatingFnc("exp(-(@0^2+@1^2)/(2*@2^2))");
   RooGenericPdf gauss("gauss","2D Guassian", generatingFnc, RooArgList(x, y, csigma));
   RooDataSet *testdata = gauss.generate(RooArgSet(x,y), Ntot);

x and y are obviously coordinates (RooRealVar’s) and csigma is the sigma of the gaussian (a RooConstVar). For some reason when csigma is set to 0.05 (about the correct value for my actual data) the generated RooDataSet has no data just below x~0. If I set csigma larger it seems to do fine. A look at some projections shows that the data is completely missing. The fit to this dataset works, but it is clearly affected. Is there anything I may have done accidentally to cause this? I will attach some short code to illustrate this problem. The script also automatically generates some plots showing the missing data.

  1. For the actual data I am fitting I have no data past a certain distance from the center of my circular region, so my gaussian distribution could be cuttoff if it’s near the edge. To correct for this I am setting up a circular range for x and y for my fit via the following:
  // Set region of map to fit (a circle)
   RooFormulaVar xlo("xlo","-sqrt(@0*@0-@1*@1)",RooArgSet(RooConst(radi), y));
   RooFormulaVar xhi("xhi","sqrt(@0*@0-@1*@1)",RooArgSet(RooConst(radi), y));   
   y.setRange("circle", -radi, radi);
   x.setRange("circle", xlo, xhi);

(where radi is the cutoff distance from the center) and fitting to my distribution via:

   RooFitResult *fitresult = extfitgauss.fitTo(*testdata, PrintLevel(-1), Range("circle"));

but the fit crashes. If I dont use RooFormulaVar’s in “x.setRange” this problem goes away. But then I’m not fitting to the circular region where my data is defined and the fit may not be accurate. Is this a bug, or is there another way I should be using to fit to a circular range?

I have attached a shortened version of my code which illustrates my problems. I have commented out the code which generates problem 2, but it’s easy enough to see what needs to be changed. If not, I can upload a version which causes problem 2.

This is my first post here, so if anything above needs changing (such as breaking these questions into two separate posts) or if you need more information please let me know.
2DGaussFit_CircularRegion.C (4.05 KB)

I came back to this recently. I believe that I have a solution to the second problem. It seems that when I set the range on x is important. For example, before I was doing things in this order:

[ul]
Set circular range on x,
Generate test data,
Create PDF to fit to test data
Do the actual fitting in specified range
[/ul]
I was defining my range before I generated my test data. However, by placing my range definition immediately before the actual fit the issue I was having seems to have gone away. The order looks something more like this now:

[ul]
Generate test data,
Create PDF to fit to test data
Set circular range on x,
Do the actual fitting in specified range
[/ul]
Is there a reason why I have to put these commands in this order?

I also ran into another issue with projecting the data. Since my actual data doesnt have anything outside the circle range it makes sense that in a plot of this simulation I should only project out the data and PDF in that range. While working in RooFit v3.17 (with Root v5.30.06) I had problems with a " *** Break *** segmentation violation" error message when it tried to do

extfitgauss.plotOn(yproj,ProjectionRange("circle"),Normalization(1.0,RooAbsReal::RelativeExpected));

which projects the fitted PDF onto the Y-axis. Specifically the problem came from using the “ProjectionRange(“circle”)” argument and I received no error when this argument was removed. I tried running the exact same script in RooFit v3.54 (with Root v5.34.00) and there was no error, so I assume this was a bug that has been fixed. There does seem to be a problem with the projection onto the X-axis where the integral is being taking over the full range of the y-variable [-2,2] and not the “circle” range. I have to explicitly define a second identical circular range in “y” and do the x-projection in that range.

I also tried to project out the data using

testdata->plotOn(xproj, CutRange("circle"));	// doesnt seem to work

which is suggested in the tutorials, however the data was not projected correctly and I had to define the range explicitly

ostringstream datacut; // define cut range explicitly datacut << "(x*x+y*y)<(" << radi*radi << ")"; testdata->plotOn(xproj, Cut(datacut.str().c_str())); // works
It looks like this is still a problem in the latest version of RooFit. I haven’t used non-circular ranges, so I dont know if these arguments work correctly with them.

As a final note, I get the error message

[#0] ERROR:InputArguments -- RooArgSet::checkForDup: ERROR argument with name extfitgauss_Int[x,y|fit_nll_extfitgauss_gaussData]_Norm[x,y] is already in this set

but I’m not sure what it means. Can anyone explain to me whether I should be concerned or not about this error?

I’ve attached a newer version of my script to show the changes I’ve made. Keep in mind that it will only work with newer versions of roofit unless you take out the y-projection of “extfitgauss”.
GaussFit2D_CircularRegion_v2.C (5.36 KB)