예제 #1
0
 def test_raise_error_no_time_coordinate(self):
     """Test that the function raises an error if no time coordinate."""
     cube = set_up_wxcube()
     cube.coord('time').rename('nottime')
     msg = "cube must have time coordinate"
     with self.assertRaisesRegex(CoordinateNotFoundError, msg):
         update_daynight(cube)
예제 #2
0
    def test_wxcode_updated_on_latlon(self):
        """Test Correct wxcodes returned for lat lon cube."""
        cube = set_up_wxcube_lat_lon()
        cube.data = self.cube_data

        expected_result = np.array(
            [[[0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1],
              [2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3],
              [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5],
              [6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6],
              [7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7],
              [8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8],
              [9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10],
              [13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14],
              [15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15],
              [16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17],
              [18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18],
              [19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20],
              [22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23],
              [25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26],
              [27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27],
              [28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
               29]]])
        result = update_daynight(cube)
        self.assertArrayEqual(result.data, expected_result)
예제 #3
0
    def test_wxcode_time_different_seconds(self):
        """ Test code works if time coordinate has a difference in the number
        of seconds, which should round to the same time in hours and minutes.
        This was raised by changes to cftime which altered its precision."""
        time_origin = "hours since 1970-01-01 00:00:00"
        calendar = "gregorian"
        dateval = datetime.datetime(2018, 9, 12, 5, 42, 59)
        numdateval = date2num(dateval, time_origin, calendar)
        time_points = [numdateval]

        cube = set_up_wxcube(time_points=time_points)
        cube.data = self.cube_data
        cube = iris.util.squeeze(cube)
        expected_result = np.array(
            [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1],
             [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3],
             [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5],
             [6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6],
             [7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7],
             [8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8],
             [9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10],
             [13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14],
             [15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15],
             [16, 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17],
             [18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18],
             [19, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20],
             [22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23],
             [25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26],
             [27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27],
             [28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29]])
        result = update_daynight(cube)

        self.assertArrayEqual(result.data, expected_result)
        self.assertEqual(result.data.shape, (16, 16))
예제 #4
0
    def test_wxcode_time_as_attribute(self):
        """ Test code works if time is an attribute not a dimension """
        cube = set_up_wxcube()
        cube.data = self.cube_data
        cube = iris.util.squeeze(cube)
        expected_result = np.array(
            [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1],
             [2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3],
             [5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5],
             [6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6],
             [7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7],
             [8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8],
             [9, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10],
             [13, 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14],
             [15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15],
             [16, 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17],
             [18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18],
             [19, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20],
             [22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23],
             [25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26],
             [27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27],
             [28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29]])
        result = update_daynight(cube)

        self.assertArrayEqual(result.data, expected_result)
        self.assertEqual(result.data.shape, (16, 16))
예제 #5
0
 def test_basic_lat_lon(self):
     """Test that the function returns a weather code lat lon cube.."""
     cube = set_up_wxcube_lat_lon()
     result = update_daynight(cube)
     self.assertIsInstance(result, Cube)
     self.assertEqual(result.name(), 'weather_code')
     self.assertEqual(result.units, Unit("1"))
     self.assertArrayEqual(result.attributes['weather_code'], self.wxcode)
     self.assertEqual(result.attributes['weather_code_meaning'],
                      self.wxmeaning)
예제 #6
0
 def test_wxcode_time_as_array(self):
     """ Test code works if time is an array of dimension > 1 """
     num1 = datetime_to_numdateval(year=2018,
                                   month=9,
                                   day=12,
                                   hour=5,
                                   minutes=0)
     num2 = datetime_to_numdateval(year=2018,
                                   month=9,
                                   day=12,
                                   hour=6,
                                   minutes=0)
     num3 = datetime_to_numdateval(year=2018,
                                   month=9,
                                   day=12,
                                   hour=7,
                                   minutes=0)
     cube = set_up_wxcube(time_points=[num1, num2, num3])
     expected_result = np.ones((3, 16, 16))
     expected_result[0, :, :] = 0
     result = update_daynight(cube)
     self.assertArrayEqual(result.data, expected_result)
예제 #7
0
    def process(self, cubes):
        """Apply the decision tree to the input cubes to produce weather
        symbol output.

        Args:
            cubes (iris.cube.CubeList):
                A cubelist containing the diagnostics required for the
                weather symbols decision tree, these at co-incident times.

        Returns:
            symbols (iris.cube.Cube):
                A cube of weather symbols.
        """
        # Check input cubes contain required data
        self.check_input_cubes(cubes)

        # Construct graph nodes dictionary
        graph = {
            key: [self.queries[key]['succeed'], self.queries[key]['fail']]
            for key in self.queries.keys()
        }

        # Search through tree for all leaves (weather code end points)
        defined_symbols = []
        for item in self.queries.values():
            for value in item.values():
                if isinstance(value, int):
                    defined_symbols.append(value)

        # Create symbol cube
        symbols = self.create_symbol_cube(cubes[0])

        # Loop over possible symbols
        for symbol_code in defined_symbols:
            # In current decision tree
            # start node is heavy_precipitation
            routes = self.find_all_routes(graph, 'heavy_precipitation',
                                          symbol_code)

            # Loop over possible routes from root to leaf
            for route in routes:
                conditions = []
                for i_node in range(len(route) - 1):
                    current_node = route[i_node]
                    current = copy.copy(self.queries[current_node])
                    try:
                        next_node = route[i_node + 1]
                    except KeyError:
                        next_node = symbol_code

                    if current['fail'] == next_node:
                        (current['threshold_condition'],
                         current['condition_combination']) = (
                             self.invert_condition(current))

                    conditions.extend(self.create_condition_chain(current))

                test_chain = self.format_condition_chain(conditions)

                # Set grid locations to suitable weather symbol
                symbols.data[np.where(eval(test_chain))] = symbol_code
        # Update symbols for day or night.
        symbols = update_daynight(symbols)
        return symbols