-
Notifications
You must be signed in to change notification settings - Fork 117
corrected longitude selection near 0 #1843
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
Changes from 3 commits
1ea307e
5d2ea27
6a78a47
3ef0819
7a41c58
0e613c0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -127,18 +127,23 @@ def process_ecmwf_data(gdir, dataset=None, ensemble_member=0, | |
| the entire time period available in the file, but with this kwarg | ||
| you can shorten it (to save space or to crop bad data) | ||
| output_filesuffix : str | ||
| this add a suffix to the output file (useful to avoid overwriting | ||
| this adds a suffix to the output file (useful to avoid overwriting | ||
| previous experiments) | ||
| """ | ||
|
|
||
| if dataset is None: | ||
| dataset = cfg.PARAMS['baseline_climate'] | ||
|
|
||
| # Use xarray to read the data | ||
| lon = gdir.cenlon + 360 if gdir.cenlon < 0 else gdir.cenlon | ||
| lat = gdir.cenlat | ||
| # Use xarray to read the data | ||
| # lon depends on the dataset and its resolution | ||
| with xr.open_dataset(get_ecmwf_file(dataset, 'tmp')) as ds: | ||
| _check_ds_validity(ds) | ||
| diffs = np.sort(ds.longitude)[1:] - np.sort(ds.longitude)[:-1] | ||
| # resolution: diffs[diffs > 0].min() (necessary approach due to flattened files) | ||
| # thresh should not be above 0 (could be because of some regional data...) | ||
| thresh = max(ds.longitude.min() - diffs[diffs > 0].min() / 2, 0) | ||
| lon = gdir.cenlon + 360 if gdir.cenlon < thresh else gdir.cenlon | ||
| yrs = ds['time.year'].data | ||
| y0 = yrs[0] if y0 is None else y0 | ||
| y1 = yrs[-1] if y1 is None else y1 | ||
|
|
@@ -162,6 +167,9 @@ def process_ecmwf_data(gdir, dataset=None, ensemble_member=0, | |
| ref_lat = float(ds['latitude']) | ||
| with xr.open_dataset(get_ecmwf_file(dataset, 'pre')) as ds: | ||
| _check_ds_validity(ds) | ||
| diffs = np.sort(ds.longitude)[1:] - np.sort(ds.longitude)[:-1] | ||
| thresh = max(ds.longitude.min() - diffs[diffs > 0].min() / 2, 0) | ||
| lon = gdir.cenlon + 360 if gdir.cenlon < thresh else gdir.cenlon | ||
|
||
| ds = ds.sel(time=slice(f'{y0}-01-01', f'{y1}-12-01')) | ||
| if dataset == 'CERA': | ||
| ds = ds.sel(number=ensemble_member) | ||
|
|
@@ -174,6 +182,9 @@ def process_ecmwf_data(gdir, dataset=None, ensemble_member=0, | |
| prcp = ds['tp'].data * 1000 * ds['time.daysinmonth'] | ||
| with xr.open_dataset(get_ecmwf_file(dataset, 'inv')) as ds: | ||
| _check_ds_validity(ds) | ||
| diffs = np.sort(ds.longitude)[1:] - np.sort(ds.longitude)[:-1] | ||
| thresh = max(ds.longitude.min() - diffs[diffs > 0].min() / 2, 0) | ||
| lon = gdir.cenlon + 360 if gdir.cenlon < thresh else gdir.cenlon | ||
|
||
| try: | ||
| ds = ds.isel(time=0) | ||
| except (ValueError): | ||
|
|
@@ -192,12 +203,19 @@ def process_ecmwf_data(gdir, dataset=None, ensemble_member=0, | |
|
|
||
| if dataset == 'ERA5dr': | ||
| with xr.open_dataset(get_ecmwf_file(dataset, 'lapserates')) as ds: | ||
| # todo: lapse rate code could be removed, as it is not included in monthly_climate_file anyways ... | ||
| diffs = np.sort(ds.longitude)[1:] - np.sort(ds.longitude)[:-1] | ||
| thresh = max(ds.longitude.min() - diffs[diffs > 0].min() / 2, 0) | ||
| lon = gdir.cenlon + 360 if gdir.cenlon < thresh else gdir.cenlon | ||
| _check_ds_validity(ds) | ||
|
||
| ds = ds.sel(time=slice(f'{y0}-01-01', f'{y1}-12-01')) | ||
| ds = ds.sel(longitude=lon, latitude=lat, method='nearest') | ||
|
|
||
| with xr.open_dataset(get_ecmwf_file(dataset, 'tempstd')) as ds: | ||
| _check_ds_validity(ds) | ||
| diffs = np.sort(ds.longitude)[1:] - np.sort(ds.longitude)[:-1] | ||
| thresh = max(ds.longitude.min() - diffs[diffs > 0].min() / 2, 0) | ||
| lon = gdir.cenlon + 360 if gdir.cenlon < thresh else gdir.cenlon | ||
| ds = ds.sel(time=slice(f'{y0}-01-01', f'{y1}-12-01')) | ||
|
||
| ds = ds.sel(longitude=lon, latitude=lat, method='nearest') | ||
| temp_std = ds['t2m_std'].data | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -105,6 +105,10 @@ def process_gswp3_w5e5_data(gdir, y0=None, y1=None, output_filesuffix=None): | |||||||||||||||||||||||
| # first temperature dataset | ||||||||||||||||||||||||
| with xr.open_dataset(path_tmp) as ds: | ||||||||||||||||||||||||
| assert ds.longitude.min() >= 0 | ||||||||||||||||||||||||
| # check that W5E5 gridpoints do not cross the "0" line (gridpoint center should be at res/2) | ||||||||||||||||||||||||
| diffs = np.sort(ds.longitude)[1:] - np.sort(ds.longitude)[:-1] | ||||||||||||||||||||||||
| res_lon = diffs[diffs > 0].min() | ||||||||||||||||||||||||
| np.testing.assert_allclose(ds.longitude.min(), res_lon / 2) | ||||||||||||||||||||||||
|
||||||||||||||||||||||||
| assert ds.longitude.min() >= 0 | |
| # check that W5E5 gridpoints do not cross the "0" line (gridpoint center should be at res/2) | |
| diffs = np.sort(ds.longitude)[1:] - np.sort(ds.longitude)[:-1] | |
| res_lon = diffs[diffs > 0].min() | |
| np.testing.assert_allclose(ds.longitude.min(), res_lon / 2) | |
| lon_min = float(ds.longitude.min()) | |
| if lon_min < 0: | |
| raise InvalidParamsError( | |
| 'W5E5 longitude coordinates must be non-negative (0–360). ' | |
| f'Found minimum longitude {lon_min}.' | |
| ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thresh = max(ds.longitude.min() - res/2, 0)is inverted relative to the comment and will also keep the original ERA5 bug: for datasets with longitude starting at 0 (ERA5), this forcesthreshto 0 so glaciers in (-res/2, 0) still get shifted to +360 and can select the 359.75 gridpoint instead of 0. It also makesthreshpositive for regional datasets withds.longitude.min() > 0, which would incorrectly shift many positive longitudes. Consider computingresonce, then using a cap of 0 (i.e.min(..., 0)) and ensureds.longitude.min()is converted to a Python float before applying min/max.