Skip to content

Commit c2ae9db

Browse files
gjm174mats-knmi
authored andcommitted
Added member and time dimension (#432)
1 parent e7c081c commit c2ae9db

File tree

1 file changed

+65
-10
lines changed

1 file changed

+65
-10
lines changed

pysteps/xarray_helpers.py

+65-10
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ def convert_input_to_xarray_dataset(
8383
precip: np.ndarray,
8484
quality: np.ndarray | None,
8585
metadata: dict[str, str | float | None],
86+
startdate: datetime | None = None,
8687
) -> xr.Dataset:
8788
"""
8889
Read a precip, quality, metadata tuple as returned by the importers
@@ -99,6 +100,8 @@ def convert_input_to_xarray_dataset(
99100
metadata: dict
100101
Metadata dictionary containing the attributes described in the
101102
documentation of :py:mod:`pysteps.io.importers`.
103+
startdate: datetime, None
104+
Datetime object containing the start date and time for the nowcast
102105
103106
Returns
104107
-------
@@ -107,7 +110,31 @@ def convert_input_to_xarray_dataset(
107110
108111
"""
109112
var_name, attrs = cf_parameters_from_unit(metadata["unit"])
110-
h, w = precip.shape
113+
114+
dims = None
115+
timesteps = None
116+
ens_number = None
117+
118+
if precip.ndim == 4:
119+
ens_number, timesteps, h, w = precip.shape
120+
dims = ["ens_number", "time", "y", "x"]
121+
122+
if startdate is None:
123+
raise Exception("startdate missing")
124+
125+
elif precip.ndim == 3:
126+
timesteps, h, w = precip.shape
127+
dims = ["time", "y", "x"]
128+
129+
if startdate is None:
130+
raise Exception("startdate missing")
131+
132+
elif precip.ndim == 2:
133+
h, w = precip.shape
134+
dims = ["y", "x"]
135+
else:
136+
raise Exception(f"Precip field shape: {precip.shape} not supported")
137+
111138
x_r = np.linspace(metadata["x1"], metadata["x2"], w + 1)[:-1]
112139
x_r += 0.5 * (x_r[1] - x_r[0])
113140
y_r = np.linspace(metadata["y1"], metadata["y2"], h + 1)[:-1]
@@ -142,25 +169,33 @@ def convert_input_to_xarray_dataset(
142169

143170
data_vars = {
144171
var_name: (
145-
["y", "x"],
172+
dims,
146173
precip,
147174
{
148175
"units": attrs["units"],
149176
"standard_name": attrs["standard_name"],
150177
"long_name": attrs["long_name"],
151178
"grid_mapping": "projection",
152-
"transform": metadata["transform"],
153-
"accutime": metadata["accutime"],
154-
"threshold": metadata["threshold"],
155-
"zerovalue": metadata["zerovalue"],
156-
"zr_a": metadata["zr_a"],
157-
"zr_b": metadata["zr_b"],
158179
},
159180
)
160181
}
182+
183+
metadata_keys = [
184+
"transform",
185+
"accutime",
186+
"threshold",
187+
"zerovalue",
188+
"zr_a",
189+
"zr_b",
190+
]
191+
192+
for metadata_field in metadata_keys:
193+
if metadata_field in metadata:
194+
data_vars[var_name][2][metadata_field] = metadata[metadata_field]
195+
161196
if quality is not None:
162197
data_vars["quality"] = (
163-
["y", "x"],
198+
dims,
164199
quality,
165200
{
166201
"units": "1",
@@ -210,6 +245,26 @@ def convert_input_to_xarray_dataset(
210245
},
211246
),
212247
}
248+
249+
if ens_number is not None:
250+
coords["ens_number"] = (
251+
["ens_number"],
252+
list(range(1, ens_number + 1, 1)),
253+
{
254+
"long_name": "ensemble member",
255+
"standard_name": "realization",
256+
"units": "",
257+
},
258+
)
259+
260+
if timesteps is not None:
261+
startdate_str = datetime.strftime(startdate, "%Y-%m-%d %H:%M:%S")
262+
263+
coords["time"] = (
264+
["time"],
265+
list(range(1, timesteps + 1, 1)),
266+
{"long_name": "forecast time", "units": "seconds since %s" % startdate_str},
267+
)
213268
if grid_mapping_var_name is not None:
214269
coords[grid_mapping_name] = (
215270
[],
@@ -223,7 +278,7 @@ def convert_input_to_xarray_dataset(
223278
"precip_var": var_name,
224279
}
225280
dataset = xr.Dataset(data_vars=data_vars, coords=coords, attrs=attrs)
226-
return dataset.sortby(["y", "x"])
281+
return dataset.sortby(dims)
227282

228283

229284
def convert_output_to_xarray_dataset(

0 commit comments

Comments
 (0)