crbanp
April 21, 2011, 8:28pm
1
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,[0],[1],[2],[3],[4],[5],[6]), low, high )
#TH1I initialized as h previously
h.Fit( fit1 , 'R' )
Is this possible?
thanks in advance,
Cameron
crbanp
April 21, 2011, 9:19pm
2
Some progress. From reading previous forum posts I defined the function with just two inputs:
def crystalball(x,par):
"""
n:par[0]
alpha:par[1]
centroid:par[2]
sigma:par[3]
peak amplitude:par[4]
background amplitude:par[5]
slope:par[6]
"""
if (x[0]-par[2])/par[3] < -par[1]:
#print x
bgkd = par[5]+par[6]*x[0]
term1 = ((par[0]/abs(par[1]))**par[0])
term2 = math.exp(-(par[1]**2)/2)
term3 = par[0]/abs(par[1])-abs(par[1])-(x[0]-par[2])/par[3]
#print bgkd
term4 = pow(float(term3),float(par[0]))
y = (bgkd+par[5]*term1*term2/term4)
else:
y = ((par[5]+x[0]*par[6])+par[4]*math.exp(-(((x[0]-par[2])/par[3])**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)
again thanks in advance
Cameron
wlav
April 22, 2011, 5:31pm
3
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
crbanp
April 22, 2011, 8:15pm
4
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