Skip to content

OPU (Organoid Processing Unit)

The OPU layer handles the low-level simulation of organoid physics.

Device

pykoppu.opu.OPU

Organoid Processing Unit (OPU) Device Class.

Represents the physical cartridge containing the organoid and MEA interface.

Source code in pykoppu/opu/device.py
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
class OPU:
    """
    Organoid Processing Unit (OPU) Device Class.

    Represents the physical cartridge containing the organoid and MEA interface.
    """

    def __init__(self, model: str = "lif_critical", capacity: int = 100):
        """
        Initialize the OPU device.

        Args:
            model (str): The biological model to use. Defaults to "lif_critical".
            capacity (int): The number of neurons/channels available. Defaults to 100.
        """
        self.model = model
        self.capacity = capacity
        self.specs = self._load_bio_specs(model)

    def _load_bio_specs(self, model: str) -> BioSpecs:
        """
        Load biological specifications for the given model.

        Args:
            model (str): The model name.

        Returns:
            BioSpecs: The physical specifications.

        Raises:
            ValueError: If the model is unknown.
        """
        if model == "lif_critical":
            # Parameters for critical regime
            # R=50*Mohm, tau=20*ms, El=-70*mV, Vt=-50*mV, Vr=-70*mV
            # I_offset=0.36*nA, sigma=2.0*mV
            return BioSpecs(
                R=50e6,       # 50 MOhm
                tau=20e-3,    # 20 ms
                El=-70e-3,    # -70 mV
                Vt=-50e-3,    # -50 mV
                Vr=-70e-3,    # -70 mV
                I_offset=0.39e-9, # 0.39 nA (Increased for higher activity)
                sigma=2.0e-3  # 2.0 mV
            )
        else:
            raise ValueError(f"Unknown model: {model}")

    def get_specs_dict(self) -> Dict[str, Any]:
        """
        Get specifications as a dictionary.

        Returns:
            Dict[str, Any]: Dictionary of specifications.
        """
        return self.specs.__dict__

__init__(model='lif_critical', capacity=100)

Initialize the OPU device.

Parameters:

Name Type Description Default
model str

The biological model to use. Defaults to "lif_critical".

'lif_critical'
capacity int

The number of neurons/channels available. Defaults to 100.

100
Source code in pykoppu/opu/device.py
39
40
41
42
43
44
45
46
47
48
49
def __init__(self, model: str = "lif_critical", capacity: int = 100):
    """
    Initialize the OPU device.

    Args:
        model (str): The biological model to use. Defaults to "lif_critical".
        capacity (int): The number of neurons/channels available. Defaults to 100.
    """
    self.model = model
    self.capacity = capacity
    self.specs = self._load_bio_specs(model)

get_specs_dict()

Get specifications as a dictionary.

Returns:

Type Description
Dict[str, Any]

Dict[str, Any]: Dictionary of specifications.

Source code in pykoppu/opu/device.py
80
81
82
83
84
85
86
87
def get_specs_dict(self) -> Dict[str, Any]:
    """
    Get specifications as a dictionary.

    Returns:
        Dict[str, Any]: Dictionary of specifications.
    """
    return self.specs.__dict__

Kernel

pykoppu.opu.Kernel

Kernel for OPU tensor operations.

Source code in pykoppu/opu/kernel.py
10
11
12
13
14
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
class Kernel:
    """
    Kernel for OPU tensor operations.
    """

    @staticmethod
    def compute_energy(J: np.ndarray, h: np.ndarray, state: np.ndarray) -> float:
        """
        Compute the energy of a given state for the Hamiltonian defined by J and h.

        E = -0.5 * x^T J x - h^T x

        Args:
            J (np.ndarray): Coupling matrix.
            h (np.ndarray): Bias vector.
            state (np.ndarray): State vector (binary or spin).

        Returns:
            float: The energy value.
        """
        # Ensure inputs are numpy arrays
        J = np.asarray(J)
        h = np.asarray(h)
        state = np.asarray(state)

        # Quadratic term: 0.5 * x^T J x
        # Note: Usually Ising model is -0.5 * ... but here we define generic quadratic form
        # Let's follow standard Ising: H = - sum J_ij s_i s_j - sum h_i s_i
        # In matrix form: E = -0.5 * s^T J s - h^T s

        quadratic = 0.5 * state.T @ J @ state
        linear = h.T @ state

        return -(quadratic + linear)

compute_energy(J, h, state) staticmethod

Compute the energy of a given state for the Hamiltonian defined by J and h.

E = -0.5 * x^T J x - h^T x

Parameters:

Name Type Description Default
J ndarray

Coupling matrix.

required
h ndarray

Bias vector.

required
state ndarray

State vector (binary or spin).

required

Returns:

Name Type Description
float float

The energy value.

Source code in pykoppu/opu/kernel.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
@staticmethod
def compute_energy(J: np.ndarray, h: np.ndarray, state: np.ndarray) -> float:
    """
    Compute the energy of a given state for the Hamiltonian defined by J and h.

    E = -0.5 * x^T J x - h^T x

    Args:
        J (np.ndarray): Coupling matrix.
        h (np.ndarray): Bias vector.
        state (np.ndarray): State vector (binary or spin).

    Returns:
        float: The energy value.
    """
    # Ensure inputs are numpy arrays
    J = np.asarray(J)
    h = np.asarray(h)
    state = np.asarray(state)

    # Quadratic term: 0.5 * x^T J x
    # Note: Usually Ising model is -0.5 * ... but here we define generic quadratic form
    # Let's follow standard Ising: H = - sum J_ij s_i s_j - sum h_i s_i
    # In matrix form: E = -0.5 * s^T J s - h^T s

    quadratic = 0.5 * state.T @ J @ state
    linear = h.T @ state

    return -(quadratic + linear)