def test_partition(self): chunks = 3 iterables = [[1, 2, 3, 4, 5, 6, 7, 8, 9], {5, 3, 8, 3, 8, 5, 8, 0, 10, 11, 15}, range(29)] for fixture in iterables: test_output = partition(fixture, chunks) assert len(fixture) == sum(map(len, test_output)) assert len(test_output) == chunks assert list(fixture) == list(chain(*test_output)) for out_chunk in test_output: assert set(out_chunk).issubset(set(fixture)) bad_input = 5 with pytest.raises(TypeError): partition(bad_input, chunks)
def flux_variability_analysis(model, reactions=None, fraction_of_optimum=0., remove_cycles=False, view=None): """Flux variability analysis. Parameters ---------- model: SolverBasedModel reactions: None or iterable The list of reaction whose lower and upper bounds should be determined. If `None`, all reactions in `model` will be assessed. view: SequentialView or MultiprocessingView or ipython.cluster.DirectView A parallelization view. Returns ------- pandas.DataFrame Pandas DataFrame containing the results of the flux variability analysis. """ if view is None: view = config.default_view if reactions is None: reactions = model.reactions with TimeMachine() as tm: if fraction_of_optimum > 0.: model.fix_objective_as_constraint(fraction=fraction_of_optimum, time_machine=tm) tm(do=int, undo=partial(setattr, model, "objective", model.objective)) reaction_chunks = (chunk for chunk in partition(reactions, len(view))) if remove_cycles: func_obj = _FvaFunctionObject(model, _cycle_free_fva) else: func_obj = _FvaFunctionObject(model, _flux_variability_analysis) chunky_results = view.map(func_obj, reaction_chunks) solution = pandas.concat(chunky_results) return FluxVariabilityResult(solution)
def _evaluator(self, candidates, args): view = args.get('view') population_chunks = (chunk for chunk in partition(candidates, len(view))) func_obj = KnockinKnockoutEvaluator(self.model, self._decoder, self.objective_function, self.simulation_method) results = view.map(func_obj, population_chunks) fitness = reduce(list.__add__, results) return fitness
def test_partition(self): chunks = 3 iterables = [ [1, 2, 3, 4, 5, 6, 7, 8, 9], {5, 3, 8, 3, 8, 5, 8, 0, 10, 11, 15}, range(29) ] for fixture in iterables: test_output = partition(fixture, chunks) assert len(fixture) == sum(map(len, test_output)) assert len(test_output) == chunks assert list(fixture) == list(chain(*test_output)) for out_chunk in test_output: assert set(out_chunk).issubset(set(fixture)) bad_input = 5 with pytest.raises(TypeError): partition(bad_input, chunks)
def flux_variability_analysis(model, reactions=None, fraction_of_optimum=0., pfba_factor=None, remove_cycles=False, view=None): """Flux variability analysis. Parameters ---------- model : cameo.core.SolverBasedModel reactions: None or iterable The list of reaction whose lower and upper bounds should be determined. If `None`, all reactions in `model` will be assessed. fraction_of_optimum : float Fix the objective of the model to a fraction of it's max. Expected to be within [0;1]. Lower values increase variability. pfba_factor : float If not None, fix the total sum of reaction fluxes to its minimum times a factor. Expected to be within [ 1;inf]. Higher factors increase flux variability to a certain point since the bound for the objective is still fixed. remove_cycles : bool If true, apply the CycleFreeFlux algorithm to remove loops from each simulated flux distribution. view: cameo.parallel.SequentialView or cameo.parallel.MultiprocessingView or ipython.cluster.DirectView A parallelization view. Returns ------- pandas.DataFrame Pandas DataFrame containing the results of the flux variability analysis. """ if view is None: view = config.default_view if reactions is None: reactions = model.reactions with TimeMachine() as tm: if fraction_of_optimum > 0.: model.fix_objective_as_constraint(fraction=fraction_of_optimum, time_machine=tm) if pfba_factor is not None: # don't add the objective-constraint again so fraction_of_optimum=0 fix_pfba_as_constraint(model, multiplier=pfba_factor, time_machine=tm, fraction_of_optimum=0) tm(do=int, undo=partial(setattr, model, "objective", model.objective)) reaction_chunks = (chunk for chunk in partition(reactions, len(view))) if remove_cycles: func_obj = _FvaFunctionObject(model, _cycle_free_fva) else: func_obj = _FvaFunctionObject(model, _flux_variability_analysis) chunky_results = view.map(func_obj, reaction_chunks) solution = pandas.concat(chunky_results) return FluxVariabilityResult(solution)
def __call__(self, candidates, args): population_chunks = (chunk for chunk in partition(candidates, len(self.view))) try: chunked_results = self.view.map(self.evaluator, population_chunks) except KeyboardInterrupt as e: self.view.shutdown() raise e fitness = reduce(list.__add__, chunked_results) return fitness
def flux_variability_analysis(model, reactions=None, fraction_of_optimum=0., remove_cycles=False, view=None): """Flux variability analysis. Parameters ---------- model: SolverBasedModel reactions: None or iterable The list of reaction whose lower and upper bounds should be determined. If `None`, all reactions in `model` will be assessed. view: SequentialView or MultiprocessingView or ipython.cluster.DirectView A parallelization view. Returns ------- pandas.DataFrame Pandas DataFrame containing the results of the flux variability analysis. """ if view is None: view = config.default_view if reactions is None: reactions = model.reactions with TimeMachine() as tm: if fraction_of_optimum > 0.: try: obj_val = model.solve().f except SolveError as e: logger.debug( "flux_variability_analyis was not able to determine an optimal solution for objective %s" % model.objective) raise e if model.objective.direction == 'max': fix_obj_constraint = model.solver.interface.Constraint( model.objective.expression, lb=fraction_of_optimum * obj_val) else: fix_obj_constraint = model.solver.interface.Constraint( model.objective.expression, ub=fraction_of_optimum * obj_val) tm(do=partial(model.solver._add_constraint, fix_obj_constraint), undo=partial(model.solver._remove_constraint, fix_obj_constraint)) reaction_chunks = (chunk for chunk in partition(reactions, len(view))) if remove_cycles == True: func_obj = _FvaFunctionObject(model, _cycle_free_fva) else: func_obj = _FvaFunctionObject(model, _flux_variability_analysis) chunky_results = view.map(func_obj, reaction_chunks) solution = pandas.concat(chunky_results) return FluxVariabilityResult(solution)
def _simplify_solutions(self, solutions): simplification = SolutionSimplification(self._evaluator) chunks = (chunk for chunk in partition(solutions, len(self._view))) try: chunked_results = self._view.map(simplification, chunks) except KeyboardInterrupt as e: self.view.shutdown() raise e solutions = reduce(list.__add__, chunked_results) return solutions
def _make_grid(grid): rows = grid.n_rows columns = math.ceil(len(grid.plots) / rows) plot = tools.make_subplots(rows=rows, cols=columns, subplot_titles=[p.layout['title'] for p in grid.plots]) plot['layout']['width'] = grid.width plot['layout']['height'] = grid.height for i, subplots in enumerate(partition(grid.plots, rows)): for j, subplot in enumerate(subplots): for trace in subplot.data: plot.append_trace(trace, i + 1, j + 1) return plot
def _evaluator(self, candidates, args): view = args.get('view') population_chunks = (chunk for chunk in partition(candidates, len(view))) kwargs = {'reference': self.wt_reference} func_obj = KnockoutEvaluator(self.model, self._decoder, self.objective_function, self.simulation_method, kwargs) try: results = view.map(func_obj, population_chunks) except KeyboardInterrupt as e: view.shutdown() raise e fitness = reduce(list.__add__, results) return fitness
def test_partition(self): chunks = 3 iterables = [[1, 2, 3, 4, 5, 6, 7, 8, 9], set([5, 3, 8, 3, 8, 5, 8, 0, 10, 11, 15]), range(29)] for fixture in iterables: test_output = partition(fixture, chunks) self.assertEqual(len(fixture), sum(map(len, test_output))) self.assertEqual(len(test_output), chunks) self.assertEqual(list(fixture), list(chain(*test_output))) for out_chunk in test_output: self.assertTrue(set(out_chunk).issubset(set(fixture))) bad_input = 5 self.assertRaises(TypeError, partition, bad_input, chunks)
def test_partition(self): chunks = 3 iterables = [ [1, 2, 3, 4, 5, 6, 7, 8, 9], {5, 3, 8, 3, 8, 5, 8, 0, 10, 11, 15}, range(29) ] for fixture in iterables: test_output = partition(fixture, chunks) self.assertEqual(len(fixture), sum(map(len, test_output))) self.assertEqual(len(test_output), chunks) self.assertEqual(list(fixture), list(chain(*test_output))) for out_chunk in test_output: self.assertTrue(set(out_chunk).issubset(set(fixture))) bad_input = 5 self.assertRaises(TypeError, partition, bad_input, chunks)
def flux_variability_analysis(model, reactions=None, fraction_of_optimum=0., remove_cycles=False, view=None): """Flux variability analysis. Parameters ---------- model: SolverBasedModel reactions: None or iterable The list of reaction whose lower and upper bounds should be determined. If `None`, all reactions in `model` will be assessed. view: SequentialView or MultiprocessingView or ipython.cluster.DirectView A parallelization view. Returns ------- pandas.DataFrame Pandas DataFrame containing the results of the flux variability analysis. """ if view is None: view = config.default_view if reactions is None: reactions = model.reactions with TimeMachine() as tm: if fraction_of_optimum > 0.: try: obj_val = model.solve().f except SolveError as e: logger.debug( "flux_variability_analyis was not able to determine an optimal solution for objective %s" % model.objective) raise e if model.objective.direction == 'max': fix_obj_constraint = model.solver.interface.Constraint(model.objective.expression, lb=fraction_of_optimum * obj_val) else: fix_obj_constraint = model.solver.interface.Constraint(model.objective.expression, ub=fraction_of_optimum * obj_val) tm(do=partial(model.solver._add_constraint, fix_obj_constraint), undo=partial(model.solver._remove_constraint, fix_obj_constraint)) reaction_chunks = (chunk for chunk in partition(reactions, len(view))) if remove_cycles == True: func_obj = _FvaFunctionObject(model, _cycle_free_fva) else: func_obj = _FvaFunctionObject(model, _flux_variability_analysis) chunky_results = view.map(func_obj, reaction_chunks) solution = pandas.concat(chunky_results) return FluxVariabilityResult(solution)
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)
def _make_grid(grid): return GridPlot(children=partition(grid.plots, grid.n_rows), name=grid.title)
def _make_grid(grid): return gridplot(children=partition(grid.plots, grid.n_rows), name=grid.title)
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 _plot_bokeh_grid(self): if len(self.plots) > 0: grid = GridPlot(children=partition(self.plots, self.nrows), title=self.title) plotting.show(grid)
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)
def phenotypic_phase_plane(model, variables=[], objective=None, points=20, view=None): """Phenotypic phase plane analysis [1]. 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. 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] if view is None: view = config.default_view with TimeMachine() as tm: if objective is not None: try: objective = model.reaction_for(objective, time_machine=tm) except KeyError: pass model.change_objective(objective, time_machine=tm) 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) 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) variable_reactions_ids = [] nice_variable_ids = [] for reaction in variable_reactions: if hasattr(reaction, "nice_id"): variable_reactions_ids.append(reaction.id) nice_variable_ids.append(reaction.nice_id) else: variable_reactions_ids.append(reaction.id) nice_variable_ids.append(reaction.id) 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): if hasattr(objective, 'nice_id'): nice_objective_id = objective.nice_id objective = objective.id else: objective = objective.id nice_objective_id = objective else: objective = str(objective) nice_objective_id = str(objective) return PhenotypicPhasePlaneResult(phase_plane, variable_reactions_ids, objective, nice_variable_ids=nice_variable_ids, nice_objective_id=nice_objective_id)