def process( self, cubes_in: Union[List[Cube], Cube, CubeList], cycletime: Optional[str] = None, ) -> Cube: """ Prepares merged input cube for cycle and grid blending. Makes updates to metadata (attributes and time-type coordinates) ONLY in so far as these are needed to ensure inputs can be merged into a single cube. Args: cubes_in: Cubes to be merged. cycletime: The cycletime in a YYYYMMDDTHHMMZ format e.g. 20171122T0100Z. Can be used in rationalise_blend_time_coordinates. Returns: Merged cube. Raises: ValueError: If self.blend_coord is not present on all cubes (unless blending over models) """ cubelist = ([cubes_in.copy()] if isinstance(cubes_in, iris.cube.Cube) else [cube.copy() for cube in cubes_in]) if self.record_run_attr is not None and self.model_id_attr is not None: set_record_run_attr(cubelist, self.record_run_attr, self.model_id_attr) if "model" in self.blend_coord: cubelist = [self._remove_blend_time(cube) for cube in cubelist] cubelist = [ self._remove_deprecation_warnings(cube) for cube in cubelist ] if (self.weighting_coord is not None and "forecast_period" in self.weighting_coord): # if blending models using weights by forecast period, unify # forecast periods (assuming validity times are identical); # method returns a new cubelist with copies of input cubes cubelist = rebadge_forecasts_as_latest_cycle( cubelist, cycletime=cycletime) # check all input cubes have the blend coordinate for cube in cubelist: if "model" not in self.blend_coord and not cube.coords( self.blend_coord): raise ValueError("{} coordinate is not present on all input " "cubes".format(self.blend_coord)) # create model ID and model configuration coordinates if blending # different models if "model" in self.blend_coord and self.model_id_attr is not None: self._create_model_coordinates(cubelist) # merge resulting cubelist result = MergeCubes()(cubelist, check_time_bounds_ranges=True) return result
def test_cubelist(self): """Test a list of cubes is returned with the latest frt""" expected = self.cube_late.copy() result = rebadge_forecasts_as_latest_cycle( [self.cube_early, self.cube_late]) self.assertIsInstance(result, iris.cube.CubeList) self.assertEqual(len(result), 2) for cube in result: for coord in ["forecast_reference_time", "forecast_period"]: self.assertEqual(cube.coord(coord), expected.coord(coord))
def test_single_cube_with_cycletime(self): """Test a single cube has its forecast reference time and period updated if cycletime is specified""" expected_frt_point = ( self.cube_late.coord("forecast_reference_time").points[0] + 2*3600) expected_fp_point = ( self.cube_late.coord("forecast_period").points[0] - 2*3600) result, = rebadge_forecasts_as_latest_cycle( [self.cube_late], cycletime=self.cycletime) self.assertEqual(result.coord("forecast_reference_time").points[0], expected_frt_point) self.assertEqual(result.coord("forecast_period").points[0], expected_fp_point)
def test_cycletime(self): """Test a list of cubes using the cycletime argument""" expected_frt_point = ( self.cube_late.coord("forecast_reference_time").points[0] + 2*3600) expected_fp_point = ( self.cube_late.coord("forecast_period").points[0] - 2*3600) result = rebadge_forecasts_as_latest_cycle( [self.cube_early, self.cube_late], cycletime=self.cycletime) for cube in result: self.assertEqual(cube.coord("forecast_reference_time").points[0], expected_frt_point) self.assertEqual(cube.coord("forecast_period").points[0], expected_fp_point)