Example #1
0
def iter_boolean_groups_from_time_regions(time_regions,
                                          tvar,
                                          yield_subset=False,
                                          raise_if_incomplete=True):
    """
    :param time_regions: Sequence of nested time region dictionaries.

    >>> [[{'month':[1,2],'year':[2024]},...],...]

    :param tvar: A temporal variable object.
    :type tvar: :class:`ocgis.TemporalVariable`
    :param bool yield_subset: If ``True``, yield a tuple with the subset of ``tvar``.
    :param bool raise_if_incomplete: If ``True``, raise an exception if the season is incomplete.
    :returns: boolean ndarray vector with yld.shape == tvar.shape
    :raises: IncompleteSeasonError
    """
    for sub_time_regions in time_regions:
        # incomplete seasons are searched for in the nested loop. this indicates if a time region group should be
        # considered a season.
        is_complete = True
        idx_append = np.array([], dtype=int)
        for time_region in sub_time_regions:
            sub, idx = tvar.get_time_region(time_region, return_indices=True)
            # insert a check to ensure there are months present for each time region
            months = set([d.month for d in sub.value_datetime])
            try:
                assert (months == set(time_region['month']))
            except AssertionError:
                if raise_if_incomplete:
                    for m in time_region['month']:
                        if m not in months:
                            raise IncompleteSeasonError(time_region, month=m)
                else:
                    is_complete = False
            idx_append = np.append(idx_append, idx)

        # if the season is complete append, otherwise pass to next iteration.
        if is_complete:
            dgroup = np.zeros(tvar.shape[0], dtype=bool)
            dgroup[idx_append] = True
        else:
            continue

        if yield_subset:
            yld = (dgroup, tvar[dgroup])
        else:
            yld = dgroup

        yield yld
Example #2
0
def get_time_regions(seasons, dates, raise_if_incomplete=True):
    """
    >>> seasons = [[6,7,8],[9,10,11],[12,1,2]]
    >>> dates = <vector of datetime objects>
    """

    # extract the years from the data vector collapsing them to a unique set then sort in ascending order
    years = list(set([d.year for d in dates]))
    years.sort()
    # determine if any of the seasons are interannual
    interannual_check = list(map(get_is_interannual, seasons))
    # holds the return value
    time_regions = []
    # the interannual cases requires two time region sequences to properly extract
    if any(interannual_check):
        # loop over years first to ensure each year is accounted for in the time region output
        for ii_year, year in enumerate(years):
            # the interannual flag is used internally for simple optimization
            for ic, cg in zip(interannual_check, seasons):
                # if no exception is raised for an incomplete season, this flag indicate whether to append to the output
                append_to_time_regions = True
                if ic:
                    # copy and sort in descending order the season because december of the current year should be first.
                    _cg = deepcopy(cg)
                    _cg.sort()
                    _cg.reverse()
                    # look for the interannual break and split the season into the current year and next year.
                    diff = np.abs(np.diff(_cg))
                    split_base = np.arange(1, len(_cg))
                    split_indices = split_base[diff > 1]
                    split = np.split(_cg, split_indices)
                    # will hold the sub-element time regions
                    sub_time_region = []
                    for ii_split, s in enumerate(split):
                        try:
                            to_append_sub = {'year': [years[ii_year + ii_split]], 'month': s.tolist()}
                            sub_time_region.append(to_append_sub)
                        # there may not be another year of data for an interannual season. we DO NOT keep incomplete
                        # seasons.
                        except IndexError:
                            # don't just blow through an incomplete season unless asked to
                            if raise_if_incomplete:
                                raise IncompleteSeasonError(None, None, None)
                            else:
                                append_to_time_regions = False
                                continue
                    to_append = sub_time_region
                else:
                    to_append = [{'year': [year], 'month': cg}]
                if append_to_time_regions:
                    time_regions.append(to_append)
    # without interannual seasons the time regions are unique combos of the years and seasons designations
    else:
        for year, season in itertools.product(years, seasons):
            time_regions.append([{'year': [year], 'month': season}])

    # ensure each time region is valid. if it is not, remove it from the returned list
    td = TemporalVariable(value=dates, dimensions=constants.DimensionName.TEMPORAL)
    remove = []
    for idx, time_region in enumerate(time_regions):
        try:
            for sub_time_region in time_region:
                td.get_time_region(sub_time_region)
        except EmptySubsetError:
            remove.append(idx)
    for xx in remove:
        time_regions.pop(xx)

    return time_regions