Open colleenbaublitz opened 1 month ago
This is related to PseudoNetCDF/coordutil.py:getproj4_from_cf_var. Line 584 relies on the repr
function.
Starting in v1.14 and updated in v1.22, numpy has a "legacy" print option that allows use of 1.x style printing.
import numpy as np
print(f'numpy v{np.__version__}')
# Output: numpy v2.0.0
a = np.float64(33.0)
for legacy in [False, '1.25']:
np.set_printoptions(legacy=legacy)
print((np.get_printoptions()['legacy'], repr(a), f'{a}', f'{a!s}', f'{a!r}', f'{a!a}', '{}'.format(a)))
# Outputs:
# (False, 'np.float64(33.0)', '33.0', '33.0', 'np.float64(33.0)', 'np.float64(33.0)', '33.0')
# ('1.25', '33.0', '33.0', '33.0', '33.0', '33.0', '33.0')
While repr has changed, f-strings with no !
or with !s
or '{}'.format(a)
all operate consistently from version to version. So, this leads me to suggest updates either using str.format or f-strings.
import numpy as np
np.set_printoptions(legacy=False)
mapstr_bits = dict(proj='lcc', lat_0=np.float64(40), lon_0=np.float64(-97), lat_1=np.float64(33), lat_2=np.float64(45), x_0=np.float64(2556000), y_0=np.float64(1728000), R=np.float64(6370000), to_meter=np.float64(12000))
mapstr_old = ' '.join(['+%s=%s' % (k, v if isinstance(v, str) else repr(v)) for k, v in mapstr_bits.items()])
mapstr_new1 = ' '.join(['+{}={}'.format(k, v) for k, v in mapstr_bits.items()])
mapstr_new2 = ' '.join([f'+{k}={v}' for k, v in mapstr_bits.items()])
print('# repr:', mapstr_old)
# repr: +proj=lcc +lat_0=np.float64(40.0) +lon_0=np.float64(-97.0) +lat_1=np.float64(33.0) +lat_2=np.float64(45.0) +x_0=np.float64(2556000.0) +y_0=np.float64(1728000.0) +R=np.float64(6370000.0) +to_meter=np.float64(12000.0)
print('# str.format:', mapstr_new1)
# str.format: +proj=lcc +lat_0=40.0 +lon_0=-97.0 +lat_1=33.0 +lat_2=45.0 +x_0=2556000.0 +y_0=1728000.0 +R=6370000.0 +to_meter=12000.0
print('# f-string', mapstr_new2)
# f-string +proj=lcc +lat_0=40.0 +lon_0=-97.0 +lat_1=33.0 +lat_2=45.0 +x_0=2556000.0 +y_0=1728000.0 +R=6370000.0 +to_meter=12000.0
Because str.format is more backward compatible, I would recommend that as a fix.
Other v2 related issues are around recfromtxt, which is removed from numpy in v2. These will be fixed concurrently.
There is a set of fixes that passes all regression tests with numpy v2 and v1.26 in Python3.9 in branch bugfix/proj-numpyv2.
This also addressed the deprecation of tostring
, several other uses of repr
, and several uses of recfromtxt
.
Using the getproj() function, encountered the following error:
Barron's solution:
First, the quick fix:
OR
Second, the bigger issue:
It looks like this is related to the new version of numpy released last month. The PseudoNetCDF code is using the builtin “repr” function to format the components of the projection. In all previous numpy versions, the repr of np.float64(33.) = '33.0'. (e.g., 1.26.4). In numpy v2, the repr has changed to np.float64(33.0). This breaks the construction of the string. So, right now, PseudoNetCDF is not compatible with numpy v2.
You can update your environment by running
python -m pip install 'numpy<2'
. Then, it should work… There are several other packages we use that are not yet numpy 2.0 compliant, so it may be best to use a 1.x for now.