def _update_time(input_time: Coord, advected_cube: Cube, timestep: timedelta) -> None: """Increment validity time on the advected cube Args: input_time: Time coordinate from source cube advected_cube: Cube containing advected data (modified in place) timestep: Time difference between the advected output and the source """ original_datetime = next(input_time.cells())[0] new_datetime = original_datetime + timestep new_time = input_time.units.date2num(new_datetime) time_coord_name = "time" time_coord_spec = TIME_COORDS[time_coord_name] time_coord = advected_cube.coord(time_coord_name) time_coord.points = new_time time_coord.convert_units(time_coord_spec.units) time_coord.points = round_close(time_coord.points, dtype=time_coord_spec.dtype)
def _calculate_forecast_period( time_coord: Coord, frt_coord: Coord, dim_coord: bool = False, coord_spec: TimeSpec = TIME_COORDS["forecast_period"], ) -> Coord: """ Calculate a forecast period from existing time and forecast reference time coordinates. Args: time_coord: Time coordinate frt_coord: Forecast reference coordinate dim_coord: If true, create an iris.coords.DimCoord instance. Default is to create an iris.coords.AuxCoord. coord_spec: Specification of units and dtype for the forecast_period coordinate. Returns: Forecast period coordinate corresponding to the input times and forecast reference times specified Warns: UserWarning: If any calculated forecast periods are negative """ # use cell() access method to get datetime.datetime instances time_points = np.array([c.point for c in time_coord.cells()]) forecast_reference_time_points = np.array([c.point for c in frt_coord.cells()]) required_lead_times = time_points - forecast_reference_time_points required_lead_times = np.array([x.total_seconds() for x in required_lead_times]) if time_coord.bounds is not None: time_bounds = np.array([c.bound for c in time_coord.cells()]) required_lead_time_bounds = time_bounds - forecast_reference_time_points required_lead_time_bounds = np.array( [[b.total_seconds() for b in x] for x in required_lead_time_bounds] ) else: required_lead_time_bounds = None coord_type = DimCoord if dim_coord else AuxCoord result_coord = coord_type( required_lead_times, standard_name="forecast_period", bounds=required_lead_time_bounds, units="seconds", ) result_coord.convert_units(coord_spec.units) if coord_spec.dtype not in FLOAT_TYPES: result_coord.points = round_close(result_coord.points) if result_coord.bounds is not None: result_coord.bounds = round_close(result_coord.bounds) result_coord.points = result_coord.points.astype(coord_spec.dtype) if result_coord.bounds is not None: result_coord.bounds = result_coord.bounds.astype(coord_spec.dtype) if np.any(result_coord.points < 0): msg = ( "The values for the time {} and " "forecast_reference_time {} coordinates from the " "input cube have produced negative values for the " "forecast_period. A forecast does not generate " "values in the past." ).format(time_coord.points, frt_coord.points) warnings.warn(msg) return result_coord