Esempio n. 1
0
    def __init__(self, model, database_format):
        """
        Class constructor

        :param Model model: cobrapy model
        :param str database_format: ModelSEED, BiGG or KEGG
        """

        self.model = model

        self.objective = linear_reaction_coefficients(self.model)
        if self.objective:
            self.objective = list(self.objective.keys())[0]
        else:
            raise Exception("No objective found")

        self.__compounds_ontology = CompoundsDBAccessor()

        self.model = model
        self.__database_format = database_format
        self.__configs = file_utilities.read_conf_file(TOOL_CONFIG_PATH)
        self.__home_path__ = ROOT_DIR

        self.__modelseedCompoundsDb = ModelSeedCompoundsDB()

        self.__define_instance_variables()

        self.write_in_progress_bar("mapping model... ", 1)
        self.mapper.map_model(database_format)
        self.write_in_progress_bar("model mapped ", 10)
Esempio n. 2
0
def _pfba_legacy(model,
                 solver,
                 already_irreversible=False,
                 fraction_of_optimum=1.0,
                 desired_objective_value=None,
                 **optimize_kwargs):
    """Perform basic pFBA (parsimonious FBA) and minimize total flux.

    The function attempts to act as a drop-in replacement for optimize. It
    will make the reaction reversible and perform an optimization, then
    force the objective value to remain the same and minimize the total
    flux. Finally, it will convert the reaction back to the irreversible
    form it was in before. See http://dx.doi.org/10.1038/msb.2010.47

    Parameters
    ----------
    model : cobra.Model
        The model
    solver : solver
        The solver object to use
    already_irreversible : bool, optional
        By default, the model is converted to an irreversible one.
        However, if the model is already irreversible, this step can be
        skipped
    fraction_of_optimum : float, optional
        Fraction of optimum which must be maintained. The original objective
        reaction is constrained to be greater than maximal_value *
        fraction_of_optimum. By default, this option is specified to be 1.0
    desired_objective_value : float, optional
        A desired objective value for the minimal solution that bypasses the
        initial optimization result.

    Updates everything in-place, returns model to original state at end.
    """
    objective_reactions = linear_reaction_coefficients(model)
    if len(objective_reactions) > 1:
        raise ValueError('pfba only supports models with'
                         ' a single objective function')

    if 'objective_sense' in optimize_kwargs:
        if optimize_kwargs['objective_sense'] == 'minimize':
            raise ValueError('Minimization not supported in pfba')
        optimize_kwargs.pop('objective_sense', None)

    if not already_irreversible:
        convert_to_irreversible(model)

    lp = solver.create_problem(model, **optimize_kwargs)
    if not desired_objective_value:
        solver.solve_problem(lp, objective_sense='maximize')
        status = solver.get_status(lp)
        if status != "optimal":
            revert_to_reversible(model)
            raise ValueError(
                "pFBA requires optimal solution status, not {}".format(status))
        desired_objective_value = solver.get_objective_value(lp)

    for i, reaction in enumerate(model.reactions):

        if reaction.objective_coefficient != 0:
            # Enforce a certain fraction of the original objective
            target = (desired_objective_value * fraction_of_optimum /
                      reaction.objective_coefficient)
            solver.change_variable_bounds(lp, i, target, reaction.upper_bound)

        # Minimize all reaction fluxes (including objective?)
        solver.change_variable_objective(lp, i, 1)

    solver.solve_problem(lp, objective_sense='minimize', **optimize_kwargs)
    solution = solver.format_solution(lp, model)

    # Return the model to its original state
    #    model.solution = solution
    revert_to_reversible(model)

    #    if solution.status == "optimal":
    #        model.solution.f = sum([coeff * reaction.x for reaction, coeff in
    #                                iteritems(objective_reactions)])

    return solution
Esempio n. 3
0
def loopless_solution(model, fluxes=None):
    """Convert an existing solution to a loopless one.

    Removes as many loops as possible (see Notes).
    Uses the method from CycleFreeFlux [1]_ and is much faster than
    `add_loopless` and should therefore be the preferred option to get loopless
    flux distributions.

    Parameters
    ----------
    model : cobra.Model
        The model to which to add the constraints.
    fluxes : dict
        A dictionary {rxn_id: flux} that assigns a flux to each reaction. If
        not None will use the provided flux values to obtain a close loopless
        solution.
        Note that this requires a linear objective function involving
        only the model reactions. This is the case if
        `linear_reaction_coefficients(model)` is a correct representation of
        the objective.

    Returns
    -------
    cobra.Solution
        A solution object containing the fluxes with the least amount of
        loops possible or None if the optimization failed (usually happening
        if the flux distribution in `fluxes` is infeasible).

    Notes
    -----

    The returned flux solution has the following properties:

    - it contains the minimal number of loops possible and no loops at all if
      all flux bounds include zero
    - it has the same exact objective value as the previous solution
    - it has the same exact exchange fluxes as the previous solution
    - all fluxes have the same sign (flow in the same direction) as the
      previous solution

    References
    ----------
    .. [1] CycleFreeFlux: efficient removal of thermodynamically infeasible
       loops from flux distributions. Desouki AA, Jarre F, Gelius-Dietrich
       G, Lercher MJ. Bioinformatics. 2015 Jul 1;31(13):2159-65. doi:
       10.1093/bioinformatics/btv096.
    """
    # Need to reoptimize otherwise spurious solution artifacts can cause
    # all kinds of havoc
    # TODO: check solution status
    if fluxes is None:
        sol = model.optimize(objective_sense=None)
        fluxes = sol.fluxes
        obj_val = sol.objective_value
    else:
        coefs = linear_reaction_coefficients(model)
        obj_val = sum(coefs[rxn] * fluxes[rxn.id] for rxn in coefs)

    prob = model.problem
    with model:
        loopless_old_obj = prob.Variable("loopless_old_objective",
                                         lb=obj_val,
                                         ub=obj_val)
        loopless_obj_constraint = prob.Constraint(
            model.solver.objective.expression - loopless_old_obj,
            lb=0,
            ub=0,
            name="loopless_obj_constraint")
        model.add_cons_vars([loopless_old_obj, loopless_obj_constraint])
        model.objective = S.Zero
        for rxn in model.reactions:
            flux = fluxes[rxn.id]
            if rxn.boundary:
                rxn.bounds = (flux, flux)
                continue
            if flux >= 0:
                rxn.lower_bound = max(0, rxn.lower_bound)
                model.objective.set_linear_coefficients({
                    rxn.forward_variable:
                    1,
                    rxn.reverse_variable:
                    -1
                })
            else:
                rxn.upper_bound = min(0, rxn.upper_bound)
                model.objective.set_linear_coefficients({
                    rxn.forward_variable:
                    -1,
                    rxn.reverse_variable:
                    1
                })

        model.solver.objective.direction = "min"

        solution = model.optimize(objective_sense=None)

    return solution