I’m trying to do a fit using a custom function. I’ve made an attempt as shown below and I’m not sure if I’m doing it in quite the right way
#/bin/usr/env python
import sys
import math
import ROOT
import numpy as np
def main():
canvas = ROOT.TCanvas(
"canvas",
"fitting",
200,
10,
500,
500
)
# create function for fitting
fit = ROOT.TF1(
"fit",
function_Frechet(),
0,
30,
4
)
fit.SetParameters(-2, 0.1, 1, 90)
fit.SetParNames("a", "m", "s", "b")
fit.SetParLimits(0, -1, -4)
fit.SetParLimits(1, 0.01, 0.2)
fit.SetParLimits(2, 0, 2)
fit.SetParLimits(3, 0, 1000)
# create histogram with example data
histogram = ROOT.TH1F(
"histogram",
"px",
1000,
-1.,
1.
)
function = ROOT.TF1(
"function",
"100.-3.*((x-0.11)**(-4.))*TMath::Exp(-(x-0.11)**3.)",
-1,
1.
)
histogram.FillRandom("function", 10000)
# fit
histogram.Fit(fit)
canvas.Print("fit.png")
# print results
parameters = fit.GetParameters()
print("fitting result: {parameter1}, {parameter2}, {parameter3}, {parameter4}".format(
parameter1 = parameters[0],
parameter2 = parameters[1],
parameter3 = parameters[2],
parameter4 = parameters[3]
))
class function_Frechet:
def __call__(self, x, parameters):
a = parameters[0] # shape
m = parameters[1] # location of minimum
s = parameters[2] # scale
b = parameters[3] # baseline
x = x[0]
y = b+(a/s)*(((x-m)/s)**(-1-a))*np.exp(-((x-m)/s)**(-a))
return y
if __name__ == "__main__":
main()
Is it correct to define the custom function via a class? It seems odd to me. I would appreciate guidance on defining the custom function, using parameters with it and any other suggestions for improvement to the code. Thanks