# Passing a function defined in python to TF1

I am stuck on how to use a function defined in python as a user defined function input to TF1 ideally I would like to do something like this:

``````
def crystalball(x,n,alpha,c,sigma,sa,ba,slope):
if (x-c)/sigma < -alpha:
bgkd = ba+slope*x
term1 = ((n/abs(alpha))**n)
term2 = math.exp(-(alpha**2)/2)
term3 = n/abs(alpha)-abs(alpha)-(x-c)/sigma
term4 = term3**n
y = (bgkd+sa*term1*term2/term4)
else:
y = ((ba+x*slope)+sa*math.exp(-(((x-c)/sigma)**2)/2))
return y

#low and high previously calculated
fit1 = TF1( 'fit1', crystalball(x,,,,,,,),  low,  high )
#TH1I initialized as h previously

h.Fit( fit1 , 'R' )
``````

Is this possible?

Cameron

Some progress. From reading previous forum posts I defined the function with just two inputs:

``````
def crystalball(x,par):
"""
n:par
alpha:par
centroid:par
sigma:par
peak amplitude:par
background amplitude:par
slope:par
"""
if (x-par)/par < -par:
#print x
bgkd = par+par*x
term1 = ((par/abs(par))**par)
term2 = math.exp(-(par**2)/2)
term3 = par/abs(par)-abs(par)-(x-par)/par
#print bgkd
term4 = pow(float(term3),float(par))
y = (bgkd+par*term1*term2/term4)
else:
y = ((par+x*par)+par*math.exp(-(((x-par)/par)**2)/2))
return y

fit1 = TF1( 'fit1', crystalball,  low,  high, 7)

fit1.SetParameters(1,1,energy,energy*1.5/(662*2.34),spectra.returnheight(energy),100,0)

h.Fit( fit1 , 'R' )

``````

but I get the error :
File “python/peakfit.py”, line 189, in fitpeaks
h.Fit( fit1 , ‘R’ )
TypeError: none of the 2 overloaded methods succeeded. Full details:
TFitResultPtr TH1::Fit(const char* formula, Option_t* option = “”, Option_t* goption = “”, Double_t xmin = 0, Double_t xmax = 0) =>
could not convert argument 1 (expected string or Unicode object, TF1 found)
TFN python function call failed (C++ exception)

Cameron

Cameron,

is there no earlier error originating from the chrystalball function? That would be printed just above the portion that you quote?

In the code itself, I can’t see anything wrong directly (assuming ‘math’ has been imported above).

A working example can be found in the ROOT nightly tests: https://root.cern.ch/svn/roottest/trunk/python/function/PyROOT_functiontests.py. Look for ‘pygaus’.

Cheers,
Wim

Wim,

thanks for the quick response. You were correct I had not set the limits on my parameters well and it was crashing when trying to take a negative number to a non-integer power, after I fixed that there were no problems. Thanks for the link to the example code too, its given me some ideas on how to simplify and extend the analysis.

-Cameron