<jupyter_start><jupyter_text>Solving M Models without Loops A type III loop is a cycle with no exchange of metabolites. Therefore, type III loops do not have flux through exchange, demand and biomass reactions, which exchange mass with the system. If flux flows through a type III loop, it has no thermodynamic driving force, which is not realistic. As long as the reaction bounds do not force flux through any reactions in the loop, a solution with flux through a loop can be collapsed into a solution without it which still allows flux through the biomass.Proof: Take the following model, where all fluxes are positive or zero (conversion of a model with negative fluxes to this form is trivial), with a flux solution $v$. All exchange, demand, and biomass, reactions (which by definition can not be a part of a loop) are denoted with $_i$ subscripts, while all others are denoted with $_j$.$$ \mathbf S \cdot v = 0$$$$ ub \ge v \ge 0 $$$$ ub_i \ge v_i \ge lb_i $$Let $v_L$ be any flux loop within $v$. Because exchange, demand, and biomass can not be in the loop, we have the following:$$v_{L,i} = 0 $$By definition, no metabolites are exchanged, so$$ \mathbf S \cdot v_L = 0 $$$$ \mathbf S \cdot (v - v_L) = 0 $$Because $v_L$ is a loop within $v$, the following are true:$$ ub \ge v \ge v_L \ge 0 $$$$ ub \ge v - v_L \ \ge 0 $$$\therefore$ $\forall v$ and $\forall v_L$ within it, $v - v_L$ is also a valid solution which will produce biomass flux. This proof does not apply to models where flux is forced through a reaction (i.e. where the lower bound is greater than 0). To optain a flux state with no flux through thermodynamically infeasible loops for all models, loopless FBA was developed by [Schellenberger et al.](http://dx.doi.org/10.1016/j.bpj.2010.12.3707) To compute this for all of these correctly parsed-models, we use the loopless FBA [implementation](http://cobrapy.readthedocs.org/en/latest/loopless.html) in [cobrapy](http://opencobra.github.io/cobrapy/) (version 0.4.0b1 or later) and the [gurobi](http://www.gurobi.com) solver (version 6.0). Because loopless FBA is an MILP, it is not guarenteed to find the optimum, but for every model we are able to find a feasible loopless solution with the algorithm.<jupyter_code>import os

import pandas

import cobra

pandas.set_option("display.max_rows", 100)<jupyter_output><empty_output><jupyter_text>Load in the models, as parsed by this [script](load_models.ipynb). We will also break up all reversible reactions into the model into two irreversible reactions in opposite directions.<jupyter_code>models = cobra.DictList()
for filename in sorted(os.listdir("sbml3")):
    if not filename.endswith(".xml"):
        continue
    models.append(cobra.io.read_sbml_model(os.path.join("sbml3", filename)))<jupyter_output><empty_output><jupyter_text>Construct the loopless models, which impose additional constraints which prevent flux from going around one of these loops.<jupyter_code>loopless_models = cobra.DictList((cobra.flux_analysis.construct_loopless_model(m) for m in models))<jupyter_output><empty_output><jupyter_text>Solve the models using gurobi, allowing the branch-and-bound solver to proceed for two minutes.<jupyter_code>loopless_solutions = {}
for loopless_model in loopless_models:
    solution = loopless_model.optimize(solver="gurobi", time_limit=120)
    loopless_solutions[loopless_model.id] = solution<jupyter_output><empty_output><jupyter_text>Constrain the models based the loopless result. Only reactions which carry flux in the loopless solution will be allowed to carry flux.<jupyter_code>constrained_loopless_models = cobra.DictList()
for model, loopless_model in zip(models, loopless_models):
    constrained = model.copy()
    constrained_loopless_models.append(constrained)
    for reaction in constrained.reactions:
        loopless_flux = loopless_model.reactions.get_by_id(reaction.id).x
        reaction.upper_bound = min(reaction.upper_bound, loopless_flux + 1e-6)<jupyter_output><empty_output><jupyter_text>Solve these problems which are constrained to be loopless exactly.<jupyter_code>loopless_exact_solutions = {
    model.id: model.optimize(solver="esolver", rational_solution=True)
    for model in constrained_loopless_models}<jupyter_output><empty_output><jupyter_text>Format the results as a table. This demonstrates these models have a feasible flux state which produce biomass without using these loops, and this loopless flux state can also be solved using exact arithmetic.<jupyter_code>results = pandas.DataFrame.from_dict(
    {model.id: {"loopless": loopless_solutions[model.id].f,
                "FBA": model.optimize().f,
                "constrained looples exact": str(loopless_exact_solutions[model.id].f)}
     for model in models},
    orient="index")
results<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.08701973001038421, 'fraction_numerical': 0.008307372793354102, 'mean_word_length': 5.02, 'pattern_counts': {'":': 3, '<': 29, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 1, 'xml': 1}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '7', 'dir': 'jupyter-structured-clean-dedup', 'id': '500983', 'license': 'CC0-1.0', 'n_tokens_mistral': 1489, 'n_tokens_neox': 1390, 'n_words': 548, 'path': 'loopless_m_models.ipynb', 'repo_name': 'aebrahim/m_model_collection', 'size': '4815'}