def test_reindex_time(self):
        """Tests whether the reindex_time function works as expected."""
        [yr, month, day] = [1850, 1, 15]
        expected_times = xr.DataArray(
            np.array([
                cftime.DatetimeProlepticGregorian(yr, month, day, 0, 0),
                cftime.DatetimeProlepticGregorian(yr, month + 1, day, 0, 0)
            ]))
        testdates1 = xr.DataArray(
            np.array([
                np.datetime64(datetime.datetime(yr, month, day, 0, 0)),
                np.datetime64(datetime.datetime(yr, month + 1, day, 0, 0))
            ]))
        testdates2 = xr.DataArray(
            np.array([
                cftime.DatetimeNoLeap(yr, month, day, 0, 0),
                cftime.DatetimeNoLeap(yr, month + 1, day, 0, 0)
            ]))
        testdates3 = xr.DataArray(
            np.array([
                cftime.Datetime360Day(yr, month, day, 0, 0),
                cftime.Datetime360Day(yr, month + 1, day, 0, 0)
            ]))
        dates_to_test = [testdates1, testdates2, testdates3]

        # Run test
        dates_converted = True
        for date_to_test in dates_to_test:
            newtimes = reindex_time(date_to_test)
            if not np.all((newtimes == expected_times).values):
                dates_converted = False
            else:
                continue
        self.assertTrue(dates_converted)
Ejemplo n.º 2
0
def test_adjust_quantiledeltamapping_year_output_time():
    """Check 'time' year and edges of QDM adjusted output

    This tests integration between `dodola.core.adjust_quantiledeltamapping_year`,
    `dodola.core.qdm_rollingyearwindow`, and
    `dodola.core.train_quantiledeltamapping`.
    """
    # Setup input data.
    target_variable = "fakevariable"
    variable_kind = "+"
    n_simdays = 85 * 365

    model_bias = 2.0
    ts_sim = np.ones(n_simdays, dtype=np.float64)
    sim = _timeseriesfactory(ts_sim + model_bias,
                             start_dt="2015-01-01",
                             variable_name=target_variable)

    target_year = 2088

    qdm = _train_simple_qdm(target_variable="fakevariable",
                            kind=variable_kind,
                            additive_bias=model_bias)
    adjusted_ds = adjust_quantiledeltamapping_year(
        simulation=sim,
        qdm=qdm,
        year=target_year,
        variable=target_variable,
    )
    assert np.unique(adjusted_ds["time"].dt.year).item() == 2088
    assert min(adjusted_ds["time"].values) == cftime.DatetimeNoLeap(
        2088, 1, 1, 0, 0, 0, 0)
    assert max(adjusted_ds["time"].values) == cftime.DatetimeNoLeap(
        2088, 12, 31, 0, 0, 0, 0)
Ejemplo n.º 3
0
Archivo: utils.py Proyecto: fzhu2e/LMRt
def year_float2datetime(year_float, resolution='day'):
    if np.min(year_float) < 0:
        raise ValueError(
            'Cannot handel negative years. Please truncate first.')
        return None
    ''' Convert an array of floats in unit of year to a datetime time; accuracy: one day
    '''
    year = np.array([int(y) for y in year_float], dtype=int)
    month = np.zeros(np.size(year), dtype=int)
    day = np.zeros(np.size(year), dtype=int)

    for i, y in enumerate(year):
        fst_day = datetime(year=y, month=1, day=1)
        lst_day = datetime(year=y + 1, month=1, day=1)
        year_length = lst_day - fst_day

        year_part = (year_float[i] - y) * year_length + timedelta(
            minutes=1)  # to fix the numerical error
        date = year_part + fst_day
        month[i] = date.month
        day[i] = date.day

    if resolution == 'day':
        time = [
            cftime.DatetimeNoLeap(y, m, d, 0, 0, 0, 0, 0, 0)
            for y, m, d in zip(year, month, day)
        ]
    elif resolution == 'month':
        time = [
            cftime.DatetimeNoLeap(y, m, 1, 0, 0, 0, 0, 0, 0)
            for y, m in zip(year, month)
        ]

    return time
Ejemplo n.º 4
0
def test_shift_cftime_singular():
    """Tests that a singular ``cftime`` is shifted the appropriate amount."""
    cftime_initial = cftime.DatetimeNoLeap(1990, 1, 1)
    cftime_expected = cftime.DatetimeNoLeap(1990, 3, 1)
    # Shift forward two months at month start.
    cftime_from_func = shift_cftime_singular(cftime_initial, 2, "MS")
    assert cftime_expected == cftime_from_func
Ejemplo n.º 5
0
def _read_single_nc(filename, yearrange, bbox):
    """Import data from single nc file, return as xarray

    Parameters:
        filename (str or pathlib.Path): full path of input netcdf file
        yearrange: (tuple): year range to be extracted from file
        bbox (tuple of float): geographical bounding box in the form:
            (lon_min, lat_min, lon_max, lat_max)

    Returns:
        dis_xarray (xarray)
    """
    dis_xarray = xr.open_dataset(filename)
    try:
        if not bbox:
            return dis_xarray.sel(time=slice(dt.datetime(yearrange[0], 1, 1),
                                       dt.datetime(yearrange[-1], 12, 31)))
        lon_min, lat_min, lon_max, lat_max = bbox
        return dis_xarray.sel(lon=slice(lon_min, lon_max), lat=slice(lat_max, lat_min),
                        time=slice(dt.datetime(yearrange[0], 1, 1),
                                   dt.datetime(yearrange[-1], 12, 31)))
    except TypeError:
        # fix date format if not datetime
        if not bbox:
            dis_xarray = dis_xarray.sel(time=slice(cftime.DatetimeNoLeap(yearrange[0], 1, 1),
                                       cftime.DatetimeNoLeap(yearrange[-1], 12, 31)))
        else:
            lon_min, lat_min, lon_max, lat_max = bbox
            dis_xarray = dis_xarray.sel(lon=slice(lon_min, lon_max), lat=slice(lat_max, lat_min),
                            time=slice(cftime.DatetimeNoLeap(yearrange[0], 1, 1),
                                       cftime.DatetimeNoLeap(yearrange[-1], 12, 31)))
        datetimeindex = dis_xarray.indexes['time'].to_datetimeindex()
        dis_xarray['time'] = datetimeindex
    return dis_xarray
Ejemplo n.º 6
0
    def fix_metadata(self, cubes):
        """Fix parent time units.

        FGOALS-f3-L Amon data may have a bad time bounds spanning 20 days.

        Parameters
        ----------
        cubes : iris.cube.CubeList
            Input cubes.

        Returns
        -------
        iris.cube.CubeList
        """
        for cube in cubes:
            if cube.attributes['table_id'] == 'Amon':
                time = cube.coord('time')
                if np.any(time.bounds[:-1, 1] != time.bounds[1:, 0]):
                    times = time.units.num2date(time.points)
                    starts = [
                        cftime.DatetimeNoLeap(c.year, c.month, 1)
                        for c in times
                    ]
                    ends = [
                        cftime.DatetimeNoLeap(c.year, c.month +
                                              1, 1) if c.month < 12 else
                        cftime.DatetimeNoLeap(c.year + 1, 1, 1) for c in times
                    ]
                    time.bounds = time.units.date2num(
                        np.stack([starts, ends], -1))
        return cubes
Ejemplo n.º 7
0
def test_cftime_datetime_mean_long_time_period():
    import cftime

    times = np.array(
        [
            [
                cftime.DatetimeNoLeap(400, 12, 31, 0, 0, 0, 0),
                cftime.DatetimeNoLeap(520, 12, 31, 0, 0, 0, 0),
            ],
            [
                cftime.DatetimeNoLeap(520, 12, 31, 0, 0, 0, 0),
                cftime.DatetimeNoLeap(640, 12, 31, 0, 0, 0, 0),
            ],
            [
                cftime.DatetimeNoLeap(640, 12, 31, 0, 0, 0, 0),
                cftime.DatetimeNoLeap(760, 12, 31, 0, 0, 0, 0),
            ],
        ]
    )

    da = DataArray(times, dims=["time", "d2"])
    result = da.mean("d2")
    expected = DataArray(
        [
            cftime.DatetimeNoLeap(460, 12, 31, 0, 0, 0, 0),
            cftime.DatetimeNoLeap(580, 12, 31, 0, 0, 0, 0),
            cftime.DatetimeNoLeap(700, 12, 31, 0, 0, 0, 0),
        ],
        dims=["time"],
    )
    assert_equal(result, expected)
Ejemplo n.º 8
0
def time_bnds_mon(years):
    return xr.DataArray(np.array([[
        cftime.date2num(cftime.DatetimeNoLeap(year, mon, 1),
                        units='days since 0001-01-01',
                        calendar='noleap') - 1,
        cftime.date2num(cftime.DatetimeNoLeap(year, mon,
                                              eom_day_noleap[mon - 1]),
                        units='days since 0001-01-01',
                        calendar='noleap')
    ] for year, mon in product(years, range(1, 13))]),
                        dims=('time', 'ntb'))
Ejemplo n.º 9
0
def remove_drift(da, ver_time, y1, y2):
    '''function takes in a raw DP DataArray and returns anomalies with lead-time dependent drift+climo removed'''
    d1 = cftime.DatetimeNoLeap(y1, 1, 1, 0, 0, 0)
    d2 = cftime.DatetimeNoLeap(y2, 12, 31, 23, 59, 59)

    masked_period = da.where((ver_time.mean('d2') > d1)
                             & (ver_time.mean('d2') < d2))
    climodrift = masked_period.mean('M').mean('Y')

    da_anom = da - climodrift

    return da_anom, climodrift
Ejemplo n.º 10
0
    def test_init_default_dates(self):
        gdl = GFDLDataLoader(data_start_date=cftime.DatetimeNoLeap(1, 1, 1),
                             data_end_date=cftime.DatetimeNoLeap(1, 12, 31))
        run_ = Run(data_loader=gdl)
        self.assertEqual(run_.default_start_date,
                         cftime.DatetimeNoLeap(1, 1, 1))
        self.assertEqual(run_.default_end_date,
                         cftime.DatetimeNoLeap(1, 12, 31))

        ddl = DictDataLoader({'monthly': '/a/'})
        run_ = Run(data_loader=ddl)
        self.assertEqual(run_.default_start_date, None)
        self.assertEqual(run_.default_end_date, None)
Ejemplo n.º 11
0
def perform_cmip6_query(conf, query_string):
    df_sub = conf.df.query(query_string)
    if (df_sub.zstore.values.size == 0):
        return df_sub

    mapper = conf.fs.get_mapper(df_sub.zstore.values[-1])
    ds = xr.open_zarr(mapper, consolidated=True)
    print("Time encoding: {} - {}".format(ds.indexes['time'],
                                          ds.indexes['time'].dtype))
    if not ds.indexes["time"].dtype in ["datetime64[ns]", "object"]:

        time_object = ds.indexes['time'].to_datetimeindex(
        )  #pd.DatetimeIndex([ds["time"].values[0]])
        print(time_object, time_object.year)
        # Convert if necesssary
        if time_object[0].year == 1:

            times = ds.indexes['time'].to_datetimeindex(
            )  # pd.DatetimeIndex([ds["time"].values])
            times_plus_2000 = []
            for t in times:
                times_plus_2000.append(
                    cftime.DatetimeNoLeap(t.year + 2000, t.month, t.day,
                                          t.hour))
            ds["time"].values = times_plus_2000
            ds = xr.decode_cf(ds)
    return ds
Ejemplo n.º 12
0
def plot_dict_with_date_keys(dict_in, title, legend=None):
    """
    Assume that keys of dict_in are 'YYYYMMDD' and values are numeric
    """
    time_units = "days since 0001-01-01 0:00:00"
    time = []
    array_val = []
    for date in dict_in.keys():
        if "log" not in date:
            (year, month, day) = date.split("-")
            time.append(cftime.DatetimeNoLeap(int(year), int(month), int(day)))
            array_val.append(dict_in[date])

    if type(array_val[0]) == list:
        dim2 = len(array_val[0])
        da = xr.DataArray(array_val, dims=["time", "dim2"])
    else:
        dim2 = None
        da = xr.DataArray(array_val, dims="time")
    da["time"] = time

    fig = plt.figure(figsize=(9.0, 5.25), clear=True)
    if dim2:
        for dim2ind in range(dim2):
            da.isel(dim2=dim2ind).plot()
    else:
        da.plot()
    if legend:
        plt.legend(legend)
    plt.title(title)
    plt.show()
Ejemplo n.º 13
0
def fix_broken_time_index(ds: xr.Dataset):
    """Fix for a single broken index in a specific file"""
    if "time" not in ds.dims:
        return

    time_dim = ds.time.values
    times_are_encoded = "units" in ds.time.attrs

    if times_are_encoded:
        wrong_id = np.argwhere(np.isclose(time_dim, 0))
    else:
        wrong_id = np.argwhere(time_dim == cftime.DatetimeNoLeap(
            year=1850, month=1, day=1, hour=0))

    if wrong_id.size == 0:
        return

    wrong_id = wrong_id[0, 0]
    if wrong_id == 0 or wrong_id == len(ds.time) - 1:
        return

    daily_gap = 1.0 if times_are_encoded else timedelta(days=1)

    is_daily = time_dim[wrong_id + 1] - time_dim[wrong_id - 1] == daily_gap * 2

    if is_daily:
        fixed_time = time_dim
        fixed_time[wrong_id] = time_dim[wrong_id - 1] + daily_gap
        attrs = ds.time.attrs
        ds["time"] = fixed_time
        ds.time.attrs = attrs
Ejemplo n.º 14
0
    def perform_cmip6_query(self, config, query_string: str) -> xr.Dataset:
        df_sub = config.df.query(query_string)
        if df_sub.zstore.values.size == 0:
            return df_sub

        mapper = config.fs.get_mapper(df_sub.zstore.values[-1])
        logging.debug("[CMIP6_IO] df_sub: {}".format(df_sub))

        ds = xr.open_zarr(mapper, consolidated=True, mask_and_scale=True)

        # print("Time encoding: {} - {}".format(ds.indexes['time'], ds.indexes['time'].dtype))
        if not ds.indexes["time"].dtype in ["datetime64[ns]", "object"]:

            time_object = ds.indexes['time'].to_datetimeindex(
            )  # pd.DatetimeIndex([ds["time"].values[0]])

            # Convert if necessary
            if time_object[0].year == 1:

                times = ds.indexes['time'].to_datetimeindex(
                )  # pd.DatetimeIndex([ds["time"].values])
                times_plus_2000 = []
                for t in times:
                    times_plus_2000.append(
                        cftime.DatetimeNoLeap(t.year + 2000, t.month, t.day,
                                              t.hour))
                ds["time"].values = times_plus_2000
                ds = xr.decode_cf(ds)

        return ds
Ejemplo n.º 15
0
def add_months(date_in, nmonth):
    """ adds the given number of months to a given date """
    year = date_in.year + (date_in.month + nmonth - 1) // 12
    mth = (date_in.month + nmonth - 1) % 12 + 1
    day = min(date_in.day,
              calendar.monthrange(1, mth)[1])  # -> this assumes LEAP YEAR
    return cft.DatetimeNoLeap(year, mth, day)
Ejemplo n.º 16
0
def make_time(year_range):
    from itertools import product
    return [
        cftime.DatetimeNoLeap(year, month, 1)
        for year, month in product(range(year_range[0], year_range[1] +
                                         1), range(1, 13))
    ]
Ejemplo n.º 17
0
def load_pdo(year_range=None, apply_ann_filter=False):
    '''read pdo from JSON file:
        https://www.ncdc.noaa.gov/teleconnections/pdo/data.json
    '''
    import json
    with open('data/pdo-data.json', 'r') as f:
        pdo_data = json.load(f)
    year = xr.DataArray([float(d[0:4]) for d in pdo_data['data'].keys()],
                        dims='time')
    mon = xr.DataArray([float(d[4:6]) for d in pdo_data['data'].keys()],
                       dims='time')
    time = xr.DataArray([
        cftime.DatetimeNoLeap(y, m, 1) for y, m in zip(year.values, mon.values)
    ],
                        dims='time')
    data = xr.DataArray([float(d) for d in pdo_data['data'].values()],
                        dims='time',
                        coords={'time': time})

    ds = xr.Dataset({'PDO': data, 'year': year, 'mon': mon})
    if year_range is not None:
        nx = np.where((year_range[0] <= year) & (year <= year_range[1]))[0]
        ds = ds.isel(time=nx)

    if apply_ann_filter:
        save_attrs = {v: ds[v].attrs for v in ds.variables}
        N = 12
        ds = ds.rolling(time=N, center=True).mean()

    return ds
Ejemplo n.º 18
0
def time_mid_mon(years):
    mid_mon = eom_day_noleap / 2 + 1.
    mid_mon_day = np.floor(mid_mon)
    mid_mon_hr = (mid_mon - mid_mon_day) * 24
    return [
        cftime.DatetimeNoLeap(year, mon, mid_mon_day[mon - 1],
                              mid_mon_hr[mon - 1])
        for year, mon in product(years, range(1, 13))
    ]
Ejemplo n.º 19
0
def load_base_data(info):

    if (info.verbose): print("Loading: "+info.atmdir + "/" + info.atmfile)

    ds = xr.open_mfdataset(info.atmdir + "/" + info.atmfile.format(info.base_vars[0]))

    for v in info.base_vars[1:]:
        this_data = xr.open_mfdataset(info.atmdir + "/" + info.atmfile.format(v))
        data = interpolate_data(this_data[v], ds)
        ds[v] = data

    # for example, this could do:
    # ds = xr.open_mfdataset(["hus_6hrLev_CanESM2_historical_r1i1p1_198001010000-198012311800.nc",
    #                     "ta_6hrLev_CanESM2_historical_r1i1p1_198001010000-198012311800.nc",
    #                     "ua_6hrLev_CanESM2_historical_r1i1p1_198001010000-198012311800.nc",
    #                     "va_6hrLev_CanESM2_historical_r1i1p1_198001010000-198012311800.nc",
    #                     "orog_fx_CanESM2_historical_r0i0p0.nc",
    #                     "sftlf_fx_CanESM2_historical_r0i0p0.nc"])
    # perhaps as :
    # ds = xr.open_mfdataset("*CanESM2*.nc")

    if (info.verbose): print("Loading base file metadata (this could take a while)")

    # Time objects have to be defined with the calendar used in the input GCM
    start_time = ds.time.values[0]

    if start_time.calendar == "360_day":
        start_date = cftime.Datetime360Day(*info.start_date.timetuple())
        end_date = cftime.Datetime360Day(*info.end_date.timetuple())

    elif start_time.calendar == "noleap":
        start_date = cftime.DatetimeNoLeap(*info.start_date.timetuple())
        end_date = cftime.DatetimeNoLeap(*info.end_date.timetuple())

    else:
        start_date = cftime.Datetime(*info.start_date.timetuple())
        end_date = cftime.Datetime(*info.end_date.timetuple())


    # subset the dataset in space and time
    return ds.sel(time= slice(start_date, end_date),
                  lat = slice(info.lat[0], info.lat[1]),
                  lon = slice(info.lon[0], info.lon[1]))
Ejemplo n.º 20
0
 def test_cftime_transform_noleap_warn(self):
     try:
         import cftime
     except:
         raise SkipTest('Test requires cftime library')
     gregorian_dates = [cftime.DatetimeNoLeap(2000, 2, 28),
                        cftime.DatetimeNoLeap(2000, 3, 1),
                        cftime.DatetimeNoLeap(2000, 3, 2)]
     curve = Curve((gregorian_dates, [1, 2, 3]))
     plot = bokeh_renderer.get_plot(curve)
     xs = plot.handles['cds'].data['x']
     self.assertEqual(xs.astype('int64'),
                      np.array([951696000000, 951868800000, 951955200000]))
     substr = (
         "Converting cftime.datetime from a non-standard calendar "
         "(noleap) to a standard calendar for plotting. This may "
         "lead to subtle errors in formatting dates, for accurate "
         "tick formatting switch to the matplotlib backend.")
     self.log_handler.assertEndsWith('WARNING', substr)
Ejemplo n.º 21
0
def datetime(
        year, month, day, hour=0, minute=0, second=0, microsecond=0,
        tzinfo=None, calendar='proleptic_gregorian'):
    """
    Retrieves a datetime-like object with the requested calendar. Calendar types
    other than proleptic_gregorian require the netcdftime module to be
    installed.

    Parameters
    ----------
    year : int,
    month  : int,
    day  : int,
    hour  : int, optional
    minute  : int, optional
    second : int, optional
    microsecond : int, optional
    tzinfo  : datetime.tzinfo, optional
        A timezone informaton class, such as from pytz. Can only be used with
        'proleptic_gregorian' calendar, as netcdftime does not support
        timezones.
    calendar : string, optional
        Should be one of 'proleptic_gregorian', 'no_leap', '365_day',
        'all_leap', '366_day', '360_day', 'julian', or 'gregorian'. Default
        is 'proleptic_gregorian', which returns a normal Python datetime.
        Other options require the netcdftime module to be installed.

    Returns
    -------
    datetime : datetime-like
        The requested datetime. May be a Python datetime, or one of the
        datetime-like types in netcdftime.
    """
    kwargs = {
        'year': year, 'month': month, 'day': day, 'hour': hour,
        'minute': minute, 'second': second, 'microsecond': microsecond
    }
    if calendar.lower() == 'proleptic_gregorian':
        return real_datetime(tzinfo=tzinfo, **kwargs)
    elif tzinfo is not None:
        raise ValueError('netcdftime does not support timezone-aware datetimes')
    elif ct is None:
        raise DependencyError(
            "Calendars other than 'proleptic_gregorian' require the netcdftime "
            "package, which is not installed.")
    elif calendar.lower() in ('all_leap', '366_day'):
        return ct.DatetimeAllLeap(**kwargs)
    elif calendar.lower() in ('no_leap', 'noleap', '365_day'):
        return ct.DatetimeNoLeap(**kwargs)
    elif calendar.lower() == '360_day':
        return ct.Datetime360Day(**kwargs)
    elif calendar.lower() == 'julian':
        return ct.DatetimeJulian(**kwargs)
    elif calendar.lower() == 'gregorian':
        return ct.DatetimeGregorian(**kwargs)
Ejemplo n.º 22
0
def make_year_constraint_all_calendars(start, end):
    """Utility function to create a dict of time constraints on year-basis

    This create a dict of the same time constraint, but for different calendars.
    Since comparisons between different calendar types are not (always) possible,
    a calendar for a time coordinate should be compared to the specific constraint
    with the same calendar.

    The calendar type (as a string) can be obtained through the coordinate's `units`
    attribute: `cube.coord('time').units.calendar`; the resulting string is the key
    for the dict, which then as a value yields the correct constraint

    Arguments
    ---------

        start, end: integer
            Start and end year. Month and day are 1, 1 for the starting year, and
            31, 12 or 30, 12 (for a 360-day calendar) for the end year

    """

    dates = {
        'default': (cftime.datetime(start, 1, 1), cftime.datetime(end, 12,
                                                                  31)),
        '360_day':
        (cftime.Datetime360Day(start, 1,
                               1), cftime.Datetime360Day(end, 12, 30)),
        '365_day': (cftime.DatetimeNoLeap(start, 1, 1),
                    cftime.DatetimeNoLeap(end, 12, 31)),
        'proleptic_gregorian': (cftime.DatetimeProlepticGregorian(start, 1, 1),
                                cftime.DatetimeProlepticGregorian(end, 12,
                                                                  31)),
        'gregorian': (cftime.DatetimeGregorian(start, 1, 1),
                      cftime.DatetimeGregorian(end, 12, 31)),
        'julian': (cftime.DatetimeJulian(start, 1, 1),
                   cftime.DatetimeJulian(end, 12, 31)),
    }
    constraints = {
        key: make_date_constraint(*value)
        for key, value in dates.items()
    }
    return constraints
Ejemplo n.º 23
0
def get_time_constraint(time_list):
    """Get the time constraint used for reading an iris cube."""

    if time_list:
        if not type(time_list) in (list, tuple):
            time_list = [time_list]
        date_pattern = '([0-9]{4})-([0-9]{1,2})-([0-9]{1,2})'
        start_date = time_list[0]
        start_year, start_month, start_day = start_date.split('-')
        assert re.search(date_pattern, start_date)

        if len(time_list) == 1:
            time_constraint = iris.Constraint(
                time=lambda t: cftime.DatetimeNoLeap(int(
                    start_year), int(start_month), int(start_day)) <= t.point)
        else:
            end_date = time_list[1]
            assert re.search(date_pattern, end_date)

            if (start_date == end_date):
                time_constraint = iris.Constraint(
                    time=iris.time.PartialDateTime(year=int(start_year),
                                                   month=int(start_month),
                                                   day=int(start_day)))
            else:
                end_year, end_month, end_day = end_date.split('-')
                start_constraint = iris.Constraint(
                    time=lambda t: cftime.DatetimeNoLeap(
                        int(start_year), int(start_month), int(start_day)
                    ) <= t.point)
                end_constraint = iris.Constraint(
                    time=lambda t: t.point <= cftime.DatetimeNoLeap(
                        int(end_year), int(end_month), int(end_day)))
                time_constraint = start_constraint & end_constraint

                #time_constraint = iris.Constraint(time=lambda t: cftime.DatetimeNoLeap(int(start_year), int(start_month), int(start_day)) <= t.point <= cftime.DatetimeNoLeap(int(end_year), int(end_month), int(end_day)))
                #time_constraint = iris.Constraint(time=lambda t: iris.time.PartialDateTime(year=int(start_year), month=int(start_month), day=int(start_day)) <= t.point <= iris.time.PartialDateTime(year=int(end_year), month=int(end_month), day=int(end_day)))
                #time_constraint = iris.Constraint(time=lambda t: iris.time.PartialDateTime(year=int(start_year), month=int(start_month), day=int(start_day)) <= t.point and iris.time.PartialDateTime(year=int(end_year), month=int(end_month), day=int(end_day)) >= t.point)
    else:
        time_constraint = iris.Constraint()

    return time_constraint
Ejemplo n.º 24
0
    def convert_vmro3_to_toz(self, scenario: str, ds: xr.Dataset,
                             baseurl: str):

        R = 287.3  # Jkg-1K-1 (Specific gas constant for air)
        T0 = 273.15  # Kelvin(Standard temperaure)
        P0 = 1.01325e5  # Pa (Standard pressure at surface)
        g0 = 9.80665  # ms-2 (Global average gravity at surface)
        Na = 6.0220e23  # Avogadro´s number

        # Integrating the total column of a trace gas from input4MPI forcing data. Here
        # P is the pressure in hPa, VMR is the colume mixing ration in ppm and TOZ is the trace gas
        # column amount in Dobson Units (DU):'bnds', 'lat', 'lon', 'plev', 'time'

        mole2ppmv = 1e6
        VMR = ds["vmro3"].values * mole2ppmv
        plev = ds["plev"].values

        times = ds["time"].values
        times_plus = []

        # Mix of Timestamp and DateTimeNoLeap - convert all to DateTimeNoLeap
        for t in times:
            if isinstance(t, datetime.datetime):
                times_plus.append(
                    cftime.DatetimeNoLeap(t.year, t.month, t.day, t.hour))
            else:
                times_plus.append(t)

        VMR = np.where(VMR > 1000, np.nan, VMR)
        plev = np.where(plev > 1000, np.nan, plev)

        TOZ = 10 * ((R * T0) / (g0 * P0)) * np.nansum(0.5 * (
            (VMR[:, 0:-2:1, :, :] + VMR[:, 1:-1:1, :, :]) *
            (plev[None, 0:-2:1, None, None] - plev[None, 1:-1:1, None, None])),
                                                      axis=1)

        # Create a dataset
        toz_ds = xr.DataArray(
            name="TOZ",
            data=TOZ,
            coords={
                'time': (['time'], times_plus),
                'lat': (['lat'], ds["lat"].values),
                'lon': (['lon'], ds["lon"].values)
            },
            dims=["time", "lat", "lon"],
        ).to_dataset()
        toz_ds.to_netcdf(baseurl + "/TOZ_{}.nc".format(scenario))

        logging.info(
            "[CMIP6_ozone] Results written to file covering period {} to {}".
            format(times_plus[0], times_plus[-1]))
        logging.info("[CMIP6_ozone] TOZ min {} to max {} and mean {}".format(
            np.nanmin(TOZ), np.nanmax(TOZ), np.nanmean(TOZ)))
Ejemplo n.º 25
0
def compute_multimodel_mean(V):
    """
    for now require spatial grids are fixed
    assume we have spatio-temporal data
    """
    v0 = V[list(V.keys())[0]]
    ds = [V[v].ds for v in V]
    tm = None
    if v0.temporal():
        tb = []
        for v in V:
            V[v].ds['time'] = [
                cftime.DatetimeNoLeap(t.dt.year, t.dt.month, t.dt.day)
                for t in V[v].ds['time']
            ]
            tbnd = V[v].timeBounds()
            tb.append(tbnd)
        t0 = max([t[0] for t in tb])
        tf = min([t[1] for t in tb])
        t0 = cftime.DatetimeNoLeap(t0.dt.year, t0.dt.month, 1)
        tf = cftime.DatetimeNoLeap(tf.dt.year, tf.dt.month, 28)
        ds = [d.sel(time=slice(t0, tf)) for d in ds]
        tm = ds[0]['time_measure']
    if v0.spatial() and not same_space_grid(V):
        res = 1.0
        lat = np.linspace(-90, 90, int(round(180 / res)) + 1)
        lon = np.linspace(0, 360, int(round(360 / res)) + 1)
        lat = 0.5 * (lat[:-1] + lat[1:])
        lon = 0.5 * (lon[:-1] + lon[1:])
        ds = [
            d.interp(coords={
                'lat': lat,
                'lon': lon
            }, method='nearest') for d in ds
        ]
    ds = [d[v0.varname] for d in ds]
    ds = xr.align(*ds, join='override')
    ds = xr.concat(ds, dim='model').mean(dim='model')
    mn = Variable(da=ds, varname=v0.varname, time_measure=tm)
    mn.ds[mn.varname].attrs = v0.ds[v0.varname].attrs
    return mn
Ejemplo n.º 26
0
def main():
    """ main function"""
    global glob

    # get the list of files
    filePaths = get_file_paths(args.f, comm.Get_rank(), args.x, args.v)

    # determine beginning and ending dates for files to be generated
    user_date0_out = user_date1_out = None
    if args.d0:
        user_date0_out = cft.DatetimeNoLeap(year=int(args.d0[0:4]),
                                            month=int(args.d0[5:7]),
                                            day=1)
    if args.d1:
        user_date1_out = next_month_1st(
            cft.DatetimeNoLeap(year=int(args.d1[0:4]),
                               month=int(args.d1[5:7]),
                               day=1))
    # now get the global information
    glob.obtain_global_info(filePaths, comm, user_date0_out, user_date1_out)

    # broadcast/receive the global information:
    glob = comm.bcast(glob, root=0)

    avg_intervals = preprocess_out_files()

    # print global information
    if comm.Get_rank() == 0:
        print("Input begin date: ", glob.date0_in)
        print("Input end date: ", glob.date1_in)
        print("Output begin date: ", glob.date0_out)
        print("Output end date: ", glob.date1_out)
        print("Number of monthly avgs to generate", glob.nmonths)
        print("Max number of months per core:", glob.m_per_proc)

    # generate the avg files:
    process_out_files(avg_intervals)

    if comm.Get_rank() == 0:
        print("done.")
Ejemplo n.º 27
0
def _get_centered_timecoord(cube):
    """Fix time coordinate.

    Time points start at the beginning of month at 00:00:00.
    """
    time = cube.coord('time')
    times = time.units.num2date(time.points)

    # get bounds
    starts = [
        cftime.DatetimeNoLeap(c.year, c.month, 1)
        for c in times
    ]
    ends = [
        cftime.DatetimeNoLeap(c.year, c.month + 1, 1) if c.month < 12
        else cftime.DatetimeNoLeap(c.year + 1, 1, 1)
        for c in times
    ]
    time.bounds = time.units.date2num(np.stack([starts, ends], -1))

    # get points
    time.points = [np.mean((t1, t2)) for t1, t2 in time.bounds]
def state_list_with_inconsistent_calendars(base_state, numpy):
    state_list = []
    state_times = [
        cftime.DatetimeNoLeap(2000, 1, 1),
        cftime.Datetime360Day(2000, 1, 2)
    ]
    for i in range(2):
        new_state = copy.deepcopy(base_state)
        for name in set(new_state.keys()).difference(["time"]):
            new_state[name].view[:] = numpy.random.randn(
                *new_state[name].extent)
        state_list.append(new_state)
        new_state["time"] = state_times[i]
    return state_list
Ejemplo n.º 29
0
def test_assert_all_valid_date_type(date_type, index):
    import cftime
    if date_type is cftime.DatetimeNoLeap:
        mixed_date_types = [
            date_type(1, 1, 1),
            cftime.DatetimeAllLeap(1, 2, 1)
        ]
    else:
        mixed_date_types = [date_type(1, 1, 1), cftime.DatetimeNoLeap(1, 2, 1)]
    with pytest.raises(TypeError):
        assert_all_valid_date_type(mixed_date_types)

    with pytest.raises(TypeError):
        assert_all_valid_date_type([1, date_type(1, 1, 1)])

    assert_all_valid_date_type([date_type(1, 1, 1), date_type(1, 2, 1)])
Ejemplo n.º 30
0
def perform_cmip6_query(conf, query_string):
    df_sub = conf.df.query(query_string)
    if (df_sub.zstore.values.size == 0):
        return df_sub

    mapper = conf.fs.get_mapper(df_sub.zstore.values[-1])
    ds = xr.open_zarr(mapper, consolidated=True)

    time_object = ds["time"].values[0]

    # Convert if necesssary
    if time_object.year == 1:

        times = ds["time"].values
        times_plus_2000 = []
        for t in times:
            times_plus_2000.append(
                cftime.DatetimeNoLeap(t.year + 2000, t.month, t.day, t.hour))
        ds["time"].values = times_plus_2000
        ds = xr.decode_cf(ds)
    return ds