Coverage for backend/ahuora-builder/src/ahuora_builder/methods/change_detection.py: 98%

31 statements  

« prev     ^ index     » next       coverage.py v7.10.7, created at 2026-06-23 21:51 +0000

1from ..properties_manager import PropertiesManager, PropertyValueId 

2import pyomo.environ as pyo 

3import idaes.logger as idaeslog 

4_log = idaeslog.getLogger(__name__) 

5 

6def get_current_values(manager: PropertiesManager)-> dict[PropertyValueId, float]: 

7 """ 

8 Returns a dictionary for each property ID, it's current value. Assumes steady state (ignores time dimension) 

9 """ 

10 current_values = {} 

11 for prop_id, prop in manager.properties.items(): 

12 if prop.corresponding_constraint is None: # We only are interested in calculated variables, as fixed variables by definition do not change. 

13 try: 

14 current_values[prop_id] = pyo.value(next(iter(prop.component.values()))) 

15 except ValueError as e: 

16 # The variable is uninitialised, set a default value of 1 

17 current_values[prop_id] = 1 

18 return current_values 

19 

20type PropertyValueChanges = list[tuple[PropertyValueId, float, float]] 

21 

22def detect_changes(current_values: dict[PropertyValueId, float], previous_values: dict[PropertyValueId, float], threshold: float = 0.1) -> PropertyValueChanges: 

23 """ 

24 Detects changes in property values between two states. 

25  

26 Args: 

27 current_values: A dictionary mapping property IDs to their current values. 

28 previous_values: A dictionary mapping property IDs to their previous values. 

29 threshold: The minimum change required to be considered significant. 

30  

31 Returns: 

32 A list of tuples containing the property ID and the current and previous values for each changed property. 

33 """ 

34 changes = [] 

35 for prop_id in current_values: 

36 if prop_id in previous_values: 36 ↛ 35line 36 didn't jump to line 35 because the condition on line 36 was always true

37 current = current_values[prop_id] 

38 previous = previous_values[prop_id] 

39 if percentage(current, previous) > threshold: 

40 changes.append((prop_id, current, previous)) 

41 changes.sort(key=lambda x: percentage(x[1], x[2]), reverse=True) 

42 return changes 

43 

44def percentage(current, previous): 

45 return (current - previous) / max(abs(previous), 1) * 100 if previous != 0 else 0 

46 

47def print_changes(changes: PropertyValueChanges, manager: PropertiesManager): 

48 for prop_id, current, previous in changes: 

49 prop_name = manager.get(prop_id).name 

50 change_percentage = percentage(current, previous) 

51 _log.info("Property: %s, Current Value: %f, Previous Value: %f, Change: %f%%", prop_name, current, previous, change_percentage)