def test_lonRange0To360_outOfBounds(self): """ Tests that lon_range_0_to_360 aborts gracefully when lon = 361 """ with self.assertRaisesRegex( SystemExit, "lon_in needs to be in the range 0 to 360"): _ = lon_range_0_to_360(361)
def test_lonRange0To360_lonIs360(self): """ Tests that input to lon_range_0_to_360 of 360 remains unchanged """ inval = 360 result = lon_range_0_to_360(inval) self.assertEqual(result, inval)
def test_lonRange0To360_lonIsNegGreaterThan1(self): """ Tests that negative inputs to lon_range_0_to_360 get 360 added to them """ inval = -0.001 result = lon_range_0_to_360(inval) self.assertEqual(result, inval + 360)
def _get_not_rectangle(lon_1, lon_2, lat_1, lat_2, longxy, latixy): """ Description ----------- """ # ensure that lon ranges 0-360 in case user entered -180 to 180 lon_1 = lon_range_0_to_360(lon_1) lon_2 = lon_range_0_to_360(lon_2) # determine the rectangle(s) # TODO This is not really "nearest" for the edges but isel didn't work rectangle_1 = (longxy >= lon_1) rectangle_2 = (longxy <= lon_2) eps = np.finfo(np.float32).eps # to avoid roundoff issue rectangle_3 = (latixy >= (lat_1 - eps)) rectangle_4 = (latixy <= (lat_2 + eps)) if lon_1 <= lon_2: # rectangles overlap union_1 = np.logical_and(rectangle_1, rectangle_2) else: # rectangles don't overlap: stradling the 0-degree meridian union_1 = np.logical_or(rectangle_1, rectangle_2) if lat_1 < -90 or lat_1 > 90 or lat_2 < -90 or lat_2 > 90: errmsg = 'lat_1 and lat_2 need to be in the range -90 to 90' abort(errmsg) elif lat_1 <= lat_2: # rectangles overlap union_2 = np.logical_and(rectangle_3, rectangle_4) else: # rectangles don't overlap: one in the north, one in the south union_2 = np.logical_or(rectangle_3, rectangle_4) # union rectangles overlap rectangle = np.logical_and(union_1, union_2) not_rectangle = np.logical_not(rectangle) return not_rectangle
def plon_type(plon): """ Function to define lon type for the parser and convert negative longitudes to 0-360 and raise error if lon is not between -180 and 360. Args: plon (str): longitude Raises: Error (ArgumentTypeError): when longitude is <-180 and >360. Returns: plon_out (float): converted longitude between 0 and 360 """ plon_float = float(plon) if plon_float < -180 or plon_float > 360: raise argparse.ArgumentTypeError( "ERROR: Longitude should be between 0 and 360 or -180 and 180." ) plon_out = lon_range_0_to_360(plon_float) return plon_out
def _get_longxy_latixy(self, _min_lon, _max_lon, _min_lat, _max_lat): """ Return longxy, latixy, cols, rows """ cols = _max_lon - _min_lon + 1 rows = _max_lat - _min_lat + 1 long = np.arange(_min_lon, _max_lon + 1) long = [lon_range_0_to_360(longitude) for longitude in long] longxy = long * np.ones((rows, cols)) compare = np.repeat([long], rows, axis=0) # alternative way to form # assert this to confirm intuitive understanding of these matrices np.testing.assert_array_equal(longxy, compare) lati = np.arange(_min_lat, _max_lat + 1) self.assertEqual(min(lati), _min_lat) self.assertEqual(max(lati), _max_lat) latixy_transp = lati * np.ones((cols, rows)) compare = np.repeat([lati], cols, axis=0) # alternative way to form # assert this to confirm intuitive understanding of these matrices np.testing.assert_array_equal(latixy_transp, compare) latixy = np.transpose(latixy_transp) return longxy, latixy, cols, rows