Skip to main content

Reliability system modeling and analysis with graph visualization

Project description

fiabilipym

Reliability system modeling and analysis with graph visualization.

fiabilipym is a modernized, Python 3 compatible distribution of the original fiabilipy library, preserving the same public API, mathematical models, and numerical behavior, while updating packaging, dependencies, and system drawing. It also adds Monte Carlo aging with Weibull lifetimes for simulation-based studies.

The goal of this project is compatibility first, modernization second.


Compatibility with fiabilipy

fiabilipym is designed to be a drop-in replacement for fiabilipy.

Guaranteed invariants:

  • Same public API (Component, System, Markov, Voter, …)
  • Same system construction semantics (E → components → S)
  • Same reliability / availability / MTTF mathematics
  • Same symbolic and numeric results

Code written for fiabilipy 2.x runs unchanged (except for Python 2 → 3 syntax).

The examples below correspond directly to the “How to build a system” section of the original fiabilipy 2.4 documentation.


What it does

  • Build reliability block diagrams
  • Compute reliability, availability, maintainability, and MTTF
  • Model systems using Markov processes
  • Draw system graphs with Matplotlib
  • Simulate aging with Weibull (Monte Carlo), yielding MTTF and R(t) curves

Canonical examples (identical behavior)

Building a component

from fiabilipym import Component
from sympy import Symbol

t = Symbol("t", positive=True)
comp = Component("C0", 1e-4)

comp.mttf
# 10000.0

comp.reliability(1000)
# 0.904837418035960

comp.reliability(t)
# exp(-0.0001*t)

comp.reliability(t=100)
# 0.990049833749168

Building a system (series)

from fiabilipym import Component, System
from sympy import Symbol

t = Symbol("t", positive=True)

power = Component("P0", 1e-6)
motor = Component("M0", 1e-3)

S = System()
S["E"] = [power]
S[power] = [motor]
S[motor] = "S"

S.mttf
# 1000000/1001

S.reliability(t)
# exp(-1001*t/1000000)

Visualization

Why Graphviz/pygraphviz is no longer required

The project moved away from a hard Graphviz/pygraphviz requirement for day-to-day usage and testing:

  • Graphviz-based installs are fragile across environments (native binaries, headers, and PATH issues).
  • Reproducibility was inconsistent across platforms, especially Windows/conda setups.
  • For this project’s block-diagram needs, Graphviz introduced unnecessary operational overhead.
  • A lightweight Matplotlib block-style approach now covers the primary visualization workflow.

System.draw() renders reliability block diagrams with Matplotlib.

import matplotlib
matplotlib.use("Agg")  # use a non-interactive backend for CI/headless runs

import matplotlib.pyplot as plt
from fiabilipym import Component, System

motor = Component("M", 1e-4, 3e-2)
power = Component("P", 1e-6, 2e-4)

system = System()
system["E"] = [power]
system[power] = [motor]
system[motor] = "S"

system.draw()
plt.tight_layout()
plt.savefig("block_diagram.png", dpi=150)

Minimal Matplotlib-only block diagram example:

import matplotlib
matplotlib.use("Agg")

import matplotlib.pyplot as plt

fig, ax = plt.subplots(figsize=(5, 2))
ax.plot([0.1, 0.9], [0.5, 0.5], color="black", linewidth=1.5)
ax.text(0.08, 0.5, "E", va="center", ha="right")
ax.text(0.92, 0.5, "S", va="center", ha="left")
ax.add_patch(plt.Rectangle((0.4, 0.4), 0.2, 0.2, fill=False, linewidth=1.5))
ax.text(0.5, 0.5, "C1", va="center", ha="center")
ax.set_axis_off()
fig.tight_layout()
fig.savefig("minimal_block_diagram.png", dpi=150)

Monte Carlo aging (Weibull)

Use Weibull distributions to sample component lifetimes, then simulate system MTTF and R(t) curves with Monte Carlo.

import numpy as np
from fiabilipym import Component, System, Weibull, weibull_eta_from_lambda

beta = 2.0
lam0 = 1e-4
eta = weibull_eta_from_lambda(lam0, beta)
dist = Weibull(beta, eta)

C0 = Component("C0", lam0).with_distribution(dist)
C1 = Component("C1", lam0).with_distribution(dist)
C2 = Component("C2", lam0).with_distribution(dist)

S = System()
S["E"] = C0
S[C0] = [C1, C2]
S[C1] = "S"
S[C2] = "S"

T = np.linspace(0, 50000, 50)
mttf_hat, R_hat = S.monte_carlo(n=50000, grid_t=T, seed=42)

Voters (k-out-of-n) support Monte Carlo as well:

import numpy as np
from fiabilipym import Component, Voter, Weibull, weibull_eta_from_lambda

beta = 2.0
lam0 = 1e-4
eta = weibull_eta_from_lambda(lam0, beta)
dist = Weibull(beta, eta)

base = Component("C", lam0).with_distribution(dist)
voter = Voter(base, M=2, N=3)

T = np.linspace(0, 50000, 50)
mttf_hat, R_hat = voter.monte_carlo(n=50000, grid_t=T, seed=42)

Notebook-style demo (architectures + plots)

The included notebook fiabilipym_weibull_montecarlo_demo.ipynb builds the five reference architectures and generates:

  • MTTF bar plot
  • Reliability R(t) curves
  • Optional MTTF vs baseline lambda sweep (mean-matched)
  • System drawings

If you want a code-only version, the snippet below mirrors the notebook's core:

import numpy as np
import matplotlib.pyplot as plt
from fiabilipym import Component, System, Voter, Weibull, weibull_eta_from_lambda

beta = 2.0
lam0 = 1e-4
eta0 = weibull_eta_from_lambda(lam0, beta)

def aging_component(name, lam, beta, eta, age0=0.0):
    c = Component(name, lam).with_distribution(Weibull(beta, eta), age0=age0)
    return c

def build_series3(lam, beta, eta):
    c1, c2, c3 = (aging_component("C1", lam, beta, eta),
                 aging_component("C2", lam, beta, eta),
                 aging_component("C3", lam, beta, eta))
    S = System()
    S["E"] = c1
    S[c1] = c2
    S[c2] = c3
    S[c3] = "S"
    return S

def build_parallel3(lam, beta, eta):
    c1, c2, c3 = (aging_component("C1", lam, beta, eta),
                 aging_component("C2", lam, beta, eta),
                 aging_component("C3", lam, beta, eta))
    S = System()
    S["E"] = [c1, c2, c3]
    S[c1] = S[c2] = S[c3] = "S"
    return S

def build_series_parallel_3stages(lam, beta, eta):
    A1, A2 = aging_component("A1", lam, beta, eta), aging_component("A2", lam, beta, eta)
    B1, B2 = aging_component("B1", lam, beta, eta), aging_component("B2", lam, beta, eta)
    C1, C2 = aging_component("C1", lam, beta, eta), aging_component("C2", lam, beta, eta)
    S = System()
    S["E"] = [A1, A2]
    S[A1] = S[A2] = "N1"
    S["N1"] = [B1, B2]
    S[B1] = S[B2] = "N2"
    S["N2"] = [C1, C2]
    S[C1] = S[C2] = "S"
    return S

def build_parallel_series_3branches(lam, beta, eta):
    A1, A2 = aging_component("A1", lam, beta, eta), aging_component("A2", lam, beta, eta)
    B1, B2 = aging_component("B1", lam, beta, eta), aging_component("B2", lam, beta, eta)
    C1, C2 = aging_component("C1", lam, beta, eta), aging_component("C2", lam, beta, eta)
    S = System()
    S["E"] = [A1, B1, C1]
    S[A1] = A2
    S[A2] = "S"
    S[B1] = B2
    S[B2] = "S"
    S[C1] = C2
    S[C2] = "S"
    return S

def build_voter_2of3(lam, beta, eta):
    base = aging_component("C", lam, beta, eta)
    return Voter(base, M=2, N=3)

ARCH_BUILDERS = {
    "Series (3)": build_series3,
    "Parallel (3)": build_parallel3,
    "Series–Parallel (3 stages)": build_series_parallel_3stages,
    "Parallel–Series (3 branches)": build_parallel_series_3branches,
    "Voter 2-out-of-3": build_voter_2of3,
}

T = np.linspace(0, 3.0 / lam0, 250)
mttf = {}
R_curves = {}
for name, builder in ARCH_BUILDERS.items():
    obj = builder(lam0, beta, eta0)
    m, R = obj.monte_carlo(n=50000, grid_t=T, seed=42)
    mttf[name] = m
    R_curves[name] = R

plt.figure()
plt.bar(list(mttf.keys()), list(mttf.values()))
plt.xticks(rotation=25, ha="right")
plt.ylabel("MTTF (Monte Carlo)")
plt.title("MTTF by architecture")
plt.tight_layout()
plt.show()

plt.figure()
for name, R in R_curves.items():
    plt.plot(T, R, label=name)
plt.xlabel("Time t")
plt.ylabel("Reliability R(t)")
plt.ylim(0, 1.02)
plt.grid(True)
plt.legend()
plt.tight_layout()
plt.show()

Installation

pip install fiabilipym

Tests

Install test dependencies (editable install):

pip install -e ".[test]"

Run with pytest:

pytest -q

Run with unittest discovery:

python -m unittest discover -s tests

Equivalent uv-based commands:

uv run --extra test pytest -q

Alternative (stdlib unittest):

PYTHONPATH=src uv run python -m unittest discover -s tests

Package structure

fiabilipym/
├── changes.md
├── pyproject.toml
├── setup.py
├── README.md
├── src/
│   └── fiabilipym/
│       ├── __init__.py
│       ├── component.py
│       ├── distribution.py
│       ├── markov.py
│       ├── system.py
│       └── voter.py
├── fiabilipym_weibull_montecarlo_demo.ipynb
└── tests/
    ├── test_markov.py
    ├── test_system.py
    ├── test_monte_carlo_systems.py
    └── test_voter_monte_carlo.py

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fiabilipym-2.0.1.tar.gz (22.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fiabilipym-2.0.1-py3-none-any.whl (18.8 kB view details)

Uploaded Python 3

File details

Details for the file fiabilipym-2.0.1.tar.gz.

File metadata

  • Download URL: fiabilipym-2.0.1.tar.gz
  • Upload date:
  • Size: 22.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.14

File hashes

Hashes for fiabilipym-2.0.1.tar.gz
Algorithm Hash digest
SHA256 11b64e5ebb371e66542d7f9d4d36c2ff45615081cf9e2410ab8ea15decb5ba72
MD5 ee3013bea4ea6c562f44aac4f75c4920
BLAKE2b-256 2af94f2e0947a6856467ed7c8d533024b2565ef337525264353fe749512fab20

See more details on using hashes here.

File details

Details for the file fiabilipym-2.0.1-py3-none-any.whl.

File metadata

  • Download URL: fiabilipym-2.0.1-py3-none-any.whl
  • Upload date:
  • Size: 18.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.14

File hashes

Hashes for fiabilipym-2.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 9ca126b5d7ad13d8da54c51c029df1160b3d312bdc0dc86b4a61aa5dc457c4c0
MD5 adca7433ada1d5b88fad70e0a8c941b7
BLAKE2b-256 7757892e4af68c77c0f4f6850fe3ed8c61c7ecc793e3ed9c0cc42901b70f2863

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page