Пример #1
0
    def construct_condition(extract_constraint, condition,
                            probability_threshold):
        """
        Create a string representing a comparison condition.

        Args:
            extract_constraint (str or list of str):
                A string, or list of strings, encoding iris constraints
                that will be used to extract the correct diagnostic cube
                (by name) from the input cube list and the correct threshold
                from that cube.
                A list should contain only cube names, operators and numbers,
                e.g. ["probability_of_lwe_snowfall_rate_above_threshold", "-",
                "probability_of_rainfall_rate_above_threshold", "*", "0.7"]
            condition (str):
                The condition statement (e.g. greater than, >).
            probability_threshold (float):
                The probability value to use in the comparison.

        Returns:
            string:
                The formatted condition statement,
                e.g.::

                  cubes.extract(Constraint(
                          name='probability_of_rainfall_rate_above_threshold',
                          coord_values={'threshold': 0.03})
                                )[0].data < 0.5)
        """
        if isinstance(extract_constraint, list):
            formatted_str = ""

            for item in extract_constraint:
                if is_variable(item):
                    formatted_str += f" cubes.extract({item})[0].data"
                else:
                    formatted_str += " " + item
            return f"({formatted_str}) {condition} {probability_threshold}"
        return "cubes.extract({})[0].data {} {}".format(
            extract_constraint, condition, probability_threshold)
Пример #2
0
    def create_condition_chain(self, test_conditions: Dict) -> List:
        """
        Construct a list of all the conditions specified in a single query.

        Args:
            test_conditions:
                A query from the decision tree.

        Returns:
            A valid condition chain is defined recursively:
            (1) If each a_1, ..., a_n is an extract expression (i.e. a
            constraint, or a list of constraints,
            operator strings and floats), and b is either "AND", "OR" or "",
            then [[a1, ..., an], b] is a valid condition chain.
            (2) If a1, ..., an are each valid conditions chain, and b is
            either "AND" or "OR", then [[a1, ..., an], b] is a valid
            condition chain.
        """
        conditions = []
        loop = 0
        for diagnostic, p_threshold, d_threshold in zip(
            test_conditions["diagnostic_fields"],
            test_conditions["probability_thresholds"],
            test_conditions["diagnostic_thresholds"],
        ):

            loop += 1

            if isinstance(diagnostic, list):
                # We have a list which could contain variable names, operators and
                # numbers. The variable names need converting into Iris Constraint
                # syntax while operators and numbers remain unchanged.
                # We expect an entry in p_threshold for each variable name, so
                # d_threshold_index is used to track these.
                d_threshold_index = -1
                extract_constraint = []
                for item in diagnostic:
                    if is_variable(item):
                        # Add a constraint from the variable name and threshold value
                        d_threshold_index += 1
                        extract_constraint.append(
                            self.construct_extract_constraint(
                                item,
                                d_threshold[d_threshold_index],
                                self.coord_named_threshold,
                            )
                        )
                    else:
                        # Add this operator or variable as-is
                        extract_constraint.append(item)
            else:
                # Non-lists are assumed to be constraints on a single variable.
                extract_constraint = self.construct_extract_constraint(
                    diagnostic, d_threshold, self.coord_named_threshold
                )
            conditions.append(
                [
                    extract_constraint,
                    test_conditions["threshold_condition"],
                    p_threshold,
                ]
            )
        condition_chain = [conditions, test_conditions["condition_combination"]]
        return condition_chain
Пример #3
0
    def create_condition_chain(self, test_conditions):
        """
        A wrapper to call the construct_condition function for all the
        conditions specified in a single query.

        Args:
            test_conditions (dict):
                A query from the decision tree.
        Returns:
            list of str:
                A list of strings that describe the conditions comprising the
                query.
                e.g.::

                  [
                    "(cubes.extract(Constraint(
                          name='probability_of_rainfall_rate_above_threshold',
                          coord_values={'threshold': 0.03})
                     )[0].data < 0.5) |
                     (cubes.extract(Constraint(
                          name=
                          'probability_of_lwe_snowfall_rate_above_threshold',
                          coord_values={'threshold': 0.03})
                     )[0].data < 0.5)"
                  ]
        """
        conditions = []
        loop = 0
        for diagnostic, p_threshold, d_threshold in zip(
                test_conditions["diagnostic_fields"],
                test_conditions["probability_thresholds"],
                test_conditions["diagnostic_thresholds"],
        ):

            loop += 1

            if isinstance(diagnostic, list):
                # We have a list which could contain variable names, operators and
                # numbers. The variable names need converting into Iris Constraint
                # syntax while operators and numbers remain unchanged.
                # We expect an entry in p_threshold for each variable name, so
                # d_threshold_index is used to track these.
                d_threshold_index = -1
                extract_constraint = []
                for item in diagnostic:
                    if is_variable(item):
                        # Add a constraint from the variable name and threshold value
                        d_threshold_index += 1
                        extract_constraint.append(
                            self.construct_extract_constraint(
                                item,
                                d_threshold[d_threshold_index],
                                self.coord_named_threshold,
                            ))
                    else:
                        # Add this operator or variable as-is
                        extract_constraint.append(item)
            else:
                # Non-lists are assumed to be strings containing one variable name.
                extract_constraint = self.construct_extract_constraint(
                    diagnostic, d_threshold, self.coord_named_threshold)
            conditions.append(
                self.construct_condition(
                    extract_constraint,
                    test_conditions["threshold_condition"],
                    p_threshold,
                ))
        condition_chain = WeatherSymbols.format_condition_chain(
            conditions,
            condition_combination=test_conditions["condition_combination"])
        return [condition_chain]