"""
Core microscopic gating model integrating all components.
This module provides the main model class that combines adsorption,
gating, geometry, and statistics into a complete microscopic gating
framework.
"""
from __future__ import annotations
from dataclasses import dataclass
import numpy as np
from .types import ArrayLike, ContactProbability, SitePairCount
from .gating import SymmetricGating, AsymmetricGating
from .statistics import BridgeCountModel, GateModel
[docs]@dataclass(frozen=True)
class MicroscopicGatingModel:
r"""
Full minimal microscopic gating model.
This is the primary interface for the microscopic gating framework,
integrating all components:
- Geometry/contact factor :math:`\langle \chi \rangle`
- Chemical closure success factor :math:`\kappa_B`
- Gating function :math:`G(\phi)` (symmetric or asymmetric)
- Bridge statistics and gate probabilities
The model implements the full chain (Eq. S16-S17, S12):
.. math::
P_{\text{bridge}}(\phi) &= \langle \chi \rangle \kappa_B G(\phi)
\langle n_b \rangle &= N_{\text{pair}} P_{\text{bridge}}(\phi)
P_{\text{open}} &= \exp(-\langle n_b \rangle)
P_{\text{closed}} &= 1 - \exp(-\langle n_b \rangle)
Parameters
----------
gating : SymmetricGating or AsymmetricGating
Gating object: :class:`SymmetricGating` for :math:`\theta(1-\theta)`
or :class:`AsymmetricGating` for :math:`\theta_P(1-\theta_N)`.
contact : ContactProbability
Geometry/contact model providing :math:`\langle \chi \rangle`.
kappa_B : float
Chemical/conformational closure success factor in (0, 1]
(or >= 0 if treated as weight).
site_pairs : SitePairCount
Site pair counts containing M and N_acc.
See Also
--------
SymmetricGating : Symmetric binding gating function.
AsymmetricGating : Asymmetric binding gating function.
LangmuirIsotherm : Standard adsorption isotherm.
Examples
--------
>>> from microscopic_gating.gating import SymmetricGating
>>> from microscopic_gating.adsorption import LangmuirIsotherm
>>> from microscopic_gating.geometry import ConstantContactProbability
>>> from microscopic_gating.types import SitePairCount
>>> isotherm = LangmuirIsotherm(K=1.0)
>>> gating = SymmetricGating(isotherm)
>>> contact = ConstantContactProbability(chi=0.5)
>>> site_pairs = SitePairCount(M=10, N_acc=5)
>>> model = MicroscopicGatingModel(gating, contact, kappa_B=0.8, site_pairs=site_pairs)
>>> model.P_bridge(1.0)
0.1
>>> model.P_open(1.0) # doctest: +SKIP
0.0067...
References
----------
- Eq. (S16): Bridge probability definition
- Eq. (S17): Mean bridge count
- Eq. (S12): Gate probabilities from Poisson statistics
"""
gating: SymmetricGating | AsymmetricGating
contact: ContactProbability
kappa_B: float
site_pairs: SitePairCount
[docs] def P_bridge(self, phi: ArrayLike) -> ArrayLike:
r"""
Calculate bridge probability per site pair.
Parameters
----------
phi : ArrayLike
Bulk concentration.
Returns
-------
p_B : ArrayLike
Bridge probability :math:`\langle \chi \rangle \kappa_B G(\phi)`,
same shape as `phi`.
"""
chi = self.contact.mean_contact()
G = self.gating.G(phi)
return chi * float(self.kappa_B) * np.asarray(G, dtype=float)
[docs] def lambda_(self, phi: ArrayLike) -> ArrayLike:
r"""
Calculate mean bridge count (Poisson intensity).
Parameters
----------
phi : ArrayLike
Bulk concentration.
Returns
-------
lam : ArrayLike
Poisson intensity :math:`\lambda(\phi) = N_{\text{pair}} P_{\text{bridge}}(\phi)`,
same shape as `phi`.
"""
pB = self.P_bridge(phi)
return BridgeCountModel(self.site_pairs).lambda_poisson(pB)
[docs] def P_open(self, phi: ArrayLike) -> ArrayLike:
r"""
Calculate gate open probability (no bridges).
Parameters
----------
phi : ArrayLike
Bulk concentration.
Returns
-------
P_open : ArrayLike
Open probability :math:`P_{\text{open}} = \exp(-\lambda(\phi))`,
same shape as `phi`.
"""
lam = self.lambda_(phi)
return GateModel().P_open(lam)
[docs] def P_closed(self, phi: ArrayLike) -> ArrayLike:
r"""
Calculate gate closed probability (at least one bridge).
Parameters
----------
phi : ArrayLike
Bulk concentration.
Returns
-------
P_closed : ArrayLike
Closed probability :math:`P_{\text{closed}} = 1 - \exp(-\lambda(\phi))`,
same shape as `phi`.
"""
lam = self.lambda_(phi)
return GateModel().P_closed(lam)