Source code for reconstruction.ecoli.dataclasses.process.rna_decay

"""
SimulationData for rna decay process
"""

from wholecell.utils import units

import autograd.numpy as anp
from autograd import jacobian
import numpy as np


[docs] class RnaDecay(object): """RnaDecay""" def __init__(self, raw_data, sim_data): self._buildRnaDecayData(raw_data, sim_data)
[docs] def _buildRnaDecayData(self, raw_data, sim_data): _ = sim_data # unused self.endoRNase_ids = [ x["endoRnase"] + sim_data.getter.get_compartment_tag(x["endoRnase"]) for x in raw_data.endoRNases ] self.kcats = (1 / units.s) * np.array( [x["kcat"].asNumber(1 / units.s) for x in raw_data.endoRNases] ) self.stats_fit = { "LossKm": 0.0, "LossKmOpt": 0.0, "RnegKmOpt": 0.0, "ResKm": 0.0, "ResKmOpt": 0.0, "ResEndoRNKm": 0.0, "ResEndoRNKmOpt": 0.0, "ResScaledKm": 0.0, "ResScaledKmOpt": 0.0, } # store Residuals re-scaled (sensitivity analysis "alpha") self.sensitivity_analysis_alpha_residual = {} self.sensitivity_analysis_alpha_regular_i_neg = {} # store Km's and Residuals re-scaled (sensitivity analysis "kcat EndoRNases") self.sensitivity_analysis_kcat = {} self.sensitivity_analysis_kcat_res_ini = {} self.sensitivity_analysis_kcat_res_opt = {} # store Km's from first-order RNA decay self.Km_first_order_decay = [] # store convergence of non-linear Km's (G(km)) self.Km_convergence = []
[docs] def km_loss_function(self, vMax, rnaConc, kDeg, isEndoRnase, alpha): """ Generates the functions used for estimating the per-RNA affinities (Michaelis-Menten constants) to the endoRNAses. The goal is to find a set of Michaelis-Menten constants such that the endoRNAse-mediated degradation under basal concentrations is consistent with the experimentally observed half-lives. If ``nonlinear`` is the rate of degradation predicted by Michaelis-Menten kinetics and ``linear`` is the rate of degradation from observed half-lives, we want:: nonlinear - linear = 0 In reality, there will be residuals ``R_aux = ``nonlinear - linear``. We care about the residuals after normalizing by the linear rate:: ``R = nonlinear / linear - 1``. In order to turn this into a minimization problem, we define the loss function as the squared sum of the residuals. Additionally, to ensure that all Km values are positive, the loss function accepts as input the logarithm of the final Km values and exponentiates them before calculating the residuals. The third-party package Autograd uses autodiff to calculate Jacobians for our loss function that can be used during minimization. Parameters ---------- vMax (float): The total endoRNase capacity, in units of amount per volume per time. rnaConc (np.ndarray): Concentrations of RNAs (amount per volume). kDeg (np.ndarray): Experimental degradation rates (per unit time). isEndoRnase (np.ndarray): Boolean array indicating endoRNase RNAs. Returns ------- tuple: A tuple containing the following functions: - **L** (*function*): The loss function to minimize. - **Lp** (*function*): The Jacobian of the loss function `L`. - **residual_f** (*function*): The residual error function. - **residual_aux_f** (*function*): The unnormalized residual error function. """ def residual_f(km): return vMax / km / kDeg / (1 + anp.sum(rnaConc / km)) - 1 def residual_aux_f(km): return vMax * rnaConc / km / (1 + anp.sum(rnaConc / km)) - kDeg * rnaConc def L(log_km): km = anp.exp(log_km) residual_squared = residual_f(km) ** 2 # Loss function return anp.sum(residual_squared) def Lp(km): return jacobian(L)(km) return ( L, Lp, residual_f, residual_aux_f, )