'''Define classes of simulation and fitting results.'''
import numpy as np
import pandas as pd
from scipy.linalg import pinv2
from ..core.mdv import MDV
from ..analysis.stats import (_chi2_test, _normal_probability, _simulated_vs_measured_MDVs,
_simulated_vs_measured_fluxes, _simulated_vs_measured_inst_MDVs,
_confidence_intervals_le, _confidence_intervals_mc, _MDV_kinetics,
_contribution_matrix, _sensitivity)
import warnings
warnings.filterwarnings('ignore', category = RuntimeWarning)
[docs]
class pDict(dict):
def __init__(self, *args, digits = 3, **kwargs):
super().__init__(*args, **kwargs)
[docs]
def __repr__(self):
itemStrs = []
for k, v in self.items():
if isinstance(v, MDV):
itemStr = '%s: %s' % (k, v)
elif isinstance(v, list):
itemStr = '%s: [%s]' % (k, ', '.join(map(str, np.round(v, self.digits))))
else:
itemStr = '%s: %s' % (k, np.round(v, self.digits))
itemStrs.append(itemStr)
return '\n'.join(itemStrs)
[docs]
class FBAResults():
'''
Parameters
----------
obj: dict
Reaction ID => coefficient, i.e., the objective function.
opt_obj: float
Optimal objective.
opt_fluxes: OrderedDict
Optimal fluxes.
'''
def __init__(self, obj, opt_obj, opt_fluxes):
'''
Parameters
----------
obj: dict
Reaction ID => coefficient, i.e., the objective function.
opt_obj: float
Optimal objective.
opt_fluxes: OrderedDict
Optimal fluxes.
'''
[docs]
self._opt_obj = opt_obj
[docs]
self._opt_fluxes = opt_fluxes
@property
[docs]
def objective(self):
objStr = ''
count = 0
for fluxid, coe in self._obj.items():
if coe > 0 and count > 0:
objStr += '+%s*%s' % (coe, fluxid)
else:
objStr += '%s*%s' % (coe, fluxid)
count += 1
return objStr
@property
[docs]
def opt_objective(self):
return round(self._opt_obj, 3)
@property
[docs]
def opt_fluxes(self):
return pDict(self._opt_fluxes)
[docs]
def __repr__(self):
return (
f'objective: {self.objective}\n'
f'optimal objective: {self.opt_objective}\n'
f'optimal fluxes\n{self.opt_fluxes}'
)
[docs]
class FVAResults():
'''
Parameters
----------
flux_ranges: dict
Reaction ID => [lower bound, upper bound].
'''
def __init__(self, flux_ranges):
'''
Parameters
----------
flux_ranges: dict
Reaction ID => [lower bound, upper bound].
'''
[docs]
self._flux_ranges = flux_ranges
@property
[docs]
def flux_ranges(self):
return pDict(self._flux_ranges)
[docs]
def __repr__(self):
return 'flux ranges\n%s' % self.flux_ranges
[docs]
class SimResults():
'''
Parameters
----------
simulated_MDVs: dict
EMU ID => MDV.
'''
def __init__(self, simulated_MDVs):
'''
Parameters
----------
simulated_MDVs: dict
EMU ID => MDV.
'''
[docs]
self._simulated_MDVs = simulated_MDVs
[docs]
self._simulated_EMUs = sorted(self._simulated_MDVs.keys())
@property
[docs]
def simulated_EMUs(self):
return self._simulated_EMUs
[docs]
def simulated_MDV(self, emuid):
'''
Parameters
emuid: str
EMU ID
'''
return self._simulated_MDVs[emuid]
[docs]
def __repr__(self):
return 'simulated MDVs\n%s' % pDict(self._simulated_MDVs)
[docs]
class InstSimResults():
'''
Parameters
----------
simulated_inst_MDVs: dict
EMU IDs => {timepoints => MDV}.
'''
def __init__(self, simulated_inst_MDVs):
'''
Parameters
----------
simulated_inst_MDVs: dict
EMU IDs => {timepoints => MDV}.
'''
[docs]
self._simulated_inst_MDVs = simulated_inst_MDVs
[docs]
self._simulated_EMUs = sorted(self._simulated_inst_MDVs)
[docs]
self._timepoints = sorted(self._simulated_inst_MDVs[self._simulated_EMUs[0]])
@property
[docs]
def simulated_EMUs(self):
return self._simulated_EMUs
@property
[docs]
def timepoints(self):
return self._timepoints
[docs]
def simulated_MDV(self, emuid):
'''
Parameters
----------
emuid: str
EMU ID.
'''
return pDict(self._simulated_inst_MDVs[emuid])
[docs]
def plot_MDV_kinetics(self, emuid, show_fig = True, output_dir = None):
'''
Parameters
----------
emuid: str
EMU ID.
show_fig: bool
Whether to show figure.
output_dir: str
Output directory.
'''
_MDV_kinetics(emuid, self._simulated_inst_MDVs[emuid], show_fig, output_dir)
[docs]
def __repr__(self):
mdvstrs = []
for emuid in self.simulated_EMUs:
mdvstr = '%s\n%s' % (emuid, self.simulated_MDV(emuid))
mdvstrs.append(mdvstr)
return 'simulated_MDVs\n' + '\n\n'.join(mdvstrs)
[docs]
class FitResults():
'''
Parameters
----------
opt_total_fluxes: ser
Total fluxes at optimal objective.
opt_net_fluxes: ser
Net fluxes at optimal objective.
opt_obj: float
Optimal value of objective.
opt_resids: array
Optimal weighted residuals.
n_meas: int
# of measurements.
n_params: int
# of parameters.
sim_MDVs: dict
EMU ID => simulated MDV.
exp_MDVs: dict
EMU ID => [means, sds].
sim_fluxes: dict
Flux ID => simulated flux.
exp_fluxes: dict
Flux ID => [mean, sd].
hessian: array
Hessian matrix at convergence.
null_space: array
Null space of stoichiometric matrix.
transform_matrix: array
Transform matrix from total fluxes to net fluxes.
sim_MDVs_der_u: array
Derivative of simulated MDVs w.r.t. free fluxes.
sim_fluxes_der_u: array
Derivative of simualted fluxes w.r.t. free fluxes.
exp_MDVs_inv_cov: array
Inversed covariance matrix of measured MDVs.
exp_fluxes_inv_cov: array
Inversed covariance matrix of measured fluxes.
is_success: bool
Whether the optimization is successful.
'''
def __init__(
self,
opt_total_fluxes,
opt_net_fluxes,
opt_obj,
opt_resids,
n_meas,
n_params,
sim_MDVs,
exp_MDVs,
sim_fluxes,
exp_fluxes,
hessian,
null_space,
transform_matrix,
sim_MDVs_der_u,
sim_fluxes_der_u,
exp_MDVs_inv_cov,
exp_fluxes_inv_cov,
is_success
):
'''
Parameters
----------
opt_total_fluxes: ser
Total fluxes at optimal objective.
opt_net_fluxes: ser
Net fluxes at optimal objective.
opt_obj: float
Optimal value of objective.
opt_resids: array
Optimal weighted residuals.
n_meas: int
# of measurements.
n_params: int
# of parameters.
sim_MDVs: dict
EMU ID => simulated MDV.
exp_MDVs: dict
EMU ID => [means, sds].
sim_fluxes: dict
Flux ID => simulated flux.
exp_fluxes: dict
Flux ID => [mean, sd].
hessian: array
Hessian matrix at convergence.
null_space: array
Null space of stoichiometric matrix.
transform_matrix: array
Transform matrix from total fluxes to net fluxes.
sim_MDVs_der_u: array
Derivative of simulated MDVs w.r.t. free fluxes.
sim_fluxes_der_u: array
Derivative of simualted fluxes w.r.t. free fluxes.
exp_MDVs_inv_cov: array
Inversed covariance matrix of measured MDVs.
exp_fluxes_inv_cov: array
Inversed covariance matrix of measured fluxes.
is_success: bool
Whether the optimization is successful.
'''
[docs]
self._opt_total_fluxes = opt_total_fluxes
[docs]
self._opt_net_fluxes = opt_net_fluxes
[docs]
self._opt_obj = opt_obj
[docs]
self.opt_resids = opt_resids
[docs]
self.simulated_MDVs = sim_MDVs
[docs]
self.measured_MDVs = exp_MDVs
[docs]
self.simulated_fluxes = sim_fluxes
[docs]
self.measured_fluxes = exp_fluxes
[docs]
self.null_space = null_space
[docs]
self.n_params = n_params
[docs]
self.dof = self.n_meas - self.n_params
[docs]
self.sim_MDVs_der_u = sim_MDVs_der_u
[docs]
self.sim_fluxes_der_u = sim_fluxes_der_u
[docs]
self.exp_MDVs_inv_cov = exp_MDVs_inv_cov
[docs]
self.exp_fluxes_inv_cov = exp_fluxes_inv_cov
[docs]
self.is_success = is_success
@property
[docs]
def n_total_fluxes(self):
return len(self._opt_total_fluxes)
@property
[docs]
def n_net_fluxes(self):
return len(self._opt_net_fluxes)
@property
[docs]
def n_free_fluxes(self):
return self.null_space.shape[1]
@property
[docs]
def opt_objective(self):
return round(self._opt_obj, 3)
@property
[docs]
def opt_total_fluxes(self):
return pDict(self._opt_total_fluxes)
@property
[docs]
def opt_net_fluxes(self):
return pDict(self._opt_net_fluxes)
@property
[docs]
def optimization_successful(self):
return self.is_success
[docs]
def chi2_test(self, confidence_level = 0.999):
'''
Perform chi square test of the optimal objective.
SSR < LB of chi square interval sometimes can be also considered as successful estimation.
Parameters
----------
confidence_level: float
Confidence level, e.g. 0.95 as 95% confidence level.
'''
_chi2_test(self._opt_obj, self.dof, confidence_level)
[docs]
def plot_normal_probability(self, show_fig = True, output_dir = None):
'''
Perform normal probability plot for residuals.
Parameters
----------
show_fig: bool
Whether to show figure.
output_dir: str
Output directory.
'''
_normal_probability(self.opt_resids, show_fig, output_dir)
[docs]
def plot_simulated_vs_measured_MDVs(self, show_fig = True, output_dir = None):
'''
Plot simulated and measured MDVs.
Parameters
----------
show_fig: bool
Whether to show figure.
output_dir: str
Output directory.
'''
_simulated_vs_measured_MDVs(
self.simulated_MDVs,
self.measured_MDVs,
show_fig,
output_dir
)
[docs]
def plot_simulated_vs_measured_fluxes(self, show_fig = True, output_dir = None):
'''
Plot simulated and measured fluxes.
Parameters
----------
show_fig: bool
Whether to show figure.
output_dir: str
Output directory.
'''
_simulated_vs_measured_fluxes(
self.simulated_fluxes,
self.measured_fluxes,
show_fig,
output_dir
)
[docs]
def estimate_confidence_intervals(self, which = 'net', confidence_level = 0.95):
'''
Calculate CI of net (total) fluxes using local estimation.
Parameters
----------
which: {"net", "total"}
* "net" if net fluxes.
* "total" if total fluxes.
confidence_level: float
Confidence level, e.g. 0.95 as 95% confidence level.
'''
if which == 'net':
totalFluxesCov = self.null_space@pinv2(self.hessian)@self.null_space.T
netFluxesCov = self.transform_matrix@totalFluxesCov@self.transform_matrix.T
irrRxns = self._opt_net_fluxes.index.intersection(
self._opt_total_fluxes.index
).tolist()
netFluxesRange = _confidence_intervals_le(
self._opt_net_fluxes,
irrRxns,
netFluxesCov,
self.dof,
confidence_level
)
return pDict(netFluxesRange)
elif which == 'total':
totalFluxesCov = self.null_space@pinv2(self.hessian)@self.null_space.T
irrRxns = self._opt_total_fluxes.index.tolist()
totalFluxesRange = _confidence_intervals_le(
self._opt_total_fluxes,
irrRxns,
totalFluxesCov,
self.dof,
confidence_level
)
return pDict(totalFluxesRange)
else:
raise ValueError('only "net" and "total" are acceptable for which argument')
[docs]
def estimate_contribution_matrix(self, which = 'net'):
'''
Calculate contribution matrix of measurement variance to net (total) flux variance.
Parameters
----------
which: {"net", "total"}
* "net" if net fluxes.
* "total" if total fluxes.
'''
freeFluxesCov = pinv2(self.hessian)
expMDVsCov = pinv2(self.exp_MDVs_inv_cov)
expFluxesCov = pinv2(self.exp_fluxes_inv_cov)
if which == 'net':
transMat = self.transform_matrix@self.null_space
fluxIdx = self._opt_net_fluxes.index
elif which == 'total':
transMat = self.null_space
fluxIdx = self._opt_total_fluxes.index
else:
raise ValueError('only "net" and "total" are acceptable for which argument')
contribMat_MDV = _contribution_matrix(
freeFluxesCov,
transMat,
self.sim_MDVs_der_u,
expMDVsCov
)
contribMat_MDV = pd.DataFrame(
contribMat_MDV,
index = fluxIdx,
columns = self._get_name_of_measurements(self.measured_MDVs)
)
contribMat_flux = _contribution_matrix(
freeFluxesCov,
transMat,
self.sim_fluxes_der_u,
expFluxesCov
)
contribMat_flux = pd.DataFrame(
contribMat_flux,
index = fluxIdx,
columns = self.measured_fluxes.keys()
)
contribMat = pd.concat((contribMat_MDV, contribMat_flux), axis = 1)
return contribMat
[docs]
def estimate_sensitivity(self, which = 'net'):
'''
Calculate sensitivity matrix of estimated net (total) flux w.r.t. measurement changes.
Parameters
----------
which: {"net", "total"}
* "net" if net fluxes.
* "total" if total fluxes.
'''
freeFluxesCov = pinv2(self.hessian)
if which == 'net':
transMat = self.transform_matrix@self.null_space
fluxIdx = self._opt_net_fluxes.index
elif which == 'total':
transMat = self.null_space
fluxIdx = self._opt_total_fluxes.index
else:
raise ValueError('only "net" and "total" are acceptable for which argument')
senMat_MDV = _sensitivity(
freeFluxesCov,
transMat,
self.sim_MDVs_der_u,
self.exp_MDVs_inv_cov
)
senMat_MDV = pd.DataFrame(
senMat_MDV,
index = fluxIdx,
columns = self._get_name_of_measurements(self.measured_MDVs)
)
senMat_flux = _sensitivity(
freeFluxesCov,
transMat,
self.sim_fluxes_der_u,
self.exp_fluxes_inv_cov
)
senMat_flux = pd.DataFrame(
senMat_flux,
index = fluxIdx,
columns = self.measured_fluxes.keys()
)
senMat = pd.concat((senMat_MDV, senMat_flux), axis = 1)
return senMat
@staticmethod
[docs]
def _get_name_of_measurements(measured_MDVs):
'''
Parameters
----------
measured_MDVs: dict
EMU ID => [means, sds].
'''
names = []
for emuid in measured_MDVs:
_, atoms = emuid.split('_')
for atom in '0'+atoms:
names.append(f'{emuid}_m{atom}')
return names
[docs]
def __repr__(self):
return f'optimal objective: {self.opt_objective} at\n{self.opt_net_fluxes}'
[docs]
class FitMCResults():
'''
Parameters
----------
total_fluxes_set: list of ser
Set of optimal total fluxes.
net_fluxes_set: list of ser
Set of optimal net fluxes.
'''
def __init__(self, total_fluxes_set, net_fluxes_set):
'''
Parameters
----------
total_fluxes_set: list of ser
Set of optimal total fluxes.
net_fluxes_set: list of ser
Set of optimal net fluxes.
'''
[docs]
self.total_fluxes_set = total_fluxes_set
[docs]
self.net_fluxes_set = net_fluxes_set
[docs]
def estimate_confidence_intervals(self, which = 'net', confidence_level = 0.95):
'''
Estimate CI from a set of fluxes.
Parameters
----------
which: {"net", "total"}
* "net" if net fluxes.
* "total" if total fluxes.
confidence_level: float
Confidence level, e.g. 0.95 as 95% confidence level.
'''
if which == 'net':
irrRxns = self.net_fluxes_set[0].index.intersection(
self.total_fluxes_set[0].index
).tolist()
netFluxesRange = _confidence_intervals_mc(
self.net_fluxes_set,
irrRxns,
confidence_level
)
return pDict(netFluxesRange)
elif which == 'total':
irrRxns = self.total_fluxes_set[0].index.tolist()
totalFluxesRange = _confidence_intervals_mc(
self.total_fluxes_set,
irrRxns,
confidence_level
)
return pDict(totalFluxesRange)
else:
raise ValueError('only "net" and "total" are acceptable for which argument')
[docs]
def __repr__(self):
return '%s' % self.estimate_confidence_intervals('net', 0.95)
[docs]
class InstFitResults(FitResults):
'''
Parameters
----------
opt_total_fluxes: ser
Total fluxes at optimal objective.
opt_net_fluxes: ser
Net fluxes at optimal objective.
opt_concs: ser
Concentrations at optimal objective.
opt_obj: float
Optimal value of objective.
opt_resids: array
Optimal weighted residuals.
n_meas: int
# of measurements.
n_params: int
# of parameters.
sim_inst_MDVs: dict
EMU ID => {t => simulated MDV}.
exp_inst_MDVs: dict
EMU ID => {t => [means, sds]}.
sim_fluxes: dict
Flux ID => simulated flux.
exp_fluxes: dict
Flux ID => [mean, sd].
hessian: array
Hessian matrix at convergence.
null_space: array
Null space of stoichiometric matrix.
transform_matrix: array
Transform matrix from total fluxes to net fluxes.
sim_inst_MDVs_der_u: array
Derivative of simulated MDVs w.r.t. free fluxes.
sim_fluxes_der_u: array
Derivative of simualted fluxes w.r.t. free fluxes.
exp_inst_MDVs_inv_cov: array
Inversed covariance matrix of measured MDVs.
exp_fluxes_inv_cov: array
Inversed covariance matrix of measured fluxes.
is_success: bool
Whether the optimization is successful.
'''
def __init__(
self,
opt_total_fluxes,
opt_net_fluxes,
opt_concs,
opt_obj,
opt_resids,
n_meas,
n_params,
sim_inst_MDVs,
exp_inst_MDVs,
sim_fluxes,
exp_fluxes,
hessian,
null_space,
transform_matrix,
sim_inst_MDVs_der_u,
sim_fluxes_der_u,
exp_inst_MDVs_inv_cov,
exp_fluxes_inv_cov,
is_success
):
'''
Parameters
----------
opt_total_fluxes: ser
Total fluxes at optimal objective.
opt_net_fluxes: ser
Net fluxes at optimal objective.
opt_concs: ser
Concentrations at optimal objective.
opt_obj: float
Optimal value of objective.
opt_resids: array
Optimal weighted residuals.
n_meas: int
# of measurements.
n_params: int
# of parameters.
sim_inst_MDVs: dict
EMU ID => {t => simulated MDV}.
exp_inst_MDVs: dict
EMU ID => {t => [means, sds]}.
sim_fluxes: dict
Flux ID => simulated flux.
exp_fluxes: dict
Flux ID => [mean, sd].
hessian: array
Hessian matrix at convergence.
null_space: array
Null space of stoichiometric matrix.
transform_matrix: array
Transform matrix from total fluxes to net fluxes.
sim_inst_MDVs_der_u: array
Derivative of simulated MDVs w.r.t. free fluxes.
sim_fluxes_der_u: array
Derivative of simualted fluxes w.r.t. free fluxes.
exp_inst_MDVs_inv_cov: array
Inversed covariance matrix of measured MDVs.
exp_fluxes_inv_cov: array
Inversed covariance matrix of measured fluxes.
is_success: bool
Whether the optimization is successful.
'''
[docs]
self._opt_total_fluxes = opt_total_fluxes
[docs]
self._opt_net_fluxes = opt_net_fluxes
[docs]
self._opt_concs = opt_concs
[docs]
self._opt_obj = opt_obj
[docs]
self.opt_resids = opt_resids
[docs]
self.simulated_inst_MDVs = sim_inst_MDVs
[docs]
self.measured_inst_MDVs = exp_inst_MDVs
[docs]
self.simulated_fluxes = sim_fluxes
[docs]
self.measured_fluxes = exp_fluxes
[docs]
self.null_space = null_space
[docs]
self.n_params = n_params
[docs]
self.dof = self.n_meas - self.n_params
[docs]
self.sim_inst_MDVs_der_u = sim_inst_MDVs_der_u
[docs]
self.sim_fluxes_der_u = sim_fluxes_der_u
[docs]
self.exp_inst_MDVs_inv_cov = exp_inst_MDVs_inv_cov
[docs]
self.exp_fluxes_inv_cov = exp_fluxes_inv_cov
[docs]
self.is_success = is_success
@property
[docs]
def n_concentrations(self):
return len(self._opt_concs)
@property
[docs]
def opt_concentrations(self):
return pDict(self._opt_concs)
[docs]
def plot_simulated_vs_measured_MDVs(self, show_fig = True, output_dir = None):
'''
Plot simulated and measured MDVs.
Parameters
----------
show_fig: bool
Whether to show figure.
output_dir: str
Output directory.
'''
_simulated_vs_measured_inst_MDVs(
self.simulated_inst_MDVs,
self.measured_inst_MDVs,
show_fig,
output_dir
)
[docs]
def estimate_confidence_intervals(self, which = 'net', confidence_level = 0.95):
'''
Calculate CI of fluxes and concentrations using local estimation.
Parameters
----------
which: {"net", "total", "conc"}
* "net" if net fluxes.
* "total" if total fluxes.
* "conc" if concentrations.
confidence_level: float
Confidence level, e.g. 0.95 as 95% confidence level.
'''
if which == 'net':
fluxHessian = self.hessian[:self.n_free_fluxes,:self.n_free_fluxes]
totalFluxesCov = self.null_space@pinv2(fluxHessian)@self.null_space.T
netFluxesCov = self.transform_matrix@totalFluxesCov@self.transform_matrix.T
irrItems = self._opt_net_fluxes.index.intersection(
self._opt_total_fluxes.index
).tolist()
netFluxesRange = _confidence_intervals_le(
self._opt_net_fluxes,
irrItems,
netFluxesCov,
self.dof,
confidence_level
)
return pDict(netFluxesRange)
elif which == 'total':
fluxHessian = self.hessian[:self.n_free_fluxes,:self.n_free_fluxes]
totalFluxesCov = self.null_space@pinv2(fluxHessian)@self.null_space.T
irrItems = self._opt_total_fluxes.index.tolist()
totalFluxesRange = _confidence_intervals_le(
self._opt_total_fluxes,
irrItems,
totalFluxesCov,
self.dof,
confidence_level
)
return pDict(totalFluxesRange)
elif which == 'conc':
concHessian = self.hessian[self.n_free_fluxes:, self.n_free_fluxes:]
concsCov = pinv2(concHessian)
irrItems = self._opt_concs.index.tolist()
concsRange = _confidence_intervals_le(
self._opt_concs,
irrItems,
concsCov,
self.dof,
confidence_level
)
return pDict(concsRange)
else:
raise ValueError('only "net", "total" and "conc" are acceptable for which argument')
[docs]
def estimate_contribution_matrix(self, which = 'net'):
'''
Calculate contribution matrix of measurement variance to net (total) flux variance.
Parameters
----------
which: {"net", "total"}
* "net" if net fluxes.
* "total" if total fluxes.
'''
fluxHessian = self.hessian[:self.n_free_fluxes,:self.n_free_fluxes]
freeFluxesCov = pinv2(fluxHessian)
expMDVsCov = pinv2(self.exp_inst_MDVs_inv_cov)
expFluxesCov = pinv2(self.exp_fluxes_inv_cov)
if which == 'net':
transMat = self.transform_matrix@self.null_space
fluxIdx = self._opt_net_fluxes.index
elif which == 'total':
transMat = self.null_space
fluxIdx = self._opt_total_fluxes.index
else:
raise ValueError('only "net" and "total" are acceptable for which argument')
contribMat_MDV = _contribution_matrix(
freeFluxesCov,
transMat,
self.sim_inst_MDVs_der_u,
expMDVsCov
)
contribMat_MDV = pd.DataFrame(
contribMat_MDV,
index = fluxIdx,
columns = self._get_name_of_measurements(self.measured_inst_MDVs)
)
contribMat_flux = _contribution_matrix(
freeFluxesCov,
transMat,
self.sim_fluxes_der_u,
expFluxesCov
)
contribMat_flux = pd.DataFrame(
contribMat_flux,
index = fluxIdx,
columns = self.measured_fluxes.keys()
)
contribMat = pd.concat((contribMat_MDV, contribMat_flux), axis = 1)
return contribMat
[docs]
def estimate_sensitivity(self, which = 'net'):
'''
Calculate sensitivity matrix of estimated net (total) flux w.r.t. measurement changes.
Parameters
----------
which: {"net", "total"}
* "net" if net fluxes.
* "total" if total fluxes.
'''
fluxHessian = self.hessian[:self.n_free_fluxes, :self.n_free_fluxes]
freeFluxesCov = pinv2(fluxHessian)
if which == 'net':
transMat = self.transform_matrix@self.null_space
fluxIdx = self._opt_net_fluxes.index
elif which == 'total':
transMat = self.null_space
fluxIdx = self._opt_total_fluxes.index
else:
raise ValueError('only "net" and "total" are acceptable for which argument')
senMat_MDV = _sensitivity(
freeFluxesCov,
transMat,
self.sim_inst_MDVs_der_u,
self.exp_inst_MDVs_inv_cov
)
senMat_MDV = pd.DataFrame(
senMat_MDV,
index = fluxIdx,
columns = self._get_name_of_measurements(self.measured_inst_MDVs)
)
senMat_flux = _sensitivity(
freeFluxesCov,
transMat,
self.sim_fluxes_der_u,
self.exp_fluxes_inv_cov
)
senMat_flux = pd.DataFrame(
senMat_flux,
index = fluxIdx,
columns = self.measured_fluxes.keys()
)
senMat = pd.concat((senMat_MDV, senMat_flux), axis = 1)
return senMat
@staticmethod
[docs]
def _get_name_of_measurements(measured_MDVs):
'''
Parameters
----------
measured_MDVs: dict
EMU ID => {t => [means, sds]}.
'''
names = []
for emuid in measured_MDVs:
for t in measured_MDVs[emuid]:
if t != 0:
_, atoms = emuid.split('_')
for atom in '0'+atoms:
names.append(f'{emuid}_m{atom}_{t}')
return names
[docs]
class InstFitMCResults(FitMCResults):
'''
Parameters
----------
total_fluxes_set: list of ser
Set of optimal total fluxes.
net_fluxes_set: list of ser
Set of optimal net fluxes.
concs_set: list of ser
Set of optimal concentrations.
'''
def __init__(self, total_fluxes_set, net_fluxes_set, concs_set):
'''
Parameters
----------
total_fluxes_set: list of ser
Set of optimal total fluxes.
net_fluxes_set: list of ser
Set of optimal net fluxes.
concs_set: list of ser
Set of optimal concentrations.
'''
super().__init__(total_fluxes_set, net_fluxes_set)
[docs]
self.concs_set = concs_set
[docs]
def estimate_confidence_intervals(self, which = 'net', confidence_level = 0.95):
'''
This method estimates CI from a set of fluxes.
Parameters
----------
which: {"net", "total", "conc"}
* "net" if net fluxes.
* "total" if total fluxes.
* "conc" if concentrations.
confidence_level: float
Confidence level, e.g. 0.95 as 95% confidence level.
'''
if which == 'net':
irrItems = self.net_fluxes_set[0].index.intersection(
self.total_fluxes_set[0].index
).tolist()
netFluxesRange = _confidence_intervals_mc(
self.net_fluxes_set,
irrItems,
confidence_level
)
return pDict(netFluxesRange)
elif which == 'total':
irrItems = self.total_fluxes_set[0].index.tolist()
totalFluxesRange = _confidence_intervals_mc(
self.total_fluxes_set,
irrItems,
confidence_level
)
return pDict(totalFluxesRange)
elif which == 'conc':
irrItems = self.concs_set[0].index.tolist()
concsRange = _confidence_intervals_mc(
self.concs_set,
irrItems,
confidence_level
)
return pDict(concsRange)
else:
raise ValueError('only "net", "total" and "conc" are acceptable for which argument')