xarray-contrib / xwrf

A lightweight interface for working with the Weather Research and Forecasting (WRF) model output in Xarray.
https://xwrf.readthedocs.io/
Apache License 2.0
59 stars 16 forks source link

[Bug]: `WRFDataArrayAccessor.destagger` does not work #99

Closed lpilz closed 2 years ago

lpilz commented 2 years ago

What happened?

It started innocently enough, with me trying to test manually whether destaggering DataArrays really works. However, it didn't and the error message reads ValueError: conflicting sizes for dimension 'x': length 200 on the data but length 199 on coordinate 'x'.

I tracked the bug down to the interpolation between left_or_bottom_cells and right_or_top_cells in _destag_variable. As weird as it sounds, xarray seems to not be able to properly add the two arrays.

While the code reads: https://github.com/xarray-contrib/xwrf/blob/37adcb0a9f60bea83e2df1f48beeb43ecdb5781b/xwrf/destagger.py#L61-L63

The sizes of the three variables (generated using print statements) are:

left_or_bottom_cells size Frozen({'x_stag': 200})
right_or_top_cells size Frozen({'x_stag': 200})
center_mean Frozen({'x_stag': 199})

This seems to be connected with WRFDatasetAccessor.postprocess() somehow, as the bug only occurs if one has called this method before

Minimal Complete Verifiable Example

# Errors with `ValueError: conflicting sizes for dimension 'x': length 200 on the data but length 199 on coordinate 'x'`
ds = xwrf.tutorial.open_dataset("wrfout").xwrf.postprocess()['U'].xwrf.destagger()

# No error
ds = xwrf.tutorial.open_dataset("wrfout")['U'].xwrf.destagger()

Relevant log output

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In [44], line 1
----> 1 ds = xwrf.tutorial.open_dataset("wrfout").xwrf.postprocess()['U'].xwrf.destagger()
      2 ds

File ~/software/projects/xwrf/xwrf/accessors.py:89, in WRFDataArrayAccessor.destagger(self, stagger_dim, unstaggered_dim_name, exclude_staggered_auxiliary_coords)
     86     else:
     87         new_coords[coord_name] = coord_data.variable
---> 89 return xr.DataArray(new_variable, coords=new_coords)

File ~/.conda/envs/xwrf-blogpost/lib/python3.9/site-packages/xarray/core/dataarray.py:412, in DataArray.__init__(self, data, coords, dims, name, attrs, indexes, fastpath)
    410 data = _check_data_shape(data, coords, dims)
    411 data = as_compatible_data(data)
--> 412 coords, dims = _infer_coords_and_dims(data.shape, coords, dims)
    413 variable = Variable(dims, data, attrs, fastpath=True)
    414 indexes, coords = _create_indexes_from_coords(coords)

File ~/.conda/envs/xwrf-blogpost/lib/python3.9/site-packages/xarray/core/dataarray.py:160, in _infer_coords_and_dims(shape, coords, dims)
    158 for d, s in zip(v.dims, v.shape):
    159     if s != sizes[d]:
--> 160         raise ValueError(
    161             f"conflicting sizes for dimension {d!r}: "
    162             f"length {sizes[d]} on the data but length {s} on "
    163             f"coordinate {k!r}"
    164         )
    166 if k in sizes and v.shape != (sizes[k],):
    167     raise ValueError(
    168         f"coordinate {k!r} is a DataArray dimension, but "
    169         f"it has shape {v.shape!r} rather than expected shape {sizes[k]!r} "
    170         "matching the dimension size"
    171     )

Environment

main branch

Anything else we need to know?

No response

lpilz commented 2 years ago

@jthielen Do you have any idea what's happening here?

jthielen commented 2 years ago

This is a really silly typo bug: it should be coord_data.variable not coord_data in

https://github.com/xarray-contrib/xwrf/blob/37adcb0a9f60bea83e2df1f48beeb43ecdb5781b/xwrf/accessors.py#L83-L85

Messy stuff with alignment can happen when you have a DataArray when you're expecting a Variable. PR incoming soon!

lpilz commented 2 years ago

Messy stuff with alignment can happen when you have a DataArray when you're expecting a Variable.

That's good to know! Thanks :)