def test_equality_constraint(model: Model) -> None: """Test equality constraint.""" model.reactions.ACALD.bounds = (-1.5, -1.5) s = sample(model, 10) assert np.allclose(s.ACALD, -1.5, atol=1e-6, rtol=0) s = sample(model, 10, method="achr") assert np.allclose(s.ACALD, -1.5, atol=1e-6, rtol=0)
def test_inequality_constraint(model: Model) -> None: """Test inequality constraint.""" co = model.problem.Constraint(model.reactions.ACALD.flux_expression, lb=-0.5) model.add_cons_vars(co) s = sample(model, 10) assert all(s.ACALD > -0.5 - 1e-6) s = sample(model, 10, method="achr") assert all(s.ACALD > -0.5 - 1e-6)
def test_equality_constraint(model): """Test equality constraint.""" model.reactions.ACALD.bounds = (-1.5, -1.5) s = sample(model, 10) assert np.allclose(s.ACALD, -1.5, atol=1e-6, rtol=0) s = sample(model, 10, method="achr") assert np.allclose(s.ACALD, -1.5, atol=1e-6, rtol=0)
def test_single_point_space(model: Model) -> None: """Test the reduction of the sampling space to one point.""" pfba_sol = pfba(model) pfba_const = model.problem.Constraint( sum(model.variables), ub=pfba_sol.objective_value ) model.add_cons_vars(pfba_const) model.reactions.Biomass_Ecoli_core.lower_bound = pfba_sol.fluxes.Biomass_Ecoli_core with pytest.raises(ValueError): sample(model, 1)
def test_inequality_constraint(model): """Test inequality constraint.""" co = model.problem.Constraint( model.reactions.ACALD.flux_expression, lb=-0.5) model.add_cons_vars(co) s = sample(model, 10) assert all(s.ACALD > -0.5 - 1e-6) s = sample(model, 10, method="achr") assert all(s.ACALD > -0.5 - 1e-6)
def _calc_fluxes(self, alg='fba', sampling_n=0): try: if sampling_n == 0: self.model.solver.problem.write(self.__class__.__name__ + '.lp') if alg == 'pfba': solution = pfba(self.model) else: solution = self.model.optimize() if solution.status == OPTIMAL: reversible_fluxes = solution.fluxes self.logger.info( f"Optimal objective: {solution.objective_value:.2f}") else: raise OptimizationError(solution.status) else: reversible_fluxes = sample( self.model, n=sampling_n, thinning=10, processes=multiprocessing.cpu_count()).mean(axis=0) irreversible_fluxes = {} for reaction, flux in reversible_fluxes.iteritems(): if flux < 0: irreversible_fluxes[reaction + '_b'] = -flux else: irreversible_fluxes[reaction] = flux return Series(irreversible_fluxes.values(), index=irreversible_fluxes.keys()) except (AttributeError, SolverError, OptimizationError) as e: self.logger.error(f'{str(e).capitalize()}') return Series([], dtype=object)
def test_inhomogeneous_sanity(model: Model) -> None: """Test standard deviation between inhomogeneous and homogeneous sampling.""" model.reactions.ACALD.bounds = (-1.5, -1.5) s_inhom = sample(model, 64) model.reactions.ACALD.bounds = (-1.5 - 1e-3, -1.5 + 1e-3) s_hom = sample(model, 64) relative_diff = (s_inhom.std() + 1e-12) / (s_hom.std() + 1e-12) assert 0.5 < relative_diff.abs().mean() < 2 model.reactions.ACALD.bounds = (-1.5, -1.5) s_inhom = sample(model, 64, method="achr") model.reactions.ACALD.bounds = (-1.5 - 1e-3, -1.5 + 1e-3) s_hom = sample(model, 64, method="achr") relative_diff = (s_inhom.std() + 1e-12) / (s_hom.std() + 1e-12) assert 0.5 < relative_diff.abs().mean() < 2
def sample_initial_concentrations(kmodel, reference_concentrations, lower_bound=0.8, upper_bound=1.2, n_samples=10, absolute_bounds=False): concentrations = np.array( [reference_concentrations[k] for k in kmodel.variables]) if kmodel.conservation_relation is None: N = len(kmodel.variables) rand = np.random.uniform(low=lower_bound, high=upper_bound, size=(N, n_samples)) # else: # Todo Also allow lower_bound = { k: v * lower_bound for k, v in reference_concentrations.items() } upper_bound = { k: v * upper_bound for k, v in reference_concentrations.items() } # Account for volume differences in compartments if kmodel.volume_ratio_func is None: effective_conservation_relations = kmodel.conservation_relation.todense( ) else: param_values = { p.symbol: p.value for p in kmodel.parameters.values() } volume_ratios = kmodel.volume_ratio_func(param_values) inv_volume_ratio_matrix = diags(1. / np.array(volume_ratios)).todense() effective_conservation_relations = kmodel.conservation_relation.todense()\ .dot(inv_volume_ratio_matrix) # Create a linear problem and sample it rhs = effective_conservation_relations.dot(concentrations) linmodel = create_linear_model(effective_conservation_relations, rhs, kmodel.reactants, lower_bound=lower_bound, upper_bound=upper_bound) return sample( linmodel, n_samples, )
def test_inhomogeneous_sanity(model): """Test whether inhomogeneous sampling gives approximately the same standard deviation as a homogeneous version.""" model.reactions.ACALD.bounds = (-1.5, -1.5) s_inhom = sample(model, 64) model.reactions.ACALD.bounds = (-1.5 - 1e-3, -1.5 + 1e-3) s_hom = sample(model, 64) relative_diff = (s_inhom.std() + 1e-12) / (s_hom.std() + 1e-12) assert 0.5 < relative_diff.abs().mean() < 2 model.reactions.ACALD.bounds = (-1.5, -1.5) s_inhom = sample(model, 64, method="achr") model.reactions.ACALD.bounds = (-1.5 - 1e-3, -1.5 + 1e-3) s_hom = sample(model, 64, method="achr") relative_diff = (s_inhom.std() + 1e-12) / (s_hom.std() + 1e-12) assert 0.5 < relative_diff.abs().mean() < 2
def test_single_point_space(model): """Test the reduction of the sampling space to one point.""" pfba_sol = pfba(model) pfba_const = model.problem.Constraint( sum(model.variables), ub=pfba_sol.objective_value) model.add_cons_vars(pfba_const) model.reactions.Biomass_Ecoli_core.lower_bound = \ pfba_sol.fluxes.Biomass_Ecoli_core with pytest.raises(ValueError): s = sample(model, 1)
def test_inhomogeneous_sanity(model): """Test whether inhomogeneous sampling gives approximately the same standard deviation as a homogeneous version.""" model.reactions.ACALD.bounds = (-1.5, -1.5) s_inhom = sample(model, 64) model.reactions.ACALD.bounds = (-1.5 - 1e-3, -1.5 + 1e-3) s_hom = sample(model, 64) relative_diff = (s_inhom.std() + 1e-12) / (s_hom.std() + 1e-12) assert 0.5 < relative_diff.abs().mean() < 2 model.reactions.ACALD.bounds = (-1.5, -1.5) s_inhom = sample(model, 64, method="achr") model.reactions.ACALD.bounds = (-1.5 - 1e-3, -1.5 + 1e-3) s_hom = sample(model, 64, method="achr") relative_diff = (s_inhom.std() + 1e-12) / (s_hom.std() + 1e-12) assert 0.5 < relative_diff.abs().mean() < 2
def test_fixed_seed(model: Model) -> None: """Test result of fixed seed for sampling.""" s1 = sample(model, 1, seed=42) s2 = sample(model, 1, seed=42) assert np.isclose(s1.TPI[0], s2.TPI[0])
def test_wrong_method(model: Model) -> None: """Test method intake sanity.""" with pytest.raises(ValueError): sample(model, 1, method="schwupdiwupp")
def test_multi_optgp(model: Model) -> None: """Test OptGP sampling (multi sample).""" s = sample(model, 10, processes=2) assert s.shape == (10, len(model.reactions))
def test_single_optgp(model: Model) -> None: """Test OptGP sampling (one sample).""" s = sample(model, 10, processes=1) assert s.shape == (10, len(model.reactions))
def test_single_achr(model: Model) -> None: """Test ACHR sampling (one sample).""" s = sample(model, 10, method="achr") assert s.shape == (10, len(model.reactions))
def test_single_achr(model): """Test ACHR sampling (one sample).""" s = sample(model, 10, method="achr") assert s.shape == (10, len(model.reactions))
def test_single_optgp(model): """Test OptGP sampling (one sample).""" s = sample(model, 10, processes=1) assert s.shape == (10, len(model.reactions))
def test_multi_optgp(model): """Test OptGP sampling (multi sample).""" s = sample(model, 10, processes=2) assert s.shape == (10, len(model.reactions))
def test_wrong_method(model): """Test method intake sanity.""" with pytest.raises(ValueError): sample(model, 1, method="schwupdiwupp")
def test_fixed_seed(model): """Test result of fixed seed for sampling.""" s1 = sample(model, 1, seed=42) s2 = sample(model, 1, seed=42) assert np.isclose(s1.TPI[0], s2.TPI[0])
ALLELE_PHENO_FILE = ENSEMBLE_DIR + "/allele_pheno_data/" ### ------------------------------------------------------------ ### Sample allele-constraint maps and popFVA landscapes for MNCs ### ------------------------------------------------------------ if GENERATE_SAMPLES == True: MODEL_SAMPLES_FILE = ENSEMBLE_DIR + "/" + MODEL_SAMPLES_FILENAME if not os.path.exists(MODEL_SAMPLES_FILE): from cobra import sampling print( "\t... generating flux samples for base cobra model...(may take >10 minutes). Only performed once!" ) rxn_flux_samples_ARCH = sampling.sample(COBRA_MODEL, 1000, method='achr', thinning=100, processes=6, seed=None) print("\t... saving flux samples for base cobra model: ", MODEL_SAMPLES_FILE) rxn_flux_samples_ARCH.to_csv(MODEL_SAMPLES_FILE) ENSEMBLE_BASEMODEL_FILE = ENSEMBLE_DIR + "/base_cobra_model.json" if not os.path.exists(ENSEMBLE_BASEMODEL_FILE): from cobra.io import save_json_model print("\t... saving base cobra model: ", ENSEMBLE_BASEMODEL_FILE) save_json_model(COBRA_MODEL, ENSEMBLE_BASEMODEL_FILE) base_flux_samples = pd.read_csv(MODEL_SAMPLES_FILE, index_col=0) ### Create Species object
def flux_sampler(S, revs, fluxCons, ratioCons, bndCons, nsims, njobs): ''' Parameters S: df, stoichiometric matrix, balanced metabolites in rows, net reactions fluxes in columns revs: ser, reaction reversibility fluxCons: ser, flux value constraints ratioCons: df, ratio range constraints, columns are ['greater_than_zero', 'smaller_than_zero'], e.g. a < v1/v2 < b will be transfromed into v1 - a*v2 > 0 and v1 - b*v2 < 0 bndCons: df, flux range constraints, columns are ['lb', 'ub'] nsims: int, # of flux distributions to simulate njobs: int, # of jobs run in parallel bndCons: df, boundary constraints of flux Returns netFluxDistribs: df, net fluxes distributions, columns are fluxes, rows are runs netFluxBnds: df, net fluxes bounds, columns are ['minimum', 'maximum'], rows are fluxes ''' model = Model() model.add_metabolites([Metabolite(i) for i in S.index]) #! only balances metabolites included model.add_reactions([Reaction(i) for i in S.columns]) for rxn in S.columns: metabs = S[rxn][S[rxn] != 0] model.reactions.get_by_id(rxn).add_metabolites(dict(metabs)) if fluxCons is not None: cons = [] for rxn, value in fluxCons.items(): con = model.problem.Constraint(model.reactions.get_by_id(rxn).flux_expression, lb = value, ub = value) cons.append(con) model.add_cons_vars(cons) if ratioCons is not None: cons = [] for ratio, ratioCon in ratioCons.iterrows(): itemsLB = [coe*model.reactions.get_by_id(rxn).flux_expression for rxn, coe in ratioCon['greater_than_zero'].items()] exprLB = reduce(lambda x, y: x+y, itemsLB) conLB = model.problem.Constraint(exprLB, lb = 0) itemsUB = [coe*model.reactions.get_by_id(rxn).flux_expression for rxn, coe in ratioCon['smaller_than_zero'].items()] exprUB = reduce(lambda x, y: x+y, itemsUB) conUB = model.problem.Constraint(exprUB, ub = 0) cons.extend([conLB, conUB]) model.add_cons_vars(cons) for rxn in bndCons.index: model.reactions.get_by_id(rxn).lower_bound = bndCons.loc[rxn, 'lb'] model.reactions.get_by_id(rxn).upper_bound = bndCons.loc[rxn, 'ub'] netFluxBnds = flux_variability_analysis(model) netFluxDistribs = sample(model, n = nsims, method = 'optgp', processes = njobs) return netFluxDistribs, netFluxBnds