CardamomOT.inference.degradations¶
Utilities for degradation rate inference and temporal epsilon estimation.
This module provides PyTorch models and helper functions used by the
CARDAMOM pipeline when learning gene-specific degradation parameters
from protein dynamics. It includes the
GeneRegulatoryODE_softmax neural ODE model and the
infer_ratio_d0_d1_unitary() routine among other utilities.
Classes¶
G_genes MLPs indépendants entraînés en parallèle via joblib. |
|
ODE model for gene regulatory dynamics with generalized softmax-based kon. |
Functions¶
|
Return a function kon(X_numpy_or_torch) -> numpy array (batch, G) |
|
Find a single scale factor minimising the total MSE across all genes jointly. |
|
Estimate ε_i = d1_i/d0_i from ODE residuals (bursty-PDMP variance matching). |
|
Estimate degradation rates and scaling factors from protein time-course data. |
|
Infer d1/d0 from full simulated trajectories via regularised LS. |
|
Simulate a trajectory given an initial state and trained ODE model. |
|
Compare real and simulated trajectories using UMAP projection. |
Module Contents¶
- CardamomOT.inference.degradations.build_kon_fn(ks, theta_inter, bias, device='cpu')¶
Return a function kon(X_numpy_or_torch) -> numpy array (batch, G) The function accepts either numpy arrays or torch tensors; it returns numpy.
- class CardamomOT.inference.degradations.KonCorrectionMLP(G_tot: int, G_genes: int, hidden_dim: int = 8)¶
Bases:
torch.nn.ModuleG_genes MLPs indépendants entraînés en parallèle via joblib. Gène i prend [P_i, kon_beta_i] → delta_mu_i. At init: delta_mu = 1 everywhere.
- class CardamomOT.inference.degradations.GeneRegulatoryODE_softmax(G, d_init, ks, theta_inter, bias, n_stimuli=1, stim_vals=None, device='cpu', kon_mlp=None, lambda_scale=1000.0)¶
Bases:
torch.nn.ModuleODE model for gene regulatory dynamics with generalized softmax-based kon. Learns gene-specific degradation rates (d) and scale factors. Optionally applies a KonCorrectionMLP multiplicative correction (Harissa branch).
- set_ratio_interpolation(t_start, t_end, ratio_t0, ratio_t1, lambda_mlp)¶
Configure time-interpolated ratio mix for the next odeint call.
- Parameters:
t_start – boundaries of the current interval (floats).
t_end – boundaries of the current interval (floats).
ratio_t0 – mean observed g = kon_harissa/kon_beta at
t_start/t_end, shape(G_genes,).ratio_t1 – mean observed g = kon_harissa/kon_beta at
t_start/t_end, shape(G_genes,).lambda_mlp – mix weight (1 = pure interpolation, 0 = pure MLP).
- forward(t, X)¶
Compute dX/dt for a given state X at time t. Includes learned scaling of theta_inter and bias. When kon_mlp is set, applies a frozen per-gene multiplicative correction. If
set_ratio_interpolationhas been called, the correction is mixed with the linearly interpolated observed training ratios at weightlambda_mlp.
- CardamomOT.inference.degradations.fit_scale_theta(X_prot, kon_beta, bias, theta_inter, ks, ns, samples_data=None)¶
Find a single scale factor minimising the total MSE across all genes jointly.
- Parameters:
X_prot –
(N, G)protein levels.kon_beta –
(N, G)mixture-inferred kon values.bias –
(G, n_modes-1)or(n_samples, G, n_modes-1)GRN basal.theta_inter –
(G, G, n_modes-1)GRN interaction tensor.ks –
(n_modes, G)softmax burst-rate amplitudes.ns – number of stimulus columns.
samples_data –
(N,)per-cell sample index when bias is 3-D, else None.
- Returns:
float, the jointly optimal scale (same for all genes).
- Return type:
scale_theta
- CardamomOT.inference.degradations.infer_ratio_d0_d1_unitary(X_prot, times, bias, theta_inter, ks, d_learned_temporal, k1_vec, n_stimuli=1, stim_schedule=None, samples_data=None, method='dopri5', rtol=1e-06, atol=1e-08, lambda_deg=0.0, prior_eps=None, outlier_quantile=0.95, min_kon=1e-06, eps_min=0.01, eps_max=100.0, verbose=True, kon_mlp=None, scale=1.0) tuple[numpy.ndarray, numpy.ndarray]¶
Estimate ε_i = d1_i/d0_i from ODE residuals (bursty-PDMP variance matching).
Theoretical background.
In the bursty PDMP actually simulated (see
BurstyPDMP), the burst parameters at intervalcntare:burst rate :
λ_i = k1_i · kon_norm_i(P) · d0_iburst size :
Exp(k1_i · d0_i / (scale · d1_i))i.e. mean burst =scale · d1_i / (k1_i · d0_i)
This ensures the mean-field ODE limit is
dP_i/dt = d1_i(kon_i/k1_i − P_i).By Campbell’s theorem (leading term for small dt):
\[\operatorname{Var}[\Delta X_i] \approx \lambda_i \cdot E[B_i^2] \cdot dt = 2\,dt\cdot k_{on,i}(P)\cdot\mathrm{scale}\, \frac{d_{1,i}^2}{k_{1,i}^2\,d_{0,i}} = \varepsilon_i \cdot h_{ic}\]where \(\varepsilon_i = d_{1,i}/d_{0,i}\) and
\[h_{ic} = 2\,dt\cdot\mathrm{scale}\cdot \frac{d_{1,i}}{k_{1,i}^2}\cdot k_{on,i}(P_c)\]The regularised method-of-moments estimator is:
\[\varepsilon_i = \frac{\sum_c (X_{\mathrm{pred},c} - X_{1,c})^2 + \lambda\,\varepsilon_{\mathrm{prior},i}} {\sum_c h_{ic} + \lambda}\]- Parameters:
X_prot –
(N, G)protein observations (all timepoints).times –
(N,)time label for each row.bias – GRN bias —
(T-1, G, n_nets)or(T-1, n_samples, G, n_nets).theta_inter –
(T-1, G, G, n_nets)GRN interaction tensor.ks –
(n_modes, G)softmax burst-rate amplitudes (already multiplied byscale_proteins).d_learned_temporal –
(T-1, G)learned protein degradation rates d1.k1_vec –
(G,)max burst rate × scale (=k1 * scale).n_stimuli – Number of stimulus columns (default 1).
stim_schedule –
{float: np.ndarray(ns)}stimulus values per time.samples_data –
(N,)per-cell sample index (optional).method – ODE solver settings.
rtol – ODE solver settings.
atol – ODE solver settings.
lambda_deg – Tikhonov weight; 0 = pure MoM, large → prior.
prior_eps –
(G,)prior for ε = d1/d0. Defaults to all-ones.outlier_quantile – Fraction of cells to keep (sorted by residual).
min_kon – Minimum kon value for a cell to contribute.
eps_min – Output clipping bounds for ε = d1/d0.
eps_max – Output clipping bounds for ε = d1/d0.
verbose – Log per-interval diagnostics.
kon_mlp – Optional
KonCorrectionMLP(Harissa branch).scale – Protein scale (
self.scale_proteins). Default 1.0.
- Returns:
(T-1, G)per-interval ε = d1/d0 estimates. eps_global :(G,)global ε pooled over all intervals.- Return type:
eps_temporal
- CardamomOT.inference.degradations.inference_degradation_prot(X_prot, times, bias, theta_inter, ks, d=None, n_epochs=500, lr=0.01, method='dopri5', rtol=1e-06, atol=1e-08, print_every=50, batch_size=None, verbose=True, n_stimuli=1, stim_schedule=None, scale_proteins=1.0, samples_data=None, kon_mlp=None, lambda_scale=1000.0, lambda_deg=0.0, lambda_mlp=0.0, g_obs_train=None) tuple[numpy.ndarray, numpy.ndarray]¶
Estimate degradation rates and scaling factors from protein time-course data.
When
biasis 3-D (n_samples, G, n_modes-1) andsamples_datais provided, one ODE module is created per sample with its own bias whiled_paramandscale_paramare shared, so a single optimizer refines the shared kinetics from all samples jointly.- Returns:
Learned degradation rates, shape (G,).
scale_learned: Learned scaling parameters, shape (G,).- Return type:
d_learned
- CardamomOT.inference.degradations.infer_ratio_d0_d1_full(X_prot, times, bias, theta_inter, ks, d_learned, k1_vec, kon_mlp, prior_d1d0=None, n_stimuli=1, stim_schedule=None, samples_data=None, method='dopri5', rtol=1e-05, atol=1e-07, n_steps=10, lambda_deg=0.0, lambda_mlp=0.5, g_obs_train=None, min_h=0.0001, verbose=True, clip_lo=0.01, clip_hi=100.0) tuple[numpy.ndarray, numpy.ndarray]¶
Infer d1/d0 from full simulated trajectories via regularised LS.
Theoretical background.
To first order in
d1/d0, the MLP correction factor satisfies:\[1 - g_i(P(t)) \approx \frac{d_{1,i}}{d_{0,i}} \cdot h_i(P(t))\]where
g_i = kon_harissa_i / kon_beta_i(learned by kon_mlp) and\[h_i(P) = \sum_j \frac{\partial\ln kon_i}{\partial X_j} \cdot (kon^{\rm eff}_j - X_j)\]where the
d_{1,j}factor is not included inh_i(uniform-d1 approximation:d_{1,j} \approx d_{1,i}for all j, so it becomes part of the ratiod_{1,i}/d_{0,i}that the LS estimates directly).Fitting strategy.
Instead of evaluating only at the terminal state, this function simulates full trajectories with
n_stepsintermediate evaluation points and fitsr_i = d1_i/d0_iby minimising over all (cell, timestep) pairs:\[\mathcal{L}(r_i) = \sum_{c,t} \bigl[y_{ict} - r_i\,h_{ict}\bigr]^2 + \lambda\,(r_i - r_{\rm prior,i})^2\]with
y_{ict} = 1 - g_i(P_c(t)). The closed-form solution is:\[r_i^* = \frac{\sum h\,y + \lambda\,r_{\rm prior}}{\sum h^2 + \lambda}\]Only (cell, timestep) pairs where
h_iandy_ihave the same sign (i.e. where the formula predictsr_i > 0) and where|h_i| > min_hare included.Usage in base.py:
ratios_temporal, ratios_global = infer_ratio_d0_d1_full(...) # temporal (one ratio per interval): self.ratios[cnt] = 1.0 / ratios_temporal[cnt] # global (one shared ratio): self.ratios[:] = (1.0 / ratios_global)[None, :]
- Parameters:
X_prot –
(N, G)protein observations across all timepoints.times –
(N,)time label for each observation.bias – GRN bias —
(G, n_modes-1)or(n_samples, G, n_modes-1).theta_inter – GRN interactions —
(G, G, n_modes-1)or(n_samples, G, G, n_modes-1).ks – Mode amplitudes, shape
(n_modes, G).d_learned – Protein degradation rates, shape
(G,)(constant) or(T-1, G)(temporal). When 2-D, intervalcntusesd_learned[cnt]for the ODE simulation.k1_vec – Kept for interface compatibility (not used internally).
kon_mlp – Trained
KonCorrectionMLP.prior_d1d0 –
(G,)prior for d1/d0 used whenlambda_deg > 0. Defaults to all-ones (quasi-stationary limit).n_stimuli – Number of stimulus columns (default 1).
stim_schedule – Dict
{float_time: np.ndarray(ns,)}; defaults to all-ones whenNone.samples_data –
(N,)per-cell sample index.method – ODE solver method (default
"dopri5").rtol – ODE solver tolerances.
atol – ODE solver tolerances.
n_steps – Number of intermediate ODE evaluation points per interval (default 10; total = n_steps+1 incl. t0, t1).
lambda_deg – Tikhonov regularisation weight — same role as in
inference_degradation_prot().0= pure LS; large values → prior.lambda_mlp –
Mix weight between the linearly interpolated observed training ratios and the MLP prediction. For a simulated state at time
tin[t1, t2]the effective ratio used asy_i = 1 - g_effis:\[g_{\rm eff} = \lambda_{\rm mlp} \Bigl[ \frac{t_2-t}{t_2-t_1}\,r_1 + \frac{t-t_1}{t_2-t_1}\,r_2 \Bigr] + (1-\lambda_{\rm mlp})\,g(P,\,k_{\rm on}(P))\]where
r_1/r_2are the mean observed MLP ratios at the training timepointst_1/t_2(shape(G_genes,)).1.0= pure linear interpolation of observed g;0.0= pure MLP prediction (original behaviour).min_h – Minimum
|h_i|to include a (cell, timestep) pair.verbose – Log per-interval diagnostics.
clip_lo – Final clamp on the estimated d1/d0.
clip_hi – Final clamp on the estimated d1/d0.
- Returns:
(T-1, G)per-interval d1/d0 estimates. ratios_global :(G,)global d1/d0 pooled over all intervals.Stimulus columns (
[:ns]) are fixed to 1.0 in both outputs.- Return type:
ratios_temporal
- CardamomOT.inference.degradations.predict_trajectory(ode_func, X0, t_span, method='dopri5', rtol=1e-06, atol=1e-08, stim_vals=None)¶
Simulate a trajectory given an initial state and trained ODE model.
- CardamomOT.inference.degradations.compare_trajectories_umap(ode_func, X_prot, times, method='dopri5')¶
Compare real and simulated trajectories using UMAP projection.