Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

roll setting the longitude values incorrectly #127

Closed
agstephens opened this issue Feb 12, 2021 · 1 comment
Closed

roll setting the longitude values incorrectly #127

agstephens opened this issue Feb 12, 2021 · 1 comment
Assignees

Comments

@agstephens
Copy link
Collaborator

Hi @ellesmith88,

I think I have found a bug in the roll code. In this example, the resulting Dataset has a set of longitudes that are not the same as the input longitudes. Here are the details:

  • input longitudes:
 lon = -179.75, -129.75, -79.75, -29.75, 20.25, 70.25, 120.25, 170.25 ;
  • requested bounding box: 1 to 300 degrees longitude

  • output longitude array: [ 1., 51., 101., 151., 201., 251.]

I think that the correct roll should return longitudes of value:

20.25, 70.25, 120.25, 170.25, 180.25, 230.25, 280.25

Note that gap between the longitude values is not constant when you wrap it.

Here is a reproducible example of the error:

$ wget "https://github.com/cedadev/mini-ceda-archive/blob/main/archive/badc/cru/data/cru_ts/cru_ts_4.04/data/wet/cru_ts4.04.1901.2019.wet.dat.nc?raw=true" -O cru_ts4.04.1901.2019.wet.dat.nc

$ ncdump -v lat,lon cru_ts4.04.1901.2019.wet.dat.nc | tail -2 | grep =
 lon = -179.75, -129.75, -79.75, -29.75, 20.25, 70.25, 120.25, 170.25 ;

$ python

>>> from clisops.ops.subset import subset
>>> ds = subset('cru_ts4.04.1901.2019.wet.dat.nc', area=['1','1','300','89'], output_type='xarray')
>>> print(ds[0].lon.values)

array([  1.,  51., 101., 151., 201., 251.], dtype=float32)
@ellesmith88
Copy link
Collaborator

@agstephens @cehbrecht

I've got this:

            first_element_value = low
            res, offset = calculate_offset(lon, first_element_value)

            # roll the dataset
            ds_roll = ds.roll(shifts={f"{lon.name}": offset}, roll_coords=True)

            # assign longitude to match the roll and copy attrs
            lon_vals = ds_roll.coords[lon.name].values

            if offset < 0:
                lon_vals = np.where(lon_vals > (360 + low), lon_vals, lon_vals % 360)
            else:
                lon_vals = np.where(lon_vals < (360 + low), lon_vals, lon_vals % -360)

            ds_roll.coords[lon.name] = lon_vals
            ds_roll.coords[lon.name].attrs = ds.coords[lon.name].attrs
            return ds_roll

Which seems to be working, but I've only tried a few tests so far. I'm not sure how I got here anymore..! We can look tomorrow morning.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants