def _make_partially_collapsed_coord(self, coord, grid, guessed_axis): """ Make a new DimCoord which represents a partially collapsed (aggregated into bins) coordinate. This dimcoord will have a grid :type coord: data_io.Coord.Coord :param coord: Coordinate to partially collapse :type grid: aggregation.aggregation_grid.AggregationGrid :param grid: grid on which this coordinate will aggregate :type guessed_axis: str :param guessed_axis: String identifier of the axis to which this coordinate belongs (e.g. 'T', 'X') :return: DimCoord """ if grid.is_time or guessed_axis == 'T': # Ensure that the limits are date/times. dt = parse_datetime.convert_datetime_components_to_datetime(grid.start, True) grid_start = Subset._convert_datetime_to_coord_unit(coord, dt) dt = parse_datetime.convert_datetime_components_to_datetime(grid.end, False) grid_end = Subset._convert_datetime_to_coord_unit(coord, dt) grid_delta = grid.delta else: # Assume to be a non-time axis (grid_start, grid_end) = Subset._fix_non_circular_limits(float(grid.start), float(grid.end)) grid_delta = float(grid.delta) new_coordinate_grid = aggregation_grid_array(grid_start, grid_end, grid_delta, grid.is_time, coord) new_coord = DimCoord(new_coordinate_grid, var_name=coord.name(), standard_name=coord.standard_name, units=coord.units) if len(new_coord.points) == 1: new_coord.bounds = [[grid_start, grid_end]] else: new_coord.guess_bounds() return new_coord
def aggregation_grid_array(start, end, delta, is_time, coordinate): if is_time: start_dt = Subset._convert_coord_unit_to_datetime(coordinate, start) end_dt = Subset._convert_coord_unit_to_datetime(coordinate, end) # Some logic to find the mid point to start on if delta.year > 0: start_dt = add_year_midpoint(start_dt, delta.year) # We make an assumption here that half a month is always 15 days. if delta.month > 0: start_dt = add_month_midpoint(start_dt, delta.month) dt = datetime.timedelta(days=delta.day, seconds=delta.second, microseconds=0, milliseconds=0, minutes=delta.minute, hours=delta.hour, weeks=0) start_dt += dt / 2 new_time_grid = [] new_time = start_dt while new_time < end_dt: new_time_grid.append(Subset._convert_datetime_to_coord_unit(coordinate, new_time)) new_year = new_time.year + delta.year new_month = new_time.month + delta.month if new_month > 12: new_month, new_year = month_past_end_of_year(new_month, new_year) # TODO this is a slightly inelegant fix for the problem of something like 30th Jan +1 month # Need to work out what correct behaviour should be in this case. try: new_time = new_time.replace(year=new_year, month=new_month) except ValueError: new_time += datetime.timedelta(days=28) new_time += datetime.timedelta(days=delta.day, seconds=delta.second, microseconds=0, milliseconds=0, minutes=delta.minute, hours=delta.hour, weeks=0) new_time_grid = numpy.array(new_time_grid) return new_time_grid else: new_grid = numpy.arange(start + delta / 2, end + delta / 2, delta) return new_grid