Beispiel #1
0
def test_linear_room_sanity(model, all_solvers):
    """Test optimization criterion and optimality for linear ROOM."""
    model.solver = all_solvers
    sol = model.optimize()
    with model:
        model.reactions.PYK.knock_out()
        knock_sol = model.optimize()

    with model:
        # Internally uses pFBA as reference solution.
        add_room(model, linear=True)
        model.reactions.PYK.knock_out()
        room_sol = model.optimize()

    with model:
        # Use FBA as reference solution.
        add_room(model, solution=sol, linear=True)
        model.reactions.PYK.knock_out()
        room_sol_ref = model.optimize()

    flux_change = (sol.fluxes - knock_sol.fluxes).abs().sum()
    flux_change_room = (sol.fluxes - room_sol.fluxes).abs().sum()
    flux_change_room_ref = (sol.fluxes - room_sol_ref.fluxes).abs().sum()
    # Expect the ROOM solution to have smaller flux changes in
    # reactions compared to a normal FBA.
    assert flux_change_room < flux_change or \
        np.isclose(flux_change_room, flux_change, atol=1E-06)
    # Expect the FBA-based reference to have less change in
    # flux distribution.
    assert flux_change_room_ref > flux_change_room or \
        np.isclose(flux_change_room_ref, flux_change_room, atol=1E-06)
Beispiel #2
0
def test_single_reaction_deletion_linear_room(room_model, room_solution,
                                              all_solvers):
    """Test single reaction deletion using linear ROOM."""
    room_model.solver = all_solvers
    expected = Series(
        {
            'v1': 10.0,
            'v2': 5.0,
            'v3': 0.0,
            'v4': 5.0,
            'v5': 5.0,
            'v6': 0.0,
            'b1': 10.0,
            'b2': 5.0,
            'b3': 5.0
        },
        index=['v1', 'v2', 'v3', 'v4', 'v5', 'v6', 'b1', 'b2', 'b3'])
    with room_model:
        room_model.reactions.v6.knock_out()
        add_room(room_model,
                 solution=room_solution,
                 delta=0.0,
                 epsilon=0.0,
                 linear=True)
        linear_room_sol = room_model.optimize()

    assert np.allclose(linear_room_sol.fluxes, expected)
Beispiel #3
0
    def test_linear_room_sanity(self, solver, threshold=0.0):
        model = construct_papin_2003_model()
        model.solver = solver
        sol = model.optimize()
        active = (sol.fluxes.abs() > threshold).sum()
        with model:
            model.reactions.v3.knock_out()
            knock_sol = model.optimize()
            knock_active = (knock_sol.fluxes.abs() > threshold).sum()

        with model:
            # Internally uses pFBA as reference solution.
            add_room(model, linear=True)
            model.reactions.v3.knock_out()
            room_sol = model.optimize()
            room_active = (room_sol.fluxes.abs() > threshold).sum()

        with model:
            # Use FBA as reference solution.
            add_room(model, solution=sol, linear=True)
            model.reactions.v3.knock_out()
            room_ref_sol = model.optimize()
            room_ref_active = (room_ref_sol.fluxes.abs() > threshold).sum()

        # Expect the ROOM solution to have a smaller number of active
        # reactions compared to a normal FBA.
        assert abs(active - room_active) <= abs(active - knock_active)
        # Expect the FBA-based reference to have more active reactions.
        assert room_ref_active >= room_active
Beispiel #4
0
def test_room_sanity(
    model: Model, all_solvers: List[str], linear: bool, delta: float, eps: float
) -> None:
    """Test optimization criterion and optimality for ROOM."""
    model.solver = all_solvers
    sol = model.optimize()
    with model:
        model.reactions.PYK.knock_out()
        knock_sol = model.optimize()

    with model:
        # let it calculate its own reference solution (pFBA)
        add_room(model, linear=linear, delta=delta, epsilon=eps)
        model.reactions.PYK.knock_out()
        room_sol = model.optimize()

    with model:
        # use the more distant FBA reference
        add_room(model, solution=sol, linear=linear, delta=delta, epsilon=eps)
        model.reactions.PYK.knock_out()
        room_sol_ref = model.optimize()

    # The
    flux_change = (sol.fluxes - knock_sol.fluxes).abs()
    flux_change_room = (sol.fluxes - room_sol.fluxes).abs()
    flux_change_room_ref = (sol.fluxes - room_sol_ref.fluxes).abs()
    rxn_count_naive = (flux_change > delta * sol.fluxes.abs() + eps + 1e-6).sum()
    rxn_count_room = (flux_change_room > delta * sol.fluxes.abs() + eps + 1e-6).sum()
    rxn_count_room_ref = (
        flux_change_room_ref > delta * sol.fluxes.abs() + eps + 1e-6
    ).sum()

    # Expect the ROOM solution to have less changed reactions then a pFBA or FBA
    assert rxn_count_room <= rxn_count_naive
    assert rxn_count_room_ref <= rxn_count_naive
Beispiel #5
0
def test_single_reaction_deletion_linear_room(
    room_model: Model, room_solution: Solution, all_solvers: List[str]
) -> None:
    """Test single reaction deletion using linear ROOM."""
    room_model.solver = all_solvers
    expected = pd.Series(
        {
            "v1": 10.0,
            "v2": 5.0,
            "v3": 0.0,
            "v4": 5.0,
            "v5": 5.0,
            "v6": 0.0,
            "b1": 10.0,
            "b2": 5.0,
            "b3": 5.0,
        },
        index=["v1", "v2", "v3", "v4", "v5", "v6", "b1", "b2", "b3"],
    )
    with room_model:
        room_model.reactions.v6.knock_out()
        add_room(
            room_model,
            solution=room_solution,
            delta=0.0,
            epsilon=0.0,
            linear=True,
        )
        linear_room_sol = room_model.optimize()

    assert np.allclose(linear_room_sol.fluxes, expected)
Beispiel #6
0
    def test_linear_room_sanity(self, solver, threshold=0.0):
        model = construct_papin_2003_model()
        model.solver = solver
        sol = model.optimize()
        active = (sol.fluxes.abs() > threshold).sum()
        with model:
            model.reactions.v3.knock_out()
            knock_sol = model.optimize()
            knock_active = (knock_sol.fluxes.abs() > threshold).sum()

        with model:
            # Internally uses pFBA as reference solution.
            add_room(model, linear=True)
            model.reactions.v3.knock_out()
            room_sol = model.optimize()
            room_active = (room_sol.fluxes.abs() > threshold).sum()

        with model:
            # Use FBA as reference solution.
            add_room(model, solution=sol, linear=True)
            model.reactions.v3.knock_out()
            room_ref_sol = model.optimize()
            room_ref_active = (room_ref_sol.fluxes.abs() > threshold).sum()

        # Expect the ROOM solution to have a smaller number of active
        # reactions compared to a normal FBA.
        assert abs(active - room_active) <= abs(active - knock_active)
        # Expect the FBA-based reference to have more active reactions.
        assert room_ref_active >= room_active
Beispiel #7
0
    def test_single_reaction_deletion_room(self, solver):
        model = construct_papin_2003_model()
        model.solver = solver
        sol = construct_papin_2003_solution()
        expected = Series({'v1': 10.0, 'v2': 5.0, 'v3': 0.0, 'v4': 5.0,
                           'v5': 5.0, 'v6': 0.0, 'b1': 10.0, 'b2': 5.0,
                           'b3': 5.0}, index=['v1', 'v2', 'v3', 'v4',
                                              'v5', 'v6', 'b1', 'b2',
                                              'b3'])
        with model:
            model.reactions.v6.knock_out()
            add_room(model, solution=sol, delta=0.0, epsilon=0.0)
            room_sol = model.optimize()

        assert numpy.allclose(room_sol.fluxes, expected)
Beispiel #8
0
def test_single_reaction_deletion_room(room_model, room_solution,
                                       all_solvers):
    """Test single reaction deletion using ROOM."""
    room_model.solver = all_solvers
    expected = Series({'v1': 10.0, 'v2': 5.0, 'v3': 0.0, 'v4': 5.0,
                       'v5': 5.0, 'v6': 0.0, 'b1': 10.0, 'b2': 5.0,
                       'b3': 5.0}, index=['v1', 'v2', 'v3', 'v4',
                                          'v5', 'v6', 'b1', 'b2',
                                          'b3'])
    with room_model:
        room_model.reactions.v6.knock_out()
        add_room(room_model, solution=room_solution, delta=0.0, epsilon=0.0)
        room_sol = room_model.optimize()

    assert np.allclose(room_sol.fluxes, expected)
Beispiel #9
0
    def test_single_reaction_deletion_room_linear(self, solver):
        model = construct_papin_2003_model()
        model.solver = solver
        sol = construct_papin_2003_solution()
        expected = Series(
            {
                'v1': 10.0,
                'v2': 5.0,
                'v3': 0.0,
                'v4': 5.0,
                'v5': 5.0,
                'v6': 0.0,
                'b1': 10.0,
                'b2': 5.0,
                'b3': 5.0
            },
            index=['v1', 'v2', 'v3', 'v4', 'v5', 'v6', 'b1', 'b2', 'b3'])
        with model:
            model.reactions.v6.knock_out()
            add_room(model, solution=sol, delta=0.0, epsilon=0.0, linear=True)
            linear_room_sol = model.optimize()

        assert numpy.allclose(linear_room_sol.fluxes, expected)
Beispiel #10
0
def test_single_reaction_deletion_room(room_model, room_solution, all_solvers):
    """Test single reaction deletion using ROOM."""
    room_model.solver = all_solvers
    expected = Series(
        {
            "v1": 10.0,
            "v2": 5.0,
            "v3": 0.0,
            "v4": 5.0,
            "v5": 5.0,
            "v6": 0.0,
            "b1": 10.0,
            "b2": 5.0,
            "b3": 5.0,
        },
        index=["v1", "v2", "v3", "v4", "v5", "v6", "b1", "b2", "b3"],
    )
    with room_model:
        room_model.reactions.v6.knock_out()
        add_room(room_model, solution=room_solution, delta=0.0, epsilon=0.0)
        room_sol = room_model.optimize()

    assert np.allclose(room_sol.fluxes, expected)
Beispiel #11
0
def _multi_deletion(model, entity, element_lists, method="fba",
                    solution=None, processes=None, **kwargs):
    """
    Provide a common interface for single or multiple knockouts.

    Parameters
    ----------
    model : cobra.Model
        The metabolic model to perform deletions in.
    entity : 'gene' or 'reaction'
        The entity to knockout (``cobra.Gene`` or ``cobra.Reaction``).
    element_lists : list
        List of iterables ``cobra.Reaction``s or ``cobra.Gene``s (or their IDs)
        to be deleted.
    method: {"fba", "moma", "linear moma", "room", "linear room"}, optional
        Method used to predict the growth rate.
    solution : cobra.Solution, optional
        A previous solution to use as a reference for (linear) MOMA or ROOM.
    processes : int, optional
        The number of parallel processes to run. Can speed up the computations
        if the number of knockouts to perform is large. If not passed,
        will be set to the number of CPUs found.
    kwargs :
        Passed on to underlying simulation functions.

    Returns
    -------
    pandas.DataFrame
        A representation of all combinations of entity deletions. The
        columns are 'growth' and 'status', where

        index : frozenset([str])
            The gene or reaction identifiers that were knocked out.
        growth : float
            The growth rate of the adjusted model.
        status : str
            The solution's status.
    """
    solver = sutil.interface_to_str(model.problem.__name__)
    if method == "moma" and solver not in sutil.qp_solvers:
        raise RuntimeError(
            "Cannot use MOMA since '{}' is not QP-capable."
            "Please choose a different solver or use FBA only.".format(solver))

    if processes is None:
        processes = CONFIGURATION.processes

    with model:
        if "moma" in method:
            add_moma(model, solution=solution, linear="linear" in method)
        elif "room" in method:
            add_room(model, solution=solution, linear="linear" in method,
                     **kwargs)

        args = set([frozenset(comb) for comb in product(*element_lists)])
        processes = min(processes, len(args))

        def extract_knockout_results(result_iter):
            result = pd.DataFrame([
                (frozenset(ids), growth, status)
                for (ids, growth, status) in result_iter
            ], columns=['ids', 'growth', 'status'])
            result.set_index('ids', inplace=True)
            return result

        if processes > 1:
            worker = dict(gene=_gene_deletion_worker,
                          reaction=_reaction_deletion_worker)[entity]
            chunk_size = len(args) // processes
            pool = multiprocessing.Pool(
                processes, initializer=_init_worker, initargs=(model,)
            )
            results = extract_knockout_results(pool.imap_unordered(
                worker,
                args,
                chunksize=chunk_size
            ))
            pool.close()
            pool.join()
        else:
            worker = dict(gene=_gene_deletion,
                          reaction=_reaction_deletion)[entity]
            results = extract_knockout_results(map(
                partial(worker, model), args))
        return results