Subtracting minimum of a RooCurve from another RooCurve point by point

Dear experts,
I have two P.D.F.s , ZSig and ZBkg. ZSig is a gaussian and ZBkg is a polynomial. I add parametric extended likelihood to them (RooExtendPdf()) and add them (RooAddPdf). I then plot them in a frame (RooPlot).

I would like to find the minimum of the polynomial pdf (ZBkg) and subtract from ZSig at every point.

When I use getCurve->GetMinimum(), to find the minimum, I get always -1111. which I know is wrong.
Please let me know where I go wrong and how I can do what I described above (finding the min and subtracting from ZSig at each point)?
Many thanks in advance,


Please read tips for efficient and successful posting and posting code

ROOT Version: Not Provided
Platform: Not Provided
Compiler: Not Provided


Hi @Natilus ,
sorry for the (super) late reply, this must have slipped through the cracks!

@moneta , could you help out here?

Cheers,
Enrico

Hi @eguiraud,
Thanks for your reply. It seems like @moneta doesn’t want to help :slightly_smiling_face:
Anyone else can help me with this question?
Thanks

Maybe @jonas :grinning_face_with_smiling_eyes:

A RooCurve is just a TGraph to my knowledge, here a similar diacussio TGraph GetMaximum() GetMinimum() i suspect the best chance is to manipulate RooCurves as if they are TGraphs.

Good morning @Natilus! Do you have some code you can upload to reproduce the problem? It’s easier for us to answer the question if we can see what you already have.

Hi everyone,
thanks for your help.
@jonas , unfortunately the code is super long, almost 2000 lines. I can upload parts of it in which I model the signal and background PDF’s and extended likelihood. would that help?

Hi @Natilus, thanks for your answer! No problem, you don’t have to share the full code. But indeed it would be very good to have the part where it models the PDF you have problems with, so I can build a minimal example for myself that I can try things out with.

Hi @jonas ,
Thanks again for your help, and sorry for my delay. following are the lines in my code defining the J/Psi signal and J/Psi background. These curves are drawn in a range, let’s say between 3.2 and 4.2.

RooRealVar JPsiMean(“JPsiMean”,“Mean of Gaussian”,JPsiMass_PDG);
RooRealVar JPsiSigma(“JPsiSigma”,“Sigma of Gaussian”, 3.32e-2);
RooGaussian JPsiSignal(“JPsiSignal”,“Signal P.D.F.”, PsiMass, JPsiMean, JPsiSigma);

RooRealVar cJPsi(“cJPsi”, “cJPsi”, 0.0, 0.0, 10.0);
RooPolynomial JPsiBkg(“JPsiBkg”,“Polynomial Background P.D.F.”, JPsiMass, RooArgList(cJPsi));

If possible, I would like to find the munimum of the background curve in this range and subtract it from the signal curve at every point.
As I mentioned before, the code is very long but if it is necessary, I can upload the entire code.
Please let me know, and thanks again.

Hi @Natilus! As explained in the thread that was linked by @RENATO_QUAGLIANI, the TGraph::GetMinimum() function simply returns the data member fMinimum which is not always set. Hence you get the default value of -1111 when you try to find the minimum.

Indeed, it’s a reasonable approach here to manipulate the TGraph directly. Building on your code snippet, I have written some example code here that shows how you can do that:

using namespace RooFit;

/// Find the minimum y-value of TGraph within interval `[xMin, xMax]`
double findMinimum(TGraph const& graph, double xMin, double xMax) {
    double yMin = std::numeric_limits<double>::max();

    auto xVals = graph.GetX();
    auto yVals = graph.GetY();

    for(int i = 0; i < graph.GetN(); ++i) {
        if (xVals[i] >= xMin && xVals[i] <= xMax) {
            yMin = std::min(yMin, yVals[i]);
        }
    }

    return yMin;
}

/// Shift the y-values of a TGraph by constant value
void shiftTGraphY(TGraph& graph, double shift) {
    for(int i = 0; i < graph.GetN(); ++i) {
        graph.SetPointY(i, graph.GetPointY(i) + shift);
    }
}

void my_example() {

    const double JPsiMass_PDG = 3.;

    RooRealVar mass("mass","mass", 1.8, 4.8);

    RooRealVar JPsiMean("JPsiMean","Mean of Gaussian",JPsiMass_PDG);
    RooRealVar JPsiSigma("JPsiSigma","Sigma of Gaussian", 0.6);
    RooGaussian JPsiSignal("JPsiSignal","Signal P.D.F.",
                                             mass, JPsiMean, JPsiSigma);

    RooPolynomial JPsiBkg("JPsiBkg","Polynomial Background P.D.F.", mass,
            RooArgSet(
                RooConst(-5.61596639 - 0.004),
                RooConst(5.24971989),
                RooConst(-1.57142857),
                RooConst(0.15406162)
            )
    );

    RooPlot* massFrame = mass.frame();
    auto sigCurve = JPsiSignal.plotOn(massFrame)->getCurve();
    auto bkgCurve = JPsiBkg.plotOn(massFrame)->getCurve();

    // Find the minimum of background curve within desired interval
    double bkgMin = findMinimum(*bkgCurve, mass.getMin(), mass.getMax());

    // Subtract the minimum from both signal and background curve
    shiftTGraphY(*bkgCurve, -bkgMin);
    shiftTGraphY(*sigCurve, -bkgMin);

    massFrame->Draw();
}

The the RooCurve directly inherits from TGraph, so the TGraph documentation can be quite useful here.

I hope my code example solves the problem for you or at least helps you to get started. If not, please let me know!

Cheers,
Jonas

Dear @jonas ,
Thank you very much for your help. This solved my problem!
Many thanks!

Excellent, thanks for letting me know! It’s always nice to get feedback that the effort to create an example was worth it :wink: