def test_return_type(self):
        """Test that an iris cubelist is returned."""

        result = TemporalInterpolation(interval_in_minutes=180).process(
            self.cube_time_0, self.cube_time_1)
        self.assertIsInstance(result, iris.cube.CubeList)
 def test_raises_error_with_no_keyword_args(self):
     """Test __init__ raises a ValueError if both interval_in_minutes
     and times keywords are unset."""
     msg = "TemporalInterpolation: One of"
     with self.assertRaisesRegex(ValueError, msg):
         TemporalInterpolation()
def process(cube_0, cube_1, interval_in_mins=None, in_times=None,
            interpolation_method='linear'):
    """Module to interpolate data between validity times.

    Interpolate data to intermediate times between the validity times of two
    cubes. This can be used to fill in missing data (e.g. for radar fields)
    or to ensure data is available at the required intervals when model data
    is not available at these times.

    Args:
        cube_0 (iris.cube.Cube):
            Cube containing the data at the beginning.
        cube_1 (iris.cube.Cube):
            Cube containing the data at the end.
        interval_in_mins (int):
            Specifies the interval in minutes at which to interpolate between
            the two input cubes.
            A number of minutes which does not divide up the interval equally
            will raise an exception.
            If intervals_in_mins is set then in_times can not be used.
            Default is None.
        in_times (str):
            Specifies the times in the format {YYYYMMDD}T{HHMM}Z
            at which to interpolate between the two input cubes.
            Where {YYYYMMDD} is year, month, day and {HHMM} is hour and minutes
            e.g 20180116T0100Z. More than one time can be provided separated
            by a space.
            If in_times are set, interval_in_mins can not be used.
            Default is None.
        interpolation_method (str):
            ["linear", "solar", "daynight"]
            Specifies the interpolation method;
            solar interpolates using the solar elevation,
            daynight uses linear interpolation but sets night time points to
            0.0 linear is linear interpolation.
            Default is linear.

    Returns:
        result (iris.cube.Cubelist):
            A list of cubes interpolated to the desired times. The
            interpolated cubes will always be in chronological order of
            earliest to latest regardless of the order of the input.
    """
    time_0, = iris_time_to_datetime(cube_0.coord('time'))
    time_1, = iris_time_to_datetime(cube_1.coord('time'))
    if time_0 < time_1:
        cube_start = cube_0
        cube_end = cube_1
    else:
        cube_start = cube_1
        cube_end = cube_0

    interval = interval_in_mins
    method = interpolation_method
    if in_times is None:
        times = in_times
    else:
        times = []
        for timestr in in_times:
            times.append(cycletime_to_datetime(timestr))

    result = (
        TemporalInterpolation(interval_in_minutes=interval,
                              times=times,
                              interpolation_method=method).process(cube_start,
                                                                   cube_end))
    return result
示例#4
0
def main(argv=None):
    """
    Interpolate data to intermediate times between the validity times of two
    cubes. This can be used to fill in missing data (e.g. for radar fields) or
    to ensure data is available at the required intervals when model data is
    not available at these times.
    """
    parser = ArgParser(description='Interpolate data between validity times ')

    parser.add_argument('infiles',
                        metavar='INFILES',
                        nargs=2,
                        help='Files contain the data at the beginning'
                        ' and end of the period (2 files required).')

    group = parser.add_mutually_exclusive_group(required=True)

    group.add_argument("--interval_in_mins",
                       metavar="INTERVAL_IN_MINS",
                       default=None,
                       type=int,
                       help="Specifies the interval in minutes"
                       " at which to interpolate "
                       "between the two input cubes."
                       " A number of minutes which does not "
                       "divide up the interval equally will "
                       "raise an exception. If intervals_in_mins "
                       "is set then times can not be set.")

    group.add_argument("--times",
                       metavar="TIMES",
                       default=None,
                       nargs="+",
                       type=str,
                       help="Specifies the times in the format "
                       "{YYYYMMDD}T{HHMM}Z "
                       " at which to interpolate "
                       "between the two input cubes."
                       "Where {YYYYMMDD} is year, month day "
                       "and {HHMM} is hour and minutes e.g "
                       "20180116T0100Z. More than one time"
                       "can be provided separated by a space "
                       "but if times are set interval_in_mins "
                       "can not be set")

    parser.add_argument("--interpolation_method",
                        metavar="INTERPOLATION_METHOD",
                        default="linear",
                        choices=["linear", "solar", "daynight"],
                        help="Specifies the interpolation method; "
                        "solar interpolates using the solar elevation, "
                        "daynight uses linear interpolation but sets"
                        " night time points to 0.0, "
                        "linear is linear interpolation. "
                        "Default is linear.")

    parser.add_argument("--output_files",
                        metavar="OUTPUT_FILES",
                        required=True,
                        nargs="+",
                        help="List of output files."
                        " The interpolated files will always be"
                        " in the chronological order of"
                        " earliest to latest "
                        " regardless of the order of the infiles.")

    args = parser.parse_args(args=argv)

    cube_0 = load_cube(args.infiles[0])
    cube_1 = load_cube(args.infiles[1])
    time_0, = iris_time_to_datetime(cube_0.coord('time'))
    time_1, = iris_time_to_datetime(cube_1.coord('time'))
    if time_0 < time_1:
        cube_start = cube_0
        cube_end = cube_1
    else:
        cube_start = cube_1
        cube_end = cube_0

    interval = args.interval_in_mins
    method = args.interpolation_method
    if args.times is None:
        times = args.times
    else:
        times = []
        for timestr in args.times:
            times.append(cycletime_to_datetime(timestr))

    interpolated_cubes = (TemporalInterpolation(
        interval_in_minutes=interval, times=times,
        interpolation_method=method).process(cube_start, cube_end))

    len_files = len(args.output_files)
    len_cubes = len(interpolated_cubes)
    if len_files == len_cubes:
        for i, cube_out in enumerate(interpolated_cubes):
            save_netcdf(cube_out, args.output_files[i])
    else:
        msg = ("Output_files do not match cubes created. "
               "{} files given but {} required.".format(len_files, len_cubes))
        raise ValueError(msg)
 def test_unknown_method(self):
     """Test __init__ raises a ValueError if method unknown."""
     msg = "TemporalInterpolation: Unknown interpolation method"
     with self.assertRaisesRegex(ValueError, msg):
         TemporalInterpolation(interval_in_minutes=60,
                               interpolation_method='invalid')
示例#6
0
def process(start_cube: cli.inputcube,
            end_cube: cli.inputcube,
            *,
            interval_in_mins: int = None,
            times: cli.comma_separated_list = None,
            interpolation_method='linear'):
    """Interpolate data between validity times.

    Interpolate data to intermediate times between the validity times of two
    cubes. This can be used to fill in missing data (e.g. for radar fields)
    or to ensure data is available at the required intervals when model data
    is not available at these times.

    Args:
        start_cube (iris.cube.Cube):
            Cube containing the data at the beginning.
        end_cube (iris.cube.Cube):
            Cube containing the data at the end.
        interval_in_mins (int):
            Specifies the interval in minutes at which to interpolate between
            the two input cubes.
            A number of minutes which does not divide up the interval equally
            will raise an exception.
            If intervals_in_mins is set then times can not be used.
        times (str):
            Specifies the times in the format {YYYYMMDD}T{HHMM}Z
            at which to interpolate between the two input cubes.
            Where {YYYYMMDD} is year, month, day and {HHMM} is hour and minutes
            e.g 20180116T0100Z. More than one time can be provided separated
            by a comma.
            If times are set, interval_in_mins can not be used.
        interpolation_method (str):
            ["linear", "solar", "daynight"]
            Specifies the interpolation method;
            solar interpolates using the solar elevation,
            daynight uses linear interpolation but sets night time points to
            0.0 linear is linear interpolation.

    Returns:
        iris.cube.CubeList:
            A list of cubes interpolated to the desired times. The
            interpolated cubes will always be in chronological order of
            earliest to latest regardless of the order of the input.
    """
    from improver.utilities.cube_manipulation import merge_cubes
    from improver.utilities.temporal import (
        cycletime_to_datetime, iris_time_to_datetime)
    from improver.utilities.temporal_interpolation import TemporalInterpolation

    time_start, = iris_time_to_datetime(start_cube.coord('time'))
    time_end, = iris_time_to_datetime(end_cube.coord('time'))
    if time_end < time_start:
        # swap cubes
        start_cube, end_cube = end_cube, start_cube

    if times is not None:
        times = [cycletime_to_datetime(timestr) for timestr in times]

    result = TemporalInterpolation(
        interval_in_minutes=interval_in_mins, times=times,
        interpolation_method=interpolation_method
    ).process(start_cube, end_cube)
    return merge_cubes(result)