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

Update w2w.py #21

Merged
merged 3 commits into from
Dec 14, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion tests/w2w_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
from w2w.w2w import main
from w2w.w2w import check_lcz_wrf_extent
from w2w.w2w import wrf_remove_urban
from w2w.w2w import main
from w2w.w2w import create_wrf_gridinfo
from w2w.w2w import calc_distance_coord
import xarray


Expand Down Expand Up @@ -120,3 +120,17 @@ def test_full_run_with_example_data(tmpdir):
assert 'geo_em.d04_LCZ_params.nc' in contents
assert 'geo_em.d04_NoUrban.nc' in contents
assert 'geo_em.d04_LCZ_extent.nc' in contents


@pytest.mark.parametrize(
('coords', 'expected'),
(
pytest.param((89, 0, 90, 1), 111194, id='near northern pole'),
pytest.param((-89, 0, -90, 1), 111194, id='near southern pole'),
pytest.param((-60, -10, -70, -12), 1115764, id='southern eastern hemisphere'),
pytest.param((-1, 0, 1, 2), 314498, id='across equator'),
pytest.param((45, 179, 46, -179), 191461, id='across dateline')
),
)
def test_calc_distance_coord(coords, expected):
assert calc_distance_coord(*coords) == pytest.approx(expected, abs=1)
63 changes: 44 additions & 19 deletions w2w/w2w.py
Original file line number Diff line number Diff line change
Expand Up @@ -225,40 +225,46 @@ def wrf_remove_urban(
for i in dst_data.south_north:
for j in dst_data.west_east:
if luse.isel(south_north=i,west_east=j) == 13:
dis = (lat.where((luse!=13) &
(luse!=17) &
(luse!=21)
)-lat.isel(south_north=i,west_east=j))**2 +\
(lon.where((luse!=13) &
(luse!=17) &
(luse!=21)
)-lon.isel(south_north=i,west_east=j))**2

dis = calc_distance_coord(
lat.where((luse!=13) & (luse!=17) & (luse!=21)),
lon.where((luse!=13) & (luse!=17) & (luse!=21)),
lat.isel(south_north=i,west_east=j),
lon.isel(south_north=i,west_east=j)
)

disflat = dis.stack(gridpoints=('south_north','west_east'))\
.reset_index('gridpoints').drop_vars(['south_north','west_east'])
aux = luse.where(dis<disflat.sortby(disflat)
aux = luse.where(dis<=disflat.sortby(disflat)
.isel(gridpoints=NPIX_NLC),drop=True)
m = stats.mode(aux.values.flatten(), nan_policy="omit")[0]
newluse[i, j] = int(m)

auxg = greenf.where(dis<disflat.sortby(disflat)
auxg = greenf.where(dis<=disflat.sortby(disflat)
.isel(gridpoints=NPIX_NLC),drop=True)\
.where(aux==newluse[i,j]).mean(dim=['south_north','west_east'])
newgreenf[:,i,j]=auxg

if luf.isel(south_north=i,west_east=j,land_cat=12)>0.:
dis = (lat.where((luf.isel(land_cat=12)==0.) &
(luf.isel(land_cat=16)==0.) &
(luf.isel(land_cat=20)==0.)
)-lat.isel(south_north=i,west_east=j))**2 +\
(lon.where((luf.isel(land_cat=12)==0.) &
(luf.isel(land_cat=16)==0.) &
(luf.isel(land_cat=20)==0.)
)-lon.isel(south_north=i,west_east=j))**2
dis = calc_distance_coord(
lat.where(
(luf.isel(land_cat=12)==0.) &
(luf.isel(land_cat=16)==0.) &
(luf.isel(land_cat=20)==0.)
),

lon.where(
(luf.isel(land_cat=12)==0.) &
(luf.isel(land_cat=16)==0.) &
(luf.isel(land_cat=20)==0.)
),
lat.isel(south_north=i,west_east=j),
lon.isel(south_north=i,west_east=j)
)

disflat = dis.stack(gridpoints=('south_north','west_east'))\
.reset_index('gridpoints').drop_vars(['south_north','west_east'])
aux = luse.where(dis<disflat.sortby(disflat)
aux = luse.where(dis<=disflat.sortby(disflat)
.isel(gridpoints=NPIX_NLC),drop=True)
m = stats.mode(aux.values.flatten(), nan_policy="omit")[0]
newlu = int(m) - 1
Expand Down Expand Up @@ -948,6 +954,25 @@ def add_urb_params_to_wrf(

return nbui_max

def calc_distance_coord(
lat1,lon1,lat2,lon2
):

'''Calculate distance using coordinates
This uses the spherical law of cosines
'''

earth_radius=6371000 #Earth radius in m
lat1r = lat1*np.pi/180.
lat2r = lat2*np.pi/180.
lon1r = lon1*np.pi/180.
lon2r = lon2*np.pi/180.

d = np.arccos(np.sin(lat1r)*np.sin(lat2r) + np.cos(lat1r)*np.cos(lat2r)*np.cos(lon2r-lon1r))*earth_radius

return d


jkittner marked this conversation as resolved.
Show resolved Hide resolved
def create_extent_file(
info,
frc_mask,
Expand Down