Exemple #1
0
def _cycle_free_fva(model, reactions=None, sloppy=True, sloppy_bound=666):
    """Cycle free flux-variability analysis. (http://cran.r-project.org/web/packages/sybilcycleFreeFlux/index.html)

    Parameters
    ----------
    model : SolverBasedModel
    reactions : list
        List of reactions whose flux-ranges should be determined.
    sloppy : boolean, optional
        If true, only fluxes v with abs(v) > sloppy_bound are checked to be futile cycles (defaults to True).
    sloppy_bound : int, optional
        The threshold bound used by sloppy (defaults to the number of the beast).
    """
    cycle_count = 0
    if reactions is None:
        reactions = model.reactions
    else:
        reactions = model._ids_to_reactions(reactions)
    fva_sol = OrderedDict()
    for reaction in reactions:
        fva_sol[reaction.id] = dict()
        model.objective = reaction
        model.objective.direction = 'min'
        try:
            solution = model.solve()
        except Unbounded:
            fva_sol[reaction.id]['lower_bound'] = -numpy.inf
            continue
        except Infeasible:
            fva_sol[reaction.id]['lower_bound'] = 0
            continue
        bound = solution.f
        if sloppy and abs(bound) < sloppy_bound:
            fva_sol[reaction.id]['lower_bound'] = bound
        else:
            logger.debug('Determine if {} with bound {} is a cycle'.format(
                reaction.id, bound))
            v0_fluxes = solution.x_dict
            v1_cycle_free_fluxes = remove_infeasible_cycles(model, v0_fluxes)
            if abs(v1_cycle_free_fluxes[reaction.id] - bound) < 10**-6:
                fva_sol[reaction.id]['lower_bound'] = bound
            else:
                logger.debug('Cycle detected: {}'.format(reaction.id))
                cycle_count += 1
                v2_one_cycle_fluxes = remove_infeasible_cycles(
                    model, v0_fluxes, fix=[reaction.id])
                with TimeMachine() as tm:
                    for key, v1_flux in six.iteritems(v1_cycle_free_fluxes):
                        if round(v1_flux, config.ndecimals) == 0 and round(
                                v2_one_cycle_fluxes[key],
                                config.ndecimals) != 0:
                            knockout_reaction = model.reactions.get_by_id(key)
                            knockout_reaction.knock_out(time_machine=tm)
                    model.objective.direction = 'min'
                    try:
                        solution = model.solve()
                    except Unbounded:
                        fva_sol[reaction.id]['lower_bound'] = -numpy.inf
                    except Infeasible:
                        fva_sol[reaction.id]['lower_bound'] = 0
                    else:
                        fva_sol[reaction.id]['lower_bound'] = solution.f

    for reaction in reactions:
        model.objective = reaction
        model.objective.direction = 'max'
        try:
            solution = model.solve()
        except Unbounded:
            fva_sol[reaction.id]['upper_bound'] = numpy.inf
            continue
        except Infeasible:
            fva_sol[reaction.id]['upper_bound'] = 0
            continue
        bound = solution.f
        if sloppy and abs(bound) < sloppy_bound:
            fva_sol[reaction.id]['upper_bound'] = bound
        else:
            logger.debug('Determine if {} with bound {} is a cycle'.format(
                reaction.id, bound))
            v0_fluxes = solution.x_dict
            v1_cycle_free_fluxes = remove_infeasible_cycles(model, v0_fluxes)
            if abs(v1_cycle_free_fluxes[reaction.id] - bound) < 1e-6:
                fva_sol[reaction.id]['upper_bound'] = v0_fluxes[reaction.id]
            else:
                logger.debug('Cycle detected: {}'.format(reaction.id))
                cycle_count += 1
                v2_one_cycle_fluxes = remove_infeasible_cycles(
                    model, v0_fluxes, fix=[reaction.id])
                with TimeMachine() as tm:
                    for key, v1_flux in six.iteritems(v1_cycle_free_fluxes):
                        if round(v1_flux, config.ndecimals) == 0 and round(
                                v2_one_cycle_fluxes[key],
                                config.ndecimals) != 0:
                            knockout_reaction = model.reactions.get_by_id(key)
                            knockout_reaction.knock_out(time_machine=tm)
                    model.objective.direction = 'max'
                    try:
                        solution = model.solve()
                    except Unbounded:
                        fva_sol[reaction.id]['upper_bound'] = numpy.inf
                    except Infeasible:
                        fva_sol[reaction.id]['upper_bound'] = 0
                    else:
                        fva_sol[reaction.id]['upper_bound'] = solution.f

    df = pandas.DataFrame.from_dict(fva_sol, orient='index')
    lb_higher_ub = df[df.lower_bound > df.upper_bound]
    # Assert that these cases really only numerical artifacts
    assert ((lb_higher_ub.lower_bound - lb_higher_ub.upper_bound) < 1e-6).all()
    df.lower_bound[lb_higher_ub.index] = df.upper_bound[lb_higher_ub.index]

    return df
Exemple #2
0
def _cycle_free_fva(model, reactions=None, sloppy=True, sloppy_bound=666):
    """Cycle free flux-variability analysis. (http://cran.r-project.org/web/packages/sybilcycleFreeFlux/index.html)

    Parameters
    ----------
    model : SolverBasedModel
    reactions : list
        List of reactions whose flux-ranges should be determined.
    sloppy : boolean, optional
        If true, only fluxes v with abs(v) > sloppy_bound are checked to be futile cycles (defaults to True).
    sloppy_bound : int, optional
        The threshold bound used by sloppy (defaults to the number of the beast).
    """
    cycle_count = 0
    if reactions is None:
        reactions = model.reactions
    else:
        reactions = model._ids_to_reactions(reactions)
    fva_sol = OrderedDict()
    for reaction in reactions:
        fva_sol[reaction.id] = dict()
        model.objective = reaction
        model.objective.direction = 'min'
        try:
            solution = model.solve()
        except Unbounded:
            fva_sol[reaction.id]['lower_bound'] = -numpy.inf
            continue
        except Infeasible:
            fva_sol[reaction.id]['lower_bound'] = 0
            continue
        bound = solution.f
        if sloppy and abs(bound) < sloppy_bound:
            fva_sol[reaction.id]['lower_bound'] = bound
        else:
            logger.debug('Determine if {} with bound {} is a cycle'.format(reaction.id, bound))
            v0_fluxes = solution.x_dict
            v1_cycle_free_fluxes = remove_infeasible_cycles(model, v0_fluxes)
            if abs(v1_cycle_free_fluxes[reaction.id] - bound) < 10 ** -6:
                fva_sol[reaction.id]['lower_bound'] = bound
            else:
                logger.debug('Cycle detected: {}'.format(reaction.id))
                cycle_count += 1
                v2_one_cycle_fluxes = remove_infeasible_cycles(model, v0_fluxes, fix=[reaction.id])
                with TimeMachine() as tm:
                    for key, v1_flux in six.iteritems(v1_cycle_free_fluxes):
                        if round(v1_flux, config.ndecimals) == 0 and round(v2_one_cycle_fluxes[key],
                                                                           config.ndecimals) != 0:
                            knockout_reaction = model.reactions.get_by_id(key)
                            knockout_reaction.knock_out(time_machine=tm)
                    model.objective.direction = 'min'
                    try:
                        solution = model.solve()
                    except Unbounded:
                        fva_sol[reaction.id]['lower_bound'] = -numpy.inf
                    except Infeasible:
                        fva_sol[reaction.id]['lower_bound'] = 0
                    else:
                        fva_sol[reaction.id]['lower_bound'] = solution.f

    for reaction in reactions:
        model.objective = reaction
        model.objective.direction = 'max'
        try:
            solution = model.solve()
        except Unbounded:
            fva_sol[reaction.id]['upper_bound'] = numpy.inf
            continue
        except Infeasible:
            fva_sol[reaction.id]['upper_bound'] = 0
            continue
        bound = solution.f
        if sloppy and abs(bound) < sloppy_bound:
            fva_sol[reaction.id]['upper_bound'] = bound
        else:
            logger.debug('Determine if {} with bound {} is a cycle'.format(reaction.id, bound))
            v0_fluxes = solution.x_dict
            v1_cycle_free_fluxes = remove_infeasible_cycles(model, v0_fluxes)
            if abs(v1_cycle_free_fluxes[reaction.id] - bound) < 1e-6:
                fva_sol[reaction.id]['upper_bound'] = v0_fluxes[reaction.id]
            else:
                logger.debug('Cycle detected: {}'.format(reaction.id))
                cycle_count += 1
                v2_one_cycle_fluxes = remove_infeasible_cycles(model, v0_fluxes, fix=[reaction.id])
                with TimeMachine() as tm:
                    for key, v1_flux in six.iteritems(v1_cycle_free_fluxes):
                        if round(v1_flux, config.ndecimals) == 0 and round(v2_one_cycle_fluxes[key],
                                                                           config.ndecimals) != 0:
                            knockout_reaction = model.reactions.get_by_id(key)
                            knockout_reaction.knock_out()
                    model.objective.direction = 'max'
                    try:
                        solution = model.solve()
                    except Unbounded:
                        fva_sol[reaction.id]['upper_bound'] = numpy.inf
                    except Infeasible:
                        fva_sol[reaction.id]['upper_bound'] = 0
                    else:
                        fva_sol[reaction.id]['upper_bound'] = solution.f

    df = pandas.DataFrame.from_dict(fva_sol, orient='index')
    lb_higher_ub = df[df.lower_bound > df.upper_bound]
    # Assert that these cases really only numerical artifacts
    assert ((lb_higher_ub.lower_bound - lb_higher_ub.upper_bound) < 1e-6).all()
    df.lower_bound[lb_higher_ub.index] = df.upper_bound[lb_higher_ub.index]

    return df