Skip to content

system_base

Orchestrates the safety analysis and coordinates visualization via observers.

SystemBase

Bases: ABC

Abstract base class for a safety system model.

It manages the system layout, triggers FIT rate calculations, and handles the generation of architectural visualizations.

Source code in src/ecc_analyzer/system_base.py
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
class SystemBase(ABC):
    """Abstract base class for a safety system model.

    It manages the system layout, triggers FIT rate calculations, and
    handles the generation of architectural visualizations.
    """

    def __init__(self, name: str, total_fit: float):
        """Initializes the system orchestrator.

        Args:
            name (str): The descriptive name of the system (e.g., "LPDDR4_System").
            total_fit (float): The total FIT rate used as the baseline for metric calculations.
        """
        self.name = name
        self.total_fit = total_fit
        self.system_layout = None
        self.asil_block = AsilBlock("Final_Evaluation")
        self.configure_system()

    @abstractmethod
    def configure_system(self):
        """Abstract method to define the internal hardware structure.

        Must be implemented by subclasses to set the `self.system_layout`.
        """
        pass

    def run_analysis(self) -> dict[str, Any]:
        """Performs a pure mathematical FIT calculation across the system.

        No visualization is triggered during this call.

        Returns:
            dict[str, Any]: A dictionary containing calculated metrics (SPFM, LFM, ASIL level).

        Raises:
            ValueError: If `configure_system` has not set a valid system layout.
        """
        if not self.system_layout:
            raise ValueError("System layout is not configured.")

        final_spfm, final_lfm = self.system_layout.compute_fit({}, {})

        return self.asil_block.compute_metrics(self.total_fit, final_spfm, final_lfm)

    def generate_pdf(self, filename: Optional[str] = None) -> dict[str, Any]:
        """Executes the analysis while simultaneously generating a PDF visualization.

        Uses the Observer Pattern to decouple logic from Graphviz commands.

        Args:
            filename (Optional[str]): Optional name for the output file.
                Defaults to "output_<system_name>".

        Returns:
            dict[str, Any]: The final system metrics dictionary.
        """
        if filename is None:
            filename = f"output_{self.name}"

        visualizer = SafetyVisualizer(self.name)

        observable_layout = ObservableBlock(self.system_layout)
        observable_layout.attach(visualizer)

        final_spfm, final_lfm, last_ports = observable_layout.compute_fit({}, {}, {})

        visualizer.on_block_computed(
            self.asil_block,
            last_ports,
            final_spfm,
            final_lfm,
            final_spfm,
            final_lfm,
        )

        visualizer.render(filename)

        return self.asil_block.compute_metrics(self.total_fit, final_spfm, final_lfm)

    def save_to_yaml(self, file_path: str):
        """Exports the current system layout to a YAML file.

        Args:
            file_path (str): The destination path for the YAML file.
        """
        config = self.system_layout.to_dict()
        with open(file_path, "w") as f:
            yaml.dump(config, f, default_flow_style=False)

    def load_from_yaml(self, file_path: str):
        """Loads a system layout from a YAML file and reconstructs the block tree.

        Args:
            file_path (str): The path to the configuration file.
        """
        with open(file_path, "r") as f:
            data = yaml.safe_load(f)
        self.system_layout = BlockFactory.from_dict(data)

    def save_to_json(self, file_path: str):
        """Exports the current system layout to a JSON file.

        Args:
            file_path (str): The destination path for the JSON file.
        """
        config = self.system_layout.to_dict()
        with open(file_path, "w") as f:
            json.dump(config, f, indent=4)

    def load_from_json(self, file_path: str):
        """Loads a system layout from a JSON file and reconstructs the block tree.

        Args:
            file_path (str): The path to the configuration file.
        """
        with open(file_path, "r") as f:
            data = json.load(f)
        self.system_layout = BlockFactory.from_dict(data)

__init__(name, total_fit)

Initializes the system orchestrator.

Parameters:

Name Type Description Default
name str

The descriptive name of the system (e.g., "LPDDR4_System").

required
total_fit float

The total FIT rate used as the baseline for metric calculations.

required
Source code in src/ecc_analyzer/system_base.py
22
23
24
25
26
27
28
29
30
31
32
33
def __init__(self, name: str, total_fit: float):
    """Initializes the system orchestrator.

    Args:
        name (str): The descriptive name of the system (e.g., "LPDDR4_System").
        total_fit (float): The total FIT rate used as the baseline for metric calculations.
    """
    self.name = name
    self.total_fit = total_fit
    self.system_layout = None
    self.asil_block = AsilBlock("Final_Evaluation")
    self.configure_system()

configure_system() abstractmethod

Abstract method to define the internal hardware structure.

Must be implemented by subclasses to set the self.system_layout.

Source code in src/ecc_analyzer/system_base.py
35
36
37
38
39
40
41
@abstractmethod
def configure_system(self):
    """Abstract method to define the internal hardware structure.

    Must be implemented by subclasses to set the `self.system_layout`.
    """
    pass

generate_pdf(filename=None)

Executes the analysis while simultaneously generating a PDF visualization.

Uses the Observer Pattern to decouple logic from Graphviz commands.

Parameters:

Name Type Description Default
filename Optional[str]

Optional name for the output file. Defaults to "output_".

None

Returns:

Type Description
dict[str, Any]

dict[str, Any]: The final system metrics dictionary.

Source code in src/ecc_analyzer/system_base.py
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
def generate_pdf(self, filename: Optional[str] = None) -> dict[str, Any]:
    """Executes the analysis while simultaneously generating a PDF visualization.

    Uses the Observer Pattern to decouple logic from Graphviz commands.

    Args:
        filename (Optional[str]): Optional name for the output file.
            Defaults to "output_<system_name>".

    Returns:
        dict[str, Any]: The final system metrics dictionary.
    """
    if filename is None:
        filename = f"output_{self.name}"

    visualizer = SafetyVisualizer(self.name)

    observable_layout = ObservableBlock(self.system_layout)
    observable_layout.attach(visualizer)

    final_spfm, final_lfm, last_ports = observable_layout.compute_fit({}, {}, {})

    visualizer.on_block_computed(
        self.asil_block,
        last_ports,
        final_spfm,
        final_lfm,
        final_spfm,
        final_lfm,
    )

    visualizer.render(filename)

    return self.asil_block.compute_metrics(self.total_fit, final_spfm, final_lfm)

load_from_json(file_path)

Loads a system layout from a JSON file and reconstructs the block tree.

Parameters:

Name Type Description Default
file_path str

The path to the configuration file.

required
Source code in src/ecc_analyzer/system_base.py
126
127
128
129
130
131
132
133
134
def load_from_json(self, file_path: str):
    """Loads a system layout from a JSON file and reconstructs the block tree.

    Args:
        file_path (str): The path to the configuration file.
    """
    with open(file_path, "r") as f:
        data = json.load(f)
    self.system_layout = BlockFactory.from_dict(data)

load_from_yaml(file_path)

Loads a system layout from a YAML file and reconstructs the block tree.

Parameters:

Name Type Description Default
file_path str

The path to the configuration file.

required
Source code in src/ecc_analyzer/system_base.py
106
107
108
109
110
111
112
113
114
def load_from_yaml(self, file_path: str):
    """Loads a system layout from a YAML file and reconstructs the block tree.

    Args:
        file_path (str): The path to the configuration file.
    """
    with open(file_path, "r") as f:
        data = yaml.safe_load(f)
    self.system_layout = BlockFactory.from_dict(data)

run_analysis()

Performs a pure mathematical FIT calculation across the system.

No visualization is triggered during this call.

Returns:

Type Description
dict[str, Any]

dict[str, Any]: A dictionary containing calculated metrics (SPFM, LFM, ASIL level).

Raises:

Type Description
ValueError

If configure_system has not set a valid system layout.

Source code in src/ecc_analyzer/system_base.py
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
def run_analysis(self) -> dict[str, Any]:
    """Performs a pure mathematical FIT calculation across the system.

    No visualization is triggered during this call.

    Returns:
        dict[str, Any]: A dictionary containing calculated metrics (SPFM, LFM, ASIL level).

    Raises:
        ValueError: If `configure_system` has not set a valid system layout.
    """
    if not self.system_layout:
        raise ValueError("System layout is not configured.")

    final_spfm, final_lfm = self.system_layout.compute_fit({}, {})

    return self.asil_block.compute_metrics(self.total_fit, final_spfm, final_lfm)

save_to_json(file_path)

Exports the current system layout to a JSON file.

Parameters:

Name Type Description Default
file_path str

The destination path for the JSON file.

required
Source code in src/ecc_analyzer/system_base.py
116
117
118
119
120
121
122
123
124
def save_to_json(self, file_path: str):
    """Exports the current system layout to a JSON file.

    Args:
        file_path (str): The destination path for the JSON file.
    """
    config = self.system_layout.to_dict()
    with open(file_path, "w") as f:
        json.dump(config, f, indent=4)

save_to_yaml(file_path)

Exports the current system layout to a YAML file.

Parameters:

Name Type Description Default
file_path str

The destination path for the YAML file.

required
Source code in src/ecc_analyzer/system_base.py
 96
 97
 98
 99
100
101
102
103
104
def save_to_yaml(self, file_path: str):
    """Exports the current system layout to a YAML file.

    Args:
        file_path (str): The destination path for the YAML file.
    """
    config = self.system_layout.to_dict()
    with open(file_path, "w") as f:
        yaml.dump(config, f, default_flow_style=False)