Skip to content

Commit

Permalink
Merge pull request #254 from jswhit/numpy2
Browse files Browse the repository at this point in the history
numpy 2 support
  • Loading branch information
jswhit authored Jul 3, 2024
2 parents 5b10ed1 + 3c8c7ff commit 362f21e
Show file tree
Hide file tree
Showing 7 changed files with 40 additions and 27 deletions.
12 changes: 2 additions & 10 deletions .github/workflows/build-conda.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,7 @@ jobs:
strategy:
matrix:
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
os: [ubuntu-latest, windows-latest, macos-latest]
platform: [x64, x32]
# debug on a single os/platform/python version
# python-version: [ "3.9"]
# os: [ubuntu-latest]
# platform: [x64]
exclude:
- os: macos-latest
platform: x32
os: [ubuntu-latest, windows-latest, macos-12]
steps:
- uses: actions/checkout@v4

Expand Down Expand Up @@ -47,4 +39,4 @@ jobs:
#fi
cd test
python test.py
pytest -vv test_latlons.py
pytest -vv -s test_latlons.py
8 changes: 3 additions & 5 deletions .github/workflows/build-windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,13 @@ jobs:
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
os: [windows-latest, macos-latest]
platform: [x64, x32]
# debug on a single os/platform/python version
# python-version: [ "3.9"]
# os: [macosx-latest]
# platform: [x64]
exclude:
- os: macos-latest
- os: macos-latest
platform: x32
steps:
- uses: actions/checkout@v4
steps:
- uses: actions/checkout@v4

- name: Setup Conda
uses: s-weigand/setup-conda@v1
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ jobs:
PROJ_LIB: /usr/share/proj
strategy:
matrix:
#python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
python-version: ["3.11"]
steps:

Expand Down
4 changes: 4 additions & 0 deletions Changelog
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ version 2.1.6 (not yet released)
gridded fields, optimize function for 50x speedup.
* Fix for issue #235 (`latlons` doesn't work when only a single latitude in grid).
* Fix for issue #241 (forecast time units in inventory wrong for 15 minute HRRR data).
* Add `len` method to open instance (issue #239).
* Numpy 2 compatibility (issue #251).
* Fix failing doctest for eccodes >= 2.34.1 (issue #245).
* use eccodes.h instead of grib_api.h, add `eccodes_version` module variable.

version 2.1.5 release
=====================
Expand Down
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
[build-system]
requires = [
"Cython>=0.29",
"oldest-supported-numpy",
"setuptools>=61",
"oldest-supported-numpy ; python_version < '3.9'",
"numpy>=2.0.0rc1,<3 ; python_version >= '3.9'",
]
build-backend = "setuptools.build_meta"

Expand Down
31 changes: 23 additions & 8 deletions src/pygrib/_pygrib.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,12 @@ npc.import_array()
ctypedef fused float_type:
float
double
ctypedef fused int_type:
int
long
long long

def redtoreg(float_type[:] redgrid_data, long[:] lonsperlat, missval=None):
def redtoreg(float_type[:] redgrid_data, int_type[:] lonsperlat, missval=None):
"""
redtoreg(redgrid_data, lonsperlat, missval=None)
Expand Down Expand Up @@ -104,7 +108,7 @@ cdef extern from "numpy/arrayobject.h":
npy_intp PyArray_ISCONTIGUOUS(ndarray arr)
npy_intp PyArray_ISALIGNED(ndarray arr)

cdef extern from "grib_api.h":
cdef extern from "eccodes.h":
ctypedef struct grib_handle
ctypedef struct grib_index
ctypedef struct grib_keys_iterator
Expand Down Expand Up @@ -193,6 +197,7 @@ def _get_grib_api_version():
major = v
return "%d.%d.%d" % (major,minor,revision)
grib_api_version = _get_grib_api_version()
eccodes_version = grib_api_version
if grib_api_version < "2.19.1":
msg="Warning: ecCodes 2.19.1 or higher is recommended. You are running"
warnings.warn('%s %s.' % (msg,grib_api_version))
Expand Down Expand Up @@ -382,6 +387,8 @@ cdef class open(object):
else:
self.has_multi_field_msgs=False
fseek(self._fd, self._offset, SEEK_SET)
def __len__(self):
return self.messages
def __iter__(self):
return self
def __next__(self):
Expand Down Expand Up @@ -1103,7 +1110,7 @@ cdef class gribmessage(object):
raise RuntimeError(_get_error_message(err))
elif typ == GRIB_TYPE_LONG:
# is value an array or a scalar?
datarr = np.asarray(value, int)
datarr = np.asarray(value, np.int_)
is_array = False
if datarr.shape:
is_array = True
Expand Down Expand Up @@ -1189,7 +1196,12 @@ cdef class gribmessage(object):
raise RuntimeError(_get_error_message(err))
return longval
else: # array
datarr = np.zeros(size, int)
if os.name == 'nt':
# this should not be necessary since np.int_ should
# be platform-dependent long, which should map to 32-bits on windows?
datarr = np.zeros(size, np.int32)
else:
datarr = np.zeros(size, np.int_)
err = grib_get_long_array(self._gh, name, <long *>datarr.data, &size)
if err:
raise RuntimeError(_get_error_message(err))
Expand Down Expand Up @@ -1315,8 +1327,9 @@ cdef class gribmessage(object):
else:
missval = 1.e30
if self.expand_reduced:
nx = self['pl'].max()
datarr = redtoreg(datarr, self['pl'], missval=missval)
lonsperlat = self['pl']
nx = lonsperlat.max()
datarr = redtoreg(datarr, lonsperlat, missval=missval)
else:
nx = None
elif self.has_key('Nx') and self.has_key('Ny'):
Expand Down Expand Up @@ -1552,7 +1565,8 @@ cdef class gribmessage(object):
lats = self['distinctLatitudes']
if lat2 < lat1 and lats[-1] > lats[0]: lats = lats[::-1]
ny = self['Nj']
nx = self['pl'].max()
lonsperlat = self['pl']
nx = lonsperlat.max()
lon1 = self['longitudeOfFirstGridPointInDegrees']
lon2 = self['longitudeOfLastGridPointInDegrees']
lons = np.linspace(lon1,lon2,nx)
Expand All @@ -1563,7 +1577,8 @@ cdef class gribmessage(object):
elif self['gridType'] == 'reduced_ll': # reduced lat/lon grid
if self.expand_reduced:
ny = self['Nj']
nx = self['pl'].max()
lonsperlat = self['pl']
nx = lonsperlat.max()
lat1 = self['latitudeOfFirstGridPointInDegrees']
lat2 = self['latitudeOfLastGridPointInDegrees']
lon1 = self['longitudeOfFirstGridPointInDegrees']
Expand Down
8 changes: 6 additions & 2 deletions test/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ def test():
[1:Precipitation rate:kg m**-2 s**-1 (avg):regular_gg:surface:level 0:fcst time 108-120 hrs (avg):from 200402291200, 2:Surface pressure:Pa (instant):regular_gg:surface:level 0:fcst time 120 hrs:from 200402291200, 3:Maximum temperature:K (instant):regular_gg:heightAboveGround:level 2 m:fcst time 108-120 hrs:from 200402291200, 4:Minimum temperature:K (instant):regular_gg:heightAboveGround:level 2 m:fcst time 108-120 hrs:from 200402291200]
>>> grbs = pygrib.open('../sampledata/flux.grb')
number of messages in file
>>> len(grbs)
4
acts like a file object
>>> grbs.tell()
0
Expand Down Expand Up @@ -234,8 +238,8 @@ def test():
>>> str('min/max %5.2f %5.2f' % (data.min(), data.max()))
'min/max 295.40 308.10'
>>> grbs = pygrib.open('../sampledata/no-radius-shapeOfEarth-7.grb2')
>>> for grb in grbs: print(grb)
1:Total precipitation:kg m-2 (accum):lambert:surface:level 0:fcst time 15-30 mins (accum):from 201804100000
>>> for grb in grbs: print(grb) # doctest:+ELLIPSIS
1:Total precipitation:kg m-2 (accum):lambert:surface:level 0:fcst time 15...-30... mins (accum):from 201804100000
>>> str(grb.packingType)
'grid_simple'
>>> grbs.close()
Expand Down

0 comments on commit 362f21e

Please sign in to comment.