Hello,
I’m trying to use PyRoot and Root’s minuit interface. The problem is that I don’t know how to tell minuit what function to minimize. In C++, I would just:
chisqMinuit = new TMinuit(1);
chisqMinuit->SetFCN(chisq_fcn);
having C++ call Python functions is not trivial, because I need to have
a way of associating the Python callable with the C++ function.
You do not post which version of ROOT you are using, but version 4.01/02
allows you to initialize a TF1 with a Python callable and then use it to fit
histograms (where the fitting is done by minuit). Thus, something works,
but I don’t see whether you can actually use a TF1 directly with TMinuit.
As for use of C++ functions from Python … I’ll give you a decent chance
if you use class statics, and then pass the parameter to SetFCN(), but I
haven’t tried, so maybe it just goes boom.
I'm using 4.00/08 currently. Do I need to upgrade to be able to initialize a TF1 with a Python callable? This sounds pretty close to what I want to be able to do.
Am I correct that as long as my makefile knows about both 'python.h' and the root libraries, that I ought to be able to write a mini-wrapper of Minuit (using static classes to hold the function and parameters)? Do you have an example of a [b]Makefile[/b] that would let me do this? (This solution isn't as "pretty" as making minuit call a python callable, but probably has a faster execution time.)
Thanks for your help,
Charles
p.s. I’m currently trying to do this on cygwin. I’ll eventually want to be able to do it on Red Hat linux as well.
# Create a Fit_jpsi_mass object
my $fit = new Jpsi::Fit_jpsi_mass ($histogram);
# initiallize the parameters
$fit->initialize_fit_parameters ();
# get a pointer on the fit function
my $fit_function = $fit->get_fit_function ();
# Call Fit with this pointer
$histogram->Fit ($fit_function, "RV");
Jpsi is a C++ library wrapped in Perl, as Root.
The class Fit_jpsi_mass contains the fit method and utilities functions.
I think use Script function in fit procedure is to slow. So, the
best is to use an “extension” C++ library like this.
I’m using 4.00/08 currently. Do I need to upgrade to be able to initialize a TF1 with
a Python callable?
Yes, the code is not included in that release. Its first public appearance is 4.01/02.
Am I correct that as long as my makefile knows about both ‘python.h’ and the root
libraries, that I ought to be able to write a mini-wrapper of Minuit (using static
classes to hold the function and parameters)? Do you have an example of a Makefile
that would let me do this?
Ehrm, I’m not quite sure in which direction you’re thinking, but I simply (ab)use
ACLiC. First, have a test.h:
Functions like this can be used in TF1, if they have a double () ( double, double* )
signature that is. But you can’t get hold of the pointer, though. Will implement …
as a (belatedly) follow up: the TMinuit::SetFCN() accepts python functions in ROOT 5.04. Note however, that the usual caveats when using references to builtins in the function signature apply, and to be able to “push” results by reference out of the function, you’ll need to dereference them on assignment as if they were passed by pointer instead of by ref (they are, sortof).
chisq, delta = 0., 0.
for i in range(nbins):
delta = (z[i]-func(x[i],y[i],par))/errorz[i]
chisq += delta*delta
f[0] = chisq[/code]
See the attached file for the full example that I lifted from an Atlas colleague of mine (thanks Chris! ). More details will be written up in the manual with the next pro version of ROOT.
you’re asking on an 11+ year old thread about a code example that I lifted at the time from someone else … Most likely the answer to all your questions is “because reasons” …
Here are some guesses …
Ad 1) f is a double&, and func is a python function. I don’t understand why you think one can be used instead of the other, so I think each is used where they are supposed to. When writing on this thread 11+ years ago, I already had not used minuit for years. I have no idea anymore what the other parameters are for.
Ad 2) Probably done as a speedup. The callback mechanism is slow. There’s some opportunity to fix this with Cling and CFFI but I’m no longer maintaining PyROOT so if that is of importance to you, I suggest you file a JIRA feature request ticket.
Ad 3) This is a simple example. One could also define a callable class (i.e. one that has a call function with the same signature as fcn) and make them (instance) data members.
Ad 4) ‘arglist’ yes, as it’s passed through C++ as a ‘double*’ (a tuple is, roughly speaking, an array of PyObject*, so type PyObject**). It can also be a numpy array, or more generally anything that exposes a proper PyBuffer or Capsule interface. The others are python-only, so can be anything you like.