def flux_variability_analysis(model, reaction_list=None, loopless=False,<EOL>fraction_of_optimum=<NUM_LIT:1.0>, pfba_factor=None,<EOL>processes=None):

if reaction_list is None:<EOL><INDENT>reaction_ids = [r.id for r in model.reactions]<EOL><DEDENT>else:<EOL><INDENT>reaction_ids = [r.id<EOL>for r in model.reactions.get_by_any(reaction_list)]<EOL><DEDENT>if processes is None:<EOL><INDENT>processes = CONFIGURATION.processes<EOL><DEDENT>num_reactions = len(reaction_ids)<EOL>processes = min(processes, num_reactions)<EOL>fva_result = DataFrame({<EOL>"<STR_LIT>": zeros(num_reactions, dtype=float),<EOL>"<STR_LIT>": zeros(num_reactions, dtype=float)<EOL>}, index=reaction_ids)<EOL>prob = model.problem<EOL>with model:<EOL><INDENT>model.slim_optimize(error_value=None,<EOL>message="<STR_LIT>"<EOL>"<STR_LIT>")<EOL>if model.solver.objective.direction == "<STR_LIT>":<EOL><INDENT>fva_old_objective = prob.Variable(<EOL>"<STR_LIT>",<EOL>lb=fraction_of_optimum * model.solver.objective.value)<EOL><DEDENT>else:<EOL><INDENT>fva_old_objective = prob.Variable(<EOL>"<STR_LIT>",<EOL>ub=fraction_of_optimum * model.solver.objective.value)<EOL><DEDENT>fva_old_obj_constraint = prob.Constraint(<EOL>model.solver.objective.expression - fva_old_objective, lb=<NUM_LIT:0>, ub=<NUM_LIT:0>,<EOL>name="<STR_LIT>")<EOL>model.add_cons_vars([fva_old_objective, fva_old_obj_constraint])<EOL>if pfba_factor is not None:<EOL><INDENT>if pfba_factor < <NUM_LIT:1.>:<EOL><INDENT>warn("<STR_LIT>",<EOL>UserWarning)<EOL><DEDENT>with model:<EOL><INDENT>add_pfba(model, fraction_of_optimum=<NUM_LIT:0>)<EOL>ub = model.slim_optimize(error_value=None)<EOL>flux_sum = prob.Variable("<STR_LIT>", ub=pfba_factor * ub)<EOL>flux_sum_constraint = prob.Constraint(<EOL>model.solver.objective.expression - flux_sum, lb=<NUM_LIT:0>, ub=<NUM_LIT:0>,<EOL>name="<STR_LIT>")<EOL><DEDENT>model.add_cons_vars([flux_sum, flux_sum_constraint])<EOL><DEDENT>model.objective = Zero  <EOL>for what in ("<STR_LIT>", "<STR_LIT>"):<EOL><INDENT>if processes > <NUM_LIT:1>:<EOL><INDENT>chunk_size = len(reaction_ids) // processes<EOL>pool = multiprocessing.Pool(<EOL>processes,<EOL>initializer=_init_worker,<EOL>initargs=(model, loopless, what[:<NUM_LIT:3>])<EOL>)<EOL>for rxn_id, value in pool.imap_unordered(_fva_step,<EOL>reaction_ids,<EOL>chunksize=chunk_size):<EOL><INDENT>fva_result.at[rxn_id, what] = value<EOL><DEDENT>pool.close()<EOL>pool.join()<EOL><DEDENT>else:<EOL><INDENT>_init_worker(model, loopless, what[:<NUM_LIT:3>])<EOL>for rxn_id, value in map(_fva_step, reaction_ids):<EOL><INDENT>fva_result.at[rxn_id, what] = value<EOL><DEDENT><DEDENT><DEDENT><DEDENT>return fva_result[["<STR_LIT>", "<STR_LIT>"]]<EOL>

Determine the minimum and maximum possible flux value for each reaction.

Parameters
----------
model : cobra.Model
    The model for which to run the analysis. It will *not* be modified.
reaction_list : list of cobra.Reaction or str, optional
    The reactions for which to obtain min/max fluxes. If None will use
    all reactions in the model (default).
loopless : boolean, optional
    Whether to return only loopless solutions. This is significantly
    slower. Please also refer to the notes.
fraction_of_optimum : float, optional
    Must be <= 1.0. Requires that the objective value is at least the
    fraction times maximum objective value. A value of 0.85 for instance
    means that the objective has to be at least at 85% percent of its
    maximum.
pfba_factor : float, optional
    Add an additional constraint to the model that requires the total sum
    of absolute fluxes must not be larger than this value times the
    smallest possible sum of absolute fluxes, i.e., by setting the value
    to 1.1 the total sum of absolute fluxes must not be more than
    10% larger than the pFBA solution. Since the pFBA solution is the
    one that optimally minimizes the total flux sum, the ``pfba_factor``
    should, if set, be larger than one. Setting this value may lead to
    more realistic predictions of the effective flux bounds.
processes : int, optional
    The number of parallel processes to run. If not explicitly passed,
    will be set from the global configuration singleton.

Returns
-------
pandas.DataFrame
    A data frame with reaction identifiers as the index and two columns:
    - maximum: indicating the highest possible flux
    - minimum: indicating the lowest possible flux

Notes
-----
This implements the fast version as described in [1]_. Please note that
the flux distribution containing all minimal/maximal fluxes does not have
to be a feasible solution for the model. Fluxes are minimized/maximized
individually and a single minimal flux might require all others to be
suboptimal.

Using the loopless option will lead to a significant increase in
computation time (about a factor of 100 for large models). However, the
algorithm used here (see [2]_) is still more than 1000x faster than the
"naive" version using ``add_loopless(model)``. Also note that if you have
included constraints that force a loop (for instance by setting all fluxes
in a loop to be non-zero) this loop will be included in the solution.

References
----------
.. [1] Computationally efficient flux variability analysis.
   Gudmundsson S, Thiele I.
   BMC Bioinformatics. 2010 Sep 29;11:489.
   doi: 10.1186/1471-2105-11-489, PMID: 20920235

.. [2] 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.


zero_cutoff = normalize_cutoff(model, zero_cutoff)<EOL>with model:<EOL><INDENT>if open_exchanges:<EOL><INDENT>for reaction in model.exchanges:<EOL><INDENT>reaction.bounds = (min(reaction.lower_bound, -<NUM_LIT:1000>),<EOL>max(reaction.upper_bound, <NUM_LIT:1000>))<EOL><DEDENT><DEDENT>if reaction_list is None:<EOL><INDENT>reaction_list = model.reactions<EOL><DEDENT>model.slim_optimize()<EOL>solution = get_solution(model, reactions=reaction_list)<EOL>reaction_list = solution.fluxes[<EOL>solution.fluxes.abs() < zero_cutoff].index.tolist()<EOL>flux_span = flux_variability_analysis(<EOL>model, fraction_of_optimum=<NUM_LIT:0.>, reaction_list=reaction_list,<EOL>processes=processes<EOL>)<EOL>return flux_span[<EOL>flux_span.abs().max(axis=<NUM_LIT:1>) < zero_cutoff].index.tolist()<EOL><DEDENT>

Find reactions that cannot carry any flux.

The question whether or not a reaction is blocked is highly dependent
on the current exchange reaction settings for a COBRA model. Hence an
argument is provided to open all exchange reactions.

Notes
-----
Sink and demand reactions are left untouched. Please modify them manually.

Parameters
----------
model : cobra.Model
    The model to analyze.
reaction_list : list, optional
    List of reactions to consider, the default includes all model
    reactions.
zero_cutoff : float, optional
    Flux value which is considered to effectively be zero
    (default model.tolerance).
open_exchanges : bool, optional
    Whether or not to open all exchange reactions to very high flux ranges.
processes : int, optional
    The number of parallel processes to run. Can speed up the computations
    if the number of reactions is large. If not explicitly
    passed, it will be set from the global configuration singleton.

Returns
-------
list
    List with the identifiers of blocked reactions.


def find_essential_genes(model, threshold=None, processes=None):

if threshold is None:<EOL><INDENT>threshold = model.slim_optimize(error_value=None) * <NUM_LIT><EOL><DEDENT>deletions = single_gene_deletion(model, method='<STR_LIT>', processes=processes)<EOL>essential = deletions.loc[deletions['<STR_LIT>'].isna() |<EOL>(deletions['<STR_LIT>'] < threshold), :].index<EOL>return {model.genes.get_by_id(g) for ids in essential for g in ids}<EOL>

Return a set of essential genes.

A gene is considered essential if restricting the flux of all reactions
that depend on it to zero causes the objective, e.g., the growth rate,
to also be zero, below the threshold, or infeasible.

Parameters
----------
model : cobra.Model
    The model to find the essential genes for.
threshold : float, optional
    Minimal objective flux to be considered viable. By default this is
    1% of the maximal objective.
processes : int, optional
    The number of parallel processes to run. If not passed,
    will be set to the number of CPUs found.
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 explicitly
    passed, it will be set from the global configuration singleton.

Returns
-------
set
    Set of essential genes


def find_essential_reactions(model, threshold=None, processes=None):

if threshold is None:<EOL><INDENT>threshold = model.slim_optimize(error_value=None) * <NUM_LIT><EOL><DEDENT>deletions = single_reaction_deletion(<EOL>model, method='<STR_LIT>', processes=processes)<EOL>essential = deletions.loc[deletions['<STR_LIT>'].isna() |<EOL>(deletions['<STR_LIT>'] < threshold), :].index<EOL>return {model.reactions.get_by_id(r) for ids in essential for r in ids}<EOL>

Return a set of essential reactions.

    A reaction is considered essential if restricting its flux to zero
    causes the objective, e.g., the growth rate, to also be zero, below the
    threshold, or infeasible.

    Parameters
    ----------
    model : cobra.Model
        The model to find the essential reactions for.
    threshold : float, optional
        Minimal objective flux to be considered viable. By default this is
        1% of the maximal objective.
    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 explicitly
        passed, it will be set from the global configuration singleton.

    Returns
    -------
    set
        Set of essential reactions


def gapfill(model, universal=None, lower_bound=<NUM_LIT>,<EOL>penalties=None, demand_reactions=True, exchange_reactions=False,<EOL>iterations=<NUM_LIT:1>):

gapfiller = GapFiller(model, universal=universal,<EOL>lower_bound=lower_bound, penalties=penalties,<EOL>demand_reactions=demand_reactions,<EOL>exchange_reactions=exchange_reactions)<EOL>return gapfiller.fill(iterations=iterations)<EOL>

Perform gapfilling on a model.

    See documentation for the class GapFiller.

    Parameters
    ----------
    model : cobra.Model
        The model to perform gap filling on.
    universal : cobra.Model, None
        A universal model with reactions that can be used to complete the
        model. Only gapfill considering demand and exchange reactions if
        left missing.
    lower_bound : float
        The minimally accepted flux for the objective in the filled model.
    penalties : dict, None
        A dictionary with keys being 'universal' (all reactions included in
        the universal model), 'exchange' and 'demand' (all additionally
        added exchange and demand reactions) for the three reaction types.
        Can also have reaction identifiers for reaction specific costs.
        Defaults are 1, 100 and 1 respectively.
    iterations : int
        The number of rounds of gapfilling to perform. For every iteration,
        the penalty for every used reaction increases linearly. This way,
        the algorithm is encouraged to search for alternative solutions
        which may include previously used reactions. I.e., with enough
        iterations pathways including 10 steps will eventually be reported
        even if the shortest pathway is a single reaction.
    exchange_reactions : bool
        Consider adding exchange (uptake) reactions for all metabolites
        in the model.
    demand_reactions : bool
        Consider adding demand reactions for all metabolites.

    Returns
    -------
    iterable
        list of lists with on set of reactions that completes the model per
        requested iteration.

    Examples
    --------
    >>> import cobra.test as ct
    >>> from cobra import Model
    >>> from cobra.flux_analysis import gapfill
    >>> model = ct.create_test_model("salmonella")
    >>> universal = Model('universal')
    >>> universal.add_reactions(model.reactions.GF6PTA.copy())
    >>> model.remove_reactions([model.reactions.GF6PTA])
    >>> gapfill(model, universal)


def extend_model(self, exchange_reactions=False, demand_reactions=True):

for rxn in self.universal.reactions:<EOL><INDENT>rxn.gapfilling_type = '<STR_LIT>'<EOL><DEDENT>new_metabolites = self.universal.metabolites.query(<EOL>lambda metabolite: metabolite not in self.model.metabolites<EOL>)<EOL>self.model.add_metabolites(new_metabolites)<EOL>existing_exchanges = []<EOL>for rxn in self.universal.boundary:<EOL><INDENT>existing_exchanges = existing_exchanges +[met.id for met in list(rxn.metabolites)]<EOL><DEDENT>for met in self.model.metabolites:<EOL><INDENT>if exchange_reactions:<EOL><INDENT>if met.id not in existing_exchanges:<EOL><INDENT>rxn = self.universal.add_boundary(<EOL>met, type='<STR_LIT>', lb=-<NUM_LIT:1000>, ub=<NUM_LIT:0>,<EOL>reaction_id='<STR_LIT>'.format(met.id))<EOL>rxn.gapfilling_type = '<STR_LIT>'<EOL><DEDENT><DEDENT>if demand_reactions:<EOL><INDENT>rxn = self.universal.add_boundary(<EOL>met, type='<STR_LIT>', lb=<NUM_LIT:0>, ub=<NUM_LIT:1000>,<EOL>reaction_id='<STR_LIT>'.format(met.id))<EOL>rxn.gapfilling_type = '<STR_LIT>'<EOL><DEDENT><DEDENT>new_reactions = self.universal.reactions.query(<EOL>lambda reaction: reaction not in self.model.reactions<EOL>)<EOL>self.model.add_reactions(new_reactions)<EOL>

Extend gapfilling model.

        Add reactions from universal model and optionally exchange and
        demand reactions for all metabolites in the model to perform
        gapfilling on.

        Parameters
        ----------
        exchange_reactions : bool
            Consider adding exchange (uptake) reactions for all metabolites
            in the model.
        demand_reactions : bool
            Consider adding demand reactions for all metabolites.


for var in self.indicators:<EOL><INDENT>if var not in self.costs:<EOL><INDENT>self.costs[var] = var.cost<EOL><DEDENT>else:<EOL><INDENT>if var._get_primal() > self.integer_threshold:<EOL><INDENT>self.costs[var] += var.cost<EOL><DEDENT><DEDENT><DEDENT>self.model.objective.set_linear_coefficients(self.costs)<EOL>

Update the coefficients for the indicator variables in the objective.

        Done incrementally so that second time the function is called,
        active indicators in the current solutions gets higher cost than the
        unused indicators.


constraints = list()<EOL>big_m = max(max(abs(b) for b in r.bounds)<EOL>for r in self.model.reactions)<EOL>prob = self.model.problem<EOL>for rxn in self.model.reactions:<EOL><INDENT>if not hasattr(rxn, '<STR_LIT>'):<EOL><INDENT>continue<EOL><DEDENT>indicator = prob.Variable(<EOL>name='<STR_LIT>'.format(rxn.id), lb=<NUM_LIT:0>, ub=<NUM_LIT:1>, type='<STR_LIT>')<EOL>if rxn.id in self.penalties:<EOL><INDENT>indicator.cost = self.penalties[rxn.id]<EOL><DEDENT>else:<EOL><INDENT>indicator.cost = self.penalties[rxn.gapfilling_type]<EOL><DEDENT>indicator.rxn_id = rxn.id<EOL>self.indicators.append(indicator)<EOL>constraint_lb = prob.Constraint(<EOL>rxn.flux_expression - big_m * indicator, ub=<NUM_LIT:0>,<EOL>name='<STR_LIT>'.format(rxn.id), sloppy=True)<EOL>constraint_ub = prob.Constraint(<EOL>rxn.flux_expression + big_m * indicator, lb=<NUM_LIT:0>,<EOL>name='<STR_LIT>'.format(rxn.id), sloppy=True)<EOL>constraints.extend([constraint_lb, constraint_ub])<EOL><DEDENT>self.model.add_cons_vars(self.indicators)<EOL>self.model.add_cons_vars(constraints, sloppy=True)<EOL>self.model.objective = prob.Objective(<EOL>Zero, direction='<STR_LIT>', sloppy=True)<EOL>self.model.objective.set_linear_coefficients({<EOL>i: <NUM_LIT:1> for i in self.indicators})<EOL>self.update_costs()<EOL>

Update gapfilling model with switches and the indicator objective.


used_reactions = list()<EOL>for i in range(iterations):<EOL><INDENT>self.model.slim_optimize(error_value=None,<EOL>message='<STR_LIT>')<EOL>solution = [self.model.reactions.get_by_id(ind.rxn_id)<EOL>for ind in self.indicators if<EOL>ind._get_primal() > self.integer_threshold]<EOL>if not self.validate(solution):<EOL><INDENT>raise RuntimeError('<STR_LIT>'<EOL>'<STR_LIT>')<EOL><DEDENT>used_reactions.append(solution)<EOL>self.update_costs()<EOL><DEDENT>return used_reactions<EOL>

Perform the gapfilling by iteratively solving the model, updating
        the costs and recording the used reactions.

        Parameters
        ----------
        iterations : int
            The number of rounds of gapfilling to perform. For every
            iteration, the penalty for every used reaction increases
            linearly. This way, the algorithm is encouraged to search for
            alternative solutions which may include previously used
            reactions. I.e., with enough iterations pathways including 10
            steps will eventually be reported even if the shortest pathway
            is a single reaction.

        Returns
        -------
        iterable
            A list of lists where each element is a list reactions that were
            used to gapfill the model.

        Raises
        ------
        RuntimeError
            If the model fails to be validated (i.e. the original model with
            the proposed reactions added, still cannot get the required flux
            through the objective).


def metabolite_summary(met, solution=None, threshold=<NUM_LIT>, fva=False,<EOL>names=False, floatfmt='<STR_LIT>'):

if names:<EOL><INDENT>emit = attrgetter('<STR_LIT:name>')<EOL><DEDENT>else:<EOL><INDENT>emit = attrgetter('<STR_LIT:id>')<EOL><DEDENT>if solution is None:<EOL><INDENT>met.model.slim_optimize(error_value=None)<EOL>solution = get_solution(met.model, reactions=met.reactions)<EOL><DEDENT>rxns = sorted(met.reactions, key=attrgetter("<STR_LIT:id>"))<EOL>rxn_id = list()<EOL>rxn_name = list()<EOL>flux = list()<EOL>reaction = list()<EOL>for rxn in rxns:<EOL><INDENT>rxn_id.append(rxn.id)<EOL>rxn_name.append(format_long_string(emit(rxn), <NUM_LIT:10>))<EOL>flux.append(solution[rxn.id] * rxn.metabolites[met])<EOL>txt = rxn.build_reaction_string(use_metabolite_names=names)<EOL>reaction.append(format_long_string(txt, <NUM_LIT> if fva is not None else <NUM_LIT:50>))<EOL><DEDENT>flux_summary = pd.DataFrame({<EOL>"<STR_LIT:id>": rxn_name,<EOL>"<STR_LIT>": flux,<EOL>"<STR_LIT>": reaction<EOL>}, index=rxn_id)<EOL>if fva is not None:<EOL><INDENT>if hasattr(fva, '<STR_LIT>'):<EOL><INDENT>fva_results = fva<EOL><DEDENT>else:<EOL><INDENT>fva_results = flux_variability_analysis(<EOL>met.model, list(met.reactions), fraction_of_optimum=fva)<EOL><DEDENT>flux_summary["<STR_LIT>"] = zeros(len(rxn_id), dtype=float)<EOL>flux_summary["<STR_LIT>"] = zeros(len(rxn_id), dtype=float)<EOL>for rxn in rxns:<EOL><INDENT>fmax = rxn.metabolites[met] * fva_results.at[rxn.id, "<STR_LIT>"]<EOL>fmin = rxn.metabolites[met] * fva_results.at[rxn.id, "<STR_LIT>"]<EOL>if abs(fmin) <= abs(fmax):<EOL><INDENT>flux_summary.at[rxn.id, "<STR_LIT>"] = fmax<EOL>flux_summary.at[rxn.id, "<STR_LIT>"] = fmin<EOL><DEDENT>else:<EOL><INDENT>flux_summary.at[rxn.id, "<STR_LIT>"] = fmin<EOL>flux_summary.at[rxn.id, "<STR_LIT>"] = fmax<EOL><DEDENT><DEDENT><DEDENT>assert flux_summary["<STR_LIT>"].sum() < <NUM_LIT>, "<STR_LIT>"<EOL>flux_summary = _process_flux_dataframe(flux_summary, fva, threshold,<EOL>floatfmt)<EOL>flux_summary['<STR_LIT>'] = <NUM_LIT:0><EOL>total_flux = flux_summary.loc[flux_summary.is_input, "<STR_LIT>"].sum()<EOL>flux_summary.loc[flux_summary.is_input, '<STR_LIT>'] =flux_summary.loc[flux_summary.is_input, '<STR_LIT>'] / total_flux<EOL>flux_summary.loc[~flux_summary.is_input, '<STR_LIT>'] =flux_summary.loc[~flux_summary.is_input, '<STR_LIT>'] / total_flux<EOL>flux_summary['<STR_LIT>'] = flux_summary.percent.apply(<EOL>lambda x: '<STR_LIT>'.format(x))<EOL>if fva is not None:<EOL><INDENT>flux_table = tabulate(<EOL>flux_summary.loc[:, ['<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT:id>',<EOL>'<STR_LIT>']].values, floatfmt=floatfmt,<EOL>headers=['<STR_LIT:%>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>']).split('<STR_LIT:\n>')<EOL><DEDENT>else:<EOL><INDENT>flux_table = tabulate(<EOL>flux_summary.loc[:, ['<STR_LIT>', '<STR_LIT>', '<STR_LIT:id>', '<STR_LIT>']].values,<EOL>floatfmt=floatfmt, headers=['<STR_LIT:%>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT>']<EOL>).split('<STR_LIT:\n>')<EOL><DEDENT>flux_table_head = flux_table[:<NUM_LIT:2>]<EOL>met_tag = "<STR_LIT>".format(format_long_string(met.name, <NUM_LIT>),<EOL>format_long_string(met.id, <NUM_LIT:10>))<EOL>head = "<STR_LIT>" + met_tag<EOL>print_(head)<EOL>print_("<STR_LIT:->" * len(head))<EOL>print_('<STR_LIT:\n>'.join(flux_table_head))<EOL>print_('<STR_LIT:\n>'.join(<EOL>pd.np.array(flux_table[<NUM_LIT:2>:])[flux_summary.is_input.values]))<EOL>print_()<EOL>print_("<STR_LIT>" + met_tag)<EOL>print_("<STR_LIT:->" * len(head))<EOL>print_('<STR_LIT:\n>'.join(flux_table_head))<EOL>print_('<STR_LIT:\n>'.join(<EOL>pd.np.array(flux_table[<NUM_LIT:2>:])[~flux_summary.is_input.values]))<EOL>

Print a summary of the production and consumption fluxes.

This method requires the model for which this metabolite is a part
to be solved.

Parameters
----------
solution : cobra.Solution, optional
    A previously solved model solution to use for generating the
    summary. If none provided (default), the summary method will
    resolve the model. Note that the solution object must match the
    model, i.e., changes to the model such as changed bounds,
    added or removed reactions are not taken into account by this
    method.
threshold : float, optional
    Threshold below which fluxes are not reported.
fva : pandas.DataFrame, float or None, optional
    Whether or not to include flux variability analysis in the output.
    If given, fva should either be a previous FVA solution matching
    the model or a float between 0 and 1 representing the
    fraction of the optimum objective to be searched.
names : bool, optional
    Emit reaction and metabolite names rather than identifiers (default
    False).
floatfmt : string, optional
    Format string for floats (default '.3g').


def model_summary(model, solution=None, threshold=<NUM_LIT>, fva=None, names=False,<EOL>floatfmt='<STR_LIT>'):

if names:<EOL><INDENT>emit = attrgetter('<STR_LIT:name>')<EOL><DEDENT>else:<EOL><INDENT>emit = attrgetter('<STR_LIT:id>')<EOL><DEDENT>objective_reactions = linear_reaction_coefficients(model)<EOL>boundary_reactions = model.exchanges<EOL>summary_rxns = set(objective_reactions.keys()).union(boundary_reactions)<EOL>if solution is None:<EOL><INDENT>model.slim_optimize(error_value=None)<EOL>solution = get_solution(model, reactions=summary_rxns)<EOL><DEDENT>obj_fluxes = pd.DataFrame({key: solution[key.id] * value for key,<EOL>value in iteritems(objective_reactions)},<EOL>index=['<STR_LIT>']).T<EOL>obj_fluxes['<STR_LIT:id>'] = obj_fluxes.apply(<EOL>lambda x: format_long_string(x.name.id, <NUM_LIT:15>), <NUM_LIT:1>)<EOL>metabolites = {m for r in boundary_reactions for m in r.metabolites}<EOL>index = sorted(metabolites, key=attrgetter('<STR_LIT:id>'))<EOL>metabolite_fluxes = pd.DataFrame({<EOL>'<STR_LIT:id>': [format_long_string(emit(m), <NUM_LIT:15>) for m in index],<EOL>'<STR_LIT>': zeros(len(index), dtype=float)<EOL>}, index=[m.id for m in index])<EOL>for rxn in boundary_reactions:<EOL><INDENT>for met, stoich in iteritems(rxn.metabolites):<EOL><INDENT>metabolite_fluxes.at[met.id, '<STR_LIT>'] += stoich * solution[rxn.id]<EOL><DEDENT><DEDENT>if fva is not None:<EOL><INDENT>if len(index) != len(boundary_reactions):<EOL><INDENT>LOGGER.warning(<EOL>"<STR_LIT>"<EOL>"<STR_LIT>")<EOL><DEDENT>metabolite_fluxes['<STR_LIT>'] = zeros(len(index), dtype=float)<EOL>metabolite_fluxes['<STR_LIT>'] = zeros(len(index), dtype=float)<EOL>if hasattr(fva, '<STR_LIT>'):<EOL><INDENT>fva_results = fva<EOL><DEDENT>else:<EOL><INDENT>fva_results = flux_variability_analysis(<EOL>model, reaction_list=boundary_reactions,<EOL>fraction_of_optimum=fva)<EOL><DEDENT>for rxn in boundary_reactions:<EOL><INDENT>for met, stoich in iteritems(rxn.metabolites):<EOL><INDENT>fmin = stoich * fva_results.at[rxn.id, '<STR_LIT>']<EOL>fmax = stoich * fva_results.at[rxn.id, '<STR_LIT>']<EOL>if abs(fmin) <= abs(fmax):<EOL><INDENT>metabolite_fluxes.at[met.id, '<STR_LIT>'] += fmin<EOL>metabolite_fluxes.at[met.id, '<STR_LIT>'] += fmax<EOL><DEDENT>else:<EOL><INDENT>metabolite_fluxes.at[met.id, '<STR_LIT>'] += fmax<EOL>metabolite_fluxes.at[met.id, '<STR_LIT>'] += fmin<EOL><DEDENT><DEDENT><DEDENT><DEDENT>metabolite_fluxes = _process_flux_dataframe(<EOL>metabolite_fluxes, fva, threshold, floatfmt)<EOL>def get_str_table(species_df, fva=False):<EOL><INDENT>"""<STR_LIT>"""<EOL>if fva:<EOL><INDENT>return tabulate(<EOL>species_df.loc[:, ['<STR_LIT:id>', '<STR_LIT>', '<STR_LIT>']].values,<EOL>floatfmt=floatfmt, tablefmt='<STR_LIT>',<EOL>headers=['<STR_LIT:id>', '<STR_LIT>', '<STR_LIT>']).split('<STR_LIT:\n>')<EOL><DEDENT>else:<EOL><INDENT>return tabulate(species_df.loc[:, ['<STR_LIT:id>', '<STR_LIT>']].values,<EOL>floatfmt=floatfmt, tablefmt='<STR_LIT>').split('<STR_LIT:\n>')<EOL><DEDENT><DEDENT>in_table = get_str_table(<EOL>metabolite_fluxes[metabolite_fluxes['<STR_LIT>']], fva=fva is not None)<EOL>out_table = get_str_table(<EOL>metabolite_fluxes[~metabolite_fluxes['<STR_LIT>']], fva=fva is not None)<EOL>obj_table = get_str_table(obj_fluxes, fva=False)<EOL>print_(tabulate(<EOL>[entries for entries in zip_longest(in_table, out_table, obj_table)],<EOL>headers=['<STR_LIT>', '<STR_LIT>', '<STR_LIT>'], tablefmt='<STR_LIT>'))<EOL>

Print a summary of the input and output fluxes of the model.

Parameters
----------
solution: cobra.Solution, optional
    A previously solved model solution to use for generating the
    summary. If none provided (default), the summary method will
    resolve the model. Note that the solution object must match the
    model, i.e., changes to the model such as changed bounds,
    added or removed reactions are not taken into account by this
    method.
threshold : float, optional
    Threshold below which fluxes are not reported.
fva : pandas.DataFrame, float or None, optional
    Whether or not to include flux variability analysis in the output.
    If given, fva should either be a previous FVA solution matching
    the model or a float between 0 and 1 representing the
    fraction of the optimum objective to be searched.
names : bool, optional
    Emit reaction and metabolite names rather than identifiers (default
    False).
floatfmt : string, optional
    Format string for floats (default '.3g').


def _process_flux_dataframe(flux_dataframe, fva, threshold, floatfmt):

abs_flux = flux_dataframe['<STR_LIT>'].abs()<EOL>flux_threshold = threshold * abs_flux.max()<EOL>if fva is None:<EOL><INDENT>flux_dataframe = flux_dataframe.loc[<EOL>abs_flux >= flux_threshold, :].copy()<EOL><DEDENT>else:<EOL><INDENT>flux_dataframe = flux_dataframe.loc[<EOL>(abs_flux >= flux_threshold) |<EOL>(flux_dataframe['<STR_LIT>'].abs() >= flux_threshold) |<EOL>(flux_dataframe['<STR_LIT>'].abs() >= flux_threshold), :].copy()<EOL><DEDENT>if fva is None:<EOL><INDENT>flux_dataframe['<STR_LIT>'] = (flux_dataframe['<STR_LIT>'] >= <NUM_LIT:0>)<EOL>flux_dataframe['<STR_LIT>'] = flux_dataframe['<STR_LIT>'].abs()<EOL><DEDENT>else:<EOL><INDENT>def get_direction(flux, fmin, fmax):<EOL><INDENT>"""<STR_LIT>"""<EOL>if flux < <NUM_LIT:0>:<EOL><INDENT>return -<NUM_LIT:1><EOL><DEDENT>elif flux > <NUM_LIT:0>:<EOL><INDENT>return <NUM_LIT:1><EOL><DEDENT>elif (fmax > <NUM_LIT:0>) & (fmin <= <NUM_LIT:0>):<EOL><INDENT>return <NUM_LIT:1><EOL><DEDENT>elif (fmax < <NUM_LIT:0>) & (fmin >= <NUM_LIT:0>):<EOL><INDENT>return -<NUM_LIT:1><EOL><DEDENT>elif ((fmax + fmin) / <NUM_LIT:2>) < <NUM_LIT:0>:<EOL><INDENT>return -<NUM_LIT:1><EOL><DEDENT>else:<EOL><INDENT>return <NUM_LIT:1><EOL><DEDENT><DEDENT>sign = flux_dataframe.apply(<EOL>lambda x: get_direction(x.flux, x.fmin, x.fmax), <NUM_LIT:1>)<EOL>flux_dataframe['<STR_LIT>'] = sign == <NUM_LIT:1><EOL>flux_dataframe.loc[:, ['<STR_LIT>', '<STR_LIT>', '<STR_LIT>']] =flux_dataframe.loc[:, ['<STR_LIT>', '<STR_LIT>', '<STR_LIT>']].multiply(<EOL>sign, <NUM_LIT:0>).astype('<STR_LIT:float>').round(<NUM_LIT:6>)<EOL>flux_dataframe.loc[:, ['<STR_LIT>', '<STR_LIT>', '<STR_LIT>']] =flux_dataframe.loc[:, ['<STR_LIT>', '<STR_LIT>', '<STR_LIT>']].applymap(<EOL>lambda x: x if abs(x) > <NUM_LIT> else <NUM_LIT:0>)<EOL><DEDENT>if fva is not None:<EOL><INDENT>flux_dataframe['<STR_LIT>'] = flux_dataframe.apply(<EOL>lambda x: ("<STR_LIT>" + floatfmt + "<STR_LIT>" +<EOL>floatfmt + "<STR_LIT>").format(x), <NUM_LIT:1>)<EOL>flux_dataframe = flux_dataframe.sort_values(<EOL>by=['<STR_LIT>', '<STR_LIT>', '<STR_LIT>', '<STR_LIT:id>'],<EOL>ascending=[False, False, False, True])<EOL><DEDENT>else:<EOL><INDENT>flux_dataframe = flux_dataframe.sort_values(<EOL>by=['<STR_LIT>', '<STR_LIT:id>'], ascending=[False, True])<EOL><DEDENT>return flux_dataframe<EOL>

Some common methods for processing a database of flux information into
    print-ready formats. Used in both model_summary and metabolite_summary.


def fastcc(model, flux_threshold=<NUM_LIT:1.0>, zero_cutoff=None):

zero_cutoff = normalize_cutoff(model, zero_cutoff)<EOL>with model:<EOL><INDENT>obj_vars = []<EOL>vars_and_cons = []<EOL>prob = model.problem<EOL>for rxn in model.reactions:<EOL><INDENT>var = prob.Variable("<STR_LIT>".format(rxn.id),<EOL>lb=<NUM_LIT:0.0>, ub=flux_threshold)<EOL>const = prob.Constraint(rxn.forward_variable +<EOL>rxn.reverse_variable -<EOL>var, name="<STR_LIT>".format(rxn.id),<EOL>lb=<NUM_LIT:0.0>)<EOL>vars_and_cons.extend([var, const])<EOL>obj_vars.append(var)<EOL><DEDENT>model.add_cons_vars(vars_and_cons)<EOL>model.objective = prob.Objective(Zero, sloppy=True, direction="<STR_LIT>")<EOL>model.objective.set_linear_coefficients({v: <NUM_LIT:1.0> for v in obj_vars})<EOL>sol = model.optimize()<EOL><DEDENT>rxns_to_remove = sol.fluxes[sol.fluxes.abs() < zero_cutoff].index<EOL>consistent_model = model.copy()<EOL>consistent_model.remove_reactions(rxns_to_remove, remove_orphans=True)<EOL>return consistent_model<EOL>

r"""
    Check consistency of a metabolic network using FASTCC [1]_.

    FASTCC (Fast Consistency Check) is an algorithm for rapid and
    efficient consistency check in metabolic networks. FASTCC is
    a pure LP implementation and is low on computation resource
    demand. FASTCC also circumvents the problem associated with
    reversible reactions for the purpose. Given a global model,
    it will generate a consistent global model i.e., remove
    blocked reactions. For more details on FASTCC, please
    check [1]_.

    Parameters
    ----------
    model: cobra.Model
        The constraint-based model to operate on.
    flux_threshold: float, optional (default 1.0)
        The flux threshold to consider.
    zero_cutoff: float, optional
        The cutoff to consider for zero flux (default model.tolerance).

    Returns
    -------
    cobra.Model
        The consistent constraint-based model.

    Notes
    -----
    The LP used for FASTCC is like so:
    maximize: \sum_{i \in J} z_i
    s.t.    : z_i \in [0, \varepsilon] \forall i \in J, z_i \in \mathbb{R}_+
              v_i \ge z_i \forall i \in J
              Sv = 0 v \in B

    References
    ----------
    .. [1] Vlassis N, Pacheco MP, Sauter T (2014)
           Fast Reconstruction of Compact Context-Specific Metabolic Network
           Models.
           PLoS Comput Biol 10(1): e1003424. doi:10.1371/journal.pcbi.1003424


def room(model, solution=None, linear=False, delta=<NUM_LIT>, epsilon=<NUM_LIT>):

with model:<EOL><INDENT>add_room(model=model, solution=solution, linear=linear, delta=delta,<EOL>epsilon=epsilon)<EOL>solution = model.optimize()<EOL><DEDENT>return solution<EOL>

Compute a single solution based on regulatory on/off minimization (ROOM).

Compute a new flux distribution that minimizes the number of active
reactions needed to accommodate a previous reference solution.
Regulatory on/off minimization (ROOM) is generally used to assess the
impact of knock-outs. Thus the typical usage is to provide a wildtype flux
distribution as reference and a model in knock-out state.

Parameters
----------
model : cobra.Model
    The model state to compute a ROOM-based solution for.
solution : cobra.Solution, optional
    A (wildtype) reference solution.
linear : bool, optional
    Whether to use the linear ROOM formulation or not (default False).
delta: float, optional
    The relative tolerance range (additive) (default 0.03).
epsilon: float, optional
    The absolute tolerance range (multiplicative) (default 0.001).

Returns
-------
cobra.Solution
    A flux distribution with minimal active reaction changes compared to
    the reference.

See Also
--------
add_room : add ROOM constraints and objective


def add_room(model, solution=None, linear=False, delta=<NUM_LIT>, epsilon=<NUM_LIT>):

if '<STR_LIT>' in model.solver.variables:<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>if solution is None:<EOL><INDENT>solution = pfba(model)<EOL><DEDENT>prob = model.problem<EOL>variable = prob.Variable("<STR_LIT>", ub=solution.objective_value)<EOL>constraint = prob.Constraint(<EOL>model.solver.objective.expression - variable,<EOL>ub=<NUM_LIT:0.0>,<EOL>lb=<NUM_LIT:0.0>,<EOL>name="<STR_LIT>"<EOL>)<EOL>model.objective = prob.Objective(Zero, direction="<STR_LIT>", sloppy=True)<EOL>vars_and_cons = [variable, constraint]<EOL>obj_vars = []<EOL>for rxn in model.reactions:<EOL><INDENT>flux = solution.fluxes[rxn.id]<EOL>if linear:<EOL><INDENT>y = prob.Variable("<STR_LIT>" + rxn.id, lb=<NUM_LIT:0>, ub=<NUM_LIT:1>)<EOL>delta = epsilon = <NUM_LIT:0.0><EOL><DEDENT>else:<EOL><INDENT>y = prob.Variable("<STR_LIT>" + rxn.id, type="<STR_LIT>")<EOL><DEDENT>w_u = flux + (delta * abs(flux)) + epsilon<EOL>upper_const = prob.Constraint(<EOL>rxn.flux_expression - y * (rxn.upper_bound - w_u),<EOL>ub=w_u, name="<STR_LIT>" + rxn.id)<EOL>w_l = flux - (delta * abs(flux)) - epsilon<EOL>lower_const = prob.Constraint(<EOL>rxn.flux_expression - y * (rxn.lower_bound - w_l),<EOL>lb=w_l, name="<STR_LIT>" + rxn.id)<EOL>vars_and_cons.extend([y, upper_const, lower_const])<EOL>obj_vars.append(y)<EOL><DEDENT>model.add_cons_vars(vars_and_cons)<EOL>model.objective.set_linear_coefficients({v: <NUM_LIT:1.0> for v in obj_vars})<EOL>

r"""
    Add constraints and objective for ROOM.

    This function adds variables and constraints for applying regulatory
    on/off minimization (ROOM) to the model.

    Parameters
    ----------
    model : cobra.Model
        The model to add ROOM constraints and objective to.
    solution : cobra.Solution, optional
        A previous solution to use as a reference. If no solution is given,
        one will be computed using pFBA.
    linear : bool, optional
        Whether to use the linear ROOM formulation or not (default False).
    delta: float, optional
        The relative tolerance range which is additive in nature
        (default 0.03).
    epsilon: float, optional
        The absolute range of tolerance which is multiplicative
        (default 0.001).

    Notes
    -----
    The formulation used here is the same as stated in the original paper [1]_.
    The mathematical expression is given below:

    minimize \sum_{i=1}^m y^i
    s.t. Sv = 0
         v_min <= v <= v_max
         v_j = 0
         j ∈ A
         for 1 <= i <= m
         v_i - y_i(v_{max,i} - w_i^u) <= w_i^u      (1)
         v_i - y_i(v_{min,i} - w_i^l) <= w_i^l      (2)
         y_i ∈ {0,1}                                (3)
         w_i^u = w_i + \delta|w_i| + \epsilon
         w_i^l = w_i - \delta|w_i| - \epsilon

    So, for the linear version of the ROOM , constraint (3) is relaxed to
    0 <= y_i <= 1.

    See Also
    --------
    pfba : parsimonious FBA

    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


def _multi_deletion(model, entity, element_lists, method="<STR_LIT>",<EOL>solution=None, processes=None, **kwargs):

solver = sutil.interface_to_str(model.problem.__name__)<EOL>if method == "<STR_LIT>" and solver not in sutil.qp_solvers:<EOL><INDENT>raise RuntimeError(<EOL>"<STR_LIT>"<EOL>"<STR_LIT>".format(solver))<EOL><DEDENT>if processes is None:<EOL><INDENT>processes = CONFIGURATION.processes<EOL><DEDENT>with model:<EOL><INDENT>if "<STR_LIT>" in method:<EOL><INDENT>add_moma(model, solution=solution, linear="<STR_LIT>" in method)<EOL><DEDENT>elif "<STR_LIT>" in method:<EOL><INDENT>add_room(model, solution=solution, linear="<STR_LIT>" in method,<EOL>**kwargs)<EOL><DEDENT>args = set([frozenset(comb) for comb in product(*element_lists)])<EOL>processes = min(processes, len(args))<EOL>def extract_knockout_results(result_iter):<EOL><INDENT>result = pd.DataFrame([<EOL>(frozenset(ids), growth, status)<EOL>for (ids, growth, status) in result_iter<EOL>], columns=['<STR_LIT>', '<STR_LIT>', '<STR_LIT:status>'])<EOL>result.set_index('<STR_LIT>', inplace=True)<EOL>return result<EOL><DEDENT>if processes > <NUM_LIT:1>:<EOL><INDENT>worker = dict(gene=_gene_deletion_worker,<EOL>reaction=_reaction_deletion_worker)[entity]<EOL>chunk_size = len(args) // processes<EOL>pool = multiprocessing.Pool(<EOL>processes, initializer=_init_worker, initargs=(model,)<EOL>)<EOL>results = extract_knockout_results(pool.imap_unordered(<EOL>worker,<EOL>args,<EOL>chunksize=chunk_size<EOL>))<EOL>pool.close()<EOL>pool.join()<EOL><DEDENT>else:<EOL><INDENT>worker = dict(gene=_gene_deletion,<EOL>reaction=_reaction_deletion)[entity]<EOL>results = extract_knockout_results(map(<EOL>partial(worker, model), args))<EOL><DEDENT>return results<EOL><DEDENT>

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.


def single_reaction_deletion(model, reaction_list=None, method="<STR_LIT>",<EOL>solution=None, processes=None, **kwargs):

return _multi_deletion(<EOL>model, '<STR_LIT>',<EOL>element_lists=_element_lists(model.reactions, reaction_list),<EOL>method=method, solution=solution, processes=processes, **kwargs)<EOL>

Knock out each reaction from a given list.

Parameters
----------
model : cobra.Model
    The metabolic model to perform deletions in.
reaction_list : iterable, optional
    ``cobra.Reaction``s to be deleted. If not passed,
    all the reactions from the model are used.
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 :
    Keyword arguments are passed on to underlying simulation functions
    such as ``add_room``.

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

    index : frozenset([str])
        The reaction identifier that was knocked out.
    growth : float
        The growth rate of the adjusted model.
    status : str
        The solution's status.


def single_gene_deletion(model, gene_list=None, method="<STR_LIT>", solution=None,<EOL>processes=None, **kwargs):

return _multi_deletion(<EOL>model, '<STR_LIT>', element_lists=_element_lists(model.genes, gene_list),<EOL>method=method, solution=solution, processes=processes, **kwargs)<EOL>

Knock out each gene from a given list.

Parameters
----------
model : cobra.Model
    The metabolic model to perform deletions in.
gene_list : iterable
    ``cobra.Gene``s to be deleted. If not passed,
    all the genes from the model are used.
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 :
    Keyword arguments are passed on to underlying simulation functions
    such as ``add_room``.

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

    index : frozenset([str])
        The gene identifier that was knocked out.
    growth : float
        The growth rate of the adjusted model.
    status : str
        The solution's status.


def double_reaction_deletion(model, reaction_list1=None, reaction_list2=None,<EOL>method="<STR_LIT>", solution=None, processes=None,<EOL>**kwargs):

reaction_list1, reaction_list2 = _element_lists(model.reactions,<EOL>reaction_list1,<EOL>reaction_list2)<EOL>return _multi_deletion(<EOL>model, '<STR_LIT>', element_lists=[reaction_list1, reaction_list2],<EOL>method=method, solution=solution, processes=processes, **kwargs)<EOL>

Knock out each reaction pair from the combinations of two given lists.

We say 'pair' here but the order order does not matter.

Parameters
----------
model : cobra.Model
    The metabolic model to perform deletions in.
reaction_list1 : iterable, optional
    First iterable of ``cobra.Reaction``s to be deleted. If not passed,
    all the reactions from the model are used.
reaction_list2 : iterable, optional
    Second iterable of ``cobra.Reaction``s to be deleted. If not passed,
    all the reactions from the model are used.
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 :
    Keyword arguments are passed on to underlying simulation functions
    such as ``add_room``.

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

    index : frozenset([str])
        The reaction identifiers that were knocked out.
    growth : float
        The growth rate of the adjusted model.
    status : str
        The solution's status.


def double_gene_deletion(model, gene_list1=None, gene_list2=None, method="<STR_LIT>",<EOL>solution=None, processes=None, **kwargs):

gene_list1, gene_list2 = _element_lists(model.genes, gene_list1,<EOL>gene_list2)<EOL>return _multi_deletion(<EOL>model, '<STR_LIT>', element_lists=[gene_list1, gene_list2],<EOL>method=method, solution=solution, processes=processes, **kwargs)<EOL>

Knock out each gene pair from the combination of two given lists.

We say 'pair' here but the order order does not matter.

Parameters
----------
model : cobra.Model
    The metabolic model to perform deletions in.
gene_list1 : iterable, optional
    First iterable of ``cobra.Gene``s to be deleted. If not passed,
    all the genes from the model are used.
gene_list2 : iterable, optional
    Second iterable of ``cobra.Gene``s to be deleted. If not passed,
    all the genes from the model are used.
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 :
    Keyword arguments are passed on to underlying simulation functions
    such as ``add_room``.

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

    index : frozenset([str])
        The gene identifiers that were knocked out.
    growth : float
        The growth rate of the adjusted model.
    status : str
        The solution's status.


if zero_cutoff is None:<EOL><INDENT>return model.tolerance<EOL><DEDENT>else:<EOL><INDENT>if zero_cutoff < model.tolerance:<EOL><INDENT>raise ValueError(<EOL>"<STR_LIT>"<EOL>"<STR_LIT>"<EOL>)<EOL><DEDENT>else:<EOL><INDENT>return zero_cutoff<EOL><DEDENT><DEDENT>


zero_cutoff = normalize_cutoff(model, zero_cutoff)<EOL>internal = [i for i, r in enumerate(model.reactions) if not r.boundary]<EOL>s_int = create_stoichiometric_matrix(model)[:, numpy.array(internal)]<EOL>n_int = nullspace(s_int).T<EOL>max_bound = max(max(abs(b) for b in r.bounds) for r in model.reactions)<EOL>prob = model.problem<EOL>to_add = []<EOL>for i in internal:<EOL><INDENT>rxn = model.reactions[i]<EOL>indicator = prob.Variable("<STR_LIT>" + rxn.id, type="<STR_LIT>")<EOL>on_off_constraint = prob.Constraint(<EOL>rxn.flux_expression - max_bound * indicator,<EOL>lb=-max_bound, ub=<NUM_LIT:0>, name="<STR_LIT>" + rxn.id)<EOL>delta_g = prob.Variable("<STR_LIT>" + rxn.id)<EOL>delta_g_range = prob.Constraint(<EOL>delta_g + (max_bound + <NUM_LIT:1>) * indicator,<EOL>lb=<NUM_LIT:1>, ub=max_bound, name="<STR_LIT>" + rxn.id)<EOL>to_add.extend([indicator, on_off_constraint, delta_g, delta_g_range])<EOL><DEDENT>model.add_cons_vars(to_add)<EOL>for i, row in enumerate(n_int):<EOL><INDENT>name = "<STR_LIT>" + str(i)<EOL>nullspace_constraint = prob.Constraint(Zero, lb=<NUM_LIT:0>, ub=<NUM_LIT:0>, name=name)<EOL>model.add_cons_vars([nullspace_constraint])<EOL>coefs = {model.variables[<EOL>"<STR_LIT>" + model.reactions[ridx].id]: row[i]<EOL>for i, ridx in enumerate(internal) if<EOL>abs(row[i]) > zero_cutoff}<EOL>model.constraints[name].set_linear_coefficients(coefs)<EOL><DEDENT>

Modify a model so all feasible flux distributions are loopless.

    In most cases you probably want to use the much faster `loopless_solution`.
    May be used in cases where you want to add complex constraints and
    objecives (for instance quadratic objectives) to the model afterwards
    or use an approximation of Gibbs free energy directions in you model.
    Adds variables and constraints to a model which will disallow flux
    distributions with loops. The used formulation is described in [1]_.
    This function *will* modify your model.

    Parameters
    ----------
    model : cobra.Model
        The model to which to add the constraints.
    zero_cutoff : positive float, optional
        Cutoff used for null space. Coefficients with an absolute value smaller
        than `zero_cutoff` are considered to be zero (default model.tolerance).

    Returns
    -------
    Nothing

    References
    ----------
    .. [1] Elimination of thermodynamically infeasible loops in steady-state
       metabolic models. Schellenberger J, Lewis NE, Palsson BO. Biophys J.
       2011 Feb 2;100(3):544-53. doi: 10.1016/j.bpj.2010.12.3707. Erratum
       in: Biophys J. 2011 Mar 2;100(5):1381.


model.objective = model.solver.interface.Objective(<EOL>Zero, direction="<STR_LIT>", sloppy=True)<EOL>objective_vars = []<EOL>for rxn in model.reactions:<EOL><INDENT>flux = fluxes[rxn.id]<EOL>if rxn.boundary:<EOL><INDENT>rxn.bounds = (flux, flux)<EOL>continue<EOL><DEDENT>if flux >= <NUM_LIT:0>:<EOL><INDENT>rxn.bounds = max(<NUM_LIT:0>, rxn.lower_bound), max(flux, rxn.upper_bound)<EOL>objective_vars.append(rxn.forward_variable)<EOL><DEDENT>else:<EOL><INDENT>rxn.bounds = min(flux, rxn.lower_bound), min(<NUM_LIT:0>, rxn.upper_bound)<EOL>objective_vars.append(rxn.reverse_variable)<EOL><DEDENT><DEDENT>model.objective.set_linear_coefficients({v: <NUM_LIT:1.0> for v in objective_vars})<EOL>


<EOL>if fluxes is None:<EOL><INDENT>sol = model.optimize(objective_sense=None)<EOL>fluxes = sol.fluxes<EOL><DEDENT>with model:<EOL><INDENT>prob = model.problem<EOL>loopless_obj_constraint = prob.Constraint(<EOL>model.objective.expression,<EOL>lb=-<NUM_LIT>, name="<STR_LIT>")<EOL>model.add_cons_vars([loopless_obj_constraint])<EOL>_add_cycle_free(model, fluxes)<EOL>solution = model.optimize(objective_sense=None)<EOL>solution.objective_value = loopless_obj_constraint.primal<EOL><DEDENT>return solution<EOL>

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.

    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 an objective value close to the original one and the same
      objective value id the objective expression can not form a cycle
      (which is usually true since it consumes metabolites)
    - 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.


def loopless_fva_iter(model, reaction, solution=False, zero_cutoff=None):

zero_cutoff = normalize_cutoff(model, zero_cutoff)<EOL>current = model.objective.value<EOL>sol = get_solution(model)<EOL>objective_dir = model.objective.direction<EOL>if reaction.boundary:<EOL><INDENT>if solution:<EOL><INDENT>return sol<EOL><DEDENT>else:<EOL><INDENT>return current<EOL><DEDENT><DEDENT>with model:<EOL><INDENT>_add_cycle_free(model, sol.fluxes)<EOL>model.slim_optimize()<EOL>if abs(reaction.flux - current) < zero_cutoff:<EOL><INDENT>if solution:<EOL><INDENT>return sol<EOL><DEDENT>return current<EOL><DEDENT>ll_sol = get_solution(model).fluxes<EOL>reaction.bounds = (current, current)<EOL>model.slim_optimize()<EOL>almost_ll_sol = get_solution(model).fluxes<EOL><DEDENT>with model:<EOL><INDENT>for rxn in model.reactions:<EOL><INDENT>rid = rxn.id<EOL>if ((abs(ll_sol[rid]) < zero_cutoff) and<EOL>(abs(almost_ll_sol[rid]) > zero_cutoff)):<EOL><INDENT>rxn.bounds = max(<NUM_LIT:0>, rxn.lower_bound), min(<NUM_LIT:0>, rxn.upper_bound)<EOL><DEDENT><DEDENT>if solution:<EOL><INDENT>best = model.optimize()<EOL><DEDENT>else:<EOL><INDENT>model.slim_optimize()<EOL>best = reaction.flux<EOL><DEDENT><DEDENT>model.objective.direction = objective_dir<EOL>return best<EOL>

Plugin to get a loopless FVA solution from single FVA iteration.

    Assumes the following about `model` and `reaction`:
    1. the model objective is set to be `reaction`
    2. the model has been optimized and contains the minimum/maximum flux for
       `reaction`
    3. the model contains an auxiliary variable called "fva_old_objective"
       denoting the previous objective

    Parameters
    ----------
    model : cobra.Model
        The model to be used.
    reaction : cobra.Reaction
        The reaction currently minimized/maximized.
    solution : boolean, optional
        Whether to return the entire solution or only the minimum/maximum for
        `reaction`.
    zero_cutoff : positive float, optional
        Cutoff used for loop removal. Fluxes with an absolute value smaller
        than `zero_cutoff` are considered to be zero (default model.tolerance).

    Returns
    -------
    single float or dict
        Returns the minimized/maximized flux through `reaction` if
        all_fluxes == False (default). Otherwise returns a loopless flux
        solution containing the minimum/maximum flux for `reaction`.


def pfba(model, fraction_of_optimum=<NUM_LIT:1.0>, objective=None, reactions=None):

reactions = model.reactions if reactions is Noneelse model.reactions.get_by_any(reactions)<EOL>with model as m:<EOL><INDENT>add_pfba(m, objective=objective,<EOL>fraction_of_optimum=fraction_of_optimum)<EOL>m.slim_optimize(error_value=None)<EOL>solution = get_solution(m, reactions=reactions)<EOL><DEDENT>return solution<EOL>

Perform basic pFBA (parsimonious Enzyme Usage Flux Balance Analysis)
    to minimize total flux.

    pFBA [1] adds the minimization of all fluxes the the objective of the
    model. This approach is motivated by the idea that high fluxes have a
    higher enzyme turn-over and that since producing enzymes is costly,
    the cell will try to minimize overall flux while still maximizing the
    original objective function, e.g. the growth rate.

    Parameters
    ----------
    model : cobra.Model
        The model
    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.
    objective : dict or model.problem.Objective
        A desired objective to use during optimization in addition to the
        pFBA objective. Dictionaries (reaction as key, coefficient as value)
        can be used for linear objectives.
    reactions : iterable
        List of reactions or reaction identifiers. Implies `return_frame` to
        be true. Only return fluxes for the given reactions. Faster than
        fetching all fluxes if only a few are needed.

    Returns
    -------
    cobra.Solution
        The solution object to the optimized model with pFBA constraints added.

    References
    ----------
    .. [1] Lewis, N. E., Hixson, K. K., Conrad, T. M., Lerman, J. A.,
       Charusanti, P., Polpitiya, A. D., Palsson, B. O. (2010). Omic data
       from evolved E. coli are consistent with computed optimal growth from
       genome-scale models. Molecular Systems Biology, 6,
       390. doi:10.1038/msb.2010.47


def add_pfba(model, objective=None, fraction_of_optimum=<NUM_LIT:1.0>):

if objective is not None:<EOL><INDENT>model.objective = objective<EOL><DEDENT>if model.solver.objective.name == '<STR_LIT>':<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>sutil.fix_objective_as_constraint(model, fraction=fraction_of_optimum)<EOL>reaction_variables = ((rxn.forward_variable, rxn.reverse_variable)<EOL>for rxn in model.reactions)<EOL>variables = chain(*reaction_variables)<EOL>model.objective = model.problem.Objective(<EOL>Zero, direction='<STR_LIT>', sloppy=True, name="<STR_LIT>")<EOL>model.objective.set_linear_coefficients({v: <NUM_LIT:1.0> for v in variables})<EOL>

Add pFBA objective

    Add objective to minimize the summed flux of all reactions to the
    current objective.

    See Also
    -------
    pfba

    Parameters
    ----------
    model : cobra.Model
        The model to add the objective to
    objective :
        An objective to set in combination with the pFBA objective.
    fraction_of_optimum : float
        Fraction of optimum which must be maintained. The original objective
        reaction is constrained to be greater than maximal_value *
        fraction_of_optimum.


def moma(model, solution=None, linear=True):

with model:<EOL><INDENT>add_moma(model=model, solution=solution, linear=linear)<EOL>solution = model.optimize()<EOL><DEDENT>return solution<EOL>

Compute a single solution based on (linear) MOMA.

Compute a new flux distribution that is at a minimal distance to a
previous reference solution. Minimization of metabolic adjustment (MOMA) is
generally used to assess the impact
of knock-outs. Thus the typical usage is to provide a wildtype flux
distribution as reference and a model in knock-out state.

Parameters
----------
model : cobra.Model
    The model state to compute a MOMA-based solution for.
solution : cobra.Solution, optional
    A (wildtype) reference solution.
linear : bool, optional
    Whether to use the linear MOMA formulation or not (default True).

Returns
-------
cobra.Solution
    A flux distribution that is at a minimal distance compared to the
    reference solution.

See Also
--------
add_moma : add MOMA constraints and objective


def add_moma(model, solution=None, linear=True):

if '<STR_LIT>' in model.solver.variables:<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>if not linear:<EOL><INDENT>model.solver = sutil.choose_solver(model, qp=True)<EOL><DEDENT>if solution is None:<EOL><INDENT>solution = pfba(model)<EOL><DEDENT>prob = model.problem<EOL>v = prob.Variable("<STR_LIT>")<EOL>c = prob.Constraint(model.solver.objective.expression - v,<EOL>lb=<NUM_LIT:0.0>, ub=<NUM_LIT:0.0>, name="<STR_LIT>")<EOL>to_add = [v, c]<EOL>model.objective = prob.Objective(Zero, direction="<STR_LIT>", sloppy=True)<EOL>obj_vars = []<EOL>for r in model.reactions:<EOL><INDENT>flux = solution.fluxes[r.id]<EOL>if linear:<EOL><INDENT>components = sutil.add_absolute_expression(<EOL>model, r.flux_expression, name="<STR_LIT>" + r.id,<EOL>difference=flux, add=False)<EOL>to_add.extend(components)<EOL>obj_vars.append(components.variable)<EOL><DEDENT>else:<EOL><INDENT>dist = prob.Variable("<STR_LIT>" + r.id)<EOL>const = prob.Constraint(r.flux_expression - dist, lb=flux, ub=flux,<EOL>name="<STR_LIT>" + r.id)<EOL>to_add.extend([dist, const])<EOL>obj_vars.append(dist ** <NUM_LIT:2>)<EOL><DEDENT><DEDENT>model.add_cons_vars(to_add)<EOL>if linear:<EOL><INDENT>model.objective.set_linear_coefficients({v: <NUM_LIT:1.0> for v in obj_vars})<EOL><DEDENT>else:<EOL><INDENT>model.objective = prob.Objective(<EOL>add(obj_vars), direction="<STR_LIT>", sloppy=True)<EOL><DEDENT>

r"""Add constraints and objective representing for MOMA.

    This adds variables and constraints for the minimization of metabolic
    adjustment (MOMA) to the model.

    Parameters
    ----------
    model : cobra.Model
        The model to add MOMA constraints and objective to.
    solution : cobra.Solution, optional
        A previous solution to use as a reference. If no solution is given,
        one will be computed using pFBA.
    linear : bool, optional
        Whether to use the linear MOMA formulation or not (default True).

    Notes
    -----
    In the original MOMA [1]_ specification one looks for the flux distribution
    of the deletion (v^d) closest to the fluxes without the deletion (v).
    In math this means:

    minimize \sum_i (v^d_i - v_i)^2
    s.t. Sv^d = 0
         lb_i <= v^d_i <= ub_i

    Here, we use a variable transformation v^t := v^d_i - v_i. Substituting
    and using the fact that Sv = 0 gives:

    minimize \sum_i (v^t_i)^2
    s.t. Sv^d = 0
         v^t = v^d_i - v_i
         lb_i <= v^d_i <= ub_i

    So basically we just re-center the flux space at the old solution and then
    find the flux distribution closest to the new zero (center). This is the
    same strategy as used in cameo.

    In the case of linear MOMA [2]_, we instead minimize \sum_i abs(v^t_i). The
    linear MOMA is typically significantly faster. Also quadratic MOMA tends
    to give flux distributions in which all fluxes deviate from the reference
    fluxes a little bit whereas linear MOMA tends to give flux distributions
    where the majority of fluxes are the same reference with few fluxes
    deviating a lot (typical effect of L2 norm vs L1 norm).

    The former objective function is saved in the optlang solver interface as
    ``"moma_old_objective"`` and this can be used to immediately extract the
    value of the former objective after MOMA optimization.

    See Also
    --------
    pfba : parsimonious FBA

    References
    ----------
    .. [1] Segrè, Daniel, Dennis Vitkup, and George M. Church. “Analysis of
           Optimality in Natural and Perturbed Metabolic Networks.”
           Proceedings of the National Academy of Sciences 99, no. 23
           (November 12, 2002): 15112. https://doi.org/10.1073/pnas.232349399.
    .. [2] Becker, Scott A, Adam M Feist, Monica L Mo, Gregory Hannum,
           Bernhard Ø Palsson, and Markus J Herrgard. “Quantitative
           Prediction of Cellular Metabolism with Constraint-Based Models:
           The COBRA Toolbox.” Nature Protocols 2 (March 29, 2007): 727.


linear_coefficients = {}<EOL>reactions = model.reactions if not reactions else reactions<EOL>try:<EOL><INDENT>objective_expression = model.solver.objective.expression<EOL>coefficients = objective_expression.as_coefficients_dict()<EOL><DEDENT>except AttributeError:<EOL><INDENT>return linear_coefficients<EOL><DEDENT>for rxn in reactions:<EOL><INDENT>forward_coefficient = coefficients.get(rxn.forward_variable, <NUM_LIT:0>)<EOL>reverse_coefficient = coefficients.get(rxn.reverse_variable, <NUM_LIT:0>)<EOL>if forward_coefficient != <NUM_LIT:0>:<EOL><INDENT>if forward_coefficient == -reverse_coefficient:<EOL><INDENT>linear_coefficients[rxn] = float(forward_coefficient)<EOL><DEDENT><DEDENT><DEDENT>return linear_coefficients<EOL>

Coefficient for the reactions in a linear objective.

    Parameters
    ----------
    model : cobra model
        the model object that defined the objective
    reactions : list
        an optional list for the reactions to get the coefficients for. All
        reactions if left missing.

    Returns
    -------
    dict
        A dictionary where the key is the reaction object and the value is
        the corresponding coefficient. Empty dictionary if there are no
        linear terms in the objective.


atoms = expression.atoms(optlang.interface.Variable)<EOL>return all(a.problem is model.solver for a in atoms)<EOL>

Check whether a sympy expression references the correct variables.

    Parameters
    ----------
    model : cobra.Model
        The model in which to check for variables.
    expression : sympy.Basic
        A sympy expression.

    Returns
    -------
    boolean
        True if all referenced variables are contained in model, False
        otherwise.


def set_objective(model, value, additive=False):

interface = model.problem<EOL>reverse_value = model.solver.objective.expression<EOL>reverse_value = interface.Objective(<EOL>reverse_value, direction=model.solver.objective.direction,<EOL>sloppy=True)<EOL>if isinstance(value, dict):<EOL><INDENT>if not model.objective.is_Linear:<EOL><INDENT>raise ValueError('<STR_LIT>'<EOL>'<STR_LIT>'<EOL>'<STR_LIT>' %<EOL>type(value))<EOL><DEDENT>if not additive:<EOL><INDENT>model.solver.objective = interface.Objective(<EOL>Zero, direction=model.solver.objective.direction)<EOL><DEDENT>for reaction, coef in value.items():<EOL><INDENT>model.solver.objective.set_linear_coefficients(<EOL>{reaction.forward_variable: coef,<EOL>reaction.reverse_variable: -coef})<EOL><DEDENT><DEDENT>elif isinstance(value, (Basic, optlang.interface.Objective)):<EOL><INDENT>if isinstance(value, Basic):<EOL><INDENT>value = interface.Objective(<EOL>value, direction=model.solver.objective.direction,<EOL>sloppy=False)<EOL><DEDENT>if not _valid_atoms(model, value.expression):<EOL><INDENT>value = interface.Objective.clone(value, model=model.solver)<EOL><DEDENT>if not additive:<EOL><INDENT>model.solver.objective = value<EOL><DEDENT>else:<EOL><INDENT>model.solver.objective += value.expression<EOL><DEDENT><DEDENT>else:<EOL><INDENT>raise TypeError(<EOL>'<STR_LIT>' % (value, model.solver))<EOL><DEDENT>context = get_context(model)<EOL>if context:<EOL><INDENT>def reset():<EOL><INDENT>model.solver.objective = reverse_value<EOL>model.solver.objective.direction = reverse_value.direction<EOL><DEDENT>context(reset)<EOL><DEDENT>

Set the model objective.

    Parameters
    ----------
    model : cobra model
       The model to set the objective for
    value : model.problem.Objective,
            e.g. optlang.glpk_interface.Objective, sympy.Basic or dict

        If the model objective is linear, the value can be a new Objective
        object or a dictionary with linear coefficients where each key is a
        reaction and the element the new coefficient (float).

        If the objective is not linear and `additive` is true, only values
        of class Objective.

    additive : boolmodel.reactions.Biomass_Ecoli_core.bounds = (0.1, 0.1)
        If true, add the terms to the current objective, otherwise start with
        an empty objective.


if isinstance(interface, ModuleType):<EOL><INDENT>interface = interface.__name__<EOL><DEDENT>return re.sub(r"<STR_LIT>", "<STR_LIT>", interface)<EOL>

Give a string representation for an optlang interface.

    Parameters
    ----------
    interface : string, ModuleType
        Full name of the interface in optlang or cobra representation.
        For instance 'optlang.glpk_interface' or 'optlang-glpk'.

    Returns
    -------
    string
       The name of the interface as a string


if len(solvers) == <NUM_LIT:0>:<EOL><INDENT>raise SolverNotFound("<STR_LIT>")<EOL><DEDENT>mip_order = ["<STR_LIT>", "<STR_LIT>", "<STR_LIT>"]<EOL>lp_order = ["<STR_LIT>", "<STR_LIT>", "<STR_LIT>"]<EOL>qp_order = ["<STR_LIT>", "<STR_LIT>"]<EOL>if mip is False and qp is False:<EOL><INDENT>for solver_name in lp_order:<EOL><INDENT>if solver_name in solvers:<EOL><INDENT>return solver_name<EOL><DEDENT><DEDENT>return list(solvers)[<NUM_LIT:0>]<EOL><DEDENT>elif qp:  <EOL><INDENT>for solver_name in qp_order:<EOL><INDENT>if solver_name in solvers:<EOL><INDENT>return solver_name<EOL><DEDENT><DEDENT>raise SolverNotFound("<STR_LIT>")<EOL><DEDENT>else:<EOL><INDENT>for solver_name in mip_order:<EOL><INDENT>if solver_name in solvers:<EOL><INDENT>return solver_name<EOL><DEDENT><DEDENT><DEDENT>raise SolverNotFound("<STR_LIT>")<EOL>

Select a solver for a given optimization problem.

    Parameters
    ----------
    mip : bool
        Does the solver require mixed integer linear programming capabilities?
    qp : bool
        Does the solver require quadratic programming capabilities?

    Returns
    -------
    string
        The name of feasible solver.

    Raises
    ------
    SolverNotFound
        If no suitable solver could be found.


def choose_solver(model, solver=None, qp=False):

if solver is None:<EOL><INDENT>solver = model.problem<EOL><DEDENT>else:<EOL><INDENT>model.solver = solver<EOL><DEDENT>if qp and interface_to_str(solver) not in qp_solvers:<EOL><INDENT>solver = solvers[get_solver_name(qp=True)]<EOL><DEDENT>return solver<EOL>

Choose a solver given a solver name and model.

    This will choose a solver compatible with the model and required
    capabilities. Also respects model.solver where it can.

    Parameters
    ----------
    model : a cobra model
        The model for which to choose the solver.
    solver : str, optional
        The name of the solver to be used.
    qp : boolean, optional
        Whether the solver needs Quadratic Programming capabilities.

    Returns
    -------
    solver : an optlang solver interface
        Returns a valid solver for the problem.

    Raises
    ------
    SolverNotFound
        If no suitable solver could be found.


def add_cons_vars_to_problem(model, what, **kwargs):

context = get_context(model)<EOL>model.solver.add(what, **kwargs)<EOL>if context:<EOL><INDENT>context(partial(model.solver.remove, what))<EOL><DEDENT>

Add variables and constraints to a Model's solver object.

    Useful for variables and constraints that can not be expressed with
    reactions and lower/upper bounds. Will integrate with the Model's context
    manager in order to revert changes upon leaving the context.

    Parameters
    ----------
    model : a cobra model
       The model to which to add the variables and constraints.
    what : list or tuple of optlang variables or constraints.
       The variables or constraints to add to the model. Must be of class
       `model.problem.Variable` or
       `model.problem.Constraint`.
    **kwargs : keyword arguments
        passed to solver.add()


context = get_context(model)<EOL>model.solver.remove(what)<EOL>if context:<EOL><INDENT>context(partial(model.solver.add, what))<EOL><DEDENT>

Remove variables and constraints from a Model's solver object.

    Useful to temporarily remove variables and constraints from a Models's
    solver object.

    Parameters
    ----------
    model : a cobra model
       The model from which to remove the variables and constraints.
    what : list or tuple of optlang variables or constraints.
       The variables or constraints to remove from the model. Must be of
       class `model.problem.Variable` or
       `model.problem.Constraint`.


def add_absolute_expression(model, expression, name="<STR_LIT>", ub=None,<EOL>difference=<NUM_LIT:0>, add=True):

Components = namedtuple('<STR_LIT>', ['<STR_LIT>', '<STR_LIT>',<EOL>'<STR_LIT>'])<EOL>variable = model.problem.Variable(name, lb=<NUM_LIT:0>, ub=ub)<EOL>upper_constraint = model.problem.Constraint(expression - variable,<EOL>ub=difference,<EOL>name="<STR_LIT>" + name),<EOL>lower_constraint = model.problem.Constraint(expression + variable,<EOL>lb=difference,<EOL>name="<STR_LIT>" + name)<EOL>to_add = Components(variable, upper_constraint, lower_constraint)<EOL>if add:<EOL><INDENT>add_cons_vars_to_problem(model, to_add)<EOL><DEDENT>return to_add<EOL>

Add the absolute value of an expression to the model.

    Also defines a variable for the absolute value that can be used in other
    objectives or constraints.

    Parameters
    ----------
    model : a cobra model
       The model to which to add the absolute expression.
    expression : A sympy expression
       Must be a valid expression within the Model's solver object. The
       absolute value is applied automatically on the expression.
    name : string
       The name of the newly created variable.
    ub : positive float
       The upper bound for the variable.
    difference : positive float
        The difference between the expression and the variable.
    add : bool
        Whether to add the variable to the model at once.

    Returns
    -------
    namedtuple
        A named tuple with variable and two constraints (upper_constraint,
        lower_constraint) describing the new variable and the constraints
        that assign the absolute value of the expression to it.


def fix_objective_as_constraint(model, fraction=<NUM_LIT:1>, bound=None,<EOL>name='<STR_LIT>'):

fix_objective_name = name.format(model.objective.name)<EOL>if fix_objective_name in model.constraints:<EOL><INDENT>model.solver.remove(fix_objective_name)<EOL><DEDENT>if bound is None:<EOL><INDENT>bound = model.slim_optimize(error_value=None) * fraction<EOL><DEDENT>if model.objective.direction == '<STR_LIT>':<EOL><INDENT>ub, lb = None, bound<EOL><DEDENT>else:<EOL><INDENT>ub, lb = bound, None<EOL><DEDENT>constraint = model.problem.Constraint(<EOL>model.objective.expression,<EOL>name=fix_objective_name, ub=ub, lb=lb)<EOL>add_cons_vars_to_problem(model, constraint, sloppy=True)<EOL>return bound<EOL>

Fix current objective as an additional constraint.

    When adding constraints to a model, such as done in pFBA which
    minimizes total flux, these constraints can become too powerful,
    resulting in solutions that satisfy optimality but sacrifices too
    much for the original objective function. To avoid that, we can fix
    the current objective value as a constraint to ignore solutions that
    give a lower (or higher depending on the optimization direction)
    objective value than the original model.

    When done with the model as a context, the modification to the
    objective will be reverted when exiting that context.

    Parameters
    ----------
    model : cobra.Model
        The model to operate on
    fraction : float
        The fraction of the optimum the objective is allowed to reach.
    bound : float, None
        The bound to use instead of fraction of maximum optimal value. If
        not None, fraction is ignored.
    name : str
        Name of the objective. May contain one `{}` placeholder which is filled
        with the name of the old objective.

    Returns
    -------
        The value of the optimized objective * fraction


if status == OPTIMAL:<EOL><INDENT>return<EOL><DEDENT>elif (status in has_primals) and not raise_error:<EOL><INDENT>warn("<STR_LIT>".format(status), UserWarning)<EOL><DEDENT>elif status is None:<EOL><INDENT>raise OptimizationError(<EOL>"<STR_LIT>")<EOL><DEDENT>else:<EOL><INDENT>raise OptimizationError("<STR_LIT>".format(status))<EOL><DEDENT>

Perform standard checks on a solver's status.


status = model.solver.status<EOL>if status != OPTIMAL:<EOL><INDENT>exception_cls = OPTLANG_TO_EXCEPTIONS_DICT.get(<EOL>status, OptimizationError)<EOL>raise exception_cls("<STR_LIT>".format(message, status))<EOL><DEDENT>

Assert model solver status is optimal.

    Do nothing if model solver status is optimal, otherwise throw
    appropriate exception depending on the status.

    Parameters
    ----------
    model : cobra.Model
        The model to check the solver status for.
    message : str (optional)
        Message to for the exception if solver status was not optimal.


obj_vars = []<EOL>prob = model.problem<EOL>for met in model.metabolites:<EOL><INDENT>s_plus = prob.Variable("<STR_LIT>" + met.id, lb=<NUM_LIT:0>)<EOL>s_minus = prob.Variable("<STR_LIT>" + met.id, lb=<NUM_LIT:0>)<EOL>model.add_cons_vars([s_plus, s_minus])<EOL>model.constraints[met.id].set_linear_coefficients(<EOL>{s_plus: <NUM_LIT:1.0>, s_minus: -<NUM_LIT:1.0>})<EOL>obj_vars.append(s_plus)<EOL>obj_vars.append(s_minus)<EOL><DEDENT>model.objective = prob.Objective(Zero, sloppy=True, direction="<STR_LIT>")<EOL>model.objective.set_linear_coefficients({v: <NUM_LIT:1.0> for v in obj_vars})<EOL>

Add a new objective and variables to ensure a feasible solution.

The optimized objective will be zero for a feasible solution and otherwise
represent the distance from feasibility (please see [1]_ for more
information).

Parameters
----------
model : cobra.Model
    The model whose feasibility is to be tested.

References
----------
.. [1] Gomez, Jose A., Kai Höffner, and Paul I. Barton.
“DFBAlab: A Fast and Reliable MATLAB Code for Dynamic Flux Balance
Analysis.” BMC Bioinformatics 15, no. 1 (December 18, 2014): 409.
https://doi.org/10.1186/s12859-014-0409-8.


if type(objective_direction) is not list:<EOL><INDENT>objective_direction = [objective_direction] * len(objectives)<EOL><DEDENT>constraints = []<EOL>for rxn_id, obj_dir in zip(objectives, objective_direction):<EOL><INDENT>model.objective = model.reactions.get_by_id(rxn_id)<EOL>model.objective_direction = obj_dir<EOL>constraints.append(fix_objective_as_constraint(model))<EOL><DEDENT>return pd.Series(constraints, index=objectives)<EOL>

Successively optimize separate targets in a specific order.

For each objective, optimize the model and set the optimal value as a
constraint. Proceed in the order of the objectives given. Due to the
specific order this is called lexicographic FBA [1]_. This
procedure is useful for returning unique solutions for a set of important
fluxes. Typically this is applied to exchange fluxes.

Parameters
----------
model : cobra.Model
    The model to be optimized.
objectives : list
    A list of reactions (or objectives) in the model for which unique
    fluxes are to be determined.
objective_direction : str or list, optional
    The desired objective direction for each reaction (if a list) or the
    objective direction to use for all reactions (default maximize).

Returns
-------
optimized_fluxes : pandas.Series
    A vector containing the optimized fluxes for each of the given
    reactions in `objectives`.

References
----------
.. [1] Gomez, Jose A., Kai Höffner, and Paul I. Barton.
“DFBAlab: A Fast and Reliable MATLAB Code for Dynamic Flux Balance
Analysis.” BMC Bioinformatics 15, no. 1 (December 18, 2014): 409.
https://doi.org/10.1186/s12859-014-0409-8.


try:<EOL><INDENT>return obj._contexts[-<NUM_LIT:1>]<EOL><DEDENT>except (AttributeError, IndexError):<EOL><INDENT>pass<EOL><DEDENT>try:<EOL><INDENT>return obj._model._contexts[-<NUM_LIT:1>]<EOL><DEDENT>except (AttributeError, IndexError):<EOL><INDENT>pass<EOL><DEDENT>return None<EOL>


def wrapper(self, new_value):<EOL><INDENT>context = get_context(self)<EOL>if context:<EOL><INDENT>old_value = getattr(self, f.__name__)<EOL>if old_value == new_value:<EOL><INDENT>return<EOL><DEDENT>context(partial(f, self, old_value))<EOL><DEDENT>f(self, new_value)<EOL><DEDENT>return wrapper<EOL>

A decorator to simplify the context management of simple object
    attributes. Gets the value of the attribute prior to setting it, and stores
    a function to set the value to the old value in the HistoryManager.


Add the corresponding method to the history stack.

        Parameters
        ----------
        operation : `function`
            A function to be called at a later time


while self._history:<EOL><INDENT>entry = self._history.pop()<EOL>entry()<EOL><DEDENT>

Trigger executions for all items in the stack in reverse order


def create_stoichiometric_matrix(model, array_type='<STR_LIT>', dtype=None):

if array_type not in ('<STR_LIT>', '<STR_LIT>') and not dok_matrix:<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>if dtype is None:<EOL><INDENT>dtype = np.float64<EOL><DEDENT>array_constructor = {<EOL>'<STR_LIT>': np.zeros, '<STR_LIT>': dok_matrix, '<STR_LIT>': lil_matrix,<EOL>'<STR_LIT>': np.zeros,<EOL>}<EOL>n_metabolites = len(model.metabolites)<EOL>n_reactions = len(model.reactions)<EOL>array = array_constructor[array_type]((n_metabolites, n_reactions),<EOL>dtype=dtype)<EOL>m_ind = model.metabolites.index<EOL>r_ind = model.reactions.index<EOL>for reaction in model.reactions:<EOL><INDENT>for metabolite, stoich in iteritems(reaction.metabolites):<EOL><INDENT>array[m_ind(metabolite), r_ind(reaction)] = stoich<EOL><DEDENT><DEDENT>if array_type == '<STR_LIT>':<EOL><INDENT>metabolite_ids = [met.id for met in model.metabolites]<EOL>reaction_ids = [rxn.id for rxn in model.reactions]<EOL>return pd.DataFrame(array, index=metabolite_ids, columns=reaction_ids)<EOL><DEDENT>else:<EOL><INDENT>return array<EOL><DEDENT>

Return a stoichiometric array representation of the given model.

    The the columns represent the reactions and rows represent
    metabolites. S[i,j] therefore contains the quantity of metabolite `i`
    produced (negative for consumed) by reaction `j`.

    Parameters
    ----------
    model : cobra.Model
        The cobra model to construct the matrix for.
    array_type : string
        The type of array to construct. if 'dense', return a standard
        numpy.array, 'dok', or 'lil' will construct a sparse array using
        scipy of the corresponding type and 'DataFrame' will give a
        pandas `DataFrame` with metabolite indices and reaction columns
    dtype : data-type
        The desired data-type for the array. If not given, defaults to float.

    Returns
    -------
    matrix of class `dtype`
        The stoichiometric matrix for the given model.


def nullspace(A, atol=<NUM_LIT>, rtol=<NUM_LIT:0>):

A = np.atleast_2d(A)<EOL>u, s, vh = np.linalg.svd(A)<EOL>tol = max(atol, rtol * s[<NUM_LIT:0>])<EOL>nnz = (s >= tol).sum()<EOL>ns = vh[nnz:].conj().T<EOL>return ns<EOL>

Compute an approximate basis for the nullspace of A.
    The algorithm used by this function is based on the singular value
    decomposition of `A`.

    Parameters
    ----------
    A : numpy.ndarray
        A should be at most 2-D.  A 1-D array with length k will be treated
        as a 2-D with shape (1, k)
    atol : float
        The absolute tolerance for a zero singular value.  Singular values
        smaller than `atol` are considered to be zero.
    rtol : float
        The relative tolerance.  Singular values less than rtol*smax are
        considered to be zero, where smax is the largest singular value.

    If both `atol` and `rtol` are positive, the combined tolerance is the
    maximum of the two; that is::
    tol = max(atol, rtol * smax)
    Singular values smaller than `tol` are considered to be zero.

    Returns
    -------
    numpy.ndarray
        If `A` is an array with shape (m, k), then `ns` will be an array
        with shape (k, n), where n is the estimated dimension of the
        nullspace of `A`.  The columns of `ns` are a basis for the
        nullspace; each element in numpy.dot(A, ns) will be approximately
        zero.

    Notes
    -----
    Taken from the numpy cookbook.


def constraint_matrices(model, array_type='<STR_LIT>', include_vars=False,<EOL>zero_tol=<NUM_LIT>):

if array_type not in ('<STR_LIT>', '<STR_LIT>') and not dok_matrix:<EOL><INDENT>raise ValueError('<STR_LIT>')<EOL><DEDENT>array_builder = {<EOL>'<STR_LIT>': np.array, '<STR_LIT>': dok_matrix, '<STR_LIT>': lil_matrix,<EOL>'<STR_LIT>': pd.DataFrame,<EOL>}[array_type]<EOL>Problem = namedtuple("<STR_LIT>",<EOL>["<STR_LIT>", "<STR_LIT:b>", "<STR_LIT>", "<STR_LIT>",<EOL>"<STR_LIT>", "<STR_LIT>"])<EOL>equality_rows = []<EOL>inequality_rows = []<EOL>inequality_bounds = []<EOL>b = []<EOL>for const in model.constraints:<EOL><INDENT>lb = -np.inf if const.lb is None else const.lb<EOL>ub = np.inf if const.ub is None else const.ub<EOL>equality = (ub - lb) < zero_tol<EOL>coefs = const.get_linear_coefficients(model.variables)<EOL>coefs = [coefs[v] for v in model.variables]<EOL>if equality:<EOL><INDENT>b.append(lb if abs(lb) > zero_tol else <NUM_LIT:0.0>)<EOL>equality_rows.append(coefs)<EOL><DEDENT>else:<EOL><INDENT>inequality_rows.append(coefs)<EOL>inequality_bounds.append([lb, ub])<EOL><DEDENT><DEDENT>var_bounds = np.array([[v.lb, v.ub] for v in model.variables])<EOL>fixed = var_bounds[:, <NUM_LIT:1>] - var_bounds[:, <NUM_LIT:0>] < zero_tol<EOL>results = Problem(<EOL>equalities=array_builder(equality_rows),<EOL>b=np.array(b),<EOL>inequalities=array_builder(inequality_rows),<EOL>bounds=array_builder(inequality_bounds),<EOL>variable_fixed=np.array(fixed),<EOL>variable_bounds=array_builder(var_bounds))<EOL>return results<EOL>

Create a matrix representation of the problem.

    This is used for alternative solution approaches that do not use optlang.
    The function will construct the equality matrix, inequality matrix and
    bounds for the complete problem.

    Notes
    -----
    To accomodate non-zero equalities the problem will add the variable
    "const_one" which is a variable that equals one.

    Arguments
    ---------
    model : cobra.Model
        The model from which to obtain the LP problem.
    array_type : string
        The type of array to construct. if 'dense', return a standard
        numpy.array, 'dok', or 'lil' will construct a sparse array using
        scipy of the corresponding type and 'DataFrame' will give a
        pandas `DataFrame` with metabolite indices and reaction columns.
    zero_tol : float
        The zero tolerance used to judge whether two bounds are the same.

    Returns
    -------
    collections.namedtuple
        A named tuple consisting of 6 matrices and 2 vectors:
        - "equalities" is a matrix S such that S*vars = b. It includes a row
          for each constraint and one column for each variable.
        - "b" the right side of the equality equation such that S*vars = b.
        - "inequalities" is a matrix M such that lb <= M*vars <= ub.
          It contains a row for each inequality and as many columns as
          variables.
        - "bounds" is a compound matrix [lb ub] containing the lower and
          upper bounds for the inequality constraints in M.
        - "variable_fixed" is a boolean vector indicating whether the variable
          at that index is fixed (lower bound == upper_bound) and
          is thus bounded by an equality constraint.
        - "variable_bounds" is a compound matrix [lb ub] containing the
          lower and upper bounds for all variables.


coefs = {}<EOL>for rxn in find_boundary_types(model, "<STR_LIT>"):<EOL><INDENT>export = len(rxn.reactants) == <NUM_LIT:1><EOL>if export:<EOL><INDENT>coefs[rxn.reverse_variable] = <NUM_LIT:1><EOL><DEDENT>else:<EOL><INDENT>coefs[rxn.forward_variable] = <NUM_LIT:1><EOL><DEDENT><DEDENT>model.objective.set_linear_coefficients(coefs)<EOL>model.objective.direction = "<STR_LIT>"<EOL>

Add a linear version of a minimal medium to the model solver.

    Changes the optimization objective to finding the growth medium requiring
    the smallest total import flux::

        minimize sum |r_i| for r_i in import_reactions

    Arguments
    ---------
    model : cobra.Model
        The model to modify.


if len(model.variables) > <NUM_LIT>:<EOL><INDENT>LOGGER.warning("<STR_LIT>"<EOL>"<STR_LIT>")<EOL><DEDENT>exchange_rxns = find_boundary_types(model, "<STR_LIT>")<EOL>big_m = max(abs(b) for r in exchange_rxns for b in r.bounds)<EOL>prob = model.problem<EOL>coefs = {}<EOL>to_add = []<EOL>for rxn in exchange_rxns:<EOL><INDENT>export = len(rxn.reactants) == <NUM_LIT:1><EOL>indicator = prob.Variable("<STR_LIT>" + rxn.id, lb=<NUM_LIT:0>, ub=<NUM_LIT:1>, type="<STR_LIT>")<EOL>if export:<EOL><INDENT>vrv = rxn.reverse_variable<EOL>indicator_const = prob.Constraint(<EOL>vrv - indicator * big_m, ub=<NUM_LIT:0>, name="<STR_LIT>" + rxn.id)<EOL><DEDENT>else:<EOL><INDENT>vfw = rxn.forward_variable<EOL>indicator_const = prob.Constraint(<EOL>vfw - indicator * big_m, ub=<NUM_LIT:0>, name="<STR_LIT>" + rxn.id)<EOL><DEDENT>to_add.extend([indicator, indicator_const])<EOL>coefs[indicator] = <NUM_LIT:1><EOL><DEDENT>model.add_cons_vars(to_add)<EOL>model.solver.update()<EOL>model.objective.set_linear_coefficients(coefs)<EOL>model.objective.direction = "<STR_LIT>"<EOL>

Add a mixed-integer version of a minimal medium to the model.

    Changes the optimization objective to finding the medium with the least
    components::

        minimize size(R) where R part of import_reactions

    Arguments
    ---------
    model : cobra.model
        The model to modify.


def _as_medium(exchanges, tolerance=<NUM_LIT>, exports=False):

LOGGER.debug("<STR_LIT>")<EOL>medium = pd.Series()<EOL>for rxn in exchanges:<EOL><INDENT>export = len(rxn.reactants) == <NUM_LIT:1><EOL>flux = rxn.flux<EOL>if abs(flux) < tolerance:<EOL><INDENT>continue<EOL><DEDENT>if export:<EOL><INDENT>medium[rxn.id] = -flux<EOL><DEDENT>elif not export:<EOL><INDENT>medium[rxn.id] = flux<EOL><DEDENT><DEDENT>if not exports:<EOL><INDENT>medium = medium[medium > <NUM_LIT:0>]<EOL><DEDENT>return medium<EOL>

Convert a solution to medium.

    Arguments
    ---------
    exchanges : list of cobra.reaction
        The exchange reactions to consider.
    tolerance : positive double
        The absolute tolerance for fluxes. Fluxes with an absolute value
        smaller than this number will be ignored.
    exports : bool
        Whether to return export fluxes as well.

    Returns
    -------
    pandas.Series
        The "medium", meaning all active import fluxes in the solution.


def minimal_medium(model, min_objective_value=<NUM_LIT:0.1>, exports=False,<EOL>minimize_components=False, open_exchanges=False):

exchange_rxns = find_boundary_types(model, "<STR_LIT>")<EOL>if isinstance(open_exchanges, bool):<EOL><INDENT>open_bound = <NUM_LIT:1000><EOL><DEDENT>else:<EOL><INDENT>open_bound = open_exchanges<EOL><DEDENT>with model as mod:<EOL><INDENT>if open_exchanges:<EOL><INDENT>LOGGER.debug("<STR_LIT>",<EOL>len(exchange_rxns))<EOL>for rxn in exchange_rxns:<EOL><INDENT>rxn.bounds = (-open_bound, open_bound)<EOL><DEDENT><DEDENT>LOGGER.debug("<STR_LIT>")<EOL>obj_const = mod.problem.Constraint(<EOL>mod.objective.expression, lb=min_objective_value,<EOL>name="<STR_LIT>")<EOL>mod.add_cons_vars([obj_const])<EOL>mod.solver.update()<EOL>mod.objective = Zero<EOL>LOGGER.debug("<STR_LIT>")<EOL>tol = mod.solver.configuration.tolerances.feasibility<EOL>if minimize_components:<EOL><INDENT>add_mip_obj(mod)<EOL>if isinstance(minimize_components, bool):<EOL><INDENT>minimize_components = <NUM_LIT:1><EOL><DEDENT>seen = set()<EOL>best = num_components = mod.slim_optimize()<EOL>if mod.solver.status != OPTIMAL:<EOL><INDENT>LOGGER.warning("<STR_LIT>")<EOL>return None<EOL><DEDENT>exclusion = mod.problem.Constraint(Zero, ub=<NUM_LIT:0>)<EOL>mod.add_cons_vars([exclusion])<EOL>mod.solver.update()<EOL>media = []<EOL>for i in range(minimize_components):<EOL><INDENT>LOGGER.info("<STR_LIT>", (i + <NUM_LIT:1>))<EOL>vars = [mod.variables["<STR_LIT>" + s] for s in seen]<EOL>if len(seen) > <NUM_LIT:0>:<EOL><INDENT>exclusion.set_linear_coefficients(<EOL>dict.fromkeys(vars, <NUM_LIT:1>))<EOL>exclusion.ub = best - <NUM_LIT:1><EOL><DEDENT>num_components = mod.slim_optimize()<EOL>if mod.solver.status != OPTIMAL or num_components > best:<EOL><INDENT>break<EOL><DEDENT>medium = _as_medium(exchange_rxns, tol, exports=exports)<EOL>media.append(medium)<EOL>seen.update(medium[medium > <NUM_LIT:0>].index)<EOL><DEDENT>if len(media) > <NUM_LIT:1>:<EOL><INDENT>medium = pd.concat(media, axis=<NUM_LIT:1>, sort=True).fillna(<NUM_LIT:0.0>)<EOL>medium.sort_index(axis=<NUM_LIT:1>, inplace=True)<EOL><DEDENT>else:<EOL><INDENT>medium = media[<NUM_LIT:0>]<EOL><DEDENT><DEDENT>else:<EOL><INDENT>add_linear_obj(mod)<EOL>mod.slim_optimize()<EOL>if mod.solver.status != OPTIMAL:<EOL><INDENT>LOGGER.warning("<STR_LIT>")<EOL>return None<EOL><DEDENT>medium = _as_medium(exchange_rxns, tol, exports=exports)<EOL><DEDENT><DEDENT>return medium<EOL>

Find the minimal growth medium for the model.

Finds the minimal growth medium for the model which allows for
model as well as individual growth. Here, a minimal medium can either
be the medium requiring the smallest total import flux or the medium
requiring the least components (ergo ingredients), which will be much
slower due to being a mixed integer problem (MIP).

Arguments
---------
model : cobra.model
    The model to modify.
min_objective_value : positive float or array-like object
    The minimum growth rate (objective) that has to be achieved.
exports : boolean
    Whether to include export fluxes in the returned medium. Defaults to
    False which will only return import fluxes.
minimize_components : boolean or positive int
    Whether to minimize the number of components instead of the total
    import flux. Might be more intuitive if set to True but may also be
    slow to calculate for large communities. If set to a number `n` will
    return up to `n` alternative solutions all with the same number of
    components.
open_exchanges : boolean or number
    Whether to ignore currently set bounds and make all exchange reactions
    in the model possible. If set to a number all exchange reactions will
    be opened with (-number, number) as bounds.

Returns
-------
pandas.Series, pandas.DataFrame or None
    A series giving the import flux for each required import
    reaction and (optionally) the associated export fluxes. All exchange
    fluxes are oriented into the import reaction e.g. positive fluxes
    denote imports and negative fluxes exports. If `minimize_components`
    is a number larger 1 may return a DataFrame where each column is a
    minimal medium. Returns None if the minimization is infeasible
    (for instance if min_growth > maximum growth rate).

Notes
-----
Due to numerical issues the `minimize_components` option will usually only
minimize the number of "large" import fluxes. Specifically, the detection
limit is given by ``integrality_tolerance * max_bound`` where ``max_bound``
is the largest bound on an import reaction. Thus, if you are interested
in small import fluxes as well you may have to adjust the integrality
tolerance at first with
`model.solver.configuration.tolerances.integrality = 1e-7` for instance.
However, this will be *very* slow for large models especially with GLPK.


if model.boundary:<EOL><INDENT>counts = pd.Series(tuple(r.compartments)[<NUM_LIT:0>] for r in model.boundary)<EOL>most = counts.value_counts()<EOL>most = most.index[most == most.max()].to_series()<EOL><DEDENT>else:<EOL><INDENT>most = None<EOL><DEDENT>like_external = compartment_shortlist["<STR_LIT:e>"] + ["<STR_LIT:e>"]<EOL>matches = pd.Series([co in like_external for co in model.compartments],<EOL>index=model.compartments)<EOL>if matches.sum() == <NUM_LIT:1>:<EOL><INDENT>compartment = matches.index[matches][<NUM_LIT:0>]<EOL>LOGGER.info("<STR_LIT>"<EOL>"<STR_LIT>" %<EOL>compartment)<EOL>return compartment<EOL><DEDENT>elif most is not None and matches.sum() > <NUM_LIT:1> and matches[most].sum() == <NUM_LIT:1>:<EOL><INDENT>compartment = most[matches[most]][<NUM_LIT:0>]<EOL>LOGGER.warning("<STR_LIT>"<EOL>"<STR_LIT>"<EOL>"<STR_LIT>"<EOL>"<STR_LIT>" % compartment)<EOL>return compartment<EOL><DEDENT>elif matches.sum() > <NUM_LIT:1>:<EOL><INDENT>raise RuntimeError("<STR_LIT>"<EOL>"<STR_LIT>"<EOL>"<STR_LIT>"<EOL>"<STR_LIT>")<EOL><DEDENT>if most is not None:<EOL><INDENT>return most[<NUM_LIT:0>]<EOL>LOGGER.warning("<STR_LIT>"<EOL>"<STR_LIT>"<EOL>"<STR_LIT>"<EOL>"<STR_LIT>"<EOL>"<STR_LIT>")<EOL><DEDENT>raise RuntimeError("<STR_LIT>"<EOL>"<STR_LIT>"<EOL>"<STR_LIT>"<EOL>"<STR_LIT>")<EOL>

Find the external compartment in the model.

    Uses a simple heuristic where the external compartment should be the one
    with the most exchange reactions.

    Arguments
    ---------
    model : cobra.Model
        A cobra model.

    Returns
    -------
    str
        The putative external compartment.


def is_boundary_type(reaction, boundary_type, external_compartment):

<EOL>sbo_term = reaction.annotation.get("<STR_LIT>", "<STR_LIT>")<EOL>if isinstance(sbo_term, list):<EOL><INDENT>sbo_term = sbo_term[<NUM_LIT:0>]<EOL><DEDENT>sbo_term = sbo_term.upper()<EOL>if sbo_term == sbo_terms[boundary_type]:<EOL><INDENT>return True<EOL><DEDENT>if sbo_term in [sbo_terms[k] for k in sbo_terms if k != boundary_type]:<EOL><INDENT>return False<EOL><DEDENT>correct_compartment = external_compartment in reaction.compartments<EOL>if boundary_type != "<STR_LIT>":<EOL><INDENT>correct_compartment = not correct_compartment<EOL><DEDENT>rev_type = True<EOL>if boundary_type == "<STR_LIT>":<EOL><INDENT>rev_type = not reaction.reversibility<EOL><DEDENT>elif boundary_type == "<STR_LIT>":<EOL><INDENT>rev_type = reaction.reversibility<EOL><DEDENT>return (reaction.boundary and not<EOL>any(ex in reaction.id for ex in excludes[boundary_type]) and<EOL>correct_compartment and rev_type)<EOL>

Check whether a reaction is an exchange reaction.

    Arguments
    ---------
    reaction : cobra.Reaction
        The reaction to check.
    boundary_type : str
        What boundary type to check for. Must be one of
        "exchange", "demand", or "sink".
    external_compartment : str
        The id for the external compartment.

    Returns
    -------
    boolean
        Whether the reaction looks like the requested type. Might be based
        on a heuristic.


def find_boundary_types(model, boundary_type, external_compartment=None):

if not model.boundary:<EOL><INDENT>LOGGER.warning("<STR_LIT>"<EOL>"<STR_LIT>"<EOL>"<STR_LIT>"<EOL>"<STR_LIT>")<EOL>return []<EOL><DEDENT>if external_compartment is None:<EOL><INDENT>external_compartment = find_external_compartment(model)<EOL><DEDENT>return model.reactions.query(<EOL>lambda r: is_boundary_type(r, boundary_type, external_compartment))<EOL>

Find specific boundary reactions.

    Arguments
    ---------
    model : cobra.Model
        A cobra model.
    boundary_type : str
        What boundary type to check for. Must be one of
        "exchange", "demand", or "sink".
    external_compartment : str or None
        The id for the external compartment. If None it will be detected
        automatically.

    Returns
    -------
    list of cobra.reaction
        A list of likely boundary reactions of a user defined type.


for c in ("<STR_LIT:'>", '<STR_LIT:">'):<EOL><INDENT>if id_str.startswith(c) and id_str.endswith(c)and id_str.count(c) == <NUM_LIT:2>:<EOL><INDENT>id_str = id_str.strip(c)<EOL><DEDENT><DEDENT>for char, escaped_char in _renames:<EOL><INDENT>id_str = id_str.replace(char, escaped_char)<EOL><DEDENT>return id_str<EOL>


for x in chain([cobra_model],<EOL>cobra_model.metabolites,<EOL>cobra_model.reactions,<EOL>cobra_model.genes):<EOL><INDENT>x.id = _escape_str_id(x.id)<EOL><DEDENT>cobra_model.repair()<EOL>gene_renamer = _GeneEscaper()<EOL>for rxn, rule in iteritems(get_compiled_gene_reaction_rules(cobra_model)):<EOL><INDENT>if rule is not None:<EOL><INDENT>rxn._gene_reaction_rule = ast2str(gene_renamer.visit(rule))<EOL><DEDENT><DEDENT>


recompute_reactions = set()  <EOL>remove_genes = []<EOL>for old_name, new_name in iteritems(rename_dict):<EOL><INDENT>try:<EOL><INDENT>gene_index = cobra_model.genes.index(old_name)<EOL><DEDENT>except ValueError:<EOL><INDENT>gene_index = None<EOL><DEDENT>old_gene_present = gene_index is not None<EOL>new_gene_present = new_name in cobra_model.genes<EOL>if old_gene_present and new_gene_present:<EOL><INDENT>old_gene = cobra_model.genes.get_by_id(old_name)<EOL>if old_gene is not cobra_model.genes.get_by_id(new_name):<EOL><INDENT>remove_genes.append(old_gene)<EOL>recompute_reactions.update(old_gene._reaction)<EOL><DEDENT><DEDENT>elif old_gene_present and not new_gene_present:<EOL><INDENT>gene = cobra_model.genes[gene_index]<EOL>cobra_model.genes._dict.pop(gene.id)  <EOL>gene.id = new_name<EOL>cobra_model.genes[gene_index] = gene<EOL><DEDENT>elif not old_gene_present and new_gene_present:<EOL><INDENT>pass<EOL><DEDENT>else:  <EOL><INDENT>pass<EOL><DEDENT><DEDENT>cobra_model.repair()<EOL>class Renamer(NodeTransformer):<EOL><INDENT>def visit_Name(self, node):<EOL><INDENT>node.id = rename_dict.get(node.id, node.id)<EOL>return node<EOL><DEDENT><DEDENT>gene_renamer = Renamer()<EOL>for rxn, rule in iteritems(get_compiled_gene_reaction_rules(cobra_model)):<EOL><INDENT>if rule is not None:<EOL><INDENT>rxn._gene_reaction_rule = ast2str(gene_renamer.visit(rule))<EOL><DEDENT><DEDENT>for rxn in recompute_reactions:<EOL><INDENT>rxn.gene_reaction_rule = rxn._gene_reaction_rule<EOL><DEDENT>for i in remove_genes:<EOL><INDENT>cobra_model.genes.remove(i)<EOL><DEDENT>

renames genes in a model from the rename_dict