Coverage for src/distopf/cim_converter/utils/phase_utils.py: 97%
37 statements
« prev ^ index » next coverage.py v7.10.6, created at 2025-09-09 17:44 -0700
« prev ^ index » next coverage.py v7.10.6, created at 2025-09-09 17:44 -0700
1"""
2Utility functions for handling phase information in CIM objects.
3Centralizes phase determination logic to ensure consistency across processors.
4"""
6import cimgraph.data_profile.cimhub_2023 as cim
9class PhaseUtils:
10 """Utility class for phase-related operations."""
12 @staticmethod
13 def get_phase_str(
14 phase_code: cim.OrderedPhaseCodeKind | cim.SinglePhaseKind | None,
15 ) -> str:
16 """
17 Convert CIM phase code to phase letter.
19 Args:
20 phase_code: CIM phase code object or value
22 Returns:
23 Phase letters
24 """
25 if phase_code is None:
26 return ""
27 assert phase_code is not None
28 return phase_code.value.lower().replace("n", "")
30 @staticmethod
31 def get_equipment_phases(equipment) -> str:
32 """
33 Get phase string from equipment by checking various phase-specific objects.
35 Args:
36 equipment: CIM equipment object
38 Returns:
39 Sorted phase string (e.g., 'abc', 'ac', 's1s2')
40 """
41 phases = set()
43 # Check for phase-specific objects
44 phase_attrs = [
45 "ACLineSegmentPhases",
46 "EnergyConsumerPhase",
47 "PowerElectronicsConnectionPhases",
48 "LinearShuntCompensatorPhases",
49 "ShuntCompensatorPhase",
50 "PowerTransformerEnd",
51 "SwitchPhases",
52 "TransformerTankEnds",
53 ]
55 for attr in phase_attrs:
56 if not hasattr(equipment, attr):
57 continue
58 phase_objects = getattr(equipment, attr)
59 if phase_objects is None:
60 continue
61 for phase_obj in phase_objects:
62 if hasattr(phase_obj, "phase"):
63 phase_letter = PhaseUtils.get_phase_str(phase_obj.phase)
64 phases.add(phase_letter)
65 if hasattr(phase_obj, "orderedPhases"):
66 phase_letter = PhaseUtils.get_phase_str(phase_obj.orderedPhases)
67 phases.add(phase_letter)
69 # If no phase-specific data found, assume three-phase
70 if not phases:
71 phases = {"a", "b", "c"}
73 return "".join(sorted(phases))
75 @staticmethod
76 def filter_standard_phases(phases: str) -> str:
77 """
78 Filter to only include standard three-phase system phases (a, b, c).
80 Args:
81 phases: Phase string that may include secondary phases
83 Returns:
84 Filtered phase string with only a, b, c phases
85 """
86 standard_phases = set()
87 for phase in phases:
88 if phase in ["a", "b", "c"]:
89 standard_phases.add(phase)
91 # Default to three-phase if no standard phases found
92 if not standard_phases:
93 standard_phases = {"a", "b", "c"}
95 return "".join(sorted(standard_phases))