diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 6d41fe7..5e36cb3 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -9,54 +9,41 @@ on:
schedule:
- cron: '0 0 * * *' # Daily “At 00:00”
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: true
+
jobs:
test:
- name: Python (${{ matrix.python-version }}, ${{ matrix.os }})
+ name: Python ${{ matrix.python-version }}, ${{ matrix.os }}
runs-on: ${{ matrix.os }}
defaults:
run:
shell: bash -l {0}
-
strategy:
fail-fast: false
matrix:
os: [ "ubuntu-latest", "macos-latest", "macos-14" ]
- python-version: [ "3.9", "3.10", "3.11", "3.12" ]
-
+ python-version: [ "3.10", "3.11", "3.12", "3.13" ]
steps:
- - name: Cancel previous runs
- uses: styfle/cancel-workflow-action@0.12.1
- with:
- access_token: ${{ github.token }}
- - name: Checkout
- uses: actions/checkout@v4
- with:
- token: ${{ github.token }}
- - name: Conda setup
- uses: conda-incubator/setup-miniconda@v3
- if: matrix.os != 'macos-14'
- with:
- python-version: ${{ matrix.python-version }}
- channels: conda-forge
- environment-file: build_envs/environment.yml
- - name: Conda setup (macOS M1)
- uses: conda-incubator/setup-miniconda@v3
- if: matrix.os == 'macos-14'
+ - name: checkout
+ uses: actions/checkout@v6
+ - name: environment setup
+ uses: conda-incubator/setup-miniconda@8ee1f361103df19b6f8c8655fd3967a8ecb162d5 # v4.0.1
with:
- installer-url: https://github.com/conda-forge/miniforge/releases/download/23.11.0-0/Mambaforge-23.11.0-0-MacOSX-arm64.sh
python-version: ${{ matrix.python-version }}
channels: conda-forge
environment-file: build_envs/environment.yml
- - name: Build WRF-Python
+ - name: build WRF-Python
run: |
python -m pip install build
python -m build .
python -m pip install dist/wrf*.whl
- - name: Run tests
+ - name: run tests
run: |
cd test/ci_tests
python utests.py
- - name: Check import
+ - name: check import
if: failure()
run: |
python -m pip show wrf-python
diff --git a/.github/workflows/pypi.yaml b/.github/workflows/pypi.yaml
index 9919c74..9206c63 100644
--- a/.github/workflows/pypi.yaml
+++ b/.github/workflows/pypi.yaml
@@ -8,19 +8,18 @@ jobs:
if: github.repository == 'NCAR/wrf-python'
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v6
- name: Set up Python
- uses: actions/setup-python@v5
+ uses: actions/setup-python@v6
with:
- python-version: '3.x'
+ python-version: '3.10'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
- python -m pip install setuptools setuptools-scm wheel twine check-manifest
+ python -m pip install build twine
- name: Build tarball and wheels
run: |
- python setup.py sdist bdist_wheel
- python -m pip wheel . -w dist --no-deps
+ python -m build
- name: Test the artifacts
run: |
python -m twine check dist/*
@@ -29,26 +28,25 @@ jobs:
if: startsWith(github.ref, 'refs/tags')
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v6
- name: Set up Python
- uses: actions/setup-python@v5
+ uses: actions/setup-python@v6
with:
- python-version: '3.x'
+ python-version: '3.10'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
- python -m pip install setuptools setuptools-scm wheel twine check-manifest
+ python -m pip install build twine
- name: Build tarball and wheels
run: |
- python setup.py sdist bdist_wheel
- python -m pip wheel . -w dist --no-deps
+ python -m build
- name: Test the artifacts
run: |
python -m twine check dist/*
- name: Publish package to PyPI
- uses: pypa/gh-action-pypi-publish@v1.12.4
+ uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # v1.14.0
with:
user: __token__
password: ${{ secrets.PYPI_WRF_PYTHON }}
skip_existing: true
- verbose: true
\ No newline at end of file
+ verbose: true
diff --git a/.readthedocs.yml b/.readthedocs.yml
index 8cb6480..abbbbb8 100644
--- a/.readthedocs.yml
+++ b/.readthedocs.yml
@@ -6,9 +6,9 @@
version: 2
build:
- os: "ubuntu-20.04"
+ os: "ubuntu-lts-latest"
tools:
- python: "mambaforge-4.10"
+ python: "miniforge3-latest"
jobs:
post_create_environment:
- python -m pip install --no-cache-dir --no-deps .
diff --git a/README.md b/README.md
index 13f6420..a39aaba 100644
--- a/README.md
+++ b/README.md
@@ -9,26 +9,21 @@ This package provides over 30 diagnostic calculations, several interpolation rou
Installation
----------------------------
- conda install -c conda-forge wrf-python
+ conda install conda-forge::wrf-python
Documentation
----------------------------------
-http://wrf-python.rtfd.org
+https://wrf-python.readthedocs.io
Citation
------------------
-If you use this software, please cite it as described at the [WRF-Python - Citation](
-https://wrf-python.readthedocs.io/en/latest/citation.html) page.
+If you use this software, please cite it as described in the [documentation](
+https://wrf-python.readthedocs.io/en/latest/citation.html).
--------------------
-*The National Center for Atmospheric Research is sponsored by the National
-Science Foundation. Any opinions, findings and conclusions or recommendations
-expressed in this material do not necessarily reflect the views of the
-National Science Foundation.*
-
-
+*This material is based upon work supported by the NSF National Center for Atmospheric Research, a major facility sponsored by the U.S. National Science Foundation and managed by the University Corporation for Atmospheric Research. Any opinions, findings and conclusions or recommendations expressed in this material do not necessarily reflect the views of the U.S. National Science Foundation.*
diff --git a/build_envs/environment.yml b/build_envs/environment.yml
index 4c646a3..27ab0a4 100644
--- a/build_envs/environment.yml
+++ b/build_envs/environment.yml
@@ -3,7 +3,7 @@ name: wrf_python_build
channels:
- conda-forge
dependencies:
- - python>=3.9, <3.13
+ - python
- compilers
- basemap
- cartopy
@@ -12,7 +12,6 @@ dependencies:
- netcdf4
- numpy
- pycodestyle
- - setuptools
- sphinx
- sphinx_rtd_theme
- sphinxcontrib-googleanalytics
diff --git a/build_envs/platform-specific/macos_arm64.yml b/build_envs/platform-specific/macos_arm64.yml
index 2e475f0..d6483dd 100644
--- a/build_envs/platform-specific/macos_arm64.yml
+++ b/build_envs/platform-specific/macos_arm64.yml
@@ -3,7 +3,7 @@ name: wrf_python_build
channels:
- conda-forge
dependencies:
- - python<3.12
+ - python
- basemap
- cartopy
- clang_osx-arm64
diff --git a/build_envs/platform-specific/macos_x64.yml b/build_envs/platform-specific/macos_x64.yml
index 2415ebe..ba798c2 100644
--- a/build_envs/platform-specific/macos_x64.yml
+++ b/build_envs/platform-specific/macos_x64.yml
@@ -3,7 +3,7 @@ name: wrf_python_build
channels:
- conda-forge
dependencies:
- - python<3.12
+ - python
- basemap
- cartopy
- clang_osx-64
diff --git a/build_envs/platform-specific/windows.yml b/build_envs/platform-specific/windows.yml
index 1053db0..46d53b2 100644
--- a/build_envs/platform-specific/windows.yml
+++ b/build_envs/platform-specific/windows.yml
@@ -4,7 +4,7 @@ channels:
- conda-forge
- msys2
dependencies:
- - python<3.12
+ - python
- basemap
- cartopy
- jupyter
diff --git a/doc/source/_templates/subproducts.txt b/doc/source/_templates/subproducts.txt
index a13b2db..8a66605 100644
--- a/doc/source/_templates/subproducts.txt
+++ b/doc/source/_templates/subproducts.txt
@@ -5,9 +5,9 @@
+--------------------+----------------------+---------------------------------------------------------------+-----------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------+
| mcin | cape_2d | 2D Max CIN | J kg-1 | **missing** (float): Fill value for output only |
+--------------------+----------------------+---------------------------------------------------------------+-----------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------+
-| lcl | cape_2d | 2D Lifted Condensation Level | J kg-1 | **missing** (float): Fill value for output only |
+| lcl | cape_2d | 2D Lifted Condensation Level | m | **missing** (float): Fill value for output only |
+--------------------+----------------------+---------------------------------------------------------------+-----------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------+
-| lfc | cape_2d | 2D Level of Free Convection | J kg-1 | **missing** (float): Fill value for output only |
+| lfc | cape_2d | 2D Level of Free Convection | m | **missing** (float): Fill value for output only |
+--------------------+----------------------+---------------------------------------------------------------+-----------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------+
| cape3d_only | cape_3d | 3D CAPE | J kg-1 | **missing** (float): Fill value for output only |
+--------------------+----------------------+---------------------------------------------------------------+-----------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------+
@@ -116,4 +116,4 @@
| | | | kt | |
| | | | | |
| | | | ft s-1 | |
-+--------------------+----------------------+---------------------------------------------------------------+-----------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------+
\ No newline at end of file
++--------------------+----------------------+---------------------------------------------------------------+-----------------------------+---------------------------------------------------------------------------------------------------------------------------------------------------------+
diff --git a/doc/source/installation.rst b/doc/source/installation.rst
index c35c7fc..016515e 100644
--- a/doc/source/installation.rst
+++ b/doc/source/installation.rst
@@ -1,139 +1,46 @@
Installation
============
-Required Dependencies
-----------------------
-
- - Python 3.9+
- - numpy (1.11 or later; 1.14 required to build on Windows)
- - wrapt (1.10 or later)
- - setuptools (38.0 or later)
-
-
-Highly Recommended Packages
-----------------------------
-
- - xarray (0.7.0 or later)
- - PyNIO (1.4.3 or later)
- - netCDF4-python (1.2.0 or later)
-
-
-Plotting Packages
--------------------------
-
- - PyNGL (1.4.3 or later)
- - matplotlib (1.4.3 or later)
- - cartopy (0.13 or later)
- - basemap (1.0.8 or later)
-
-
Installing via Conda
---------------------
The easiest way to install wrf-python is using
-`Conda `_::
+`Conda `_::
- conda install -c conda-forge wrf-python
+ conda install conda-forge::wrf-python
.. note::
- If you use conda to install wrf-python on a supercomputer like
- Yellowstone or Cheyenne, we recommend that you do not load any python
+ If you use Conda to install WRF-Python on a supercomputer like
+ Derecho or Casper, we recommend that you do not load any Python
related modules via the 'module load' command. The packages installed
- by the 'module load' system will not play nicely with packages installed
- via conda.
+ by the 'module load' system may not play nicely with packages installed
+ via Conda.
- Further, some systems will install python packages to a ~/.local directory,
- which will be found by the miniconda python interpreter and cause various
+ Further, some systems will install Python packages to a ~/.local directory,
+ which will be found by the Conda Python interpreter and cause various
import problems. If you have a ~/.local directory, we strongly suggest
renaming it (mv ~/.local ~/.local_backup).
-Installing on Yellowstone
-----------------------------
-
-On Yellowstone, wrf-python can also be installed using the module load system,
-if this is preferred over using conda.
-
-Unfortunately, because wrf-python requires newer dependencies, it is not
-available using the 'all-python-libs' module, so many of the dependencies
-need to be manually installed (most are for xarray).
-
-Also, make sure you are running in the gnu/4.8.2 compiler environment or
-you will get import errors for a missing libquadmath library when you
-go to import wrf-python.
-
-To install::
+WRF-Python on NSF NCAR HPC
+--------------------------
- module load gnu/4.8.2 or module swap intel gnu/4.8.2
- module load python/2.7.7
- module load numpy/1.11.0 wrapt/1.10.10 scipy/0.17.1 bottleneck/1.1.0 numexpr/2.6.0 pyside/1.1.2 matplotlib/1.5.1 pandas/0.18.1 netcdf4python/1.2.4 xarray/0.8.2
- module load wrf-python/1.0.1
+WRF-Python is included in the `NCAR Python Library `_ on the NSF NCAR HPC systems or can be installed using a supported package manager of your choice.
Installing via Source Code
--------------------------
Installation via source code will require a Fortran and C compiler in order
-to run f2py. You can get them
-`here `_.
+to run F2PY.
-The source code is available via github:
+The source code is available on GitHub:
https://github.com/NCAR/wrf-python
-Or PyPI:
-
-https://pypi.python.org/pypi/wrf-python
-
-To install, if you do not need OpenMP support, change your working directory
+To install, change your working directory
to the wrf-python source directory and run::
$ pip install .
-
-Beginning with wrf-python 1.1, OpenMP is supported, but preprocessing the
-ompgen.F90 file is required, which also requires running f2py to
-build the .pyf file. To simplify this process, you can use the build scripts in
-the *build_scripts* directory as a guide, or just call the script directly.
-
-Below is a sample from a build script for GNU compiler with OpenMP enabled:
-
-.. code-block:: none
-
- cd ../fortran/build_help
-
- gfortran -o sizes -fopenmp omp_sizes.f90
-
- python sub_sizes.py
-
- cd ..
-
- gfortran -E ompgen.F90 -fopenmp -cpp -o omp.f90
-
- f2py *.f90 -m _wrffortran -h wrffortran.pyf --overwrite-signature
-
- cd ..
-
- python setup.py clean --all
-
- python setup.py config_fc --f90flags="-mtune=generic -fopenmp" build_ext --libraries="gomp" build
-
- pip install .
-
-Beginning with numpy 1.14, f2py extensions can now be built using the MSVC
-compiler and mingw gfortran compiler. Numpy 1.14 is required to build
-wrf-python for Python 3.5+.
-
-.. note::
-
- If you are building on a supercomputer and receiving linker related
- errors (e.g. missing symbols, undefined references, etc), you probably
- need to unset the LDFLAGS environment variable. System administrators on
- supercomputing systems often define LDFLAGS for you so that you don't need
- to worry about where libraries like NetCDF are installed. Unfortunately,
- this can cause problems with the numpy.distutils build system. To fix,
- using the build command from above::
-
- $ unset LDFLAGS python setup.py config_fc --f90flags="-mtune=generic -fopenmp" build_ext --libraries="gomp" build
-
-
+
diff --git a/doc/source/new.rst b/doc/source/new.rst
index 6e8719d..03eb680 100644
--- a/doc/source/new.rst
+++ b/doc/source/new.rst
@@ -4,6 +4,28 @@ What's New
Releases
-------------
+v1.4.2 (December 2025)
+- Release 1.4.2
+- Remove Python upper version pin and drop Python 3.9
+
+v1.4.1 (November 2025)
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+- Release 1.4.1
+- Support for Python 3.13
+- Fix to accommodate recent netCDF4 changes
+- Remove pkg_resources
+- Correct units for LCL and LFC in the subproduct diagnostics documentation
+
+v1.4.0 (May 2025)
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+- Release 1.4.0
+- Transition to CMake build using scikit-build-core
+- Packaging updates and adoption of pyproject.toml
+- Support for Python 3.12
+- Support for macOS ARM architecture
+
v1.3.2 (February 2019)
^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/doc/source/plot.rst b/doc/source/plot.rst
index fb69a7f..19b7392 100644
--- a/doc/source/plot.rst
+++ b/doc/source/plot.rst
@@ -23,9 +23,6 @@ should be aware of a few shortcomings when working with WRF data.
- The rotated pole projection requires the x and y limits to be set manually
using set_xlim and set_ylim.
-- You can't place latitude and longitude labels on the axes when using
- any projection other than Mercator or LatLon.
-
Plotting a Two-dimensional Field
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -89,7 +86,10 @@ Plotting a Two-dimensional Field
ax.set_ylim(cartopy_ylim(smooth_slp))
# Add the gridlines
- ax.gridlines(color="black", linestyle="dotted")
+ gl = ax.gridlines(draw_labels=True, color="black", linestyle="dotted")
+ gl.right_labels = False
+ gl.x_inline = False
+ gl.top_labels = False
plt.title("Sea Level Pressure (hPa)")
diff --git a/pyproject.toml b/pyproject.toml
index 5047e19..da4ae17 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -12,7 +12,7 @@ maintainers = [
]
description = "Diagnostic and interpolation routines for WRF-ARW data."
readme = "README.md"
-requires-python = ">=3.9, <3.13"
+requires-python = ">=3.10"
keywords = [
"python", "wrf-python", "wrf", "forecast", "model",
"weather research and forecasting", "interpolation",
@@ -26,10 +26,11 @@ classifiers = [
"Intended Audience :: Developers",
"License :: OSI Approved :: Apache Software License",
"Programming Language :: Fortran",
- "Programming Language :: Python :: 3.9",
+ "Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
+ "Programming Language :: Python :: 3.13",
"Topic :: Scientific/Engineering :: Atmospheric Science",
"Topic :: Software Development",
"Operating System :: POSIX",
diff --git a/src/wrf/__init__.py b/src/wrf/__init__.py
index 39cd608..99334d9 100644
--- a/src/wrf/__init__.py
+++ b/src/wrf/__init__.py
@@ -1,25 +1,8 @@
from __future__ import (absolute_import, division, print_function)
import os
-import pkg_resources
-
-try:
- from . import api
- from .api import *
-except ImportError:
- # For gfortran+msvc combination, extra shared libraries may exist
- # (stored by numpy.distutils)
- if os.name == "nt":
- req = pkg_resources.Requirement.parse("wrf-python")
- extra_dll_dir = pkg_resources.resource_filename(req,
- "wrf-python/.libs")
- if os.path.isdir(extra_dll_dir):
- os.environ["PATH"] += os.pathsep + extra_dll_dir
-
- from . import api
- from .api import *
- else:
- raise
+from . import api
+from .api import *
__all__ = []
__all__.extend(api.__all__)
diff --git a/src/wrf/constants.py b/src/wrf/constants.py
index d660c62..827fed3 100644
--- a/src/wrf/constants.py
+++ b/src/wrf/constants.py
@@ -59,11 +59,15 @@ class ProjectionTypes(object):
np.dtype(np.uint32): 4294967295,
np.dtype(np.int64): Constants.DEFAULT_FILL_INT64,
np.dtype(np.uint64): 18446744073709551614,
- np.dtype(np.float_): Constants.DEFAULT_FILL_DOUBLE,
np.dtype(np.float32): Constants.DEFAULT_FILL_FLOAT,
np.dtype(np.float64): Constants.DEFAULT_FILL_DOUBLE
}
+try:
+ _DEFAULT_FILL_MAP[np.dtype(np.float_)] = Constants.DEFAULT_FILL_DOUBLE
+except AttributeError:
+ pass
+
if version_info >= (3, ):
_DEFAULT_FILL_MAP[np.int_] = Constants.DEFAULT_FILL_INT64
else:
diff --git a/src/wrf/util.py b/src/wrf/util.py
index 40229c7..99ef9ae 100644
--- a/src/wrf/util.py
+++ b/src/wrf/util.py
@@ -9,6 +9,7 @@
from types import GeneratorType
import datetime as dt
from inspect import getmodule
+from netCDF4 import Dataset
try:
from inspect import signature
@@ -134,7 +135,14 @@ def is_multi_file(wrfin):
is a single NetCDF file object.
"""
- return (isinstance(wrfin, Iterable) and not isstr(wrfin))
+ if isinstance(wrfin, Dataset):
+ is_iterable = False
+ elif isinstance(wrfin, Iterable):
+ is_iterable = True
+ else:
+ is_iterable = False
+
+ return (is_iterable and not isstr(wrfin))
def has_time_coord(wrfnc):
diff --git a/src/wrf/version.py b/src/wrf/version.py
index b7b278a..daa50c7 100644
--- a/src/wrf/version.py
+++ b/src/wrf/version.py
@@ -1 +1 @@
-__version__ = "1.3.4.1"
+__version__ = "1.4.2"
diff --git a/test/ci_tests/utests.py b/test/ci_tests/utests.py
index 5ae40e1..133afb0 100644
--- a/test/ci_tests/utests.py
+++ b/test/ci_tests/utests.py
@@ -107,7 +107,7 @@ def test(self):
# print (hts_850)
hts_850 = interplevel(hts, p, 850)
- nt.assert_allclose(to_np(hts_850), ref_ht_850)
+ nt.assert_allclose(to_np(hts_850), ref_ht_850, rtol=1e-06)
elif (varname == "vertcross"):
ref_ht_cross = _get_refvals(referent, "vertcross", repeat, multi)