Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
82 commits
Select commit Hold shift + click to select a range
8b92e71
import directly to xarray and rewrite utils_transformation to work wi…
mats-knmi Jul 17, 2024
23825dd
convert to_rainrate function also
mats-knmi Jul 17, 2024
9952bd3
Rewrite more code to xarray
mats-knmi Jul 18, 2024
904bce8
conversion.py works on the xarray datamodel
mats-knmi Jul 18, 2024
b3aa009
fix converters.py
mats-knmi Jul 18, 2024
016d28f
make dimension.py xarray compatible (#397)
mats-knmi Aug 12, 2024
e7c081c
make all nowcast methods xarray compatible (#414)
mats-knmi Sep 2, 2024
c2ae9db
Added member and time dimension (#432)
gjm174 Sep 23, 2024
9ea07fc
Initial commit to branch
sidekock Oct 8, 2024
53a98a9
Working on _apply_noise_and_ar_model method
sidekock Oct 8, 2024
0c5185f
Only update function needs to be added
sidekock Oct 8, 2024
46bc44a
Fully refactored code
sidekock Oct 9, 2024
eb33c06
Possible solution for errors solved
sidekock Oct 9, 2024
a1ce4bc
Fixed small bug in _nowcast_main
sidekock Oct 9, 2024
b002354
Name changes from feedback Ruben
sidekock Oct 22, 2024
e105a24
Name changes from feedback Ruben v2
sidekock Oct 22, 2024
b6c47af
Name changes from feedback Ruben v3
sidekock Oct 22, 2024
5aaf24d
Added config dataclass to steps nowcast
sidekock Oct 31, 2024
fa9a1ef
Added config dataclass to steps nowcast, v2
sidekock Oct 31, 2024
3da1696
Added config dataclass to steps nowcast, v3
sidekock Oct 31, 2024
8c7982c
Added config dataclass to steps nowcast, v4
sidekock Oct 31, 2024
aa26517
Added config dataclass to steps nowcast, fixed some assignment issues…
sidekock Oct 31, 2024
ff2e2be
Fixed num_ensemble_workers bug
sidekock Oct 31, 2024
2543683
Added params and state dataclasses
sidekock Oct 31, 2024
37739de
Implemented a reset of the states and params to allow for multiple fo…
sidekock Oct 31, 2024
f123bde
Removed some redundant fields
sidekock Oct 31, 2024
1a71e61
Update pysteps/nowcasts/steps.py
sidekock Nov 4, 2024
db953fb
Added suggested changed by Mats regarding __ and typing
sidekock Nov 4, 2024
eff9248
Possible fix for static code analysis
sidekock Nov 4, 2024
663a9a2
Added the needed documentation to the class
sidekock Nov 4, 2024
3226042
Merge remote-tracking branch 'origin/refactoring_steps' into xarray/main
mats-knmi Nov 6, 2024
2066f14
Refactored all names in the steps blending code from old to new
sidekock Nov 18, 2024
72d0fbc
Made some name changes but test still do not pass
sidekock Nov 18, 2024
1ce563e
Fixed naming changes, now the tests pass
sidekock Nov 18, 2024
fbe551b
Built the rough scaffolding for the blending class
sidekock Nov 18, 2024
46a93e5
Refactored untill no rain case
sidekock Nov 27, 2024
1eede39
Added code to estimation of ar parameters of radar
sidekock Nov 28, 2024
a18f1f6
Next go, start with forecast loop #7
sidekock Nov 29, 2024
8d16c11
Added some uniformity between nowcast and blending steps. Now at # 8.…
sidekock Dec 2, 2024
88df97d
Small changes since prev commit
sidekock Dec 2, 2024
7ee0020
All code is tranfered. Last part of the main loop needs to be refactored
sidekock Dec 2, 2024
f387981
Everything is refactored, no test ran as of yet
sidekock Dec 5, 2024
760c185
Old forecast function is updated to fit newly refactored code
sidekock Dec 5, 2024
8d8905a
Removed old code which is no longer used
sidekock Dec 5, 2024
d6249f5
6 more tests that fail
sidekock Dec 5, 2024
38702b3
All tests pass, still need to fix TODOs
sidekock Dec 5, 2024
5ff1713
Updated gitignore
sidekock Dec 5, 2024
d999501
Cleanup of params and state dataclasses, next step: better typing
sidekock Dec 6, 2024
ed20ecc
Cleanup of params and state dataclasses, now all tests pass
sidekock Dec 6, 2024
701e726
Added correct typing to all parts of params and state
sidekock Dec 6, 2024
b9de511
Ready for pull request
sidekock Dec 6, 2024
38ed195
Made changes for Codacy review
sidekock Dec 6, 2024
32b656f
Added aditional tests which currently fail in master branch
sidekock Dec 16, 2024
4fe9f78
Update .gitignore
sidekock Dec 16, 2024
b31d55c
Used the __zero_precip_time in __zero_precipitation_forecast()
sidekock Dec 16, 2024
cc02593
Changed typing hints to python 3.10+ version
sidekock Dec 16, 2024
4e4a148
Added comments back to the State dataclass
sidekock Dec 16, 2024
0f4e037
Changed the self.__state.velocity_perturbations = [] to self.__params…
sidekock Dec 17, 2024
9f413aa
Added code changes as suggested by Ruben, comments and documentation …
sidekock Dec 18, 2024
c72d953
Added frozen functionality to dataclasses, removed reset_state and fi…
sidekock Dec 19, 2024
00f057b
Added frozen dataclass to nowcast
sidekock Dec 19, 2024
1b82512
The needed checks are done for this TODO so it can be removed
sidekock Dec 19, 2024
47ab6c3
Use the seed in all rng in blending code (#449)
mats-knmi Jan 2, 2025
48187c4
Removed deepcopy of worker_state. The state is now accessable to all …
sidekock Jan 3, 2025
9b216a7
Update to probmatching comments to keep in track with main
sidekock Jan 8, 2025
4e2d4b7
Merge remote-tracking branch 'origin/master' into xarray/main
mats-knmi Jan 14, 2025
2ff8e2c
Merge remote-tracking branch 'origin/refactor-steps-in-blending-code'…
mats-knmi Jan 14, 2025
561e7ac
Fix for multithreading issue, this produces exactly the same results …
sidekock Jan 20, 2025
4fb784e
New commit for new pr
sidekock Jan 20, 2025
9f48c66
Merge remote-tracking branch 'origin/refactor-steps-in-blending-code'…
mats-knmi Jan 29, 2025
7d1e91e
Fix more of the unit tests with the new xarray based code (#454)
mats-knmi Sep 8, 2025
eef8d1d
Add XR comment
mats-knmi Sep 8, 2025
fc666a6
Merge remote-tracking branch 'origin/master' into xarray/main
mats-knmi Sep 9, 2025
325aab3
fix tests that failed during merge with master
mats-knmi Sep 9, 2025
d9f6f6a
Xarray/add more xr comments (#504)
mats-knmi Sep 10, 2025
e9ddf0f
test_datasets.py to xarray (#511)
larsbonnefoy Sep 10, 2025
7455efe
Xarray/passing more tests (#512)
sidekock Sep 10, 2025
73bf8b2
Xarray/fix even more tests (#513)
mats-knmi Sep 10, 2025
7791b4a
make last test discoverable and fix dimension test
mats-knmi Sep 11, 2025
2330b01
Fixed test_exports, Required hardcoding some passing test as exporter…
larsbonnefoy Sep 11, 2025
7771632
All specific IO tests are done (#519)
sidekock Sep 12, 2025
d77f1b4
removed failing plugin test. Cookiecutter does not work correctly wit…
larsbonnefoy Sep 12, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ci/ci_test_env.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ dependencies:
- pillow
- pyproj
- scipy
- xarray
# Optional dependencies
- dask
- pyfftw
Expand Down
1 change: 1 addition & 0 deletions environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ dependencies:
- pillow
- pyproj
- scipy
- xarray
4 changes: 3 additions & 1 deletion environment_dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ dependencies:
- dask
- pyfftw
- h5py
- PyWavelets
- pygrib
- black
- pytest-cov
Expand All @@ -31,3 +30,6 @@ dependencies:
- scikit-image
- pandas
- rasterio
- xarray
- geotiff
- cookiecutter
14 changes: 6 additions & 8 deletions pysteps/datasets.py
Original file line number Diff line number Diff line change
Expand Up @@ -434,10 +434,8 @@ def load_dataset(case="fmi", frames=14):

Returns
-------
rainrate: array-like
Precipitation data in mm/h. Dimensions: [time, lat, lon]
metadata: dict
The metadata observations attributes.
rainrate: Dataset
A dataset containing the precipitation data in mm/h and quality rasters and associated metadata. Dimensions: [time, lat, lon]
timestep: number
Time interval between composites in minutes.
"""
Expand Down Expand Up @@ -476,11 +474,11 @@ def load_dataset(case="fmi", frames=14):
# Read the radar composites
importer = io.get_method(data_source["importer"], "importer")
importer_kwargs = data_source["importer_kwargs"]
reflectivity, _, metadata = io.read_timeseries(
file_names, importer, **importer_kwargs
reflectivity = io.read_timeseries(
file_names, importer, timestep=data_source["timestep"], **importer_kwargs
)

# Convert to rain rate
precip, metadata = conversion.to_rainrate(reflectivity, metadata)
precip = conversion.to_rainrate(reflectivity)

return precip, metadata, data_source["timestep"]
return precip, data_source["timestep"]
14 changes: 11 additions & 3 deletions pysteps/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@

import numpy as np

from pysteps.xarray_helpers import convert_input_to_xarray_dataset


def _add_extra_kwrds_to_docstrings(target_func, extra_kwargs_doc_text):
"""
Expand All @@ -30,6 +32,8 @@ def _add_extra_kwrds_to_docstrings(target_func, extra_kwargs_doc_text):
"""
# Clean up indentation from docstrings for the
# docstrings to be merged correctly.
if target_func.__doc__ is None:
return target_func
extra_kwargs_doc = inspect.cleandoc(extra_kwargs_doc_text)
target_func.__doc__ = inspect.cleandoc(target_func.__doc__)

Expand Down Expand Up @@ -66,7 +70,7 @@ def postprocess_import(fillna=np.nan, dtype="double"):
def _postprocess_import(importer):
@wraps(importer)
def _import_with_postprocessing(*args, **kwargs):
precip, *other_args = importer(*args, **kwargs)
precip, quality, metadata = importer(*args, **kwargs)

_dtype = kwargs.get("dtype", dtype)

Expand All @@ -88,7 +92,9 @@ def _import_with_postprocessing(*args, **kwargs):
mask = ~np.isfinite(precip)
precip[mask] = _fillna

return (precip.astype(_dtype),) + tuple(other_args)
return convert_input_to_xarray_dataset(
precip.astype(_dtype), quality, metadata
)

extra_kwargs_doc = """
Other Parameters
Expand Down Expand Up @@ -124,7 +130,9 @@ def new_function(*args, **kwargs):
target motion_method_func function.
"""

input_images = args[0]
dataset = args[0]
precip_var = dataset.attrs["precip_var"]
input_images = dataset[precip_var].values
if input_images.ndim != 3:
raise ValueError(
"input_images dimension mismatch.\n"
Expand Down
62 changes: 55 additions & 7 deletions pysteps/downscaling/rainfarm.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@
"""

import warnings

import xarray as xr
import numpy as np
from scipy.signal import convolve
from pysteps.utils.spectral import rapsd
from pysteps.utils.dimension import aggregate_fields
from pysteps.xarray_helpers import compute_lat_lon


def _gaussianize(precip):
Expand Down Expand Up @@ -210,7 +211,7 @@ def _balanced_spatial_average(array, kernel):


def downscale(
precip,
precip_dataset: xr.Dataset,
ds_factor,
alpha=None,
threshold=None,
Expand All @@ -224,8 +225,8 @@ def downscale(

Parameters
----------
precip: array_like
Array of shape (m, n) containing the input field.
precip: xarray.Dataset
Xarray dataset containing the input field.
The input is expected to contain rain rate values.
All values are required to be finite.
alpha: float, optional
Expand Down Expand Up @@ -266,6 +267,8 @@ def downscale(
"""

# Validate inputs
precip_var = precip_dataset.attrs["precip_var"]
precip = precip_dataset[precip_var].values.squeeze()
if not np.isfinite(precip).all():
raise ValueError("All values in 'precip' must be finite.")
if not isinstance(ds_factor, int) or ds_factor <= 0:
Expand Down Expand Up @@ -297,8 +300,50 @@ def downscale(
noise_field /= noise_field.std()
noise_field = np.exp(noise_field)

y_new = np.arange(
precip_dataset.y.values[0]
- precip_dataset.y.attrs["stepsize"]
+ precip_dataset.y.attrs["stepsize"] / ds_factor,
precip_dataset.y.values[-1] + precip_dataset.y.attrs["stepsize"] / ds_factor,
precip_dataset.y.attrs["stepsize"] / ds_factor,
)
x_new = np.arange(
precip_dataset.x.values[0]
- precip_dataset.y.attrs["stepsize"]
+ precip_dataset.x.attrs["stepsize"] / ds_factor,
precip_dataset.x.values[-1] + precip_dataset.x.attrs["stepsize"] / ds_factor,
precip_dataset.x.attrs["stepsize"] / ds_factor,
)
lat, lon = compute_lat_lon(x_new, y_new, precip_dataset.attrs["projection"])
noise_dataset = xr.Dataset(
data_vars={precip_var: (["time", "y", "x"], [noise_field])},
coords={
"time": (["time"], precip_dataset.time.values, precip_dataset.time.attrs),
"y": (
["y"],
y_new,
{
**precip_dataset.y.attrs,
"stepsize": precip_dataset.y.attrs["stepsize"] / ds_factor,
},
),
"x": (
["x"],
x_new,
{
**precip_dataset.x.attrs,
"stepsize": precip_dataset.x.attrs["stepsize"] / ds_factor,
},
),
"lon": (["y", "x"], lon, precip_dataset.lon.attrs),
"lat": (["y", "x"], lat, precip_dataset.lat.attrs),
},
attrs=precip_dataset.attrs,
)

# Aggregate the noise field to low resolution
noise_lowres = aggregate_fields(noise_field, ds_factor, axis=(0, 1))
noise_lowres_dataset = aggregate_fields(noise_dataset, ds_factor, dim=("y", "x"))
noise_lowres = noise_lowres_dataset[precip_var].values.squeeze()

# Expand input and noise fields to high resolution
precip_expanded = np.kron(precip, np.ones((ds_factor, ds_factor)))
Expand All @@ -322,8 +367,11 @@ def downscale(
if threshold is not None:
precip_highres[precip_highres < threshold] = 0

precip_highres_dataset = noise_dataset.copy(deep=True)
precip_highres_dataset[precip_var][:] = [precip_highres]

# Return the downscaled field and optionally the spectral slope alpha
if return_alpha:
return precip_highres, alpha
return precip_highres_dataset, alpha

return precip_highres
return precip_highres_dataset
4 changes: 2 additions & 2 deletions pysteps/io/exporters.py
Original file line number Diff line number Diff line change
Expand Up @@ -511,12 +511,12 @@ def initialize_forecast_exporter_netcdf(

if metadata["unit"] == "mm/h":
var_name = "precip_intensity"
var_standard_name = None
var_standard_name = "instantaneous_precipitation_rate"
var_long_name = "instantaneous precipitation rate"
var_unit = "mm h-1"
elif metadata["unit"] == "mm":
var_name = "precip_accum"
var_standard_name = None
var_standard_name = "accumulated_precipitation"
var_long_name = "accumulated precipitation"
var_unit = "mm"
elif metadata["unit"] == "dBZ":
Expand Down
Loading
Loading