python-3.xpython-2.7numpyscipygauss

How to receive tuple as an argument to a function in python 3?


I have some code that was working fine in python2. I need to translate it to python3. There is one piece of it that I can't understand how to adapt.

Here is some code.

Function with error

def gauss((x, y), x0, y0, intens, sigma):
    return intens*numpy.exp(-(numpy.power(x-x0, 2)+numpy.power(y-y0, 2))/(2.*sigma**2)).ravel()

Caller function

def dofwhm(psfdata):
    x = numpy.arange(psfdata.shape[1])
    y = numpy.arange(psfdata.shape[0])
    x, y = numpy.meshgrid(x, y)
    popt, pcov = opt.curve_fit(gauss, (x, y), psfdata.ravel(), p0=[psfdata.shape[1]/2, psfdata.shape[0]/2, psfdata[psfdata.shape[1]/2, psfdata.shape[0]/2], 5.0])

    return 2.355*abs(popt[3])

The error that I get is

Traceback (most recent call last):
  File "catalog.py", line 8, in <module>
    import cutPsf
  File "/Users/igor/GALPHAT/pypygalphat/preprocessingNew/cutPsf.py", line 9
    def gauss((x, y), x0, y0, intens, sigma):
              ^
SyntaxError: invalid syntax

Can somebody help me how to adapt it for python3?

UPDATE: Well, @hpaulj answer seems to be right. I found that there are routine to convert Python2 code to Python3 code. After running on target file 2to3 -w cutPsf.py as a result I get the suggested solution from hpaulj. Unfortunately it results in fallowing error:

Traceback (most recent call last):
  File "catalog.py", line 323, in <module>
    cutPsf.run(tempDir+galaxy.psffile, outDirFits+galaxy.psffile)
  File "/Users/igor/GALPHAT/pypygalphat_p3/preprocessingNew/cutPsf.py", line 63, in run
    coeffwhm = dofwhm(newPsf)
  File "/Users/igor/GALPHAT/pypygalphat_p3/preprocessingNew/cutPsf.py", line 20, in dofwhm
    psfdata.shape[1]/2, psfdata.shape[0]/2, psfdata[psfdata.shape[1]/2, psfdata.shape[0]/2], 5.0])
IndexError: only integers, slices (`:`), ellipsis (`...`), numpy.newaxis (`None`) and integer or boolean arrays are valid indices

As said before, everything runs perfectly with Python2...


Solution

  • do the unpacking later

    def gauss(xy, x0, y0, intens, sigma):
        x, y = xy
        return intens*numpy.exp(-(numpy.power(x-x0, 2)+numpy.power(y-y0, 2))/(2.*sigma**2)).ravel()
    

    I suggested this based on the typical scipy optimized requirements, where the user defined function is called with f(x, *args), where x is the variable (possibly array) that is optimized. But curve_fit is different.

    scipy.optimize.curve_fit(f, xdata, ydata, p0=None,...)
    

    Where the f (your gauss?) satisfies:

    ydata = f(xdata, *params) + eps 
    

    https://docs.scipy.org/doc/scipy/reference/generated/scipy.optimize.curve_fit.html

    I guess my suggestion is still valid if xdata is the (x,y) tuple, or array made from that. And ydata is psfdata.ravel().