예제 #1
0
def test_load_variable_non_0001_refdate(load_variable_data_loader, year):
    def preprocess(ds, **kwargs):
        # This function converts our testing data (encoded with a units
        # attribute with a reference data of 0001-01-01) to one
        # with a reference data of 0004-01-01 (to do so we also need
        # to offset the raw time values by three years).
        three_yrs = 1095.
        ds['time'] = ds['time'] - three_yrs
        ds['time'].attrs['units'] = 'days since 0004-01-01 00:00:00'
        ds['time'].attrs['calendar'] = 'noleap'
        ds['time_bounds'] = ds['time_bounds'] - three_yrs
        ds['time_bounds'].attrs['units'] = 'days since 0004-01-01 00:00:00'
        ds['time_bounds'].attrs['calendar'] = 'noleap'
        return ds

    load_variable_data_loader.preprocess_func = preprocess

    result = load_variable_data_loader.load_variable(
        condensation_rain,
        DatetimeNoLeap(year, 1, 1),
        DatetimeNoLeap(year, 12, 31),
        intvl_in='monthly')
    filepath = os.path.join(
        os.path.split(ROOT_PATH)[0], 'netcdf',
        '000{}0101.precip_monthly.nc'.format(year))
    expected = xr.open_dataset(filepath)['condensation_rain']
    np.testing.assert_allclose(result.values, expected.values)
예제 #2
0
def test_load_variable_preprocess(load_variable_data_loader):
    def preprocess(ds, **kwargs):
        if kwargs['start_date'] == DatetimeNoLeap(5, 1, 1):
            ds['condensation_rain'] = 10. * ds['condensation_rain']
        return ds

    load_variable_data_loader.preprocess_func = preprocess

    result = load_variable_data_loader.load_variable(condensation_rain,
                                                     DatetimeNoLeap(5, 1, 1),
                                                     DatetimeNoLeap(5, 12, 31),
                                                     intvl_in='monthly')
    filepath = os.path.join(
        os.path.split(ROOT_PATH)[0], 'netcdf', '00050101.precip_monthly.nc')
    expected = 10. * xr.open_dataset(filepath)['condensation_rain']
    np.testing.assert_allclose(result.values, expected.values)

    result = load_variable_data_loader.load_variable(condensation_rain,
                                                     DatetimeNoLeap(4, 1, 1),
                                                     DatetimeNoLeap(4, 12, 31),
                                                     intvl_in='monthly')
    filepath = os.path.join(
        os.path.split(ROOT_PATH)[0], 'netcdf', '00040101.precip_monthly.nc')
    expected = xr.open_dataset(filepath)['condensation_rain']
    np.testing.assert_allclose(result.values, expected.values)
예제 #3
0
def test_recursively_compute_grid_attr_error(load_variable_data_loader):
    # Should fail because zsurf is not provided to the example_model object
    zsurf = Var(name=ZSURF_STR, def_time=False, def_vert=False,
                def_lon=True, def_lat=True)
    with pytest.raises(AttributeError):
        load_variable_data_loader.recursively_compute_variable(
            zsurf, DatetimeNoLeap(5, 1, 1),
            DatetimeNoLeap(5, 12, 31), model=example_model,
            intvl_in='monthly')
예제 #4
0
def test_recursively_compute_grid_attr(load_variable_data_loader):
    result = load_variable_data_loader.recursively_compute_variable(
        bk, DatetimeNoLeap(5, 1, 1),
        DatetimeNoLeap(5, 12, 31), model=example_model,
        intvl_in='monthly')
    filepath = os.path.join(os.path.split(ROOT_PATH)[0], 'netcdf',
                            '00060101.sphum_monthly.nc')
    expected = _open_ds_catch_warnings(filepath)['bk']
    np.testing.assert_array_equal(result.values, expected.values)
예제 #5
0
def test_recursively_compute_variable_native(load_variable_data_loader):
    result = load_variable_data_loader.recursively_compute_variable(
        condensation_rain, DatetimeNoLeap(5, 1, 1),
        DatetimeNoLeap(5, 12, 31),
        intvl_in='monthly')
    filepath = os.path.join(os.path.split(ROOT_PATH)[0], 'netcdf',
                            '00050101.precip_monthly.nc')
    expected = _open_ds_catch_warnings(filepath)['condensation_rain']
    np.testing.assert_array_equal(result.values, expected.values)
예제 #6
0
def test_recursively_compute_variable_one_level(load_variable_data_loader):
    one_level = Var(
        name='one_level', variables=(condensation_rain, condensation_rain),
        func=lambda x, y: x + y)
    result = load_variable_data_loader.recursively_compute_variable(
        one_level, DatetimeNoLeap(5, 1, 1), DatetimeNoLeap(5, 12, 31),
        intvl_in='monthly')
    filepath = os.path.join(os.path.split(ROOT_PATH)[0], 'netcdf',
                            '00050101.precip_monthly.nc')
    expected = 2. * _open_ds_catch_warnings(filepath)['condensation_rain']
    np.testing.assert_array_equal(result.values, expected.values)
예제 #7
0
def test_recursively_compute_grid_attr_multi_level(load_variable_data_loader):
    one_level = Var(name='one_level', variables=(bk, ), func=lambda x: 2 * x)
    multi_level = Var(name='multi_level',
                      variables=(one_level, bk),
                      func=lambda x, y: x + y)
    result = load_variable_data_loader.recursively_compute_variable(
        multi_level,
        DatetimeNoLeap(5, 1, 1),
        DatetimeNoLeap(5, 12, 31),
        model=example_model,
        intvl_in='monthly')
    filepath = os.path.join(
        os.path.split(ROOT_PATH)[0], 'netcdf', '00060101.sphum_monthly.nc')
    expected = 3 * xr.open_dataset(filepath)['bk']
    np.testing.assert_array_equal(result.values, expected.values)
예제 #8
0
    def __init__(self, ncpath1, ncpath2, tim1, tim2, ppt1, ppt2):

        mpersec_to_mmperday = 86400000.

        self.tim1 = tim1
        self.tim2 = tim2

        # open as xarray dataset
        self.ncmod1 = xr.open_dataset(ncpath1)
        self.ncmod2 = xr.open_dataset(ncpath2)
        var_ppt1 = self.ncmod1[ppt1]
        var_ppt2 = self.ncmod2[ppt2]
        self.var = (var_ppt1 + var_ppt2) * mpersec_to_mmperday

        # modify time coordinate for CESM (1 month backwards)
        oldtime = self.var['time']
        newtime_beg = DatetimeNoLeap(oldtime.dt.year[0],
                                     oldtime.dt.month[0] - 1,
                                     oldtime.dt.day[0])
        newtime = xr.cftime_range(start=newtime_beg,
                                  periods=np.shape(oldtime)[0],
                                  freq='MS',
                                  calendar='noleap')
        self.var = self.var.assign_coords(time=newtime)

        # time subset
        # this subsetting allows for DJF mean that includes only D of the firt year and JF of the last year plus one
        self.vtsub = self.var.sel(
            time=slice(str(self.tim1) + '-03-01',
                       str(self.tim2) + '-02-01'))
예제 #9
0
    def __init__(self, ncpath, tim1, tim2, varcode, zm=False):

        self.tim1 = tim1
        self.tim2 = tim2

        # open as xarray dataset
        self.ncmod = xr.open_dataset(ncpath)
        self.var = self.ncmod[varcode]

        # modify time coordinate for CESM (1 month backwards)
        oldtime = self.var['time']
        newtime_beg = DatetimeNoLeap(oldtime.dt.year[0],
                                     oldtime.dt.month[0] - 1,
                                     oldtime.dt.day[0])
        newtime = xr.cftime_range(start=newtime_beg,
                                  periods=np.shape(oldtime)[0],
                                  freq='MS',
                                  calendar='noleap')
        self.var = self.var.assign_coords(time=newtime)

        # time subset
        # this subsetting allows for DJF mean that includes only D of the firt year and JF of the last year plus one
        self.vtsub = self.var.sel(
            time=slice(str(self.tim1) + '-03-01',
                       str(self.tim2) + '-02-01'))

        # if zonal mean
        if zm:
            self.vtsub = self.vtsub.isel(lon=0)

        # fill in missing values
        self.vtsub = self.vtsub.fillna(0)
예제 #10
0
def test_parse_array_of_cftime_strings():
    from cftime import DatetimeNoLeap

    strings = np.array(['2000-01-01', '2000-01-02'])
    expected = np.array(
        [DatetimeNoLeap(2000, 1, 1),
         DatetimeNoLeap(2000, 1, 2)])

    result = _parse_array_of_cftime_strings(strings, DatetimeNoLeap)
    np.testing.assert_array_equal(result, expected)

    # Test scalar array case
    strings = np.array('2000-01-01')
    expected = np.array(DatetimeNoLeap(2000, 1, 1))
    result = _parse_array_of_cftime_strings(strings, DatetimeNoLeap)
    np.testing.assert_array_equal(result, expected)
예제 #11
0
def test_load_variable_mask_and_scale(load_variable_data_loader):
    def convert_all_to_missing_val(ds, **kwargs):
        ds['condensation_rain'] = 0. * ds['condensation_rain'] + 1.0e20
        ds['condensation_rain'].attrs['_FillValue'] = 1.0e20
        return ds

    load_variable_data_loader.preprocess_func = convert_all_to_missing_val

    data = load_variable_data_loader.load_variable(condensation_rain,
                                                   DatetimeNoLeap(5, 1, 1),
                                                   DatetimeNoLeap(5, 12, 31),
                                                   intvl_in='monthly')

    num_non_missing = np.isfinite(data).sum().item()
    expected_num_non_missing = 0
    assert num_non_missing == expected_num_non_missing
예제 #12
0
def test_parse_array_of_cftime_strings():
    from cftime import DatetimeNoLeap

    strings = np.array([["2000-01-01", "2000-01-02"], ["2000-01-03", "2000-01-04"]])
    expected = np.array(
        [
            [DatetimeNoLeap(2000, 1, 1), DatetimeNoLeap(2000, 1, 2)],
            [DatetimeNoLeap(2000, 1, 3), DatetimeNoLeap(2000, 1, 4)],
        ]
    )

    result = _parse_array_of_cftime_strings(strings, DatetimeNoLeap)
    np.testing.assert_array_equal(result, expected)

    # Test scalar array case
    strings = np.array("2000-01-01")
    expected = np.array(DatetimeNoLeap(2000, 1, 1))
    result = _parse_array_of_cftime_strings(strings, DatetimeNoLeap)
    np.testing.assert_array_equal(result, expected)
예제 #13
0
    def setUp(self):
        self.date1_365_day = DatetimeNoLeap(-5000, 1, 2, 12)
        self.date2_365_day = DatetimeNoLeap(-5000, 1, 3, 12)
        self.date3_gregorian = DatetimeGregorian(1969, 7, 20, 12)

        # last day of the Julian calendar in the mixed Julian/Gregorian calendar
        self.date4_gregorian = DatetimeGregorian(1582, 10, 4)
        # first day of the Gregorian calendar in the mixed Julian/Gregorian calendar
        self.date5_gregorian = DatetimeGregorian(1582, 10, 15)

        self.date6_proleptic_gregorian = DatetimeProlepticGregorian(
            1582, 10, 15)

        self.date7_360_day = Datetime360Day(2000, 1, 1)

        self.date8_julian = DatetimeJulian(1582, 10, 4)

        # a datetime.datetime instance (proleptic Gregorian calendar)
        self.datetime_date1 = datetime(1969, 7, 21, 12)

        self.delta = timedelta(hours=25)
def preprocess(filename, varcode, tim1, tim2, vertical=False):

    # extract variable
    var = xr.open_dataset(filename)[varcode]

    # modify time coordinate for CESM (1 month backwards)
    oldtime = var['time']
    newtime_beg = DatetimeNoLeap(oldtime.dt.year[0], oldtime.dt.month[0] - 1,
                                 oldtime.dt.day[0])
    newtime = xr.cftime_range(start=newtime_beg,
                              periods=np.shape(oldtime)[0],
                              freq='MS',
                              calendar='noleap')
    var = var.assign_coords(time=newtime)

    # time subset - start in March, end in February
    var = var.sel(time=slice(str(tim1) + '-03-01', str(tim2) + '-02-01'))

    # Adjust lon values to make sure they are within (-180, 180)
    lon_name = 'lon'

    var['_longitude_adjusted'] = xr.where(var[lon_name] > 180,
                                          var[lon_name] - 360, var[lon_name])

    # reassign the new coords to as the main lon coords
    # and sort DataArray using new coordinate values
    var = (var.swap_dims({
        lon_name: '_longitude_adjusted'
    }).sel(**{
        '_longitude_adjusted': sorted(var._longitude_adjusted)
    }).drop(lon_name))

    var = var.rename({'_longitude_adjusted': lon_name})

    # latitude subset
    #var = var.sel(lat=slice(20,80), lon=slice(-90,40))

    # convert variable and dimensions to numpy arrays
    npvar = var.values
    nptime = var['time'].values
    nplat = var['lat'].values
    nplon = var['lon'].values
    if vertical:
        nplev = var['level'].values

    # for cos latitude weighting later
    coslat = np.cos(np.deg2rad(nplat))

    return (npvar, nptime, nplev, nplat, nplon,
            coslat) if vertical else (npvar, nptime, nplat, nplon, coslat)
예제 #15
0
def rm_leap(data: xr.DataArray) -> xr.DataArray:
    """Remove lear days and replace time axis with cftime.DatetimeNoLeap."""
    february = 2
    leap_day = 29
    data = data.sel(
        time=~((data.time.dt.month == february) & (data.time.dt.day == leap_day)),
    )
    days_since_first = np.cumsum(
        np.append(data.time[1:].values - data.time[:-1].values, timedelta(1)),
    )
    data["time"] = [
        DatetimeNoLeap(*data.time[0].values.tolist().timetuple()) + dt
        for dt in days_since_first
    ]

    return data
예제 #16
0
def test_fieldset_nonstandardtime(calendar, tmpdir, filename='test_nonstandardtime.nc', xdim=4, ydim=6):
    from cftime import DatetimeNoLeap, Datetime360Day
    filepath = tmpdir.join(filename)

    if calendar == 'noleap':
        dates = [DatetimeNoLeap(0, m, 1) for m in range(1, 13)]
    else:
        dates = [Datetime360Day(0, m, 1) for m in range(1, 13)]
    da = xr.DataArray(np.random.rand(12, xdim, ydim),
                      coords=[dates, range(xdim), range(ydim)],
                      dims=['time', 'lon', 'lat'], name='U')
    da.to_netcdf(str(filepath))

    dims = {'lon': 'lon', 'lat': 'lat', 'time': 'time'}
    field = Field.from_netcdf(filepath, 'U', dims)
    assert field.grid.time_origin.calendar == 'cftime'
예제 #17
0
   def __init__(self, ncpath='', tim1='', tim2='', var=''):
        
       self.tim1 = tim1
       self.tim2 = tim2

       # open as xarray dataset
       self.ncmod = xr.open_dataset(ncpath)
       self.var = self.ncmod[var]

       # modify time coordinate for CESM (1 month backwards)
       oldtime = self.var['time']
       newtime_beg = DatetimeNoLeap(oldtime.dt.year[0],oldtime.dt.month[0]-1,oldtime.dt.day[0])
       newtime = xr.cftime_range(start=newtime_beg, periods=np.shape(oldtime)[0], freq='MS', calendar='noleap')
       self.var = self.var.assign_coords(time=newtime)
       #self.var, self.dimdict = basic_functions.extract_var_dims(ncpath, varname='TREFHT', xlonname='lon', xlatname='lat', xtimname='time')
       #self.var = self.var.isel(lat=slice(0,2), lon=slice(0,2))

       yr_to_dec = 10
예제 #18
0
    def __init__(self, ncpath1, ncpath2, tim1, tim2, ppt1, ppt2):
        
        mpersec_to_mmperday = 86400000.

        self.tim1 = tim1
        self.tim2 = tim2
        
        # open as xarray dataset
        self.ncmod1 = xr.open_dataset(ncpath1)
        self.ncmod2 = xr.open_dataset(ncpath2)
        var_ppt1 = self.ncmod1[ppt1]
        var_ppt2 = self.ncmod2[ppt2]
        self.var = (var_ppt1 + var_ppt2)*mpersec_to_mmperday

        # modify time coordinate for CESM (1 month backwards)
        oldtime = self.var['time']
        newtime_beg = DatetimeNoLeap(oldtime.dt.year[0],oldtime.dt.month[0]-1,oldtime.dt.day[0])
        newtime = xr.cftime_range(start=newtime_beg, periods=np.shape(oldtime)[0], freq='MS', calendar='noleap')
        self.var = self.var.assign_coords(time=newtime)
예제 #19
0
    def setUp(self):
        self.date1_365_day = DatetimeNoLeap(-5000, 1, 2, 12)
        self.date2_365_day = DatetimeNoLeap(-5000, 1, 3, 12)
        self.date3_gregorian = DatetimeGregorian(1969,  7, 20, 12)

        # last day of the Julian calendar in the mixed Julian/Gregorian calendar
        self.date4_gregorian = DatetimeGregorian(1582, 10, 4)
        # first day of the Gregorian calendar in the mixed Julian/Gregorian calendar
        self.date5_gregorian = DatetimeGregorian(1582, 10, 15)

        self.date6_proleptic_gregorian = DatetimeProlepticGregorian(1582, 10, 15)

        self.date7_360_day = Datetime360Day(2000, 1, 1)

        self.date8_julian = DatetimeJulian(1582, 10, 4)

        # a datetime.datetime instance (proleptic Gregorian calendar)
        self.datetime_date1 = datetime(1969,  7, 21, 12)

        self.delta = timedelta(hours=25)
예제 #20
0
   def __init__(self, ncpath='', tim1='', tim2='', var=''):
        
       self.tim1 = tim1
       self.tim2 = tim2

       # open as xarray dataset
       self.ncmod = xr.open_dataset(ncpath)
       self.var = self.ncmod[var]

       # zonal mean - choose single longitude 
       self.var = self.var.isel(lon=0)

       # modify time coordinate for CESM (1 month backwards)
       oldtime = self.var['time']
       newtime_beg = DatetimeNoLeap(oldtime.dt.year[0],oldtime.dt.month[0]-1,oldtime.dt.day[0])
       newtime = xr.cftime_range(start=newtime_beg, periods=np.shape(oldtime)[0], freq='MS', calendar='noleap')
       self.var = self.var.assign_coords(time=newtime)

       self.var = self.var.fillna(0)

       self.trend_scaling = 30.
예제 #21
0
class DateTime(unittest.TestCase):
    def setUp(self):
        self.date1_365_day = DatetimeNoLeap(-5000, 1, 2, 12)
        self.date2_365_day = DatetimeNoLeap(-5000, 1, 3, 12)
        self.date3_gregorian = DatetimeGregorian(1969,  7, 20, 12)

        # last day of the Julian calendar in the mixed Julian/Gregorian calendar
        self.date4_gregorian = DatetimeGregorian(1582, 10, 4)
        # first day of the Gregorian calendar in the mixed Julian/Gregorian calendar
        self.date5_gregorian = DatetimeGregorian(1582, 10, 15)

        self.date6_proleptic_gregorian = DatetimeProlepticGregorian(1582, 10, 15)

        self.date7_360_day = Datetime360Day(2000, 1, 1)

        self.date8_julian = DatetimeJulian(1582, 10, 4)

        # a datetime.datetime instance (proleptic Gregorian calendar)
        self.datetime_date1 = datetime(1969,  7, 21, 12)

        self.delta = timedelta(hours=25)

    def test_add(self):
        dt = self.date1_365_day
        # datetime + timedelta
        self.assertEqual(dt + self.delta, # add 25 hours
                         dt.replace(day=dt.day + 1, hour=dt.hour + 1))

        # timedelta + datetime
        self.assertEqual(self.delta + dt, # add 25 hours
                         dt.replace(day=dt.day + 1, hour=dt.hour + 1))

        # test the Julian/Gregorian transition
        self.assertEqual(self.date4_gregorian + self.delta,
                         DatetimeGregorian(1582, 10, 15, 1))

        # The Julian calendar has no invalid dates
        self.assertEqual(self.date8_julian + self.delta,
                         DatetimeJulian(1582, 10, 5, 1))

        # Test going over the year boundary.
        self.assertEqual(DatetimeGregorian(2000, 11, 1) + timedelta(days=30 + 31),
                         DatetimeGregorian(2001, 1, 1))

        # Year 2000 is a leap year.
        self.assertEqual(DatetimeGregorian(2000, 1, 1) + timedelta(days=31 + 29),
                         DatetimeGregorian(2000, 3, 1))

        # Test the 366_day calendar.
        self.assertEqual(DatetimeAllLeap(1, 1, 1) + timedelta(days=366 * 10 + 31),
                         DatetimeAllLeap(11, 2, 1))

        # The Gregorian calendar has no year zero.
        self.assertEqual(DatetimeGregorian(-1, 12, 31) + self.delta,
                         DatetimeGregorian(1, 1, 1, 1))

        def invalid_add_1():
            self.date1_365_day + 1

        def invalid_add_2():
            1 + self.date1_365_day

        for func in [invalid_add_1, invalid_add_2]:
            self.assertRaises(TypeError, func)

    def test_sub(self):
        # subtracting a timedelta
        previous_day = self.date1_365_day - self.delta
        self.assertEqual(previous_day.day, self.date1_365_day.day - 1)

        def total_seconds(td):
            """Equivalent to td.total_seconds() on Python >= 2.7. See
            https://docs.python.org/2/library/datetime.html#datetime.timedelta.total_seconds
            """
            return (td.microseconds + (td.seconds + td.days * 24 * 3600) * 10**6) / 10**6

        # sutracting two netcdftime.datetime instances
        delta = self.date2_365_day - self.date1_365_day
        # date1 and date2 are exactly one day apart
        self.assertEqual(total_seconds(delta), 86400)

        # subtracting netcdftime.datetime from datetime.datetime
        delta = self.datetime_date1 - self.date3_gregorian
        # real_date2 and real_date1 are exactly one day apart
        self.assertEqual(total_seconds(delta), 86400)

        # subtracting datetime.datetime from netcdftime.datetime
        delta = self.date3_gregorian - self.datetime_date1
        # real_date2 and real_date1 are exactly one day apart
        self.assertEqual(total_seconds(delta), -86400)

        # Test the Julian/Gregorian transition.
        self.assertEqual(self.date5_gregorian - self.delta,
                         DatetimeGregorian(1582, 10, 3, 23))

        # The proleptic Gregorian calendar does not have invalid dates.
        self.assertEqual(self.date6_proleptic_gregorian - self.delta,
                         DatetimeProlepticGregorian(1582, 10, 13, 23))

        # The Gregorian calendar has no year zero.
        self.assertEqual(DatetimeGregorian(1, 1, 1) - self.delta,
                         DatetimeGregorian(-1, 12, 30, 23))

        # The 360_day calendar has year zero.

        self.assertEqual(self.date7_360_day - timedelta(days=2000 * 360),
                         Datetime360Day(0, 1, 1))

        # Test going over the year boundary.
        self.assertEqual(DatetimeGregorian(2000, 3, 1) - timedelta(days=29 + 31 + 31),
                         DatetimeGregorian(1999, 12, 1))

        # Year 2000 is a leap year.
        self.assertEqual(DatetimeGregorian(2000, 3, 1) - self.delta,
                         DatetimeGregorian(2000, 2, 28, 23))

        def invalid_sub_1():
            self.date1_365_day - 1

        def invalid_sub_2():
            1 - self.date1_365_day

        def invalid_sub_3():
            self.date1_365_day - self.datetime_date1

        def invalid_sub_4():
            self.datetime_date1 - self.date1_365_day

        def invalid_sub_5():
            self.date3_gregorian - self.date1_365_day

        for func in [invalid_sub_1, invalid_sub_2]:
            self.assertRaises(TypeError, func)

        for func in [invalid_sub_3, invalid_sub_4, invalid_sub_5]:
            self.assertRaises(ValueError, func)

    def test_replace(self):
        self.assertEqual(self.date1_365_day.replace(year=4000).year, 4000)
        self.assertEqual(self.date1_365_day.replace(month=3).month, 3)
        self.assertEqual(self.date1_365_day.replace(day=3).day, 3)
        self.assertEqual(self.date1_365_day.replace(hour=3).hour, 3)
        self.assertEqual(self.date1_365_day.replace(minute=3).minute, 3)
        self.assertEqual(self.date1_365_day.replace(second=3).second, 3)
        self.assertEqual(self.date1_365_day.replace(microsecond=3).microsecond, 3)
        self.assertEqual(self.date1_365_day.replace(dayofwk=3).dayofwk, 3)
        self.assertEqual(self.date1_365_day.replace(dayofyr=3).dayofyr, 3)

    def test_pickling(self):
        "Test reversibility of pickling."
        import pickle

        date = Datetime360Day(year=1, month=2, day=3, hour=4, minute=5, second=6, microsecond=7)
        self.assertEqual(date, pickle.loads(pickle.dumps(date)))

    def test_misc(self):
        "Miscellaneous tests."
        # make sure repr succeeds
        repr(self.date1_365_day)

        # make sure strftime without a format string works
        self.assertEqual(self.date3_gregorian.strftime(None),
                         "1969-07-20 12:00:00")

        def invalid_year():
            DatetimeGregorian(0, 1, 1) + self.delta

        def invalid_month():
            DatetimeGregorian(1, 13, 1) + self.delta

        def invalid_day():
            DatetimeGregorian(1, 1, 32) + self.delta

        def invalid_gregorian_date():
            DatetimeGregorian(1582, 10, 5) + self.delta

        for func in [invalid_year, invalid_month, invalid_day, invalid_gregorian_date]:
            self.assertRaises(ValueError, func)

    def test_richcmp(self):
        # compare datetime and datetime
        self.assertTrue(self.date1_365_day == self.date1_365_day)
        self.assertFalse(self.date1_365_day == self.date2_365_day)
        self.assertTrue(self.date1_365_day < self.date2_365_day)
        self.assertFalse(self.date1_365_day < self.date1_365_day)
        self.assertTrue(self.date2_365_day > self.date1_365_day)
        self.assertFalse(self.date1_365_day > self.date2_365_day)
        # compare real_datetime and datetime
        self.assertTrue(self.datetime_date1 > self.date3_gregorian)
        # compare datetime and real_datetime
        self.assertFalse(self.date3_gregorian > self.datetime_date1)

        def not_comparable_1():
            "compare two datetime instances with different calendars"
            self.date1_365_day > self.date3_gregorian

        def not_comparable_2():
            "compare a datetime instance with a non-standard calendar to real_datetime"
            self.date2_365_day > self.datetime_date1

        def not_comparable_3():
            "compare datetime.datetime to netcdftime.datetime with a non-gregorian calendar"
            self.datetime_date1 > self.date2_365_day

        def not_comparable_4():
            "compare a datetime instance to something other than a datetime"
            self.date1_365_day > 0

        for func in [not_comparable_1, not_comparable_2, not_comparable_3, not_comparable_4]:
            self.assertRaises(TypeError, func)
예제 #22
0
        [datetime(2020, 3, 21, 12, 0, 0), 0.0, 0.0, 1.0],
        [datetime(2020, 3, 21, 18, 0, 0), -90.0, 0.0, 1.0],
        [datetime(2020, 3, 21, 18, 0, 0), 270.0, 0.0, 1.0],
        [datetime(2020, 7, 6, 12, 0, 0), -90.0, 0.0, -0.0196310],
        [datetime(2020, 7, 6, 9, 0, 0), 40.0, 40.0, 0.9501915],
        [datetime(2020, 7, 6, 12, 0, 0), 0.0, 90.0, 0.3843733],
    ),
)
def test__sun_zenith_angle(time, lon, lat, expected):
    assert cos_zenith_angle(time, lon, lat) == pytest.approx(expected, abs=1e-3)


@pytest.mark.parametrize(
    "invalid_time",
    (
        DatetimeNoLeap(2000, 1, 1),
        np.array([DatetimeNoLeap(2000, 1, 1), DatetimeNoLeap(2000, 2, 1)]),
    ),
    ids=["scalar", "array"],
)
def test__sun_zenith_angle_invalid_time(invalid_time):
    with pytest.raises(ValueError, match="model_time has an invalid date type"):
        cos_zenith_angle(invalid_time, 0.0, 0.0)


def test_cos_zenith_angle_dataarray():
    time = DatetimeJulian(2020, 3, 21, 12, 0, 0)
    lat = 0
    lon = 0
    dataset = xr.Dataset(
        {"time": ([], time), "lat": (["x"], [lat]), "lon": (["x"], [lon])}
예제 #23
0
파일: run.py 프로젝트: geosciz/nc2im_cesm2
    'snw_day_CESM2_historical_r11i1p1f1_gn_20000101-20150101.nc',  #  6
    'ts_Amon_CESM2_historical_r11i1p1f1_gn_200001-201412.nc',  #  7
    'tsl_Lmon_CESM2_historical_r11i1p1f1_gn_200001-201412.nc',  #  8
    'soil_mon_ERA5_2015.nc',  #  9
    'landmask_CESM2.nc',  # 10
    'phis_CESM2.nc'
]  # 11

chdir(nc_path)

dss = []
for nc in ncs:
    ds = open_dataset(nc)
    dss.append(ds)

start_date = DatetimeNoLeap(start_year, start_month, start_day)
end_date = DatetimeNoLeap(end_year, end_month, end_day)
dates = []
date = start_date
while date <= end_date:
    dates.append(date)
    date += timedelta(hours=6)

for date in dates:
    # datetime
    tnum = date.year, date.month, date.day, date.hour
    t6hr = DatetimeNoLeap(tnum[0], tnum[1], tnum[2], tnum[3])
    tday = DatetimeNoLeap(tnum[0], tnum[1], tnum[2]) + timedelta(days=1)
    if tnum[1] is 2:
        mid_day = 14
    else:
예제 #24
0
import numpy as np
import pytest
import xarray as xr

from aospy.internal_names import (
    LON_STR,
    TIME_STR,
    TIME_BOUNDS_STR,
    BOUNDS_STR,
)

_DATE_RANGES = {
    'datetime': (datetime.datetime(2000, 1,
                                   1), datetime.datetime(2002, 12, 31)),
    'datetime64': (np.datetime64('2000-01-01'), np.datetime64('2002-12-31')),
    'cftime': (DatetimeNoLeap(2000, 1, 1), DatetimeNoLeap(2002, 12, 31)),
    'str': ('2000', '2002')
}


@pytest.fixture()
def alt_lat_str():
    return 'LATITUDE'


@pytest.fixture()
def var_name():
    return 'a'


@pytest.fixture
예제 #25
0
)


@pytest.mark.parametrize(('input_dtype', 'expected_dtype'),
                         [(np.float32, np.float64), (np.int, np.int)])
def test_maybe_cast_to_float64(input_dtype, expected_dtype):
    da = xr.DataArray(np.ones(3, dtype=input_dtype))
    result = _maybe_cast_to_float64(da).dtype
    assert result == expected_dtype


_DATE_RANGES = {
    'datetime': (datetime.datetime(2000, 1,
                                   1), datetime.datetime(2002, 12, 31)),
    'datetime64': (np.datetime64('2000-01-01'), np.datetime64('2002-12-31')),
    'cftime': (DatetimeNoLeap(2000, 1, 1), DatetimeNoLeap(2002, 12, 31)),
    'str': ('2000', '2002')
}


@pytest.fixture(params=_DATE_RANGES.values(), ids=list(_DATE_RANGES.keys()))
def generate_file_set_args(request):
    start_date, end_date = request.param
    return dict(var=condensation_rain,
                start_date=start_date,
                end_date=end_date,
                domain='atmos',
                intvl_in='monthly',
                dtype_in_vert='sigma',
                dtype_in_time='ts',
                intvl_out=None)
예제 #26
0
 def preprocess(ds, **kwargs):
     if kwargs['start_date'] == DatetimeNoLeap(5, 1, 1):
         ds['condensation_rain'] = 10. * ds['condensation_rain']
     return ds
예제 #27
0
class DateTime(unittest.TestCase):
    def setUp(self):
        self.date1_365_day = DatetimeNoLeap(-5000, 1, 2, 12)
        self.date2_365_day = DatetimeNoLeap(-5000, 1, 3, 12)
        self.date3_gregorian = DatetimeGregorian(1969, 7, 20, 12)

        # last day of the Julian calendar in the mixed Julian/Gregorian calendar
        self.date4_gregorian = DatetimeGregorian(1582, 10, 4)
        # first day of the Gregorian calendar in the mixed Julian/Gregorian calendar
        self.date5_gregorian = DatetimeGregorian(1582, 10, 15)

        self.date6_proleptic_gregorian = DatetimeProlepticGregorian(
            1582, 10, 15)

        self.date7_360_day = Datetime360Day(2000, 1, 1)

        self.date8_julian = DatetimeJulian(1582, 10, 4)

        # a datetime.datetime instance (proleptic Gregorian calendar)
        self.datetime_date1 = datetime(1969, 7, 21, 12)

        self.delta = timedelta(hours=25)

    def test_add(self):
        dt = self.date1_365_day
        # datetime + timedelta
        self.assertEqual(
            dt + self.delta,  # add 25 hours
            dt.replace(day=dt.day + 1, hour=dt.hour + 1))

        # timedelta + datetime
        self.assertEqual(
            self.delta + dt,  # add 25 hours
            dt.replace(day=dt.day + 1, hour=dt.hour + 1))

        # test the Julian/Gregorian transition
        self.assertEqual(self.date4_gregorian + self.delta,
                         DatetimeGregorian(1582, 10, 15, 1))

        # The Julian calendar has no invalid dates
        self.assertEqual(self.date8_julian + self.delta,
                         DatetimeJulian(1582, 10, 5, 1))

        # Test going over the year boundary.
        self.assertEqual(
            DatetimeGregorian(2000, 11, 1) + timedelta(days=30 + 31),
            DatetimeGregorian(2001, 1, 1))

        # Year 2000 is a leap year.
        self.assertEqual(
            DatetimeGregorian(2000, 1, 1) + timedelta(days=31 + 29),
            DatetimeGregorian(2000, 3, 1))

        # Test the 366_day calendar.
        self.assertEqual(
            DatetimeAllLeap(1, 1, 1) + timedelta(days=366 * 10 + 31),
            DatetimeAllLeap(11, 2, 1))

        # The Gregorian calendar has no year zero.
        self.assertEqual(
            DatetimeGregorian(-1, 12, 31) + self.delta,
            DatetimeGregorian(1, 1, 1, 1))

        def invalid_add_1():
            self.date1_365_day + 1

        def invalid_add_2():
            1 + self.date1_365_day

        for func in [invalid_add_1, invalid_add_2]:
            self.assertRaises(TypeError, func)

    def test_sub(self):
        # subtracting a timedelta
        previous_day = self.date1_365_day - self.delta
        self.assertEqual(previous_day.day, self.date1_365_day.day - 1)

        def total_seconds(td):
            """Equivalent to td.total_seconds() on Python >= 2.7. See
            https://docs.python.org/2/library/datetime.html#datetime.timedelta.total_seconds
            """
            return (td.microseconds +
                    (td.seconds + td.days * 24 * 3600) * 10**6) / 10**6

        # sutracting two netcdftime.datetime instances
        delta = self.date2_365_day - self.date1_365_day
        # date1 and date2 are exactly one day apart
        self.assertEqual(total_seconds(delta), 86400)

        # subtracting netcdftime.datetime from datetime.datetime
        delta = self.datetime_date1 - self.date3_gregorian
        # real_date2 and real_date1 are exactly one day apart
        self.assertEqual(total_seconds(delta), 86400)

        # subtracting datetime.datetime from netcdftime.datetime
        delta = self.date3_gregorian - self.datetime_date1
        # real_date2 and real_date1 are exactly one day apart
        self.assertEqual(total_seconds(delta), -86400)

        # Test the Julian/Gregorian transition.
        self.assertEqual(self.date5_gregorian - self.delta,
                         DatetimeGregorian(1582, 10, 3, 23))

        # The proleptic Gregorian calendar does not have invalid dates.
        self.assertEqual(self.date6_proleptic_gregorian - self.delta,
                         DatetimeProlepticGregorian(1582, 10, 13, 23))

        # The Gregorian calendar has no year zero.
        self.assertEqual(
            DatetimeGregorian(1, 1, 1) - self.delta,
            DatetimeGregorian(-1, 12, 30, 23))

        # The 360_day calendar has year zero.

        self.assertEqual(self.date7_360_day - timedelta(days=2000 * 360),
                         Datetime360Day(0, 1, 1))

        # Test going over the year boundary.
        self.assertEqual(
            DatetimeGregorian(2000, 3, 1) - timedelta(days=29 + 31 + 31),
            DatetimeGregorian(1999, 12, 1))

        # Year 2000 is a leap year.
        self.assertEqual(
            DatetimeGregorian(2000, 3, 1) - self.delta,
            DatetimeGregorian(2000, 2, 28, 23))

        def invalid_sub_1():
            self.date1_365_day - 1

        def invalid_sub_2():
            1 - self.date1_365_day

        def invalid_sub_3():
            self.date1_365_day - self.datetime_date1

        def invalid_sub_4():
            self.datetime_date1 - self.date1_365_day

        def invalid_sub_5():
            self.date3_gregorian - self.date1_365_day

        for func in [invalid_sub_1, invalid_sub_2]:
            self.assertRaises(TypeError, func)

        for func in [invalid_sub_3, invalid_sub_4, invalid_sub_5]:
            self.assertRaises(ValueError, func)

    def test_replace(self):
        self.assertEqual(self.date1_365_day.replace(year=4000).year, 4000)
        self.assertEqual(self.date1_365_day.replace(month=3).month, 3)
        self.assertEqual(self.date1_365_day.replace(day=3).day, 3)
        self.assertEqual(self.date1_365_day.replace(hour=3).hour, 3)
        self.assertEqual(self.date1_365_day.replace(minute=3).minute, 3)
        self.assertEqual(self.date1_365_day.replace(second=3).second, 3)
        self.assertEqual(
            self.date1_365_day.replace(microsecond=3).microsecond, 3)
        self.assertEqual(self.date1_365_day.replace(dayofwk=3).dayofwk, 3)
        self.assertEqual(self.date1_365_day.replace(dayofyr=3).dayofyr, 3)

    def test_pickling(self):
        "Test reversibility of pickling."
        import pickle

        date = Datetime360Day(year=1,
                              month=2,
                              day=3,
                              hour=4,
                              minute=5,
                              second=6,
                              microsecond=7)
        self.assertEqual(date, pickle.loads(pickle.dumps(date)))

    def test_misc(self):
        "Miscellaneous tests."
        # make sure repr succeeds
        repr(self.date1_365_day)

        # make sure strftime without a format string works
        self.assertEqual(self.date3_gregorian.strftime(None),
                         "1969-07-20 12:00:00")

        def invalid_year():
            DatetimeGregorian(0, 1, 1) + self.delta

        def invalid_month():
            DatetimeGregorian(1, 13, 1) + self.delta

        def invalid_day():
            DatetimeGregorian(1, 1, 32) + self.delta

        def invalid_gregorian_date():
            DatetimeGregorian(1582, 10, 5) + self.delta

        for func in [
                invalid_year, invalid_month, invalid_day,
                invalid_gregorian_date
        ]:
            self.assertRaises(ValueError, func)

    def test_richcmp(self):
        # compare datetime and datetime
        self.assertTrue(self.date1_365_day == self.date1_365_day)
        self.assertFalse(self.date1_365_day == self.date2_365_day)
        self.assertTrue(self.date1_365_day < self.date2_365_day)
        self.assertFalse(self.date1_365_day < self.date1_365_day)
        self.assertTrue(self.date2_365_day > self.date1_365_day)
        self.assertFalse(self.date1_365_day > self.date2_365_day)
        # compare real_datetime and datetime
        self.assertTrue(self.datetime_date1 > self.date3_gregorian)
        # compare datetime and real_datetime
        self.assertFalse(self.date3_gregorian > self.datetime_date1)

        def not_comparable_1():
            "compare two datetime instances with different calendars"
            self.date1_365_day > self.date3_gregorian

        def not_comparable_2():
            "compare a datetime instance with a non-standard calendar to real_datetime"
            self.date2_365_day > self.datetime_date1

        def not_comparable_3():
            "compare datetime.datetime to netcdftime.datetime with a non-gregorian calendar"
            self.datetime_date1 > self.date2_365_day

        def not_comparable_4():
            "compare a datetime instance to something other than a datetime"
            self.date1_365_day > 0

        for func in [
                not_comparable_1, not_comparable_2, not_comparable_3,
                not_comparable_4
        ]:
            self.assertRaises(TypeError, func)
예제 #28
0
    os.path.split(ROOT_PATH)[0], 'netcdf', '000[4-6]0101.precip_monthly.nc')
sphum_files = os.path.join(
    os.path.split(ROOT_PATH)[0], 'netcdf', '00060101.sphum_monthly.nc')
file_map = {
    'monthly': {
        'condensation_rain': precip_files,
        'convection_rain': precip_files,
        'sphum': sphum_files,
        'ps': sphum_files
    }
}
example_run = Run(
    name='example_run',
    description=('Control simulation of the idealized moist model'),
    data_loader=NestedDictDataLoader(file_map),
    default_start_date=DatetimeNoLeap(4, 1, 1),
    default_end_date=DatetimeNoLeap(6, 12, 31))

example_model = Model(name='example_model',
                      grid_file_paths=((os.path.join(
                          os.path.split(ROOT_PATH)[0], 'netcdf',
                          '00060101.sphum_monthly.nc'),
                                        os.path.join(
                                            os.path.split(ROOT_PATH)[0],
                                            'netcdf', 'im.landmask.nc')), ),
                      runs=[example_run],
                      load_grid_data=True,
                      grid_attrs={
                          LAND_MASK_STR: 'custom_land_mask',
                          LON_STR: 'custom_lon'
                      })