TMinuit and ctypes issue (pyROOT)

I working in pyroot and I am trying to perform a fit using TMinuit. The fit worked fine with a previous root releases (the nightlies from a pair of months ago) and then now gives me the error:

... line 123, in MinuitLinearFit
    minuit.mnexcm("MIGRAD", arglist, 2,ierflg)
TypeError: void TMinuit::mnexcm(const char* comand, double* plist, int llist, int& ierflg) =>
    TypeError: 'c_double' object does not support item assignment

Here the relevant part of my code:

minuit = ROOT.TMinuit(2)#.Fitter(0, 2)
arglist = array('d',2*[0])
arglist[0] =1.0
arglist[0] = 500000 
ierflg = ctypes.c_int(0)
minuit.mnexcm("SET ERR",arglist,1,ierflg)
minuit.mnparm(0, 'offset',1,0.1,-1,1,ierflg)
minuit.mnparm(1, 'slope',1,0.1,-0.3,0.3,ierflg)          
minuit.mnexcm("MIGRAD", arglist, 2,ierflg)

def linearChi2(npar, gin, f, par, istatus ):
    vec = yy-(par[0]+par[1]*(xx-25))#SLOPEOFFSETUNCORR
    chi2 = np.linalg.multi_dot( [vec.T, invCov, vec] )
    f[0] = chi2

Between the working version and the current one changed only the deprecated ierflg=ROOT.Long(0) into ierflg = ctypes.c_int(0), but the problems seems related to the way I am passing arglist, If I understood correctly.

I did some try:

  • I tried to define arglist as: arglist = (ctypes.c_double * 2)() but the error is unchanged

  • I tried to use ROOT.TVirtualFitter.Fitter instead of TMinuit (changing all the methods accordingly) but I face the same error also with TVirtualFitter.

  • I tried to comment the two minuit.mnparm(…) lines. In this case the error disappears but the fit is different.

Can somebody help me?
Thank you very much in advance,

ROOT Version: /cvmfs/
Platform: CentOS Linux release 7.4.1708 (Core)
Compiler: +gcc (GCC) version 8.30.0

It might be related to the new pyROOT. @etejedor can you help?


You did the right thing when defining ierflg as a ctypes.c_int, as ROOT.Long was deprecated already in 6.20 and ctypes should be used from now on.

Now, the error you see happens because in linearChi2, f is a Double_t& parameter, which means in Python it is now a ctypes.c_double. So, instead of writing f[0] = chi2, you need to do f.value = chi2. value is an attribute of ctypes types that allows you to set the value.

Just citing this test:

and this ticket:

since they are relevant.

Thank you very much for your reply. It works perfectly (actually I was thinking that the issue can be a .value somewhere, because it’s the typical change between ROOT.Double() and ctypes.c_double(), but I did not realized that also linearChi2 call was affected).

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.