Ejemplo n.º 1
0
    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)
Ejemplo n.º 2
0
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)
Ejemplo n.º 3
0
    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
Ejemplo n.º 4
0
    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)
Ejemplo n.º 5
0
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)
Ejemplo n.º 6
0
    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
Ejemplo n.º 7
0
    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
Ejemplo n.º 8
0
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)
Ejemplo n.º 9
0
    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
Ejemplo n.º 10
0
    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
Ejemplo n.º 11
0
    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
Ejemplo n.º 12
0
    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
Ejemplo n.º 13
0
    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
Ejemplo n.º 14
0
    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
Ejemplo n.º 15
0
    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)
Ejemplo n.º 16
0
    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)
Ejemplo n.º 17
0
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)
Ejemplo n.º 18
0
    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
Ejemplo n.º 19
0
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)
Ejemplo n.º 20
0
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)
Ejemplo n.º 21
0
 def _make_grid(grid):
     return GridPlot(children=partition(grid.plots, grid.n_rows),
                     name=grid.title)
Ejemplo n.º 22
0
 def _make_grid(grid):
     return gridplot(children=partition(grid.plots, grid.n_rows),
                     name=grid.title)
Ejemplo n.º 23
0
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)
Ejemplo n.º 24
0
 def _plot_bokeh_grid(self):
     if len(self.plots) > 0:
         grid = GridPlot(children=partition(self.plots, self.nrows), title=self.title)
         plotting.show(grid)
Ejemplo n.º 25
0
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)
Ejemplo n.º 26
0
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)