Пример #1
0
 def test_parse_eligibilities(self):
     event = {
         "classifier_set": ["a", "?"],
         "age_eligibility": [],
         "eligibility": [1],
         "target": [1.0, 1, "A", "1", "dist1", "1", 100]
     }
     classifiers, classifier_values, aggregates = \
         self.get_mock_classifiers()
     e = self.assemble_disturbance_events_table([event])
     sit_events = sit_disturbance_event_parser.parse(
         e,
         classifiers,
         classifier_values,
         aggregates,
         self.get_mock_disturbance_types(),
         None,
         separate_eligibilities=True)
     elgibilities_input = pd.DataFrame(
         columns=["id", "pool_filter", "state_filter"],
         data=[[1, "pool_expression_1", "state_expression_1"]])
     sit_eligibilities = sit_disturbance_event_parser.parse_eligibilities(
         sit_events, elgibilities_input)
     self.assertTrue(
         list(sit_eligibilities.columns) == [
             x["name"]
             for x in sit_format.get_disturbance_eligibility_format()
         ])
Пример #2
0
    def test_undefined_sort_type_error(self):
        """check if an error is raised when an invalid sort type is specified
        """
        event = {
            "classifier_set": ["a", "?"],
            "age_eligibility": ["True", -1, -1, -1, -1],
            "eligibility": [-1] * self.get_num_eligibility_cols(),
            "target": [1.0, "UNDEFINED", "A", 100, "dist1", 2, 100]
        }

        classifiers, classifier_values, aggregates = \
            self.get_mock_classifiers()
        with self.assertRaises(ValueError):
            e = self.assemble_disturbance_events_table([event])
            sit_disturbance_event_parser.parse(
                e, classifiers, classifier_values, aggregates,
                self.get_mock_disturbance_types(), self.get_mock_age_classes())
Пример #3
0
    def test_incorrect_number_of_classifiers_error(self):
        """checks that the format has the correct number of columns
        according to the defined classifiers
        """
        event = {
            "classifier_set": ["a", "?", "EXTRA"],
            "age_eligibility": ["False", -1, -1, -1, -1],
            "eligibility": [-1] * self.get_num_eligibility_cols(),
            "target": [1.0, "1", "A", 100, "dist1", 2, 100]
        }

        classifiers, classifier_values, aggregates = \
            self.get_mock_classifiers()
        with self.assertRaises(ValueError):
            e = self.assemble_disturbance_events_table([event])
            sit_disturbance_event_parser.parse(
                e, classifiers, classifier_values, aggregates,
                self.get_mock_disturbance_types(), self.get_mock_age_classes())
Пример #4
0
    def test_undefined_age_class_error(self):
        """check that an error is raised if the using_age_class is set
        to true and any of the age class ids are not valid
        """
        event = {
            "classifier_set": ["a", "?"],
            "age_eligibility": ["True", -1, -1, -1, "UNDEFINED"],
            "eligibility": [-1] * self.get_num_eligibility_cols(),
            "target": [1.0, "1", "A", 100, "dist1", 2, 100]
        }

        classifiers, classifier_values, aggregates = \
            self.get_mock_classifiers()
        with self.assertRaises(ValueError):
            e = self.assemble_disturbance_events_table([event])
            sit_disturbance_event_parser.parse(
                e, classifiers, classifier_values, aggregates,
                self.get_mock_disturbance_types(), self.get_mock_age_classes())
Пример #5
0
    def test_differing_hw_sw_age_criteria_error(self):
        """check that an error is raised if hw age and sw age criteria
        differ (CBM only has stand age)
        """
        event = {
            "classifier_set": ["a", "?"],
            "age_eligibility": ["False", -1, 10, -1, 20],
            "eligibility": [-1] * self.get_num_eligibility_cols(),
            "target": [1.0, "1", "A", 100, "dist1", 2, 100]
        }

        classifiers, classifier_values, aggregates = \
            self.get_mock_classifiers()
        with self.assertRaises(ValueError):
            e = self.assemble_disturbance_events_table([event])
            sit_disturbance_event_parser.parse(
                e, classifiers, classifier_values, aggregates,
                self.get_mock_disturbance_types(), self.get_mock_age_classes())
Пример #6
0
    def test_undefined_classifier_value_error(self):
        """checks that the format has values that are either wildcards or
        classifier sets drawn from the set of defined classifiers values
        and aggregates
        """
        event = {
            "classifier_set": ["UNDEFINED", "?"],
            "age_eligibility": ["False", -1, -1, -1, -1],
            "eligibility": [-1] * self.get_num_eligibility_cols(),
            "target": [1.0, "1", "A", 100, "dist1", 2, 100]
        }

        classifiers, classifier_values, aggregates = \
            self.get_mock_classifiers()
        with self.assertRaises(ValueError):
            e = self.assemble_disturbance_events_table([event])
            sit_disturbance_event_parser.parse(
                e, classifiers, classifier_values, aggregates,
                self.get_mock_disturbance_types(), self.get_mock_age_classes())
Пример #7
0
    def test_expected_value_with_numeric_classifier_values(self):
        """Checks that numeric classifiers that appear in events data
        are parsed as strings
        """
        event = {
            "classifier_set": [1, 2.0],
            "age_eligibility": ["False", -1, -1, -1, -1],
            "eligibility": [-1] * self.get_num_eligibility_cols(),
            "target": [1.0, "1", "A", 100, "dist1", 2, 100]
        }

        classifiers = pd.DataFrame(data=[(1, "classifier1"),
                                         (2, "classifier2")],
                                   columns=["id", "name"])
        classifier_values = pd.DataFrame(
            data=[(1, "1", "a"), (1, "b", "b"), (2, "a", "a")],
            columns=["classifier_id", "name", "description"])
        aggregates = [{
            'classifier_id': 1,
            'name': 'agg1',
            'description': 'agg2',
            'classifier_values': ['a', 'b']
        }, {
            'classifier_id': 1,
            'name': 'agg2',
            'description': 'agg2',
            'classifier_values': ['a', 'b']
        }, {
            'classifier_id': 2,
            'name': '2.0',
            'description': 'agg1',
            'classifier_values': ['a']
        }]

        e = self.assemble_disturbance_events_table([event])
        result = sit_disturbance_event_parser.parse(
            e, classifiers, classifier_values, aggregates,
            self.get_mock_disturbance_types(), self.get_mock_age_classes())
        self.assertTrue(list(result.classifier1) == ["1"])
        self.assertTrue(list(result.classifier2) == ["2.0"])
Пример #8
0
 def test_parse_eligibilities_error_on_missing_id(self):
     event = {
         "classifier_set": ["a", "?"],
         "age_eligibility": [],
         "eligibility": [2],  # missing
         "target": [1.0, 1, "A", "1", "dist1", "1", 100]
     }
     classifiers, classifier_values, aggregates = \
         self.get_mock_classifiers()
     e = self.assemble_disturbance_events_table([event])
     sit_events = sit_disturbance_event_parser.parse(
         e,
         classifiers,
         classifier_values,
         aggregates,
         self.get_mock_disturbance_types(),
         None,
         separate_eligibilities=True)
     elgibilities_input = pd.DataFrame(
         columns=["id", "pool_filter", "state_filter"], data=[[1, "", ""]])
     with self.assertRaises(ValueError):
         sit_disturbance_event_parser.parse_eligibilities(
             sit_events, elgibilities_input)
Пример #9
0
def parse(sit_classifiers,
          sit_disturbance_types,
          sit_age_classes,
          sit_inventory,
          sit_yield,
          sit_events=None,
          sit_transitions=None,
          sit_eligibilities=None):
    """Parses and validates CBM Standard import tool formatted data including
    the complicated interdependencies in the SIT format. Returns an object
    containing the validated result.

    The returned object has the following properties:

     - classifiers: a pandas.DataFrame of classifiers in the sit_classifiers
        input
     - classifier_values: a pandas.DataFrame of the classifier values in the
        sit_classifiers input
     - classifier_aggregates: a dictionary of the classifier aggregates
        in the sit_classifiers input
     - disturbance_types: a pandas.DataFrame based on the disturbance types in
        the sit_disturbance_types input
     - age_classes: a pandas.DataFrame of the age classes based on
        sit_age_classes
     - inventory: a pandas.DataFrame of the inventory based on sit_inventory
     - yield_table: a pandas.DataFrame of the merchantable volume yield curves
        in the sit_yield input
     - disturbance_events: a pandas.DataFrame of the disturbance events based
        on sit_events.  If the sit_events parameter is None this field is None.
     - transition_rules: a pandas.DataFrame of the transition rules based on
        sit_transitions.  If the sit_transitions parameter is None this field
        is None.
     - disturbance_eligibilities: a pandas.DataFrame of the disturbance event
        eligibilities based on sit_eligibilities.  If the sit_events parameter
        is None this field is None.

    Args:
        sit_classifiers (pandas.DataFrame): SIT formatted classifiers
        sit_disturbance_types (pandas.DataFrame): SIT formatted disturbance
            types
        sit_age_classes (pandas.DataFrame): SIT formatted age classes
        sit_inventory (pandas.DataFrame): SIT formatted inventory
        sit_yield (pandas.DataFrame): SIT formatted yield curves
        sit_events (pandas.DataFrame, optional): SIT formatted disturbance
            events
        sit_transitions (pandas.DataFrame, optional): SIT formatted transition
            rules. Defaults to None.
        sit_eligibilities (pandas.DataFrame, optional): SIT formatted
            disturbance eligibilities. Defaults to None.

    Returns:
        object: an object containing parsed and validated SIT dataset
    """
    s = SimpleNamespace()
    classifiers, classifier_values, classifier_aggregates = \
        sit_classifier_parser.parse(sit_classifiers)
    s.classifiers = classifiers
    s.classifier_values = classifier_values
    s.classifier_aggregates = classifier_aggregates
    s.disturbance_types = sit_disturbance_type_parser.parse(
        sit_disturbance_types)
    s.age_classes = sit_age_class_parser.parse(sit_age_classes)
    s.inventory = sit_inventory_parser.parse(sit_inventory, classifiers,
                                             classifier_values,
                                             s.disturbance_types,
                                             s.age_classes)
    s.yield_table = sit_yield_parser.parse(sit_yield, s.classifiers,
                                           s.classifier_values, s.age_classes)

    if sit_events is not None:
        separate_eligibilities = False
        if sit_eligibilities is not None:
            separate_eligibilities = True
        s.disturbance_events = sit_disturbance_event_parser.parse(
            sit_events, s.classifiers, s.classifier_values,
            s.classifier_aggregates, s.disturbance_types, s.age_classes,
            separate_eligibilities)
        if sit_eligibilities is not None:
            s.disturbance_eligibilities = \
                sit_disturbance_event_parser.parse_eligibilities(
                    s.disturbance_events, sit_eligibilities)
        else:
            s.disturbance_eligibilities = None
    else:
        s.disturbance_events = None
        s.disturbance_eligibilities = None
    if sit_transitions is not None:
        s.transition_rules = sit_transition_rule_parser.parse(
            sit_transitions, s.classifiers, s.classifier_values,
            s.classifier_aggregates, s.disturbance_types, s.age_classes)
    else:
        s.transition_rules = None
    return s
Пример #10
0
def create_sit_rule_based_processor(
        sit,
        cbm,
        random_func=np.random.rand,
        reset_parameters=True,
        sit_events=None,
        sit_disturbance_eligibilities=None,
        sit_transition_rules=None,
        event_sort: EventSort = EventSort.disturbance_type):
    """initializes a class for processing SIT rule based disturbances.

    Args:
        sit (object): sit instance as returned by :py:func:`load_sit`
        cbm (object): initialized instance of the CBM model
        random_func (func, optional): A function of a single integer that
            returns a numeric 1d array whose length is the integer argument.
            Defaults to np.random.rand.
        reset_parameters (bool): if set to true,
            cbm_vars.parameters.disturbance_type and
            cbm_vars.parameters.reset_age will be reset prior to computing
            new disturbances and transition rules.
        sit_events (pandas.DataFrame, optional): if specified the returned rule
            base processor is based on the specified sit_events input.  The
            value will be parsed and validated (sit_classifiers,
            sit_disturbance_type etc.) based on the values in the specified sit
            object.
        sit_disturbance_eligibilities (pandas.DataFrame, optional): SIT
            formatted disturbance eligibilities. Cannot be specified without
            also specified sit_events using the disturbance-eligibility
            formatting. Defaults to None.
        sit_transition_rules (pandas.DataFrame, optional):  if specified the
            returned rule base processor is based on  the specified
            sit_transition_rules input.  The value will be parsed and validated
            (sit_classifiers, sit_disturbance_type etc.) based on the values in
            the specified sit object. Note if the sit_disturbance_events
            parameter is set, but this parameter is not set the
            transition_rules (if any) attached to the specified sit object will
            be used by default.  If null transition rules are required with
            non-null sit_events set this parameter to a dataframe with zero
            rows `pandas.DataFrame()`.  Defaults to None.
        event_sort (EventSort): one of the EventSort values, which determines
            the order in which the supplied sit_events are applied within a
            given timestep.

    Raises:
        ValueError: cannot specify sit_disturbance_eligibilities with no
            specified sit_events

    Returns:
        SITRuleBasedProcessor: an object for processing SIT rule based
            disturbances
    """

    separate_eligibilities = sit_disturbance_eligibilities is not None
    disturbance_events = None
    disturbance_eligibilities = None
    transition_rules = None
    if sit_events is not None:

        disturbance_events = sit_disturbance_event_parser.parse(
            sit_events,
            sit.sit_data.classifiers,
            sit.sit_data.classifier_values,
            sit.sit_data.classifier_aggregates,
            sit.sit_data.disturbance_types,
            sit.sit_data.age_classes,
            separate_eligibilities=separate_eligibilities)

        if sit_disturbance_eligibilities is not None:
            disturbance_eligibilities = \
                sit_disturbance_event_parser.parse_eligibilities(
                    sit_events, sit_disturbance_eligibilities)
    else:
        disturbance_events = sit.sit_data.disturbance_events
        disturbance_eligibilities = sit.sit_data.disturbance_eligibilities
        if separate_eligibilities:
            raise ValueError(
                "cannot specify sit_disturbance_eligibilities with no "
                "specified sit_events")

    if sit_transition_rules is not None:
        if len(sit_transition_rules.index) == 0:
            transition_rules = None
        else:
            transition_rules = sit_transition_rule_parser.parse(
                sit_transition_rules, sit.sit_data.classifiers,
                sit.sit_data.classifier_values,
                sit.sit_data.classifier_aggregates,
                sit.sit_data.disturbance_types, sit.sit_data.age_classes)
    else:
        transition_rules = sit.sit_data.transition_rules

    classifiers_config = get_classifiers(sit.sit_data.classifiers,
                                         sit.sit_data.classifier_values)

    tr_constants = SimpleNamespace(
        group_err_max=sit_transition_rule_parser.GROUPED_PERCENT_ERR_MAX,
        classifier_value_postfix=sit_format.get_tr_classifier_set_postfix(),
        wildcard=sit_classifier_parser.get_wildcard_keyword())

    return sit_rule_based_processor.sit_rule_based_processor_factory(
        cbm=cbm,
        random_func=random_func,
        classifiers_config=classifiers_config,
        classifier_aggregates=sit.sit_data.classifier_aggregates,
        sit_events=_initialize_events(disturbance_events, sit.sit_mapping,
                                      sit.sit_data.disturbance_types,
                                      event_sort),
        sit_transitions=_initialize_transition_rules(transition_rules,
                                                     sit.sit_mapping),
        tr_constants=tr_constants,
        sit_disturbance_eligibilities=disturbance_eligibilities,
        reset_parameters=reset_parameters)