RooFit: How to constrain two lines to meet to form triangle

Hi everyone,

I have a question on how to build a “triangle PDF” in RooFit. Currently, I am trying the following:

  // This is the variable
  RooRealVar trueInvMass("trueInvMass","True invariant ll mass", 0.0, 130.0, "GeV");

  // These are the parameters
  RooRealVar leftCut("leftCut","left cut",1.0, 0.0, 3.0);
  RooRealVar middleCut("middleCut","middle cut",99.0, 90.0, 105.0);
  RooRealVar rightVar("rightVar","right var",3.0, 0.0, 11.0);
  // I do this so that the right cut is always to the right of the middle cut
  RooFormulaVar rightCut("rightCut", "@0+@1", RooArgList(middleCut, rightVar));

  RooGenericPdf trianglePdf("trianglePdf", "my triangle", 
			    "(@0 > @1)*(@0 < @2)*(@0 - @1)+(@0 > @2)*(@0 < @3)*(@3 - @0)", 
			    RooArgList(trueInvMass, leftCut, middleCut, rightCut));

But with this method, the two lines (left and right) don’t meet at the top, the apex of the triangle. So my question is: How do I build in the constraint that the two lines should meet at the top to actually form a triangle PDF???

Thanks a lot for your advice,


Hi Karsten,

I think you’re better off using a compiled class because it is much easier
to formulate your p.d.f that way and to make it work as intended.

This is very easy to do. First make a skeleton class for a p.d.f with
three variables

root> RooClassFactory::makeClass(“RooTriangePdf”,“x,a,b,c”) ;

which will generate RooTrianglePdf.cxx and RooTrianglePdf.h.
Edit the evaluate() function in the .cxx class which out of the box
looks like

Double_t RooTrianglePdf::evaluate() const
return 1.0 ;

For a triangle starting at ‘x=a’ with apex at ‘x=b’ and ending at ‘x=c’ this would
e.g. be

Double_t RooTrianglePdf::evaluate() const
if (x<a) return 0 ;
if (x<b) return (x-a)/(b-a) ;
if (x<c) return (c-x)/(c-b) ;
return 0 ;

then compile and load the class

root> .L RooTrianglePdf.cxx+