Strange problems for using TMinuit through pyroot

I met a very strange problem when using pyroot.
The code sample is below, I explain a bit here:

function tfconst.minsolve() uses TMinuit to minimize a chi square value to give a set of parameters. tfconst.minchisq is just the chi square finally get by the function. The purpose of below codes is to find the minimum chisq by ajusting the number of data used. “chisqmin” here is a local variable only. I print it out before and after minsolve() function and found
that its value suddenly changed to the new tfconst.minchisq!

I tried to call another function instead of minsolve(), and chisqmin did not change after the function calling. So I guess this is related to use of TMinuit through pyroot? Anyone can give some clues for the cause of this problem?

 chisqmin=1000
 for i  in xrange(19):
        ... ...
        print chisqmin
        tfconst.minsolve(sizeli,li)
        print chisqmin
        lchisq=tfconst.minchisq
        
        if lchisq<chisqmin:
            iMin=li
            chisqmin=lchisq

Hi,

yes, this is known: Python does not distinguish between by-reference and by-value operations, and the hack in PyROOT to allow double& to be an out-parameter then modifies the actual object passed into the call. If you then have a (local) reference to it (here minchisq), that then points to the same actual object and hence will be changed as well.

In newer versions of ROOT, the argument to pass through double& is not a Python float, but a ROOT.Double. See here:http://savannah.cern.ch/bugs/?21356.

Cheers,
Wim

Thanks for the reply.

But the version of ROOT I am using is 5.14/00b released on Jan 17.
according to date of the bug-fixing page, the versions should have
already solved the problem, right?

Maybe my ROOT version is still not new enough? If that is the case,
could you give me some instructions ? The condition is that I have
no root previlege of system and want to make some dispatches on the
present version .

Thanks in advance.

Hi,

no, 5.14 does not have this mod. But a simple assignment like you do in your code above can’t be solved this way in any case (think of python float object assignments as passing double& around, not copy-by-value double assignments).

There are a couple of ways around this. One of them is to create a new object to be passed into minuit everytime (this is what you’d do with Double() in ROOT 5.15). The alternative is to ensure that your minchisq points to a new object (i.e., really is a new local variable). The easiest way to do that, is to add 0.0 to it in the assignment:chisqmin=lchisq+0.0(the reason that that works is that the + operator is in C, so the returned value is not cached by the interpreter; you can verify that with the id() function, i.e. that id(lchisq) != id(minchisq) after adding 0.0).

HTH,
Wim