Computation of a TH1 with exponential function and error propagation

Dear experts,
I have the following problems:

I have 4 TH1D named p0, p1, p2 and z (each of them declared with Sumw2 option and with assigned errors on each of the filled bins). All histograms have the same number of bins and are needed
to compute the total histogram y according to the equation

y = exp (exponent) +p2,

where

exponent=p0+p1*x

Is there any function for TH1 that allows doing so?
Or am i forced to do this with y->SetBinContent(i, TMath::Exp(exponent->GetBinContent(i)))
for all bins i ?

If so, how would the error be propagated, considering that I should later add also the p2 histogram?

Thanks a lot for your help
Cheers,
Davide

I’m afraid you will have to do it yourself, but maybe @moneta knows a simpler way of doing it…

Hi,

You are applying a very specific functions on the histograms, so you would need to compute it yourself , by getting the bin contents from the histogram and eventually compute the errors using for example error propagation.

Best Regards

Lorenzo

You could get there half way, though. You can compute p0 + p1*x by doing:

auto exponent = p1->Clone("exponent");
exponent->Multiply(x);
exponent->Add(p0);

Then you need to manually calculate exp(exponent), including error propagation and can then do:

result->Add(p2);

These steps propagate the errors correctly (you might have to set the TH1::SetSumw2 flag before, though).


If you are using PyROOT, you could be using this class, which I threw together quickly. It allows computing a histogram where the new bin content is a function of the old bin content. It performs error propagation.

import ROOT
import math


class Func(object):
    """Function that can calculate f(h)"""

    def __init__(self, f_str, pars=None):
        self.f = ROOT.TF1(str(id(self)), f_str)
        self.f_str = f_str
        if pars is None:
            if self.f.GetNpar() >= 1:
                self.f.SetParameters(*[1] * self.f.GetNpar())
        else:
            self.f.SetParameters(*pars)

    def __call__(self, h, name="temp"):
        nbins = h.GetNbinsX()
        self.f.SetRange(h.GetBinLowEdge(1),
                        h.GetBinLowEdge(nbins) + h.GetBinWidth(nbins))
        h2 = h.Clone(name)
        for i in range(1, nbins + 1):
            y, e = h.GetBinContent(i), h.GetBinError(i)
            yf = self.f(y)
            if math.isinf(yf) or math.isnan(yf):
                yf = 0.
            h2.SetBinContent(i, yf)

            df = self.f.Derivative(y)
            if math.isinf(df) or math.isnan(df):
                df = 0.
            h2.SetBinError(i, e * abs(df))
        return h2

    def __str__(self):
        return self.f_str


if __name__ == "__main__":
    h = ROOT.TH1D("h", "h", 100, -10, 10)
    h.FillRandom("gaus")
    f = Func("TMath::Sqrt(x)")
    h2 = f(h)

    h.Draw("e")
    h2.Draw("samee")

Hi Graipher,
it is basically what I did,
since I couldn’t find a way to compute the exponential of a histogram WITH automatic handle of the error propagation.
Thanks
Davide

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