diff --git a/tests/test_grid.py b/tests/test_grid.py index 043fd61..9dbb857 100644 --- a/tests/test_grid.py +++ b/tests/test_grid.py @@ -86,3 +86,15 @@ def test_grid_construction_against_own_latlon(test_grid, cf_grid_mapping_name): decimal=2, err_msg=f"Computed {varname + '_M'} does not match with raw output", ) + + +@pytest.mark.parametrize( + 'test_grid', + [ + 'ideal', + ], + indirect=True, +) +def test_ideal_grid(test_grid): + grid_params = _wrf_grid_from_dataset(test_grid) + assert grid_params['crs'] is None diff --git a/tests/test_postprocess.py b/tests/test_postprocess.py index 4cfb506..13c3afe 100644 --- a/tests/test_postprocess.py +++ b/tests/test_postprocess.py @@ -61,7 +61,7 @@ def test_include_projection_coordinates(sample_dataset): @pytest.mark.parametrize( - 'sample_dataset', set(xwrf.tutorial.sample_datasets.keys()) - {'tiny'}, indirect=True + 'sample_dataset', set(xwrf.tutorial.sample_datasets.keys()) - {'tiny', 'ideal'}, indirect=True ) def test_grid_mapping_is_in_all_vars(sample_dataset): dataset = xwrf.postprocess._include_projection_coordinates(sample_dataset) diff --git a/xwrf/grid.py b/xwrf/grid.py index 3ef133b..40e9c34 100644 --- a/xwrf/grid.py +++ b/xwrf/grid.py @@ -38,7 +38,10 @@ def _wrf_grid_from_dataset(ds: xr.Dataset) -> Mapping[Hashable, pyproj.CRS | np. 'center_lon': cen_lon, } - if proj_id == 1: + if proj_id == 0: + # Idealized Run, Cartesian grid + pass + elif proj_id == 1: # Lambert pargs['proj'] = 'lcc' del pargs['center_lon'] @@ -57,14 +60,20 @@ def _wrf_grid_from_dataset(ds: xr.Dataset) -> Mapping[Hashable, pyproj.CRS | np. else: raise NotImplementedError(f'WRF proj not implemented yet: {proj_id}') - # Construct the pyproj CRS (letting errors fail through) - crs = pyproj.CRS(pargs) + if proj_id == 0: + # As this is an idealized run, there is no physical CRS + crs = None + e, n = cen_lon, cen_lat + else: + # Construct the pyproj CRS (letting errors fail through) + crs = pyproj.CRS(pargs) + + # Get grid specifications + trf = pyproj.Transformer.from_crs(wgs84, crs, always_xy=True) + e, n = trf.transform(cen_lon, cen_lat) - # Get grid specifications - trf = pyproj.Transformer.from_crs(wgs84, crs, always_xy=True) nx = ds.sizes['west_east'] ny = ds.sizes['south_north'] - e, n = trf.transform(cen_lon, cen_lat) x0 = -(nx - 1) / 2.0 * dx + e # DL corner y0 = -(ny - 1) / 2.0 * dy + n # DL corner diff --git a/xwrf/postprocess.py b/xwrf/postprocess.py index 2d7ccf2..ecfe012 100644 --- a/xwrf/postprocess.py +++ b/xwrf/postprocess.py @@ -105,11 +105,12 @@ def _include_projection_coordinates(ds: xr.Dataset) -> xr.Dataset: for dim in horizontal_dims: ds[dim] = (dim, grid_components[dim], config.get(f'cf_attribute_map.{dim}')) - # Include CRS - ds['wrf_projection'] = (tuple(), grid_components['crs'], grid_components['crs'].to_cf()) - for varname in ds.data_vars: - if any(dim in ds[varname].dims for dim in horizontal_dims): - ds[varname].attrs['grid_mapping'] = 'wrf_projection' + # Include CRS if we don't have idealized coords + if grid_components['crs'] is not None: + ds['wrf_projection'] = (tuple(), grid_components['crs'], grid_components['crs'].to_cf()) + for varname in ds.data_vars: + if any(dim in ds[varname].dims for dim in horizontal_dims): + ds[varname].attrs['grid_mapping'] = 'wrf_projection' return ds diff --git a/xwrf/tutorial.py b/xwrf/tutorial.py index b2e0a99..b0d87ad 100644 --- a/xwrf/tutorial.py +++ b/xwrf/tutorial.py @@ -38,6 +38,7 @@ def _construct_cache_dir(path): 'tiny': 'data/tiny.nc', 'met_em_sample': 'data/met_em.d01.2005-08-28_12:00:00.nc', 'wrfout': 'data/wrfout_d01_2099-10-01_00:00:00.nc', + 'ideal': 'data/ideal.nc', } @@ -65,6 +66,7 @@ def open_dataset( * ``"mercator"`` * ``"met_em_sample"`` * ``"wrfout"`` + * ``"ideal"`` Parameters ----------