<jupyter_start><jupyter_text>Fitting with ROOT (copied from the root web-page)ROOT is a modular scientific software toolkit. It provides all the functionalities needed to deal with big data processing, statistical analysis, visualisation and storage. It is mainly written in C++ but integrated with other languages such as Python and R.root web page can be found here: https://root.cern.ch/<jupyter_code># load root libraries and some math
import ROOT
import math as m
# create some dummy data histogram and fill it with random data gaussian distributed
histgaus = ROOT.TH1F("hgaus","hgaus", 100, -5, 5)
histgaus.FillRandom("gaus",1000)
c1 = ROOT.TCanvas("c1","c1")
histgaus.Draw()
c1.Draw()<jupyter_output><empty_output><jupyter_text>ROOT comes with its own function class called 'TF1'. This recognizes already some predefined functions like:* 'gaus': Gaussian with the parameters normalization, mean, and sigma* 'expo': exponential function* 'pol0', 'pol1', ....: polynomial 0th, 1st, ... order* 'sin(x)': sinus* 'cos(x)': cosinus * ...For further information see the [TF1](https://root.cern/doc/master/classTF1.html) and [TFormula](https://root.cern/doc/master/classTFormula.html) reference.<jupyter_code># to initialize a root function with a predefined function you have to give 4 parameters:
# 1: the name, chose as you like, but ROOT will complain if the name already was used
# 2: the identifier for a predefined function, here a Gaussian so "gaus" is used
# 3,4: the min and max of the Range
fungaus = ROOT.TF1("fungaus", "gaus", -5, 5)

#some information on the function can be obtained by using the 'Print()' function
fungaus.Print()

# the initial values of the 3 parameters are usually 0, so set some dummy values to see something when 
# drawing the function
fungaus.SetParameters(1, 1, 1)
fungaus.Draw()
c1.Draw()<jupyter_output><empty_output><jupyter_text>**NOTE**: setting initial parameters is important as this may be the difference between a good or a bad fit result! Badly chosen initial parameters can lead to failed fits or running into a local, instead of the global, minimum. Fitting is now simple by asking the data histogram this (also see [TH1::Fit Reference](https://root.cern/doc/master/classTH1.htmla7e7d34c91d5ebab4fc9bba3ca47dabdd))<jupyter_code>histgaus.Fit(fungaus)
histgaus.Draw()
c1.Draw()
# in some case fitting a subrange can be benificial. This is done by setting the range of the function:
fungaus.SetRange(-1, 1)

# and using the option "R" when fitting
histgaus.Fit(fungaus, "R")
histgaus.Draw()
c1.Draw()
# one also can use user defined functions, they have to have the format f(x,y) where x and p are interpreted 
# as vectors. x represents the input values (x[0]=x, x[1]=y, x[2]=z ...), and p the parameters of the function

# example: my own defintiion of a gaussian 
def mygausdef(x,p):
    # some save guards to prevent division by zero and make it positive
    if p[0] < 0 :
        return 0.
    if p[2] == 0:
        return 0.
    return p[0]*m.exp(-(x[0]-p[1])*(x[0]-p[1])/2/p[2]/p[2])


# to use a user defined function you have to initialize with 5 parameters:
# 1: the name
# 2: the function you want to use
# 3,4: min and max of the range
# 5: the number of parameters the function has (3 in this case)
mygaus = ROOT.TF1("mygaus", mygausdef, -5, 5, 3)
histgaus.Fit(mygaus)
histgaus.Draw()
c1.Draw()<jupyter_output><empty_output><jupyter_text>**Oops!** **Exercise**: Try to fix the fit!<jupyter_code># one can combine arbitrary functions like in the 
# examples below and "[0]" will be interpreted as 0th parameter of the new function etc. 
myfun2 = ROOT.TF1("myfun2","[0]+[1]*x+[2]*x*x+[3]*sin(x)+[4]*expo(5)", -5, 5)

# NOTE: the "(5)" in the predefined "expo(5)" denotes that the parameters for that function start at the 5th position
#   so the function has 7 parameters ([0] .. [4] + the 2 from the exponential)

myfun2.Print()
histgaus.Fit(myfun2)
histgaus.Draw()
c1.Draw()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.11424968474148801, 'fraction_numerical': 0.02648171500630517, 'mean_word_length': 4.806734992679356, 'pattern_counts': {'":': 0, '<': 18, '<?xml version=': 0, '>': 17, 'https://': 4, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '4', 'dir': 'jupyter-structured-clean-dedup', 'id': '245352', 'license': 'MIT', 'n_tokens_mistral': 1353, 'n_tokens_neox': 1283, 'n_words': 511, 'path': 'examples/jupyter_notebooks/004_fitting_with_root.ipynb', 'repo_name': 'klieret/HEPFittingTutorial', 'size': '3965'}