예제 #1
0
def find_unbalanced_reactions_milp(model, unbalanced_reactions=None):

    if unbalanced_reactions is None:
        unbalanced_reactions = [rxn.id for rxn in model.reactions.values()
                                if len(rxn.get_substrates()) == 0 or len(rxn.get_products()) == 0]
        unbalanced_reactions.append(model.biomass_reaction)

    reactions = [rxn for rxn in model.reactions.values() if rxn.id not in unbalanced_reactions]

    solver = solver_instance()

    for m_id in model.metabolites:
        solver.add_variable(m_id, lb=0, update_problem=False)
        solver.add_variable('y_' + m_id, vartype=VarType.BINARY, update_problem=False)

    solver.update()

    for rxn in reactions:
        solver.add_constraint('c_' + rxn.id, rxn.stoichiometry, '=', 0, update_problem=False)

    for m_id in model.metabolites:
        solver.add_constraint('b_' + m_id, {m_id: 1, 'y_' + m_id: 1}, '>', 1, update_problem=False)

    solution = solver.solve(linear={'y_' + m_id: 1 for m_id in model.metabolites}, minimize=True)

    return solution
예제 #2
0
def check_mass_conservation(model, unbalanced_reactions=None):

    if unbalanced_reactions is None:
        unbalanced_reactions = [rxn.id for rxn in model.reactions.values()
                                if len(rxn.get_substrates()) == 0 or len(rxn.get_products()) == 0]
        unbalanced_reactions.append(model.biomass_reaction)

    reactions = [rxn for rxn in model.reactions.values() if rxn.id not in unbalanced_reactions]

    solver = solver_instance()

    for m_id in model.metabolites:
        solver.add_variable(m_id, lb=1, update_problem=False)

    solver.update()

    for rxn in reactions:
        solver.add_constraint('c_' + rxn.id, rxn.stoichiometry, '=', 0, update_problem=False)

    solver.update()

    solution = solver.solve(linear={m_id: 1 for m_id in model.metabolites}, minimize=True)

    result = solution.status == Status.OPTIMAL

    return result, solution
예제 #3
0
def simulate_ensemble(ensemble,
                      method='FBA',
                      constraints=None,
                      solver=None,
                      get_fluxes=True):
    """ Simulate an Ensemble Model

    Args:
        ensemble (EnsembleModel): ensemble model
        method (str): simulation method (default: 'FBA')
        constraints (dict): additional constraints (optional)
        solver (Solver): solver instance (optional)
        get_fluxes (bool): if True returns flux distributions for all models,
            otherwise only the objective function values are returned (default: True)

    Returns:
        ensemble flux distributions or ensemble objective function values

    """

    if method not in ['FBA', 'pFBA']:
        print('Method not available:', method)
        return

    if not solver:
        solver = solver_instance(ensemble.model)

    if get_fluxes:
        flux_sample = OrderedDict([(r_id, [None] * ensemble.size)
                                   for r_id in ensemble.model.reactions])
    else:
        objective = [None] * ensemble.size

    for i in range(ensemble.size):
        current = ensemble.get_constraints(i)

        if constraints:
            current.update(constraints)

        if method == 'FBA':
            sol = FBA(ensemble.model,
                      constraints=current,
                      solver=solver,
                      get_values=get_fluxes)

        if method == 'pFBA':
            sol = pFBA(ensemble.model, constraints=current, solver=solver)

        if sol.status == Status.OPTIMAL:
            if get_fluxes:
                for r_id in ensemble.model.reactions:
                    flux_sample[r_id][i] = sol.values[r_id]
            else:
                objective[i] = sol.fobj

    if get_fluxes:
        return flux_sample
    else:
        return objective
예제 #4
0
def find_unbalanced_reactions_lp(model,
                                 unbalanced_reactions=None,
                                 abstol=1e-6):

    if unbalanced_reactions is None:
        unbalanced_reactions = [
            rxn.id for rxn in model.reactions.values()
            if len(rxn.get_substrates()) == 0 or len(rxn.get_products()) == 0
        ]
        unbalanced_reactions.append(model.biomass_reaction)

    reactions = [
        r_id for r_id in model.reactions if r_id not in unbalanced_reactions
    ]

    solver = solver_instance()

    for m_id in model.metabolites:
        solver.add_variable(m_id, lb=1, update_problem=False)

    objective = {}
    for r_id in reactions:
        solver.add_variable('p_' + r_id, lb=0, update_problem=False)
        solver.add_variable('n_' + r_id, lb=0, update_problem=False)
        objective['p_' + r_id] = 1
        objective['n_' + r_id] = 1

    solver.update()

    for r_id in reactions:
        lhs_p = {'p_' + r_id: -1}
        lhs_n = {'n_' + r_id: 1}
        lhs_p.update(model.reactions[r_id].stoichiometry)
        lhs_n.update(model.reactions[r_id].stoichiometry)
        solver.add_constraint('cp_' + r_id,
                              lhs_p,
                              '<',
                              0,
                              update_problem=False)
        solver.add_constraint('cn_' + r_id,
                              lhs_n,
                              '>',
                              0,
                              update_problem=False)

    solution = solver.solve(objective, minimize=True)

    balance = {
        r_id: -solution.values['n_' + r_id] + solution.values['p_' + r_id]
        for r_id in reactions
        if (abs(solution.values['n_' + r_id]) > abstol
            or abs(solution.values['p_' + r_id]) > abstol)
    }

    return balance
예제 #5
0
def scanCAFBA(model, values, we=8.3e-4, wr=0.169, pmax=0.484):
    solver = solver_instance(model)
    solutions = {}

    for value in values:
        solutions[value] = CAFBA(model,
                                 wc=value,
                                 we=we,
                                 wr=wr,
                                 pmax=pmax,
                                 solver=solver)

    return solutions
예제 #6
0
def simulate_ensemble(ensemble, method='FBA', constraints=None, solver=None, get_fluxes=True):
    """ Simulate an Ensemble Model

    Args:
        ensemble (EnsembleModel): ensemble model
        method (str): simulation method (default: 'FBA')
        constraints (dict): additional constraints (optional)
        solver (Solver): solver instance (optional)
        get_fluxes (bool): if True returns flux distributions for all models,
            otherwise only the objective function values are returned (default: True)

    Returns:
        ensemble flux distributions or ensemble objective function values

    """

    if method not in ['FBA', 'pFBA']:
        print('Method not available:', method)
        return

    if not solver:
        solver = solver_instance(ensemble.model)

    if get_fluxes:
        flux_sample = OrderedDict([(r_id, [None] * ensemble.size) for r_id in ensemble.model.reactions])
    else:
        objective = [None] * ensemble.size

    for i in range(ensemble.size):
        current = ensemble.get_constraints(i)

        if constraints:
            current.update(constraints)

        if method == 'FBA':
            sol = FBA(ensemble.model, constraints=current, solver=solver, get_values=get_fluxes)

        if method == 'pFBA':
            sol = pFBA(ensemble.model, constraints=current, solver=solver)

        if sol.status == Status.OPTIMAL:
            if get_fluxes:
                for r_id in ensemble.model.reactions:
                    flux_sample[r_id][i] = sol.values[r_id]
            else:
                objective[i] = sol.fobj

    if get_fluxes:
        return flux_sample
    else:
        return objective
예제 #7
0
파일: sampler.py 프로젝트: saezlab/hlrcc
def fix_futile_cycles(model, samples):
    # Initialise environmental conditionsz
    env = {}

    # Set lower bound of all ireversible reactions to 0
    env.update(
        {rid: (0, r.ub)
         for rid, r in model.reactions.items() if r.lb > 0})

    # Close exachnge reactions bounds: lower = upper = 0
    env.update({
        rid: (0, 0)
        for rid, r in model.reactions.items() if rid.startswith('R_EX_')
        or rid.startswith('R_sink_') or rid.startswith('R_DM_')
    })

    # Run FVA
    fva = FVA(model, constraints=env)

    # Identify reactions in futile cycles
    futile_cycle_reactions = {
        rid
        for rid, (lb, ub) in fva.items()
        if (lb is None) or (ub is None) or (lb < 0) or (ub > 0)
    }

    # Verbose
    print '[INFO] %d futile cycle reactions found: %s' % (
        len(futile_cycle_reactions), '; '.join(futile_cycle_reactions))

    # Fix reactions values and minimise futile cycle reactions
    if len(futile_cycle_reactions) > 0:
        solver = solver_instance(model)

        for i in samples.index:
            env.update({
                rid: (samples.ix[i, rid], samples.ix[i, rid])
                for rid in samples if rid not in futile_cycle_reactions
            })

            fba = abs_min_fba(model,
                              constraints=env,
                              reactions=futile_cycle_reactions,
                              solver=solver)

            for rid in futile_cycle_reactions:
                samples.ix[i, rid] = fba.values[rid]

    return samples
예제 #8
0
파일: sampler.py 프로젝트: saezlab/hlrcc
def get_warmup_points(model, constraints=None):
    # Calculate warm-up points running FVA
    solver = solver_instance(model)
    fva = fva_with_values(model, constraints=constraints, solver=solver)

    # Get upper and lower bounds
    reactions, lb, ub = zip(*[(r, fva[r][0].fobj if fva[r][0] else -np.Inf,
                               fva[r][1].fobj if fva[r][1] else np.Inf)
                              for r in fva])
    reactions, lb, ub = np.array(reactions), np.array(lb), np.array(ub)

    # Warm-up points
    warmup_points = np.array([[fva[r][i].values[r_in] for r_in in reactions]
                              for r in reactions for i in [0, 1]
                              if fva[r][i]]).T

    return lb, ub, warmup_points, reactions
예제 #9
0
def ensemble_essentiality(ensemble, constraints, voting_thresholds, min_growth=0.1):

        solver = solver_instance(ensemble.model)
        essential_all = []

        for i in range(ensemble.size):
            current = ensemble.get_constraints(i)

            if constraints:
                current.update(constraints)

            essential = essential_genes(ensemble.model, constraints=current, min_growth=min_growth, solver=solver)
            essential_all.extend(essential)


        results =[{gene for gene in ensemble.model.genes
                  if essential_all.count(gene)/float(ensemble.size) >= t}
                  for t in voting_thresholds]

        return results
예제 #10
0
def find_unbalanced_reactions_lp(model, unbalanced_reactions=None, abstol=1e-6):

    if unbalanced_reactions is None:
        unbalanced_reactions = [rxn.id for rxn in model.reactions.values()
                                if len(rxn.get_substrates()) == 0 or len(rxn.get_products()) == 0]
        unbalanced_reactions.append(model.biomass_reaction)

    reactions = [r_id for r_id in model.reactions if r_id not in unbalanced_reactions]

    solver = solver_instance()

    for m_id in model.metabolites:
        solver.add_variable(m_id, lb=1, update_problem=False)

    objective = {}
    for r_id in reactions:
        solver.add_variable('p_' + r_id, lb=0, update_problem=False)
        solver.add_variable('n_' + r_id, lb=0, update_problem=False)
        objective['p_' + r_id] = 1
        objective['n_' + r_id] = 1

    solver.update()

    for r_id in reactions:
        lhs_p = {'p_' + r_id: -1}
        lhs_n = {'n_' + r_id: 1}
        lhs_p.update(model.reactions[r_id].stoichiometry)
        lhs_n.update(model.reactions[r_id].stoichiometry)
        solver.add_constraint('cp_' + r_id, lhs_p, '<', 0, update_problem=False)
        solver.add_constraint('cn_' + r_id, lhs_n, '>', 0, update_problem=False)

    solution = solver.solve(objective, minimize=True)

    balance = {r_id: -solution.values['n_' + r_id] + solution.values['p_' + r_id]
               for r_id in reactions
               if (abs(solution.values['n_' + r_id]) > abstol
                   or abs(solution.values['p_' + r_id]) > abstol)}

    return balance
예제 #11
0
def simulate_biolog(model, medium, source, compounds, main_compounds, max_uptake=10, min_growth=0.1, verbose=False,
                    add_transporters=False, add_sinks=False, ensemble=False, voting_thresholds=None,
                    flavor=None):

    if ensemble:
        ensemble = model
        model = ensemble.model

    if flavor == 'seed':
        ex_rxn_format = 'EX_{}_e0'
    else:
        ex_rxn_format = 'R_EX_{}_e'

    env = Environment.from_compounds(medium, max_uptake=max_uptake, exchange_format='"{}"'.format(ex_rxn_format))
    constraints = env.apply(model, inplace=False, warning=False)

    for cmpd in main_compounds[source]:
        main_compound_rxn = ex_rxn_format.format(cmpd)
        constraints[main_compound_rxn] = (0, None)
    
    no_exchange = []
    not_in_model = []
    growth_pred = {}

    if flavor == 'seed':
        model_mets = {m_id[:-3] for m_id in model.metabolites}
    else:
        model_mets = {m_id[2:-2] for m_id in model.metabolites}

    new_rxns = []

    if add_transporters:
        model = model.copy()
        for met in compounds:
            met_e = ('{}_e0' if flavor == 'seed' else 'M_{}_e').format(met)
            met_c = ('{}_c0' if flavor == 'seed' else 'M_{}_c').format(met)
            if met_e not in model.metabolites and met_c in model.metabolites:
                if flavor == 'seed':
                    rxn_str = 'EX_{}: {} <-> [0, 0]'.format(met_e, met_c)
                else:
                    rxn_str = 'R_EX_{}_e: {} <-> [0, 0]'.format(met, met_c)
                new_rxns.append(model.add_reaction_from_str(rxn_str))

    if add_sinks:
        model = model.copy()
        for m_id in model.metabolites:
            if m_id.endswith('_c'):
                rxn_str = 'Sink_{}: {} --> '.format(m_id, m_id)
                model.add_reaction_from_str(rxn_str)

    solver = solver_instance(model)

    summary = {}

    for met in compounds:

        growth_pred[met] = [None]*len(voting_thresholds) if ensemble else None
        r_id = ex_rxn_format.format(met)

        if r_id in model.reactions:
            tmp = constraints[r_id] if r_id in constraints else (0, 0)
            constraints[r_id] = (-max_uptake, 0)
            if ensemble:
                growth_all = simulate_ensemble(ensemble, constraints=constraints, solver=solver, get_fluxes=False)
                growth_bool = [rate > min_growth if rate is not None else False for rate in growth_all]
                growth_pred[met] = [sum(growth_bool)/float(ensemble.size) >= t for t in voting_thresholds]
            else:
                sol = FBA(model, constraints=constraints, solver=solver)
                if sol.status == Status.OPTIMAL:
                    growth_pred[met] = sol.fobj > min_growth
                else:
                    growth_pred[met] = False
                constraints[r_id] = tmp

        else:
            if met in model_mets:
                no_exchange.append(met)
            else:
                not_in_model.append(met)

    if verbose and no_exchange:
        print 'No exchange reactions in model:', ' '.join(sorted(no_exchange))

    if verbose and not_in_model:
        print 'Metabolites not in model:', ' '.join(sorted(not_in_model))

    return growth_pred
예제 #12
0
파일: sampler.py 프로젝트: saezlab/hlrcc
def abs_min_fba(model, constraints=None, reactions=None, solver=None):
    if not solver:
        solver = solver_instance(model)

    if not reactions:
        reactions = model.reactions.keys()

    if not hasattr(solver, 'pFBA_flag'):
        solver.pFBA_flag = True
        for r_id in reactions:
            if model.reactions[r_id].reversible:
                pos, neg = r_id + '+', r_id + '-'
                solver.add_variable(pos,
                                    0,
                                    None,
                                    persistent=False,
                                    update_problem=False)
                solver.add_variable(neg,
                                    0,
                                    None,
                                    persistent=False,
                                    update_problem=False)
        solver.update()
        for r_id in reactions:
            if model.reactions[r_id].reversible:
                pos, neg = r_id + '+', r_id + '-'
                solver.add_constraint('c' + pos, {
                    r_id: -1,
                    pos: 1
                },
                                      '>',
                                      0,
                                      persistent=False,
                                      update_problem=False)
                solver.add_constraint('c' + neg, {
                    r_id: 1,
                    neg: 1
                },
                                      '>',
                                      0,
                                      persistent=False,
                                      update_problem=False)
        solver.update()

    objective = dict()
    for r_id in reactions:
        if model.reactions[r_id].reversible:
            pos, neg = r_id + '+', r_id + '-'
            objective[pos] = 1
            objective[neg] = 1
        else:
            objective[r_id] = 1

    solution = solver.solve(objective, minimize=True, constraints=constraints)

    # post process
    if solution.status == Status.OPTIMAL:
        for r_id in reactions:
            if model.reactions[r_id].reversible:
                pos, neg = r_id + '+', r_id + '-'
                del solution.values[pos]
                del solution.values[neg]

    return solution
예제 #13
0
파일: sampler.py 프로젝트: saezlab/hlrcc
def fva_with_values(model,
                    obj_percentage=0,
                    reactions=None,
                    constraints=None,
                    loopless=False,
                    internal=None,
                    solver=None):
    """ Run Flux Variability Analysis (FVA).

    Arguments:
        model (CBModel): a constraint-based model
        obj_percentage (float): minimum percentage of growth rate (default 0.0, max: 1.0)
        reactions (list): list of reactions to analyze (default: all)
        constraints (dict): additional constraints (optional)
        loopless (bool): run looplessFBA internally (very slow) (default: false)
        internal (list): list of internal reactions for looplessFBA (optional)
        solver (Solver): pre-instantiated solver instance (optional)

    Returns:
        dict: flux variation ranges
    """

    _constraints = {}
    if constraints:
        _constraints.update(constraints)

    if not solver:
        solver = solver_instance(model)

    if obj_percentage > 0:
        target = model.detect_biomass_reaction()
        solution = FBA(model,
                       objective={target: 1},
                       constraints=constraints,
                       solver=solver)
        _constraints[target] = (obj_percentage * solution.fobj, None)

    if not reactions:
        reactions = model.reactions.keys()

    variability = OrderedDict([(r_id, [None, None]) for r_id in reactions])

    for r_id in reactions:
        if loopless:
            solution = looplessFBA(model, {r_id: 1},
                                   True,
                                   constraints=_constraints,
                                   internal=internal,
                                   solver=solver,
                                   get_values=True)
        else:
            solution = FBA(model, {r_id: 1},
                           True,
                           constraints=_constraints,
                           solver=solver,
                           get_values=True)

        if solution.status == Status.OPTIMAL:
            variability[r_id][0] = solution
        elif solution.status == Status.UNBOUNDED:
            pass
        elif solution.status == Status.INF_OR_UNB:
            pass
        elif solution.status == Status.INFEASIBLE:
            warn('Infeasible solution status')
        else:
            warn('Unknown solution status')

    for r_id in reactions:
        if loopless:
            solution = looplessFBA(model, {r_id: 1},
                                   False,
                                   constraints=_constraints,
                                   internal=internal,
                                   solver=solver,
                                   get_values=True)
        else:
            solution = FBA(model, {r_id: 1},
                           False,
                           constraints=_constraints,
                           solver=solver,
                           get_values=True)

        if solution.status == Status.OPTIMAL:
            variability[r_id][1] = solution
        elif solution.status == Status.UNBOUNDED:
            pass
        elif solution.status == Status.INF_OR_UNB:
            pass
        elif solution.status == Status.INFEASIBLE:
            warn('Infeasible solution status')
        else:
            warn('Unknown solution status')

    return variability
예제 #14
0
def CAFBA(model,
          wc=0,
          we=8.3e-4,
          wr=0.169,
          pmax=0.484,
          carbon_source="M_glc__D_e",
          constraints=None,
          solver=None):

    if solver is None:
        solver = solver_instance(model)

    if hasattr(solver, 'CAFBA_flag'):
        uptake = solver.uptake
        enzymatic = solver.enzymatic
    else:
        solver.CAFBA_flag = True
        solver.uptake = []
        solver.enzymatic = []
        uptake = solver.uptake
        enzymatic = solver.enzymatic

        for r_id in model.reactions:
            if model.reactions[r_id].reversible:
                pos, neg = r_id + '+', r_id + '-'
                solver.add_variable(pos,
                                    0,
                                    None,
                                    persistent=False,
                                    update_problem=False)
                solver.add_variable(neg,
                                    0,
                                    None,
                                    persistent=False,
                                    update_problem=False)
        solver.update()

        for r_id in model.reactions:
            if model.reactions[r_id].reversible:
                pos, neg = r_id + '+', r_id + '-'
                solver.add_constraint('c' + pos, {
                    r_id: -1,
                    pos: 1
                },
                                      '>',
                                      0,
                                      persistent=False,
                                      update_problem=False)
                solver.add_constraint('c' + neg, {
                    r_id: 1,
                    neg: 1
                },
                                      '>',
                                      0,
                                      persistent=False,
                                      update_problem=False)
        solver.update()

        for r_id, rxn in model.reactions.items():
            compartments = model.get_reaction_compartments(r_id)

            if carbon_source in rxn.stoichiometry and len(compartments) == 2:
                if rxn.reversible:
                    uptake.append(r_id + '+')
                    uptake.append(r_id + '-')
                else:
                    uptake.append(r_id)

            if len(compartments) == 1 and rxn.gpr is not None:
                if rxn.reversible:
                    enzymatic.append(r_id + '+')
                    enzymatic.append(r_id + '-')
                else:
                    enzymatic.append(r_id)

    main_constr = {}
    for r_id in enzymatic:
        main_constr[r_id] = we
    for r_id in uptake:
        main_constr[r_id] = wc
    main_constr[model.biomass_reaction] = wr

    solver.add_constraint('alloc',
                          main_constr,
                          '=',
                          pmax,
                          persistent=False,
                          update_problem=True)

    solution = solver.solve(model.get_objective(),
                            minimize=False,
                            constraints=constraints)

    if solution is not None:
        solution.p_enz = sum(we * solution.values[r_id] for r_id in enzymatic)
        solution.p_upt = sum(wc * solution.values[r_id] for r_id in uptake)
        solution.p_rib = wr * solution.values[model.biomass_reaction]
        solution.enzymatic = {
            r_id: solution.values[r_id]
            for r_id in enzymatic
        }
        solution.uptake = {r_id: solution.values[r_id] for r_id in uptake}

    solver.remove_constraint('alloc')

    return solution
예제 #15
0
def myCFBA(model,
           w_e=0.001,
           w_r=0.5,
           spontaneous='G_s0001',
           constraints=None,
           solver=None):

    if solver is None:
        solver = solver_instance(model)

    if hasattr(solver, 'myCFBA_flag'):
        new_vars = solver.new_vars
    else:
        solver.myCFBA_flag = True
        solver.new_vars = []
        new_vars = solver.new_vars
        tmp = []

        for r_id, rxn in model.reactions.items():
            if rxn.gpr is not None and spontaneous not in rxn.get_associated_genes(
            ):
                if rxn.reversible:
                    pos, neg = r_id + '+', r_id + '-'
                    solver.add_variable(pos,
                                        0,
                                        None,
                                        persistent=False,
                                        update_problem=False)
                    solver.add_variable(neg,
                                        0,
                                        None,
                                        persistent=False,
                                        update_problem=False)
                    new_vars.append(pos)
                    new_vars.append(neg)
                    tmp.append(r_id)
                else:
                    new_vars.append(r_id)
        solver.update()

        for r_id in tmp:
            pos, neg = r_id + '+', r_id + '-'
            solver.add_constraint('c' + pos, {
                r_id: -1,
                pos: 1
            },
                                  '>',
                                  0,
                                  persistent=False,
                                  update_problem=False)
            solver.add_constraint('c' + neg, {
                r_id: 1,
                neg: 1
            },
                                  '>',
                                  0,
                                  persistent=False,
                                  update_problem=False)
        solver.update()

    alloc_constr = {r_id: w_e for r_id in new_vars}
    alloc_constr[model.biomass_reaction] = w_r

    solver.add_constraint('alloc',
                          alloc_constr,
                          '<',
                          1,
                          persistent=False,
                          update_problem=True)

    solution = solver.solve(model.get_objective(),
                            minimize=False,
                            constraints=constraints)

    if solution is not None:
        solution.v_sum = sum(solution.values[r_id] for r_id in new_vars)
    solver.remove_constraint('alloc')

    return solution