コード例 #1
0
    def test_add_constraint(self, core_model):
        cache = ProblemCache(core_model)

        def add_var(model, var_id):
            return model.solver.interface.Variable(var_id, ub=0)

        def add_constraint(m, const_id, var):
            return m.solver.interface.Constraint(var, lb=-10, ub=10, name=const_id)

        def update_constraint(model, const, var):
            return setattr(const, "ub", 1000)

        for i in range(10):
            cache.add_variable("%i" % i, add_var, None)
            cache.add_constraint("c%i" % i, add_constraint, update_constraint, cache.variables["%i" % i])

        for i in range(10):
            assert cache.constraints["c%i" % i] in core_model.solver.constraints
            assert cache.constraints["c%i" % i].ub == 10
            assert cache.constraints["c%i" % i].lb == -10
            assert core_model.solver.constraints["c%i" % i].ub == 10
            assert core_model.solver.constraints["c%i" % i].lb == -10

        for i in range(10):
            cache.add_constraint("c%i" % i, add_constraint, update_constraint, cache.variables["%i" % i])
            assert core_model.solver.constraints["c%i" % i].ub == 1000

        cache.reset()

        for i in range(10):
            with pytest.raises(KeyError):
                core_model.solver.variables.__getitem__("%i" % i)
            with pytest.raises(KeyError):
                core_model.solver.constraints.__getitem__("c%i" % i)
コード例 #2
0
    def test_add_variable(self, core_model):
        cache = ProblemCache(core_model)

        def add_var(model, var_id):
            return model.solver.interface.Variable(var_id, ub=0)

        def update_var(model, var):
            return setattr(var, "ub", 1000)
        for i in range(10):
            cache.add_variable("%i" % i, add_var, update_var)

        for i in range(10):
            assert cache.variables["%i" % i] in core_model.solver.variables
            assert cache.variables["%i" % i].ub == 0
            assert core_model.solver.variables["%i" % i].ub == 0

        for i in range(10):
            cache.add_variable("%i" % i, add_var, update_var)
            assert cache.variables["%i" % i].ub == 1000
            assert core_model.solver.variables["%i" % i].ub == 1000

        cache.reset()

        for i in range(10):
            with pytest.raises(KeyError):
                core_model.solver.variables.__getitem__("%i" % i)
コード例 #3
0
ファイル: simulation.py プロジェクト: biosustain/cameo
def lmoma(model, reference=None, cache=None, reactions=None, *args, **kwargs):
    """Linear Minimization Of Metabolic Adjustment [1].

    Parameters
    ----------
    model: cobra.Model
    reference: FluxDistributionResult, dict
    cache: ProblemCache
    reactions: list

    Returns
    -------
    FluxDistributionResult
        Contains the result of the solver.

    References
    ----------
    .. [1] Becker, S. A., Feist, A. M., Mo, M. L., Hannum, G., Palsson, B. Ø., & Herrgard, M. J. (2007).
     Quantitative prediction of cellular metabolism with constraint-based models: the COBRA Toolbox.
     Nature Protocols, 2(3), 727–38. doi:10.1038/nprot.2007.99

    """
    volatile = False
    if cache is None:
        volatile = True
        cache = ProblemCache(model)

    cache.begin_transaction()

    if not isinstance(reference, (dict, pandas.Series, FluxDistributionResult)):
        raise TypeError("reference must be a flux distribution (dict or FluxDistributionResult")

    try:
        for rid, flux_value in six.iteritems(reference):
            reaction = model.reactions.get_by_id(rid)

            def create_variable(model, var_id, lb):
                var = model.solver.interface.Variable(var_id, lb=lb)
                return var

            pos_var_id = "u_%s_pos" % rid
            cache.add_variable(pos_var_id, create_variable, None, 0)

            neg_var_id = "u_%s_neg" % rid
            cache.add_variable(neg_var_id, create_variable, None, 0)

            # ui = vi - wt
            def update_upper_constraint(model, constraint, var, reaction, flux_value):
                if constraint.lb != flux_value:
                    constraint.lb = flux_value

            def create_upper_constraint(model, constraint_id, var, reaction, flux_value):
                constraint = model.solver.interface.Constraint(reaction.flux_expression + var,
                                                               lb=flux_value,
                                                               sloppy=True,
                                                               name=constraint_id)
                return constraint

            cache.add_constraint("lmoma_const_%s_ub" % rid, create_upper_constraint, update_upper_constraint,
                                 cache.variables[pos_var_id], reaction, flux_value)

            def update_lower_constraint(model, constraint, var, reaction, flux_value):
                if constraint.ub != flux_value:
                    constraint.ub = flux_value

            def create_lower_constraint(model, constraint_id, var, reaction, flux_value):
                constraint = model.solver.interface.Constraint(reaction.flux_expression - var,
                                                               ub=flux_value,
                                                               sloppy=True,
                                                               name=constraint_id)
                return constraint

            cache.add_constraint("lmoma_const_%s_lb" % rid, create_lower_constraint, update_lower_constraint,
                                 cache.variables[neg_var_id], reaction, flux_value)

        def create_objective(model, variables):
            return model.solver.interface.Objective(add([mul((One, var)) for var in variables]),
                                                    direction="min",
                                                    sloppy=False)
        cache.add_objective(create_objective, None, cache.variables.values())

        solution = model.optimize(raise_error=True)
        if reactions is not None:
            result = FluxDistributionResult(
                {r: solution.get_primal_by_id(r) for r in reactions}, solution.objective_value)
        else:
            result = FluxDistributionResult.from_solution(solution)
        return result

    except Exception as e:
        cache.rollback()
        raise e

    finally:
        if volatile:
            cache.reset()
コード例 #4
0
ファイル: simulation.py プロジェクト: biosustain/cameo
def room(model, reference=None, cache=None, delta=0.03, epsilon=0.001, reactions=None, *args, **kwargs):
    """Regulatory On/Off Minimization [1].

    Parameters
    ----------
    model: cobra.Model
    reference: FluxDistributionResult, dict
    delta: float
    epsilon: float
    cache: ProblemCache

    Returns
    -------
    FluxDistributionResult
        Contains the result of the linear solver.

    References
    ----------
    .. [1] Tomer Shlomi, Omer Berkman and Eytan Ruppin, "Regulatory on/off minimization of metabolic
     flux changes after genetic perturbations", PNAS 2005 102 (21) 7695-7700; doi:10.1073/pnas.0406346102

    """
    volatile = False
    if cache is None:
        volatile = True
        cache = ProblemCache(model)
    elif not isinstance(cache, ProblemCache):
        raise TypeError("Invalid cache object (must be a cameo.util.ProblemCache)")

    cache.begin_transaction()

    if not isinstance(reference, (dict, pandas.Series, FluxDistributionResult)):
        raise TypeError("reference must be a flux distribution (dict or FluxDistributionResult")

    try:
        for rid, flux_value in six.iteritems(reference):
            reaction = model.reactions.get_by_id(rid)

            def create_variable(model, var_id):
                return model.solver.interface.Variable(var_id, type="binary")

            cache.add_variable("y_%s" % rid, create_variable, None)

            def create_upper_constraint(model, constraint_id, reaction, variable, flux_value, epsilon):
                w_u = flux_value + delta * abs(flux_value) + epsilon
                return model.solver.interface.Constraint(
                    reaction.flux_expression - variable * (reaction.upper_bound - w_u),
                    ub=w_u,
                    sloppy=True,
                    name=constraint_id)

            def update_upper_constraint(model, constraint, reaction, variable, flux_value, epsilon):
                w_u = flux_value + delta * abs(flux_value) + epsilon
                constraint.set_linear_coefficients({variable: reaction.upper_bound - w_u})
                constraint.ub = w_u

            cache.add_constraint("room_const_%s_upper" % rid, create_upper_constraint, update_upper_constraint,
                                 reaction, cache.variables["y_%s" % rid], flux_value, epsilon)

            def create_lower_constraint(model, constraint_id, reaction, variable, flux_value, epsilon):
                w_l = flux_value - delta * abs(flux_value) - epsilon
                return model.solver.interface.Constraint(
                    reaction.flux_expression - variable * (reaction.lower_bound - w_l),
                    lb=w_l,
                    sloppy=True,
                    name=constraint_id)

            def update_lower_constraint(model, constraint, reaction, variable, flux_value, epsilon):
                w_l = flux_value - delta * abs(flux_value) - epsilon
                constraint.set_linear_coefficients({variable: reaction.lower_bound - w_l})
                constraint.lb = w_l

            cache.add_constraint("room_const_%s_lower" % rid, create_lower_constraint, update_lower_constraint,
                                 reaction, cache.variables["y_%s" % rid], flux_value, epsilon)

        model.objective = model.solver.interface.Objective(add([mul([One, var]) for var in cache.variables.values()]),
                                                           direction='min')

        solution = model.optimize(raise_error=True)
        if reactions is not None:
            result = FluxDistributionResult(
                {r: solution.get_primal_by_id(r) for r in reactions}, solution.objective_value)
        else:
            result = FluxDistributionResult.from_solution(solution)
        return result

    except Exception as e:
        cache.rollback()
        raise e

    finally:
        if volatile:
            cache.reset()
コード例 #5
0
ファイル: simulation.py プロジェクト: biosustain/cameo
def moma(model, reference=None, cache=None, reactions=None, *args, **kwargs):
    """
    Minimization of Metabolic Adjustment[1]

    Parameters
    ----------
    model: cobra.Model
    reference: FluxDistributionResult, dict
    cache: ProblemCache
    reactions: list

    Returns
    -------
    FluxDistributionResult
        Contains the result of the solver.

    References
    ----------
    .. [1] Segrè, D., Vitkup, D., & Church, G. M. (2002). Analysis of optimality in natural and perturbed metabolic
     networks. Proceedings of the National Academy of Sciences of the United States of America, 99(23), 15112–7.
     doi:10.1073/pnas.232349399

    """
    volatile = False
    if cache is None:
        volatile = True
        cache = ProblemCache(model)

    cache.begin_transaction()
    try:
        for rid, flux_value in six.iteritems(reference):

            def create_variable(model, variable_id):
                var = model.solver.interface.Variable(variable_id)
                return var

            var_id = "moma_aux_%s" % rid

            cache.add_variable(var_id, create_variable, None)

            def create_constraint(model, constraint_id, var, reaction, flux_value):
                constraint = model.solver.interface.Constraint(reaction.flux_expression - var,
                                                               lb=flux_value,
                                                               ub=flux_value,
                                                               name=constraint_id)
                return constraint

            def update_constraint(model, constraint, var, reaction, flux_value):
                if constraint.lb != flux_value:
                    constraint.lb = flux_value
                    constraint.ub = flux_value

            constraint_id = "moma_const_%s" % rid
            reaction = model.reactions.get_by_id(rid)
            cache.add_constraint(constraint_id, create_constraint, update_constraint,
                                 cache.variables[var_id], reaction, flux_value)

        def create_objective(model, variables):
            return model.solver.interface.Objective(Add(*[FloatOne * var ** 2 for var in variables]),
                                                    direction="min",
                                                    sloppy=True)

        cache.add_objective(create_objective, None, cache.variables.values())

        solution = model.optimize(raise_error=True)

        if reactions is not None:
            result = FluxDistributionResult(
                {r: solution.get_primal_by_id(r) for r in reactions}, solution.objective_value)
        else:
            result = FluxDistributionResult.from_solution(solution)
        return result
    except Exception as e:
        cache.rollback()
        raise e
    finally:
        if volatile:
            cache.reset()
コード例 #6
0
ファイル: simulation.py プロジェクト: parnodorf/cameo
def room(model, reference=None, cache=None, delta=0.03, epsilon=0.001, reactions=None, *args, **kwargs):
    """Regulatory On/Off Minimization [1].

    Parameters
    ----------
    model: cobra.Model
    reference: FluxDistributionResult, dict
    delta: float
    epsilon: float
    cache: ProblemCache

    Returns
    -------
    FluxDistributionResult
        Contains the result of the linear solver.

    References
    ----------
    .. [1] Tomer Shlomi, Omer Berkman and Eytan Ruppin, "Regulatory on/off minimization of metabolic
     flux changes after genetic perturbations", PNAS 2005 102 (21) 7695-7700; doi:10.1073/pnas.0406346102

    """
    volatile = False
    if cache is None:
        volatile = True
        cache = ProblemCache(model)
    elif not isinstance(cache, ProblemCache):
        raise TypeError("Invalid cache object (must be a cameo.util.ProblemCache)")

    cache.begin_transaction()

    if not isinstance(reference, (dict, pandas.Series, FluxDistributionResult)):
        raise TypeError("reference must be a flux distribution (dict or FluxDistributionResult")

    try:
        for rid, flux_value in six.iteritems(reference):
            reaction = model.reactions.get_by_id(rid)

            def create_variable(model, var_id):
                return model.solver.interface.Variable(var_id, type="binary")

            cache.add_variable("y_%s" % rid, create_variable, None)

            def create_upper_constraint(model, constraint_id, reaction, variable, flux_value, epsilon):
                w_u = flux_value + delta * abs(flux_value) + epsilon
                return model.solver.interface.Constraint(
                    reaction.flux_expression - variable * (reaction.upper_bound - w_u),
                    ub=w_u,
                    sloppy=True,
                    name=constraint_id)

            def update_upper_constraint(model, constraint, reaction, variable, flux_value, epsilon):
                w_u = flux_value + delta * abs(flux_value) + epsilon
                constraint.set_linear_coefficients({variable: reaction.upper_bound - w_u})
                constraint.ub = w_u

            cache.add_constraint("room_const_%s_upper" % rid, create_upper_constraint, update_upper_constraint,
                                 reaction, cache.variables["y_%s" % rid], flux_value, epsilon)

            def create_lower_constraint(model, constraint_id, reaction, variable, flux_value, epsilon):
                w_l = flux_value - delta * abs(flux_value) - epsilon
                return model.solver.interface.Constraint(
                    reaction.flux_expression - variable * (reaction.lower_bound - w_l),
                    lb=w_l,
                    sloppy=True,
                    name=constraint_id)

            def update_lower_constraint(model, constraint, reaction, variable, flux_value, epsilon):
                w_l = flux_value - delta * abs(flux_value) - epsilon
                constraint.set_linear_coefficients({variable: reaction.lower_bound - w_l})
                constraint.lb = w_l

            cache.add_constraint("room_const_%s_lower" % rid, create_lower_constraint, update_lower_constraint,
                                 reaction, cache.variables["y_%s" % rid], flux_value, epsilon)

        model.objective = model.solver.interface.Objective(add([mul([One, var]) for var in cache.variables.values()]),
                                                           direction='min')

        solution = model.optimize(raise_error=True)
        if reactions is not None:
            result = FluxDistributionResult({r: solution.get_primal_by_id(r) for r in reactions}, solution.f)
        else:
            result = FluxDistributionResult.from_solution(solution)
        return result

    except Exception as e:
        cache.rollback()
        raise e

    finally:
        if volatile:
            cache.reset()
コード例 #7
0
ファイル: simulation.py プロジェクト: parnodorf/cameo
def lmoma(model, reference=None, cache=None, reactions=None, *args, **kwargs):
    """Linear Minimization Of Metabolic Adjustment [1].

    Parameters
    ----------
    model: cobra.Model
    reference: FluxDistributionResult, dict
    cache: ProblemCache
    reactions: list

    Returns
    -------
    FluxDistributionResult
        Contains the result of the solver.

    References
    ----------
    .. [1] Becker, S. A., Feist, A. M., Mo, M. L., Hannum, G., Palsson, B. Ø., & Herrgard, M. J. (2007).
     Quantitative prediction of cellular metabolism with constraint-based models: the COBRA Toolbox.
     Nature Protocols, 2(3), 727–38. doi:10.1038/nprot.2007.99

    """
    volatile = False
    if cache is None:
        volatile = True
        cache = ProblemCache(model)

    cache.begin_transaction()

    if not isinstance(reference, (dict, pandas.Series, FluxDistributionResult)):
        raise TypeError("reference must be a flux distribution (dict or FluxDistributionResult")

    try:
        for rid, flux_value in six.iteritems(reference):
            reaction = model.reactions.get_by_id(rid)

            def create_variable(model, var_id, lb):
                var = model.solver.interface.Variable(var_id, lb=lb)
                return var

            pos_var_id = "u_%s_pos" % rid
            cache.add_variable(pos_var_id, create_variable, None, 0)

            neg_var_id = "u_%s_neg" % rid
            cache.add_variable(neg_var_id, create_variable, None, 0)

            # ui = vi - wt
            def update_upper_constraint(model, constraint, var, reaction, flux_value):
                if constraint.lb != flux_value:
                    constraint.lb = flux_value

            def create_upper_constraint(model, constraint_id, var, reaction, flux_value):
                constraint = model.solver.interface.Constraint(reaction.flux_expression + var,
                                                               lb=flux_value,
                                                               sloppy=True,
                                                               name=constraint_id)
                return constraint

            cache.add_constraint("lmoma_const_%s_ub" % rid, create_upper_constraint, update_upper_constraint,
                                 cache.variables[pos_var_id], reaction, flux_value)

            def update_lower_constraint(model, constraint, var, reaction, flux_value):
                if constraint.ub != flux_value:
                    constraint.ub = flux_value

            def create_lower_constraint(model, constraint_id, var, reaction, flux_value):
                constraint = model.solver.interface.Constraint(reaction.flux_expression - var,
                                                               ub=flux_value,
                                                               sloppy=True,
                                                               name=constraint_id)
                return constraint

            cache.add_constraint("lmoma_const_%s_lb" % rid, create_lower_constraint, update_lower_constraint,
                                 cache.variables[neg_var_id], reaction, flux_value)

        def create_objective(model, variables):
            return model.solver.interface.Objective(add([mul((One, var)) for var in variables]),
                                                    direction="min",
                                                    sloppy=False)
        cache.add_objective(create_objective, None, cache.variables.values())

        solution = model.optimize(raise_error=True)
        if reactions is not None:
            result = FluxDistributionResult({r: solution.get_primal_by_id(r) for r in reactions}, solution.f)
        else:
            result = FluxDistributionResult.from_solution(solution)
        return result

    except Exception as e:
        cache.rollback()
        raise e

    finally:
        if volatile:
            cache.reset()
コード例 #8
0
ファイル: simulation.py プロジェクト: parnodorf/cameo
def moma(model, reference=None, cache=None, reactions=None, *args, **kwargs):
    """
    Minimization of Metabolic Adjustment[1]

    Parameters
    ----------
    model: cobra.Model
    reference: FluxDistributionResult, dict
    cache: ProblemCache
    reactions: list

    Returns
    -------
    FluxDistributionResult
        Contains the result of the solver.

    References
    ----------
    .. [1] Segrè, D., Vitkup, D., & Church, G. M. (2002). Analysis of optimality in natural and perturbed metabolic
     networks. Proceedings of the National Academy of Sciences of the United States of America, 99(23), 15112–7.
     doi:10.1073/pnas.232349399

    """
    volatile = False
    if cache is None:
        volatile = True
        cache = ProblemCache(model)

    cache.begin_transaction()
    try:
        for rid, flux_value in six.iteritems(reference):

            def create_variable(model, variable_id):
                var = model.solver.interface.Variable(variable_id)
                return var

            var_id = "moma_aux_%s" % rid

            cache.add_variable(var_id, create_variable, None)

            def create_constraint(model, constraint_id, var, reaction, flux_value):
                constraint = model.solver.interface.Constraint(reaction.flux_expression - var,
                                                               lb=flux_value,
                                                               ub=flux_value,
                                                               name=constraint_id)
                return constraint

            def update_constraint(model, constraint, var, reaction, flux_value):
                if constraint.lb != flux_value:
                    constraint.lb = flux_value
                    constraint.ub = flux_value

            constraint_id = "moma_const_%s" % rid
            reaction = model.reactions.get_by_id(rid)
            cache.add_constraint(constraint_id, create_constraint, update_constraint,
                                 cache.variables[var_id], reaction, flux_value)

        def create_objective(model, variables):
            return model.solver.interface.Objective(Add(*[FloatOne * var ** 2 for var in variables]),
                                                    direction="min",
                                                    sloppy=True)

        cache.add_objective(create_objective, None, cache.variables.values())

        solution = model.optimize(raise_error=True)

        if reactions is not None:
            result = FluxDistributionResult({r: solution.get_primal_by_id(r) for r in reactions}, solution.f)
        else:
            result = FluxDistributionResult.from_solution(solution)
        return result
    except Exception as e:
        cache.rollback()
        raise e
    finally:
        if volatile:
            cache.reset()
コード例 #9
0
def lmoma(model, reference=None, cache=None, *args, **kwargs):
    """Linear Minimization Of Metabolic Adjustment.

    Parameters
    ----------
    model: SolverBasedModel
    reference: dict
    objective: str or reaction or optlang.Objective
        An objective to be minimized/maximized for
    volatile: boolean
    cache: dict

    Returns
    -------
    FluxDistributionResult
        Contains the result of the linear solver.

    """
    volatile = False
    if cache is None:
        volatile = True
        cache = ProblemCache(model)

    cache.begin_transaction()

    if not isinstance(reference, (dict, FluxDistributionResult)):
        raise TypeError("reference must be a flux distribution (dict or FluxDistributionResult")

    try:
        for rid, flux_value in six.iteritems(reference):
            reaction = model.reactions.get_by_id(rid)

            def create_variable(model, var_id, lb):
                var = model.solver.interface.Variable(var_id, lb=lb)
                return var

            pos_var_id = "u_%s_pos" % rid
            cache.add_variable(pos_var_id, create_variable, None, 0)

            neg_var_id = "u_%s_neg" % rid
            cache.add_variable(neg_var_id, create_variable, None, 0)

            # ui = vi - wt
            def update_upper_constraint(model, constraint, var, reaction, flux_value):
                constraint.lb = flux_value

            def create_upper_constraint(model, constraint_id, var, reaction, flux_value):
                constraint = model.solver.interface.Constraint(reaction.flux_expression + var,
                                                               lb=flux_value,
                                                               sloppy=True,
                                                               name=constraint_id)
                return constraint

            cache.add_constraint("c_%s_ub" % rid, create_upper_constraint, update_upper_constraint,
                                 cache.variables[pos_var_id], reaction, flux_value)

            def update_lower_constraint(model, constraint, var, reaction, flux_value):
                constraint.ub = flux_value

            def create_lower_constraint(model, constraint_id, var, reaction, flux_value):
                constraint = model.solver.interface.Constraint(reaction.flux_expression - var,
                                                               ub=flux_value,
                                                               sloppy=True,
                                                               name=constraint_id)
                return constraint

            cache.add_constraint("c_%s_lb" % rid, create_lower_constraint, update_lower_constraint,
                                 cache.variables[neg_var_id], reaction, flux_value)

        model.objective = model.solver.interface.Objective(add([mul([One, var]) for var in cache.variables.values()]),
                                                           direction="min")

        try:
            return FluxDistributionResult(model.solve())
        except SolveError as e:
            raise e
    except Exception as e:
        cache.rollback()
        raise e

    finally:
        if volatile:
            cache.reset()