Skip to content

Commit

Permalink
Merge pull request #1411 from pnnl/RT/JDJ/refactor-rmr
Browse files Browse the repository at this point in the history
Refactor all RMR and RMI to RMD
  • Loading branch information
JacksonJ-KC authored Jul 30, 2024
2 parents 7623338 + 46672f9 commit 0ae0ea0
Show file tree
Hide file tree
Showing 350 changed files with 986,958 additions and 1,261,608 deletions.
2 changes: 1 addition & 1 deletion docs/section10/10-7.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@
**Rule Assertion:**
- Case 1: if modeled efficiency equals the expected efficiency AND the capacity was defined AND the aggregation factor is either irrelevant or defined, then pass: `if modeled_efficiency_b == expected_baseline_eff_b AND not was_capacity_not_defined and zone_aggregation_factor_undefined_and_needed == FALSE: PASS`
- Case 2: Elif capacity was not defined or and zone_aggregation_factor_undefined_and_needed equal TRUE but the modeled efficiency equals the highest (most conservative) efficiency in the appropriate table based on system type then UNDETERMINED: `elif (was_capacity_not_defined or zone_aggregation_factor_undefined_and_needed == TRUE) AND modeled_efficiency_b == most_conservative_eff == TRUE: UNDETERMINED and raise message "The expected baseline efficiency could not be determined because cooling capacity and/or zone_aggregation_factor were not defined. Check if the modeled baseline DX cooling efficiency was established correctly based upon equipment capacity and type. The modeled efficiency matches the capacity bracket in Appendix G efficiency tables with the highest efficiency (i.e., most conservative efficiency has been modeled)."`
- Case 2: Elif capacity was not defined or zone_aggregation_factor_undefined_and_needed equal TRUE but the modeled efficiency equals the highest (most conservative) efficiency in the appropriate table based on system type then UNDETERMINED: `elif (was_capacity_not_defined or zone_aggregation_factor_undefined_and_needed == TRUE) AND modeled_efficiency_b == most_conservative_eff == TRUE: UNDETERMINED and raise message "The expected baseline efficiency could not be determined because cooling capacity and/or zone_aggregation_factor were not defined. Check if the modeled baseline DX cooling efficiency was established correctly based upon equipment capacity and type. The modeled efficiency matches the capacity bracket in Appendix G efficiency tables with the highest efficiency (i.e., most conservative efficiency has been modeled)."`
- Case 3: Elif capacity was not defined or zone_aggregation_factor_undefined_and_needed equal TRUE and efficiency does not equal the highest (most conservative) efficiency in the appropriate table based on system type then UNDETERMINED: `elif (was_capacity_not_defined or zone_aggregation_factor_undefined_and_needed == TRUE) AND modeled_efficiency_b < most_conservative_eff: UNDETERMINED and raise_message "The expected baseline efficiency could not be determined because cooling capacity and/or zone aggregation factor were not defined. Check if the modeled baseline DX cooling efficiency was established correctly based upon equipment capacity and type."`
- Case 4: Else, fail: `else: FAIL`

Expand Down
2 changes: 1 addition & 1 deletion rct229/report_engine/rct_report.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def generate(self, rct_outcome, report_dir):
-------
"""
invalid_msg = rct_outcome["invalid_rmrs"]
invalid_msg = rct_outcome["invalid_rmds"]
# Sort the outcomes by id or rule_id
if "id" in rct_outcome["outcomes"][0]:
id_key = "id"
Expand Down
6 changes: 3 additions & 3 deletions rct229/reports/project_report.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ def print_rule_report(report):


def print_summary_report(report):
invalid_rmrs = report["invalid_rmrs"]
if invalid_rmrs:
invalid_rmds = report["invalid_rmds"]
if invalid_rmds:
print("----------------------------------")
print(f"Invalid RMDs: {str(invalid_rmrs)}")
print(f"Invalid RMDs: {str(invalid_rmds)}")
else:
outcomes = report["outcomes"]
summary_dict = aggregate_outcomes(outcomes)
Expand Down
14 changes: 7 additions & 7 deletions rct229/rule_engine/engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,12 +102,12 @@ def evaluate_all_rules(ruleset_model_path_list):
return report


def evaluate_rule(rule, rmrs, test=False):
def evaluate_rule(rule, rmds, test=False):
"""Evaluates a single rule against an RMD trio
Parameters
----------
rmrs : RuleSetModels
rmds : RuleSetModels
Object containing the RMDs required by enum schema
test: Boolean
A flag to indicate whether the evaluate rule is a software test workflow or not.
Expand All @@ -117,7 +117,7 @@ def evaluate_rule(rule, rmrs, test=False):
dict
A dictionary of the form:
{
invalid_rmrs: dict - The keys are the names of the invalid RMDs.
invalid_rmds: dict - The keys are the names of the invalid RMDs.
The values are the corresponding schema validation errors.
outcomes: [dict] - A list containing a single rule outcome as
a dictionary of the form:
Expand All @@ -131,7 +131,7 @@ def evaluate_rule(rule, rmrs, test=False):
}
"""

return evaluate_rules([rule], rmrs, test=test)
return evaluate_rules([rule], rmds, test=test)


def evaluate_rules(
Expand Down Expand Up @@ -172,7 +172,7 @@ def evaluate_rules(
}
"""

# Validate the rmrs against the schema and other high-level checks
# Validate the rmds against the schema and other high-level checks
outcomes = []
invalid_rmds = {}
rmds_used = get_rmd_instance()
Expand Down Expand Up @@ -207,7 +207,7 @@ def evaluate_rules(
len(invalid_rmds) == 0,
f"Optional RPDs provided are invalid. See error messages in terminal.",
)
# Evaluate the rules if all the used rmrs are valid
# Evaluate the rules if all the used rmds are valid
# Replace the numbers that have schema units in the RMDs with the
# appropriate pint quantities
# TODO: quantitization should happen right after schema validation and
Expand Down Expand Up @@ -247,6 +247,6 @@ def evaluate_rules(
)

return {
"invalid_rmrs": invalid_rmds,
"invalid_rmds": invalid_rmds,
"outcomes": calcq_to_str(unit_system, outcomes),
}
34 changes: 17 additions & 17 deletions rct229/rule_engine/rule_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ def evaluate(self, rmds, data={}):
This method also orchestrates the high-level workflow for any rule.
Namely:
- Call get_context(rmrs); check for any missing RMD contexts
- Call get_context(rmds); check for any missing RMD contexts
- Call is_applicable(context)
- Call manual_check_required()
- Call rule_check()
Expand Down Expand Up @@ -243,7 +243,7 @@ def _get_context(self, rmds, rmd_context=None):
Returns
-------
RuleSetModels
Object containing the contexts for RMDs; an RMR's context is set to None if the corresponding flag
Object containing the contexts for RMDs; an RMD's context is set to None if the corresponding flag
in self.rmds_used is not set
"""
rmd_context = self.rmd_context if rmd_context is None else rmd_context
Expand All @@ -263,7 +263,7 @@ def _get_context(self, rmds, rmd_context=None):
return ruleset_models

def get_context(self, rmds, data=None):
"""Gets the context for each RMR
"""Gets the context for each RMD
May be be overridden for different behavior
Expand All @@ -272,27 +272,27 @@ def get_context(self, rmds, data=None):
rmds : RuleSetModels
Object containing the RMDs for each required ruleset model types
A return value of None indicates that the context
does not exist in one or more of the RMRs used.
does not exist in one or more of the RMDs used.
data : An optional data object. It is ignored by this base implementation.
Returns
-------
RulesetModelTypes or str
The return value from self._get_context() when the context exists
in each RMR for which the correponding self.rmds_used flag is set;
in each RMD for which the correponding self.rmds_used flag is set;
otherwise retrns a string such as "MISSING_BASELINE" that indicates all
the RMRs that are missing.
the RMDs that are missing.
"""

context = self._get_context(rmds)
missing_contexts = []
ruleset_model_types = rmds.get_ruleset_model_types()
for ruleset_model in ruleset_model_types:
if (
# rmr used
# rmd used
self.rmds_used[ruleset_model]
and not (
# and rmr is not optional
# and rmd is not optional
self.rmds_used_optional
and self.rmds_used_optional[ruleset_model]
)
Expand Down Expand Up @@ -430,7 +430,7 @@ def is_applicable(self, context, data=None):
Parameters
----------
context : RuleSetModels
Object containing the contexts for RMRs
Object containing the contexts for RMDs
data : An optional data object. It is ignored by this base implementation.
Returns
Expand All @@ -454,7 +454,7 @@ def get_not_applicable_msg(self, context, data=None):
Parameters
----------
context : RuleSetModels
Object containing the contexts for RMRs
Object containing the contexts for RMDs
calc_vals : dict | None
data : dict | None
An optional data dictionary
Expand All @@ -477,7 +477,7 @@ def get_calc_vals(self, context, data=None):
Parameters
----------
context : RuleSetModels
Object containing the contexts for RMRs
Object containing the contexts for RMDs
data : An optional data object. It is ignored by this base implementation.
Returns
Expand All @@ -500,7 +500,7 @@ def manual_check_required(self, context, calc_vals=None, data=None):
Parameters
----------
context : RuleSetModels
Object containing the contexts for RMRs
Object containing the contexts for RMDs
calc_vals : dict or None
data : An optional data object. It is ignored by this base implementation.
Expand All @@ -526,7 +526,7 @@ def get_manual_check_required_msg(self, context, calc_vals=None, data=None):
Parameters
----------
context : RuleSetModels
Object containing the contexts for RMRs
Object containing the contexts for RMDs
calc_vals : dict or None
data : An optional data object. It is ignored by this base implementation.
Expand All @@ -548,7 +548,7 @@ def rule_check(self, context, calc_vals=None, data=None):
Parameters
----------
context : RuleSetModels
Object containing the contexts for RMRs
Object containing the contexts for RMDs
calc_vals: dictionary
Dictionary contains calculated values for rule check and reporting.
data : An optional data object. It is ignored by this base implementation.
Expand All @@ -570,7 +570,7 @@ def is_tolerance_fail(self, context, calc_vals=None, data=None):
Parameters
----------
context : RuleSetModels
Object containing the contexts for RMRs
Object containing the contexts for RMDs
calc_vals : dict or None
data : An optional data object. It is ignored by this base implementation.
Expand All @@ -595,7 +595,7 @@ def get_fail_msg(self, context, calc_vals=None, data=None):
Parameters
----------
context : RuleSetModels
Object containing the contexts for RMRs
Object containing the contexts for RMDs
calc_vals : dict or None
data : An optional data object. It is ignored by this base implementation.
Expand All @@ -621,7 +621,7 @@ def get_pass_msg(self, context, calc_vals=None, data=None):
Parameters
----------
context : RuleSetModels
Object containing the contexts for RMRs
Object containing the contexts for RMDs
calc_vals : dict or None
data : An optional data object. It is ignored by this base implementation.
Expand Down
4 changes: 2 additions & 2 deletions rct229/rule_engine/rule_base_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ def test__rule_definition_base__evaluate__with_true_rule_check():


# Testing RuleDefinitionBase get_context method ------------------
def test__rule_definition_base__get_context__with_missing_rmrs():
def test__rule_definition_base__get_context__with_missing_rmds():
assert (
BASE_RULE_1.get_context(
produce_ruleset_model_description(
Expand All @@ -178,7 +178,7 @@ def test__rule_definition_base__get_context__with_missing_rmrs():
)


def test__rule_definition_base__get_context__with_rmrs_present():
def test__rule_definition_base__get_context__with_rmds_present():
context = BASE_RULE_1.get_context(
produce_ruleset_model_description(
USER=RMD_1, BASELINE_0=RMD_2, PROPOSED=RMD_EMPTY
Expand Down
10 changes: 5 additions & 5 deletions rct229/rule_engine/rule_list_indexed_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ def create_context_list(self, context, data):
----------
context : RuleSetModels
Object containing the contexts for RMDs required by the ruleset.
The base implementation here takes the list context from the rmr context
The base implementation here takes the list context from the rmd context
and assumes each part is a list.
data : An optional data object. It is ignored by this base implementation.
Expand All @@ -116,16 +116,16 @@ def create_context_list(self, context, data):
list of RuleSetModels
A list of context
"""
UNKNOWN_INDEX_RMR = "Unknown index_rmd"
UNKNOWN_INDEX_RMD = "Unknown index_rmd"
CONTEXT_NOT_LIST = "The list contexts must be lists"

match_by = self.match_by

# The index RMR must be either user, baseline, or proposed
# The index RMD must be either user, baseline, or proposed
if self.index_rmd not in context.get_ruleset_model_types():
raise ValueError(UNKNOWN_INDEX_RMR)
raise ValueError(UNKNOWN_INDEX_RMD)

# The index RMR must be used
# The index RMD must be used
context_on_list = any(
map(
lambda ruleset_model: self.index_rmd == ruleset_model
Expand Down
4 changes: 2 additions & 2 deletions rct229/rule_engine/tests/test_rules.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@


class MyRuleDefinition(RuleDefinitionBase):
def __init__(self, user_rmr, baseline_rmr, proposed_rmr):
def __init__(self, user_rmd, baseline_rmd, proposed_rmd):
self.id = "15-1"
self.description = "My description"
self.rmd_context = "transformers"
super(MyRuleDefinition, self).__init__(user_rmr, baseline_rmr, proposed_rmr)
super(MyRuleDefinition, self).__init__(user_rmd, baseline_rmd, proposed_rmd)

def check_applicability(self):
return True
Expand Down
22 changes: 11 additions & 11 deletions rct229/rulesets/ashrae9012019/data_fns/extra_schema_fns_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
proposed_equals_user,
)

TEST_RMI = {
TEST_RMD = {
"id": "test_rmd",
"buildings": [
{
Expand Down Expand Up @@ -154,16 +154,16 @@
}


TEST_RMD_FULL = {
TEST_RPD_FULL = {
"id": "229",
"ruleset_model_descriptions": [TEST_RMI],
"ruleset_model_descriptions": [TEST_RMD],
"data_timestamp": "2024-02-12T09:00Z",
}


def test__compare_context_pair__identical():
proposed = TEST_RMD_FULL
user = TEST_RMD_FULL
proposed = TEST_RPD_FULL
user = TEST_RPD_FULL
error_msg_list = []
assert compare_context_pair(
proposed,
Expand All @@ -177,8 +177,8 @@ def test__compare_context_pair__identical():


def test__proposed_equals_user__identical():
proposed = TEST_RMD_FULL
user = TEST_RMD_FULL
proposed = TEST_RPD_FULL
user = TEST_RPD_FULL
error_msg_list = []
assert proposed_equals_user(
index_context=proposed,
Expand All @@ -188,8 +188,8 @@ def test__proposed_equals_user__identical():


def test__compare_context_pair__different():
proposed = TEST_RMD_FULL
user = deepcopy(TEST_RMD_FULL)
proposed = TEST_RPD_FULL
user = deepcopy(TEST_RPD_FULL)
user["ruleset_model_descriptions"][0]["buildings"][0][
"building_open_schedule"
] = "always_1"
Expand All @@ -210,8 +210,8 @@ def test__compare_context_pair__different():


def test__proposed_equals_user__different():
proposed = TEST_RMD_FULL
user = deepcopy(TEST_RMD_FULL)
proposed = TEST_RPD_FULL
user = deepcopy(TEST_RPD_FULL)
user["ruleset_model_descriptions"][0]["buildings"][0][
"building_open_schedule"
] = "always_1"
Expand Down
Loading

0 comments on commit 0ae0ea0

Please sign in to comment.