11import os
2+ from datetime import datetime
23
4+ import cftime
35import numpy as np
46import pytest
7+ import xarray as xr
58
6- from xarray_subset_grid .utils import (
7- normalize_bbox_x_coords ,
8- normalize_polygon_x_coords ,
9- ray_tracing_numpy ,
10- )
9+ import xarray_subset_grid .utils as xsg_utils
1110
1211# normalize_polygon_x_coords tests.
1312
@@ -69,12 +68,7 @@ def get_test_file_dir():
6968)
7069def test_normalize_x_coords (lons , poly , norm_poly ):
7170 lons = np .array (lons )
72- normalized_polygon = normalize_polygon_x_coords (lons , np .array (poly ))
73- print (f"{ lons = } " )
74- print (f"{ poly = } " )
75- print (f"{ norm_poly = } " )
76- print (f"{ normalized_polygon = } " )
77-
71+ normalized_polygon = xsg_utils .normalize_polygon_x_coords (lons , np .array (poly ))
7872 assert np .allclose (normalized_polygon , norm_poly )
7973
8074
@@ -97,7 +91,7 @@ def test_normalize_x_coords(lons, poly, norm_poly):
9791)
9892def test_normalize_x_coords_bbox (lons , bbox , norm_bbox ):
9993 lons = np .array (lons )
100- normalized_polygon = normalize_bbox_x_coords (lons , bbox )
94+ normalized_polygon = xsg_utils . normalize_bbox_x_coords (lons , bbox )
10195 assert np .allclose (normalized_polygon , norm_bbox )
10296
10397
@@ -122,6 +116,82 @@ def test_ray_tracing_numpy():
122116 ]
123117 )
124118
125- result = ray_tracing_numpy (points [:, 0 ], points [:, 1 ], poly )
119+ result = xsg_utils . ray_tracing_numpy (points [:, 0 ], points [:, 1 ], poly )
126120
127121 assert np .array_equal (result , [False , True , False ])
122+
123+
124+ @pytest .mark .parametrize (
125+ "num, unit" ,
126+ [
127+ (512 , "bytes" ),
128+ (2048 , "KB" ),
129+ (3 * 1024 ** 2 , "MB" ),
130+ ],
131+ )
132+ def test_format_bytes (num , unit ):
133+ assert unit in xsg_utils .format_bytes (num )
134+
135+
136+ def test_asdatetime_none ():
137+ assert xsg_utils .asdatetime (None ) is None
138+
139+
140+ def test_asdatetime_datetime_passthrough ():
141+ dt = datetime (2020 , 6 , 15 , 12 , 30 , 0 )
142+ assert xsg_utils .asdatetime (dt ) is dt
143+
144+
145+ def test_asdatetime_cftime_passthrough ():
146+ dt = cftime .datetime (2020 , 6 , 15 , 12 )
147+ assert xsg_utils .asdatetime (dt ) is dt
148+
149+
150+ def test_asdatetime_parse_string ():
151+ dt = xsg_utils .asdatetime ("2020-06-15T12:30:00" )
152+ assert dt .year == 2020 and dt .month == 6 and dt .day == 15
153+
154+
155+ def test_compute_2d_subset_mask_all_inside ():
156+ ny , nx = 5 , 5
157+ lat = np .linspace (40.0 , 44.0 , ny )
158+ lon = np .linspace (- 74.0 , - 70.0 , nx )
159+ lat2d , lon2d = np .meshgrid (lat , lon , indexing = "ij" )
160+ lat_da = xr .DataArray (lat2d , dims = ("y" , "x" ))
161+ lon_da = xr .DataArray (lon2d , dims = ("y" , "x" ))
162+ poly = np .array ([(- 75.0 , 39.0 ), (- 69.0 , 39.0 ), (- 69.0 , 45.0 ), (- 75.0 , 45.0 )])
163+ mask = xsg_utils .compute_2d_subset_mask (lat_da , lon_da , poly )
164+ assert mask .dims == ("y" , "x" )
165+ assert mask .all ()
166+
167+
168+ def test_compute_2d_subset_mask_partial ():
169+ # Include explicit lon/lat nodes inside the polygon so the mask can be checked at a
170+ # non-boundary grid point (ray-casting is ambiguous on polygon edges).
171+ lat = np .array ([40.0 , 40.5 , 41.0 , 43.0 , 46.0 ])
172+ lon = np .array ([- 74.5 , - 73.75 , - 73.0 , - 71.0 , - 68.0 ])
173+ lat2d , lon2d = np .meshgrid (lat , lon , indexing = "ij" )
174+ lat_da = xr .DataArray (lat2d , dims = ("y" , "x" ))
175+ lon_da = xr .DataArray (lon2d , dims = ("y" , "x" ))
176+ poly = np .array ([(- 74.5 , 40.0 ), (- 73.0 , 40.0 ), (- 73.0 , 41.0 ), (- 74.5 , 41.0 )])
177+ mask = xsg_utils .compute_2d_subset_mask (lat_da , lon_da , poly )
178+ assert mask .dims == ("y" , "x" )
179+ assert mask .any ()
180+ assert not mask .all ()
181+ i_inside = int (np .where (lat == 40.5 )[0 ][0 ])
182+ j_inside = int (np .where (lon == - 73.75 )[0 ][0 ])
183+ assert mask .values [i_inside , j_inside ]
184+ assert not mask .values [- 1 , - 1 ]
185+
186+
187+ def test_compute_2d_subset_mask_list_polygon_coerced ():
188+ """list/tuple polygon vertices are accepted (coerced via normalize_polygon_x_coords)."""
189+ ny , nx = 5 , 5
190+ lat = np .linspace (40.0 , 44.0 , ny )
191+ lon = np .linspace (- 74.0 , - 70.0 , nx )
192+ lat2d , lon2d = np .meshgrid (lat , lon , indexing = "ij" )
193+ lat_da = xr .DataArray (lat2d , dims = ("y" , "x" ))
194+ lon_da = xr .DataArray (lon2d , dims = ("y" , "x" ))
195+ poly = [(- 75.0 , 39.0 ), (- 69.0 , 39.0 ), (- 69.0 , 45.0 ), (- 75.0 , 45.0 )]
196+ mask = xsg_utils .compute_2d_subset_mask (lat_da , lon_da , poly )
197+ assert mask .all ()
0 commit comments