def test_one_variable_sequential(self): ppp = phenotypic_phase_plane(self.model, ['EX_o2_LPAREN_e_RPAREN_'], view=SequentialView()) assert_dataframes_equal(ppp, REFERENCE_PPP_o2_EcoliCore) ppp = phenotypic_phase_plane(self.model, 'EX_o2_LPAREN_e_RPAREN_', view=SequentialView()) assert_dataframes_equal(ppp, REFERENCE_PPP_o2_EcoliCore)
class TestSequentialView(unittest.TestCase): def setUp(self): self.view = SequentialView() def test_map(self): self.assertEqual(self.view.map(to_the_power_of_2, list(range(100))), SOLUTION) def test_apply(self): for i in range(100): self.assertEqual(self.view.apply(to_the_power_of_2, i), SOLUTION[i])
def test_one_variable_sequential_yield(self, core_model): ppp = phenotypic_phase_plane(core_model, ['EX_o2_LPAREN_e_RPAREN_'], view=SequentialView()) assert_data_frames_equal(ppp, REFERENCE_PPP_o2_EcoliCore, sort_by=['EX_o2_LPAREN_e_RPAREN_']) ppp = phenotypic_phase_plane(core_model, 'EX_o2_LPAREN_e_RPAREN_', view=SequentialView()) assert_data_frames_equal(ppp, REFERENCE_PPP_o2_EcoliCore, sort_by=['EX_o2_LPAREN_e_RPAREN_'])
def __call__(self, point): self._set_bounds(point[1]) return (point[1], flux_variability_analysis(self.model, reactions=self.included_reactions, remove_cycles=False, view=SequentialView()))
def test_flux_variability_sequential_remove_cycles(self, core_model): original_objective = core_model.objective fva_solution = flux_variability_analysis( core_model, fraction_of_optimum=0.999999419892, remove_cycles=True, view=SequentialView()) assert REFERENCE_FVA_SOLUTION_ECOLI_CORE['upper_bound']['FRD7'] > 666. assert round(abs(fva_solution['upper_bound']['FRD7'] - 0.), 7) == 0 for key in fva_solution.data_frame.index: if REFERENCE_FVA_SOLUTION_ECOLI_CORE['lower_bound'][key] > -666: assert abs(fva_solution['lower_bound'][key] - REFERENCE_FVA_SOLUTION_ECOLI_CORE['lower_bound'] [key]) < 0.0001 if REFERENCE_FVA_SOLUTION_ECOLI_CORE['upper_bound'][key] < 666: assert abs(fva_solution['upper_bound'][key] - REFERENCE_FVA_SOLUTION_ECOLI_CORE['upper_bound'] [key]) < 0.0001 cycle_reac = cameo.Reaction("minus_PGI") # Create fake cycle cycle_reac.lower_bound = -1000 core_model.add_reaction(cycle_reac) cycle_reac.add_metabolites({ met: -c for met, c in core_model.reactions.PGI.metabolites.items() }) fva_solution = flux_variability_analysis(core_model, remove_cycles=False, reactions=["PGI"]) assert fva_solution.data_frame.loc["PGI", "upper_bound"] == 1000 fva_solution = flux_variability_analysis(core_model, remove_cycles=True, reactions=["PGI"]) assert fva_solution.data_frame.loc["PGI", "upper_bound"] < 666 assert original_objective == core_model.objective
def test_run_multiobjective(self): result_file = os.path.join(CURRENT_PATH, "data", "reaction_knockout_multi_objective.pkl") objective1 = biomass_product_coupled_yield( "Biomass_Ecoli_core_N_LPAREN_w_FSLASH_GAM_RPAREN__Nmet2", "EX_ac_LPAREN_e_RPAREN_", "EX_glc_LPAREN_e_RPAREN_") objective2 = number_of_knockouts() objective = [objective1, objective2] rko = ReactionKnockoutOptimization(model=self.model, simulation_method=fba, objective_function=objective, heuristic_method=inspyred.ec.emo.NSGA2, seed=SEED) # self.assertEqual(rko.random.random(), 0.1915194503788923) results = rko.run(max_evaluations=3000, pop_size=10, view=SequentialView()) # print(rko.random.random(), 0.545818634701) with open(result_file, 'rb') as in_file: if six.PY3: expected_results = pickle.load(in_file, encoding="latin1") else: expected_results = pickle.load(in_file) assert_frame_equal(results.solutions, expected_results.solutions)
def test_run_single_objective(self): result_file = os.path.join(CURRENT_PATH, "data", "reaction_knockout_single_objective.pkl") objective = biomass_product_coupled_yield( "Biomass_Ecoli_core_N_LPAREN_w_FSLASH_GAM_RPAREN__Nmet2", "EX_ac_LPAREN_e_RPAREN_", "EX_glc_LPAREN_e_RPAREN_") rko = ReactionKnockoutOptimization(model=self.model, simulation_method=fba, objective_function=objective, seed=SEED) # self.assertEqual(rko.random.random(), 0.1915194503788923) results = rko.run(max_evaluations=3000, pop_size=10, view=SequentialView()) # self.assertEqual(rko.random.random(), 0.9268454219291495) with open(result_file, 'rb') as in_file: if six.PY3: expected_results = pickle.load(in_file, encoding="latin1") else: expected_results = pickle.load(in_file) assert_frame_equal(results.solutions, expected_results.solutions)
def test_two_variables_sequential(self, core_model): ppp2d = phenotypic_phase_plane( core_model, ['EX_o2_LPAREN_e_RPAREN_', 'EX_glc_LPAREN_e_RPAREN_'], view=SequentialView()) assert_data_frames_equal( ppp2d, REFERENCE_PPP_o2_glc_EcoliCore, sort_by=['EX_o2_LPAREN_e_RPAREN_', 'EX_glc_LPAREN_e_RPAREN_'])
def effective_upper_bound(self): model = self.model fva_result = flux_analysis.flux_variability_analysis( model, reactions=[self], view=SequentialView(), remove_cycles=False) return fva_result['upper_bound'][self.id]
def __call__(self, point): self._set_bounds(point[1]) fva_result = flux_variability_analysis(self.model, reactions=self.included_reactions, remove_cycles=False, view=SequentialView()).data_frame fva_result['lower_bound'] = fva_result.lower_bound.apply(lambda v: 0 if abs(v) < non_zero_flux_threshold else v) fva_result['upper_bound'] = fva_result.upper_bound.apply(lambda v: 0 if abs(v) < non_zero_flux_threshold else v) return point[1], fva_result
def test_flux_variability_sequential(self, core_model): original_objective = core_model.objective fva_solution = flux_variability_analysis(core_model, fraction_of_optimum=0.999999419892, remove_cycles=False, view=SequentialView()) pfba_fva = flux_variability_analysis(core_model, fraction_of_optimum=1, pfba_factor=1).data_frame assert_data_frames_equal(fva_solution, REFERENCE_FVA_SOLUTION_ECOLI_CORE) assert_data_frames_equal(fva_solution, REFERENCE_FVA_SOLUTION_ECOLI_CORE) assert original_objective == core_model.objective assert sum(abs(pfba_fva.lower_bound)) - 518.422 < 0.001 assert sum(abs(pfba_fva.upper_bound)) - 518.422 < 0.001
def test_flux_variability_sequential(self): fva_solution = flux_variability_analysis(self.model, fraction_of_optimum=0.999999419892, remove_cycles=False, view=SequentialView()) assert_data_frames_equal(fva_solution, REFERENCE_FVA_SOLUTION_ECOLI_CORE) for key in fva_solution.data_frame.index: self.assertAlmostEqual(fva_solution['lower_bound'][key], REFERENCE_FVA_SOLUTION_ECOLI_CORE['lower_bound'][key], delta=0.00001) self.assertAlmostEqual(fva_solution['upper_bound'][key], REFERENCE_FVA_SOLUTION_ECOLI_CORE['upper_bound'][key], delta=0.00001) assert_data_frames_equal(fva_solution, REFERENCE_FVA_SOLUTION_ECOLI_CORE)
def test_flux_variability_sequential_remove_cycles(self): fva_solution = flux_variability_analysis(self.model, fraction_of_optimum=0.999999419892, remove_cycles=True, view=SequentialView()) self.assertGreater(REFERENCE_FVA_SOLUTION_ECOLI_CORE['upper_bound']['FRD7'], 666.) self.assertAlmostEqual(fva_solution['upper_bound']['FRD7'], 0.) for key in fva_solution.data_frame.index: if REFERENCE_FVA_SOLUTION_ECOLI_CORE['lower_bound'][key] > -666: self.assertAlmostEqual(fva_solution['lower_bound'][key], REFERENCE_FVA_SOLUTION_ECOLI_CORE['lower_bound'][key], delta=0.0001) if REFERENCE_FVA_SOLUTION_ECOLI_CORE['upper_bound'][key] < 666: self.assertAlmostEqual(fva_solution['upper_bound'][key], REFERENCE_FVA_SOLUTION_ECOLI_CORE['upper_bound'][key], delta=0.0001) cycle_reac = cameo.Reaction("minus_PGI") # Create fake cycle cycle_reac.lower_bound = -1000 self.model.add_reaction(cycle_reac) cycle_reac.add_metabolites({met: -c for met, c in self.model.reactions.PGI.metabolites.items()}) fva_solution = flux_variability_analysis(self.model, remove_cycles=False, reactions=["PGI"]) self.assertEqual(fva_solution.data_frame.loc["PGI", "upper_bound"], 1000) fva_solution = flux_variability_analysis(self.model, remove_cycles=True, reactions=["PGI"]) self.assertTrue(fva_solution.data_frame.loc["PGI", "upper_bound"] < 666)
def test_flux_variability_sequential_remove_cycles(self): fva_solution = flux_variability_analysis( self.model, fraction_of_optimum=0.999999419892, remove_cycles=True, view=SequentialView()) self.assertGreater( REFERENCE_FVA_SOLUTION_ECOLI_CORE['upper_bound']['FRD7'], 1000.) self.assertAlmostEqual(fva_solution['upper_bound']['FRD7'], 0.) for key in fva_solution.data_frame.index: if abs(REFERENCE_FVA_SOLUTION_ECOLI_CORE['lower_bound'] [key]) < 1000: self.assertAlmostEqual( fva_solution['lower_bound'][key], REFERENCE_FVA_SOLUTION_ECOLI_CORE['lower_bound'][key], delta=0.0001) if abs(REFERENCE_FVA_SOLUTION_ECOLI_CORE['upper_bound'] [key]) < 1000: self.assertAlmostEqual( fva_solution['upper_bound'][key], REFERENCE_FVA_SOLUTION_ECOLI_CORE['upper_bound'][key], delta=0.0001)
def setUp(self): self.view = SequentialView()
def default(self): product = None output_format = None auto_select = self.app.pargs.yes_all if self.app.pargs.product is None: print("Argument --product must be provided") exit(1) else: product = self.app.pargs.product if self.app.pargs.output_format is None: if auto_select: output_format = "xlsx" print("Output format will be Excel") else: formats = [ "%i - %s (.%s)\n" % (i + 1, OUTPUT_FORMATS_EXPLANATION[ext], ext) for i, ext in enumerate(VALID_OUTPUT_FORMATS) ] choice = input("Choose your output format:\n" + "".join(formats) + "Enter [1]:") if choice == "": choice = "1" try: choice = int(choice) output_format = VALID_OUTPUT_FORMATS[choice - 1] except TypeError: print("Invalid choice %s" % choice) exit(1) else: output_format = self.app.pargs.output_format if output_format not in VALID_OUTPUT_FORMATS: print("Invalid input format") if self.app.pargs.output is None: output = self.app.pargs.product + "." + output_format if auto_select: print("Output will be written to %s" % output) else: choice = input("Enter your output path (%s):" % output) if choice != "": output = choice else: output = self.app.pargs.output if self.app.pargs.host is None: _hosts = ['ecoli', 'yeast'] else: _hosts = self.app.pargs.host _hosts = [getattr(hosts, host) for host in _hosts] if self.app.pargs.multiprocess: view = MultiprocessingView(processes=self.app.pargs.cores) else: view = SequentialView() design.debug = self.app.pargs.test results = design(product=product, hosts=_hosts, view=view, aerobic=not self.app.pargs.anaerobic) results['heterologous_pathway'] = results.heterologous_pathway.apply( str) results['manipulations'] = results.manipulations.apply(str) OUTPUT_WRITER[output_format](results, output)
def design(product, host, output, format, cores, aerobic, differential_fva, heuristic_optimization, max_pathway_predictions, differential_fva_points, pathway_prediction_timeout, heuristic_optimization_timeout, logging): """Compute strain designs for desired product.""" from cameo.api.designer import design from cameo.api.hosts import hosts from cameo.parallel import MultiprocessingView, SequentialView logger.setLevel(logging) cameo_logger.setLevel(logging) hosts = [getattr(hosts, host) for host in host] if cores > 1: if sys.platform == 'darwin': # check if numpy is compatible with multiprocessing logger.debug( 'On OS X, testing if numpy is compatible with multiprocessing') import numpy logger.debug('numpy.config: {}'.format( numpy.__config__.blas_opt_info)) if 'Accelerate' in str(numpy.__config__.blas_opt_info): click.echo(click.style( 'WARNING! It looks like the present installation of numpy ' 'is linked against the accelerate framework, which ' 'unfortunately is incompatible with multiprocessing' 'and might cause the program to hang at some point. ' 'Either set --cores 1 to run sequentially or consider ' 'installing numpy via conda (https://conda.io/docs/installation.html), ' 'which should fix this issue. \n' 'Proceed with caution ...', fg='red'), err=True) click.confirm('Do you want to proceed?', abort=True) view = MultiprocessingView(processes=cores) elif cores == 1: view = SequentialView() design.options.pathway_prediction_timeout = pathway_prediction_timeout * 60 design.options.heuristic_optimization_timeout = heuristic_optimization_timeout design.options.max_pathway_predictions = max_pathway_predictions design.options.differential_fva = differential_fva design.options.heuristic_optimization = heuristic_optimization design.options.differential_fva_points = differential_fva_points results = design(product=product, hosts=hosts, view=view, aerobic=aerobic) click.echo(results) for output, format in zip(output, format): if format == 'pickle': click.echo('Pickling results into {}'.format(output)) with open(output, 'wb') as f: pickle.dump(results, f) else: click.echo('Writing results into {} using format "{}"'.format( output, format)) results[ 'heterologous_pathway'] = results.heterologous_pathway.apply( str) results['manipulations'] = results.manipulations.apply(str) OUTPUT_WRITER[format](results, output) click.echo(results)
def phenotypic_phase_plane(model, variables=[], objective=None, source=None, points=20, view=None): """Phenotypic phase plane analysis [1]. Implements a phenotypic phase plan analysis with interpretation same as that presented in [1] but calculated by optimizing the model for all steps of the indicated variables (instead of using shadow prices). Parameters ---------- model: SolverBasedModel variables: str or reaction or iterable A reaction ID, reaction, or list of reactions to be varied. objective: str or reaction or optlang.Objective or Metabolite, optional An objective, a reaction's flux, or a metabolite's production to be minimized/maximized (defaults to the current model objective). source: Reaction or reaction identifier The reaction to use as the source when calculating mass and carbon yield. Set to the medium reaction with the highest input carbon flux if left none. points: int or iterable Number of points to be interspersed between the variable bounds. A list of same same dimensions as `variables` can be used to specify variable specific numbers of points. view: SequentialView or MultiprocessingView or ipython.cluster.DirectView A parallelization view. Returns ------- PhenotypicPhasePlaneResult The phenotypic phase plane with flux, mol carbon input / mol carbon output, gram input / gram output References ---------- [1] Edwards, J. S., Ramakrishna, R. and Palsson, B. O. (2002). Characterizing the metabolic phenotype: a phenotype phase plane analysis. Biotechnology and Bioengineering, 77(1), 27–36. doi:10.1002/bit.10047 """ if isinstance(variables, str): variables = [variables] elif isinstance(variables, cameo.core.reaction.Reaction): variables = [variables] variable_ids = [ var if isinstance(var, str) else var.id for var in variables ] if view is None: view = config.default_view with TimeMachine() as tm: if objective is not None: if isinstance(objective, Metabolite): try: objective = model.reactions.get_by_id("DM_%s" % objective.id) except KeyError: objective = model.add_demand(objective, time_machine=tm) # try: # objective = model.reaction_for(objective, time_machine=tm) # except KeyError: # pass model.change_objective(objective, time_machine=tm) if source: source_reaction = model._reaction_for(source) else: source_reaction = _get_c_source_reaction(model) variable_reactions = model._ids_to_reactions(variables) variables_min_max = flux_variability_analysis( model, reactions=variable_reactions, view=SequentialView()) grid = [ numpy.linspace(lower_bound, upper_bound, points, endpoint=True) for reaction_id, lower_bound, upper_bound in variables_min_max.data_frame.loc[variable_ids].itertuples() ] grid_generator = itertools.product(*grid) chunks_of_points = partition(list(grid_generator), len(view)) evaluator = _PhenotypicPhasePlaneChunkEvaluator( model, variable_reactions, source_reaction) chunk_results = view.map(evaluator, chunks_of_points) envelope = reduce(list.__add__, chunk_results) nice_variable_ids = [_nice_id(reaction) for reaction in variable_reactions] variable_reactions_ids = [reaction.id for reaction in variable_reactions] phase_plane = pandas.DataFrame( envelope, columns=(variable_reactions_ids + [ 'objective_lower_bound', 'objective_upper_bound', 'c_yield_lower_bound', 'c_yield_upper_bound', 'mass_yield_lower_bound', 'mass_yield_upper_bound' ])) if objective is None: objective = model.objective nice_objective_id = _nice_id(objective) objective = objective.id if isinstance(objective, Reaction) else str(objective) return PhenotypicPhasePlaneResult( phase_plane, variable_reactions_ids, objective, nice_variable_ids=nice_variable_ids, source_reaction=_nice_id(source_reaction), nice_objective_id=nice_objective_id)
def test_one_variable_sequential_metabolite(self): ppp = phenotypic_phase_plane(self.model, ['EX_o2_LPAREN_e_RPAREN_'], self.model.metabolites.ac_c, view=SequentialView()) assert_data_frames_equal(ppp, REFERENCE_PPP_o2_EcoliCore_ac, sort_by=['EX_o2_LPAREN_e_RPAREN_'])
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. from __future__ import absolute_import, print_function import os import warnings from multiprocessing import cpu_count from multiprocessing.queues import Full, Empty import pytest from cameo.parallel import SequentialView views = [SequentialView()] try: from cameo.parallel import MultiprocessingView views.append(MultiprocessingView()) except ImportError: MultiprocessingView = None try: from cameo.parallel import RedisQueue except ImportError: RedisQueue = None try: with warnings.catch_warnings(): warnings.simplefilter("ignore")
def phenotypic_phase_plane(model, variables=[], objective=None, points=20, view=None): """Phenotypic phase plane analysis. Parameters ---------- model: SolverBasedModel variables: str or reaction or iterable A reaction ID, reaction, or list of reactions to be varied. objective: str or reaction or optlang.Objective or Metabolite, optional An objective, a reaction's flux, or a metabolite's production to be minimized/maximized (defaults to the current model objective). points: int or iterable Number of points to be interspersed between the variable bounds. A list of same same dimensions as `variables` can be used to specify variable specific numbers of points. view: SequentialView or MultiprocessingView or ipython.cluster.DirectView A parallelization view. Returns ------- PhenotypicPhasePlaneResult The phenotypic phase plane. """ if isinstance(variables, str): variables = [variables] elif isinstance(variables, cameo.core.reaction.Reaction): variables = [variables] if view is None: view = config.default_view with TimeMachine() as tm: if objective is not None: if isinstance(objective, Metabolite): objective = model.add_demand(objective, time_machine=tm) tm(do=partial(setattr, model, 'objective', objective), undo=partial(setattr, model, 'objective', model.objective)) variable_reactions = model._ids_to_reactions(variables) variables_min_max = flux_variability_analysis( model, reactions=variable_reactions, view=SequentialView()) grid = [ numpy.linspace(lower_bound, upper_bound, points, endpoint=True) for reaction_id, lower_bound, upper_bound in variables_min_max.data_frame.itertuples() ] grid_generator = itertools.product(*grid) original_bounds = dict([(reaction, (reaction.lower_bound, reaction.upper_bound)) for reaction in variable_reactions]) chunks_of_points = partition(list(grid_generator), len(view)) evaluator = _PhenotypicPhasePlaneChunkEvaluator( model, variable_reactions) chunk_results = view.map(evaluator, chunks_of_points) envelope = reduce(list.__add__, chunk_results) for reaction, bounds in six.iteritems(original_bounds): reaction.lower_bound = bounds[0] reaction.upper_bound = bounds[1] variable_reactions_ids = [ reaction.id for reaction in variable_reactions ] phase_plane = pandas.DataFrame( envelope, columns=(variable_reactions_ids + ['objective_lower_bound', 'objective_upper_bound'])) if objective is None: objective = model.objective if isinstance(objective, Reaction): objective = objective.id else: objective = str(objective) return PhenotypicPhasePlaneResult(phase_plane, variable_reactions_ids, objective)