-
-
Notifications
You must be signed in to change notification settings - Fork 40
Open
Labels
rules-engineIssues related to the Python rules engineIssues related to the Python rules enginetechnical
Description
We removed this code that would help support derived outliers, should they be chosen to be implemented in a later version.
test_engine.py
@pytest.fixture()
def sample_intermediate_energy_bill_inputs_with_outlier() -> (
list[engine.IntermediateEnergyBill]
):
intermediate_energy_bill_inputs = [
engine.IntermediateEnergyBill(
_dummy_processed_energy_bill_input,
[41.7, 41.6, 32, 25.4],
60,
AnalysisType.ALLOWED_HEATING_USAGE,
True,
False,
),
engine.IntermediateEnergyBill(
_dummy_processed_energy_bill_input,
[28, 29, 30, 29],
50,
AnalysisType.ALLOWED_HEATING_USAGE,
True,
False,
),
engine.IntermediateEnergyBill(
_dummy_processed_energy_bill_input,
[32, 35, 35, 38],
45,
AnalysisType.ALLOWED_HEATING_USAGE,
True,
False,
),
engine.IntermediateEnergyBill(
_dummy_processed_energy_bill_input,
[41, 43, 42, 42],
30,
AnalysisType.ALLOWED_HEATING_USAGE,
True,
False,
),
engine.IntermediateEnergyBill(
_dummy_processed_energy_bill_input,
[72, 71, 70, 69],
0.96,
AnalysisType.NOT_ALLOWED_IN_CALCULATIONS,
False,
False,
),
]
return intermediate_energy_bill_inputs
...
def test_bp_ua_with_outlier(
sample_heat_load_inputs, sample_intermediate_energy_bill_inputs_with_outlier
):
home = engine.Home.calculate(
sample_heat_load_inputs,
sample_intermediate_energy_bill_inputs_with_outlier,
dhw_input=None,
initial_balance_point=58,
)
# expect that ua_1 is considered an outlier and not used in winter_processed_energy_bills
ua_2, ua_3, ua_4 = [bill.ua for bill in home.winter_processed_energy_bills]
assert home.balance_point == 60.5
assert ua_2 == approx(1455.03, abs=0.01)
assert ua_3 == approx(1617.65, abs=0.01)
assert ua_4 == approx(1486.49, abs=0.01)
assert home.avg_ua == approx(1519.72, abs=1)
assert home.stdev_pct == approx(0.0463, abs=0.01)
engine.py
while new_stdev_pct > stdev_pct_max:
outliers = [
abs(bill.ua - avg_ua)
for bill in winter_processed_energy_bills
if bill.ua is not None
]
biggest_outlier = max(outliers)
biggest_outlier_idx = outliers.index(biggest_outlier)
outlier = winter_processed_energy_bills.pop(
biggest_outlier_idx
) # removes the biggest outlier
outlier.eliminated_as_outlier = True
uas_i = [
processed_energy_bill.ua
for processed_energy_bill in winter_processed_energy_bills
if processed_energy_bill.ua is not None
]
avg_ua_i = sts.mean(uas_i)
stdev_pct_i = sts.pstdev(uas_i) / avg_ua_i
if (
# the outlier has been removed
new_stdev_pct - stdev_pct_i
< max_stdev_pct_diff
): # if it's a small enough change
# add the outlier back in
winter_processed_energy_bills.append(
outlier
) # then it's not worth removing it, and we exit
outlier.eliminated_as_outlier = False
break # may want some kind of warning to be raised as well
else:
uas, avg_ua, stdev_pct = uas_i, avg_ua_i, stdev_pct_i
results = Home._refine_balance_point(
balance_point=balance_point,
balance_point_sensitivity=next_balance_point_sensitivity,
avg_ua=avg_ua,
stdev_pct=stdev_pct,
thermostat_set_point=thermostat_set_point,
winter_processed_energy_bills=winter_processed_energy_bills,
)
new_balance_point = results.balance_point
new_avg_ua = results.avg_ua
new_stdev_pct = results.stdev_pct
balance_point_graph_records_extension = (
results.balance_point_graph_records_extension
)
if isinstance(balance_point_graph_records_extension, list):
balance_point_graph.records.extend(
balance_point_graph_records_extension
)
Metadata
Metadata
Assignees
Labels
rules-engineIssues related to the Python rules engineIssues related to the Python rules enginetechnical