0

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...

Igor Kolesnikov
  • 133
  • 1
  • 8
  • Is the `def gauss((x, y), x0,...` your code, or from an imported library? – hpaulj Nov 12 '19 at 20:00
  • @hpaulj can't say for sure, Im not the author... – Igor Kolesnikov Nov 12 '19 at 20:07
  • In py2, `/` is integer divide; in py3 the result may be float. `//` does integer divide. The `/2` in `psfdata[psfdata.shape[1]/2, psfdata.shape[0]/2]` is probably causing the problem. Also newer `numpy` is pickier about indexing with floats; older versions tended to let that slide. – hpaulj Nov 13 '19 at 17:21
  • Yeah, // instead of / works only. Maybe it would be nice to add it to the answer. – Igor Kolesnikov Nov 13 '19 at 18:14

2 Answers2

4

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().

hpaulj
  • 221,503
  • 14
  • 230
  • 353
0

You need to make some modification with * operator.

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()

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])
JS Guru
  • 343
  • 1
  • 3
  • 11
  • After your sucesstions: im getting 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]) IndexError: only integers, slices (`:`), ellipsis (`...`), numpy.newaxis (`None`) and integer or boolean arrays are valid indices – Igor Kolesnikov Nov 12 '19 at 20:06
  • 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]) Can you expand (x, y) as x, y directly in opt.curve_fit function? – JS Guru Nov 12 '19 at 20:23