KAHIBARO
Discord Login Register

25.6. F. Common Fit Functions

Overview

This appendix lists common fit functions that you will use frequently with ROOT. It focuses on their standard mathematical form, typical ROOT usage, and common parameter conventions. You can use this as a quick reference when choosing and configuring a model for your fit.

Whenever you see a function written as a textual expression in ROOT, it is usually passed as a string to a TF1 or to a fitting method, for example:

cpp
TF1 *f = new TF1("f", "gaus", xmin, xmax);
hist->Fit("f");

In the tables below, “par[0]”, “par[1]”, and so on refer to the internal parameter array of a TF1 object.

Important rule: The meaning of parameters in ROOT’s built‑in function codes (for example "gaus") follows ROOT conventions and is not always the same as textbook amplitude or normalization. Always check the parameter definition before interpreting fit results.

Gaussian and Related Peak Functions

Standard Gaussian

ROOT built‑in code: "gaus" (or "gausn" for normalized form).

Mathematical form for "gaus":
$$
f(x) = p_0 \exp\!\left( -\frac{1}{2} \left( \frac{x - p_1}{p_2} \right)^2 \right)
$$

Parameter mapping:

ParameterName (common)Meaning
par[0]amplitudePeak height at $x = \mu$
par[1]mean$\mu$, central value of the peak
par[2]sigma$\sigma$, standard deviation of peak

The integral of this form is:
$$
\int_{-\infty}^{\infty} f(x)\,dx = p_0 \, p_2 \sqrt{2\pi}.
$$

ROOT also provides "gausn", which is normalized such that:
$$
\int_{-\infty}^{\infty} f(x)\,dx = p_0,
$$
so in that case par[0] represents the total area under the Gaussian.

Gaussian parameters: In "gaus", par[0] is the height of the peak, not the area. In "gausn", par[0] is the area (integral). Always choose the variant that matches how you want to interpret the result.

Typical usage:

cpp
TF1 *g = new TF1("g", "gaus", xlow, xhigh);
hist->Fit("g");

Multiple Gaussians

You can sum multiple Gaussians to model more complex structures or overlapping peaks. ROOT does not have a special keyword for this, you combine them in an expression, for example:

cpp
TF1 *g2 = new TF1("g2",
                  "gaus(0) + gaus(3)",  // first gaus uses par[0..2], second gaus uses par[3..5]
                  xlow, xhigh);

Here:

Sub‑functionParameters
gaus(0)par[0], par[1], par[2]
gaus(3)par[3], par[4], par[5]

The parameter meaning is the same as for "gaus".

Crystal Ball Function

The Crystal Ball function is often used in particle physics to model a Gaussian core with a power‑law tail, usually on the low side.

A common definition is:
$$
f(x;\alpha,n,\bar{x},\sigma) =
N \times
\begin{cases}
\exp\!\left( -\frac{(x-\bar{x})^2}{2\sigma^2} \right), & \text{for } \frac{x-\bar{x}}{\sigma} > -\alpha, \\
A \left( B - \frac{x-\bar{x}}{\sigma} \right)^{-n}, & \text{for } \frac{x-\bar{x}}{\sigma} \le -\alpha,
\end{cases}
$$
with
$$
A = \left( \frac{n}{|\alpha|} \right)^n \exp\!\left( -\frac{|\alpha|^2}{2} \right),
\quad
B = \frac{n}{|\alpha|} - |\alpha|.
$$

ROOT provides several variants such as crystalball in ROOT::Math. In many analyses, users implement their own C++ function or a TF1 with an expression. A typical parameter order is:

par indexMeaning
par[0]Overall normalization $N$
par[1]Mean $\bar{x}$
par[2]Width $\sigma$
par[3]Tail parameter $\alpha$
par[4]Tail exponent $n$

Crystal Ball conventions: There are several sign conventions and parameter orders in use. Always document your chosen definition and check that your code and interpretation agree.

Polynomial Functions

General Polynomial

ROOT built‑in code: "polN" where N is the order, for example "pol0", "pol1", "pol2", and so on.

General form for "polN":
$$
f(x) = \sum_{k=0}^{N} p_k\,x^k.
$$

Examples:

  1. Constant (offset) "pol0":
    $$
    f(x) = p_0
    $$
  2. Linear "pol1":
    $$
    f(x) = p_0 + p_1 x
    $$
  3. Quadratic "pol2":
    $$
    f(x) = p_0 + p_1 x + p_2 x^2
    $$

Parameter mapping:

"polN"ParameterMeaning
anypar[k]coefficient of $x^k$

Usage example:

cpp
TF1 *lin = new TF1("lin", "pol1", xlow, xhigh);
hist->Fit("lin");  // linear fit

Polynomials are often used to describe smooth backgrounds under peaks.

Polynomial order: Use the lowest polynomial order that adequately describes the background. High‑order polynomials can absorb features that should belong to your signal and can lead to unstable fits.

Exponential and Power Law Functions

Exponential Functions

ROOT built‑in code: "expo" for a simple exponential.

Standard "expo" form:
$$
f(x) = \exp\left(p_0 + p_1 x\right).
$$

This can also be written as:
$$
f(x) = A \exp(\lambda x),
\quad
A = e^{p_0},
\quad
\lambda = p_1.
$$

Parameter mapping:

ParameterMeaning
par[0]log amplitude, $\ln A$
par[1]exponential slope, $\lambda$

Usage example:

cpp
TF1 *ex = new TF1("ex", "expo", xlow, xhigh);
hist->Fit("ex");

If you want a non‑standard exponential form, such as $A \exp(-x/\tau)$, you can define it explicitly:

cpp
TF1 *ex2 = new TF1("ex2", "[0]*exp(-x/[1])", xlow, xhigh);
// par[0] = A, par[1] = tau

Power Laws

ROOT does not have a dedicated keyword for simple power laws, but they are easy to define with an expression:

General power law:
$$
f(x) = A x^{n}.
$$

You can write this in ROOT as:

cpp
TF1 *powlaw = new TF1("powlaw", "[0]*pow(x, [1])", xlow, xhigh);
// par[0] = A, par[1] = n

Or, to avoid issues near $x = 0$, you may shift the variable:
$$
f(x) = A (x - x_0)^n,
$$
using, for example,

cpp
TF1 *powlawShift = new TF1("powlawShift", "[0]*pow(x-[2],[1])", xlow, xhigh);
// par[0] = A, par[1] = n, par[2] = x0

Exponential vs power law: Exponentials behave as straight lines in a semi‑log plot, while power laws are straight lines in a log‑log plot. Choose the function that matches the physical expectation and the scaling behavior of your data.

Breit–Wigner and Resonance Shapes

Resonances in particle physics are often modeled with Breit–Wigner functions or variants that include detector resolution.

Nonrelativistic Breit–Wigner

A simple Breit–Wigner line shape (also known as a Lorentzian) is:
$$
f(E) = \frac{A}{(E - E_0)^2 + (\Gamma / 2)^2},
$$
where:

SymbolMeaning
$A$amplitude or scale factor
$E_0$resonance energy (position)
$\Gamma$full width at half maximum (FWHM)

A common ROOT definition:

cpp
TF1 *bw = new TF1("bw",
                  "[0]/((x-[1])*(x-[1]) + 0.25*[2]*[2])",
                  xlow, xhigh);
// par[0] = A, par[1] = E0, par[2] = Gamma

Relativistic Breit–Wigner

A relativistic version is used when the energy dependence is important, for example:
$$
f(m) = \frac{A\,m_0\Gamma}{(m^2 - m_0^2)^2 + m_0^2\Gamma^2},
$$
where $m$ is the invariant mass, $m_0$ is the resonance mass, and $\Gamma$ is the width.

You can implement this with:

cpp
TF1 *rbw = new TF1("rbw",
                   "[0]*[1]*[2] / ((x*x - [1]*[1])*(x*x - [1]*[1]) + [1]*[1]*[2]*[2])",
                   xlow, xhigh);
// par[0] = amplitude, par[1] = m0, par[2] = Gamma

Detector resolution is often modeled by convolving a Breit–Wigner with a Gaussian. In practice, this is often approximated with specialized functions (for example, Voigt profile) or with numerical convolutions.

Resonance fits: The choice between nonrelativistic and relativistic Breit–Wigner, and the inclusion of detector resolution, can significantly affect extracted masses and widths. The function form must match the physics model you want to test.

Step, Error, and Sigmoid Functions

Error Function and Integrated Gaussian

The error function is related to the integral of a Gaussian and is useful for modeling turn‑on curves and cumulative distributions.

Standard definition:
$$
\operatorname{erf}(z) = \frac{2}{\sqrt{\pi}} \int_0^z e^{-t^2}\,dt.
$$

ROOT provides TMath::Erf for use in expressions:

cpp
TF1 *turnOn = new TF1("turnOn",
                      "[0] * 0.5 * (1 + TMath::Erf((x-[1]) / (sqrt(2)*[2])))",
                      xlow, xhigh);
// par[0] = plateau height, par[1] = threshold, par[2] = sigma of turn-on

This function represents a smoothed step, similar to the integral of a Gaussian.

Logistic (Sigmoid) Function

A logistic function is another common model for efficiency curves and smooth steps:
$$
f(x) = \frac{A}{1 + \exp\left( -\frac{x - x_0}{k} \right)},
$$
where $A$ is the plateau value, $x_0$ is the midpoint, and $k$ controls the slope.

In ROOT:

cpp
TF1 *sigm = new TF1("sigm",
                    "[0] / (1 + exp(-(x-[1])/[2]))",
                    xlow, xhigh);
// par[0] = A, par[1] = x0, par[2] = k

Turn‑on functions: For trigger or detector efficiency curves, a smoothed step such as an error function or logistic function is usually more realistic than a sharp step. Using a discontinuous function can cause unstable fits and unphysical parameter errors.

Combinations of Signal and Background

Most realistic fits involve both a signal component and a background component. ROOT lets you combine any of the previously defined functions into a composite model.

Typical Signal plus Background Model

A common example is a Gaussian signal plus a polynomial background:

cpp
TF1 *model = new TF1("model",
                     "gaus(0) + pol1(3)",  // Gaussian uses par[0..2], linear background uses par[3..4]
                     xlow, xhigh);

Parameter mapping:

Index rangeSub‑functionTypical meaning
0,1,2gaus(0)signal amplitude, mean, sigma
3,4pol1(3)background offset and slope

Another example is a Breit–Wigner plus exponential background:

cpp
TF1 *model2 = new TF1("model2",
                      "[0]/((x-[1])*(x-[1]) + 0.25*[2]*[2]) + exp([3] + [4]*x)",
                      xlow, xhigh);
// par[0..2] = resonance parameters, par[3..4] = log amplitude and slope of background

You can also build more complex combinations, for example multiple peaks over a curved background.

Composite model parameters: When combining sub‑functions like gaus(0) and pol1(3), keep a clear record of which parameter index corresponds to which physical quantity. Mislabeling parameters is a common source of confusion and incorrect physics conclusions.

Discrete Distributions for Counting

Although histograms are typically fitted with continuous functions, you may occasionally need to fit discrete distributions, especially for low‑count data.

Poisson Distribution

The Poisson probability mass function is:
$$
P(k; \mu) = \frac{\mu^k e^{-\mu}}{k!}, \quad k = 0,1,2,\dots
$$

In ROOT, you can use TMath::Poisson or TMath::PoissonI in an expression:

cpp
TF1 *pois = new TF1("pois", "[1]*TMath::PoissonI(x, [0])", -0.5, 19.5);
// par[0] = mean mu, par[1] = overall scale (for counts)

Here TMath::PoissonI(k, mu) gives the probability for integer k. You often scale by a normalization factor to compare to histogram counts.

Binomial Distribution

The binomial probability mass function is:
$$
P(k; n, p) = \binom{n}{k} p^k (1-p)^{n-k}.
$$

ROOT provides TMath::Binomial:

cpp
TF1 *bino = new TF1("bino",
                    "[2]*TMath::Binomial([0], x)*pow([1], x)*pow(1-[1], [0]-x)",
                    -0.5, n + 0.5);
// par[0] = n, par[1] = p, par[2] = scale

For most practical histogram fits, especially for larger counts, Poisson or binomial models are more often used via likelihood fits rather than direct function fitting.

Discrete data: For very low statistics, chi‑square fits with continuous functions can give biased results. In that case, use binned or unbinned likelihood methods that treat the counts as Poisson or binomial variables.

Using Built‑In Math Functions in Expressions

ROOT’s fit functions can use many functions from TMath and the C standard library directly in the function string. Some commonly used ones in fit definitions are:

FunctionDescription
exp(x)exponential
log(x)natural logarithm
sqrt(x)square root
sin(x), cos(x)trigonometric functions
TMath::Erf(x)error function
TMath::BreitWigner(x, m0, gamma)Breit–Wigner function
TMath::Voigt(x, sigma, gamma)Voigt profile (Gaussian convoluted with Lorentzian)

Example with TMath::BreitWigner:

cpp
TF1 *rbw2 = new TF1("rbw2",
                    "[0]*TMath::BreitWigner(x, [1], [2])",
                    xlow, xhigh);
// par[0] = amplitude, par[1] = m0, par[2] = Gamma

Expression functions: When using TMath functions in expressions, ensure the correct namespace and argument order. Mistakes in the function call often lead to subtle mis‑modeling rather than obvious errors.

This appendix is intended as a starting point. For precise and up‑to‑date details, always consult the ROOT reference for TF1, TMath, and the specific classes or functions you use in your fits.

Views: 10

Comments

Please login to add a comment.

Don't have an account? Register now!