예제 #1
0
def test_gapfilling(salmonella):
    """Test Gapfilling."""
    m = Model()
    m.add_metabolites([Metabolite(m_id) for m_id in ["a", "b", "c"]])
    exa = Reaction("EX_a")
    exa.add_metabolites({m.metabolites.a: 1})
    b2c = Reaction("b2c")
    b2c.add_metabolites({m.metabolites.b: -1, m.metabolites.c: 1})
    dmc = Reaction("DM_c")
    dmc.add_metabolites({m.metabolites.c: -1})
    m.add_reactions([exa, b2c, dmc])
    m.objective = 'DM_c'

    universal = Model()
    a2b = Reaction("a2b")
    a2d = Reaction("a2d")
    universal.add_reactions([a2b, a2d])
    a2b.build_reaction_from_string("a --> b", verbose=False)
    a2d.build_reaction_from_string("a --> d", verbose=False)

    # # GrowMatch
    # result = gapfilling.growMatch(m, universal)[0]
    result = gapfill(m, universal)[0]
    assert len(result) == 1
    assert result[0].id == "a2b"

    # # SMILEY
    # result = gapfilling.SMILEY(m, "b", universal)[0]
    with m:
        m.objective = m.add_boundary(m.metabolites.b, type='demand')
        result = gapfill(m, universal)[0]
        assert len(result) == 1
        assert result[0].id == "a2b"

    # # 2 rounds of GrowMatch with exchange reactions
    # result = gapfilling.growMatch(m, None, ex_rxns=True, iterations=2)
    result = gapfill(m, None, exchange_reactions=True, iterations=2)
    assert len(result) == 2
    assert len(result[0]) == 1
    assert len(result[1]) == 1
    assert {i[0].id for i in result} == {"EX_b", "EX_c"}

    # somewhat bigger model
    universal = Model("universal_reactions")
    with salmonella as model:
        for i in [i.id for i in model.metabolites.f6p_c.reactions]:
            reaction = model.reactions.get_by_id(i)
            universal.add_reactions([reaction.copy()])
            model.remove_reactions([reaction])
        gf = GapFiller(model,
                       universal,
                       penalties={'TKT2': 1e3},
                       demand_reactions=False)
        solution = gf.fill()
        assert 'TKT2' not in {r.id for r in solution[0]}
        assert gf.validate(solution[0])
예제 #2
0
파일: expand.py 프로젝트: opencobra/Medusa
def _integer_iterative_binary_gapfill(model,
                                      phenotype_dict,
                                      cycle_order,
                                      universal=None,
                                      output_ensemble_size=0,
                                      lower_bound=0.05,
                                      penalties=False,
                                      demand_reactions=False,
                                      exchange_reactions=False,
                                      integer_threshold=1E-6):

    gapfiller = GapFiller(model,
                          universal=universal,
                          lower_bound=lower_bound,
                          penalties=penalties,
                          demand_reactions=demand_reactions,
                          exchange_reactions=exchange_reactions,
                          integer_threshold=integer_threshold)
    original_costs = gapfiller.costs

    solutions = []
    for cycle_num in range(0, output_ensemble_size):
        print("starting cycle number " + str(cycle_num))
        cycle_reactions = set()
        for condition in cycle_order[cycle_num]:
            gapfiller.model.medium = phenotype_dict[condition]
            # gapfill and get the solution. The 0 index is necessary because
            # gapfill will return a list of lists; we are only taking the
            # first (and only) list here.
            gapfilled_reactions = gapfiller.fill()[0]
            cycle_reactions = cycle_reactions | set(gapfilled_reactions)
            # iterate through indicators, find those corresponding to the
            # gapfilled reactions from any iteration within this cycle, and
            # reset their cost to 0. Doing this for all reactions from any
            # iteration within the cycle is necessary because cobrapy's
            # gapfill function performs update_costs, which will reset costs
            # and iteratively increase them; without this manual override
            # performed here, costs for previous conditions within a cycle
            # would revert to 1 instead of the desired 0
            for reaction_indicator in [
                    indicator for indicator in gapfiller.indicators
            ]:
                if reaction_indicator.rxn_id in cycle_reactions:
                    gapfiller.costs[reaction_indicator] = 0
            gapfiller.model.objective.set_linear_coefficients(gapfiller.costs)
        solutions.append(list(cycle_reactions))
        gapfiller.model.objective.set_linear_coefficients(original_costs)
    return solutions
예제 #3
0
def checkProduction(model, metabolite):
    #modtmp = set_medium(model, minmed)
    modtmp = model.copy()
    #print modtmp.medium
    #print refmod.metabolites.get_by_id("atp[c]").reactions
    #refmod.reactions.rxn05115.upper_bound=1000
    #modnew.add_reactions([refmod.reactions.rxn00533])

    newM = []
    for m in refmod.metabolites:
        if m not in modtmp.metabolites:
            newM.append(m.copy())
    modtmp.add_metabolites(newM)

    m = modtmp.metabolites.get_by_id(metabolite)
    modtmp.objective = modtmp.add_boundary(m, type='demand')
    sol = modtmp.slim_optimize()
    if round(sol, 12) > 0:
        print m.id, m.name, "can be produced:", sol
    else:
        print m.id, m.name, "CANNOT be produced:", sol
        print "\t --> try to find reactions for gapfilling"
        #print gapfill(modtmp, refmod)
        filler = GapFiller(modtmp, refmod, integer_threshold=1e-32).fill()
        print filler
        for r in filler[0]:
            print "\t", r.id, r.reaction
        return filler
예제 #4
0
파일: gapfill.py 프로젝트: maringos/gapseq
def checkReaction(model, reaction, direction=1):
    modtmp = set_medium(model, minmed)
    rea = modtmp.reactions.get_by_id(reaction)

    modtmp.objective = {rea:direction}
    sol = modtmp.optimize()
    if round(sol.objective_value ,12) > 0:
        print rea.id, rea.name, "can be used:", sol.objective_value
        print "\t Carbon source usage", carbon, sol.fluxes[carbon]
        return sol
    else:
        print rea.id, rea.name, "CANNOT be used:", sol.objective_value
        print "\t --> try to find reactions for gapfilling"
        try:
            gapsol = GapFiller(modtmp, refmod, demand_reactions=False).fill()
        except RuntimeError:
            print "\t => Runtime error: lowering the integer_threshold?"
            return
        except:
            print "\t => failed:", sys.exc_info()[0]
            return
        if len(gapsol[0]) > 0:
            print "\t => could be fixed:", ",".join([r.id for r in gapsol[0]])
            model.add_reactions([r for r in gapsol[0] if r not in model.reactions])
            print "\t Carbon source usage", carbon, sol.fluxes[carbon]
예제 #5
0
    def test_optimization(self):

        model = cobra.io.read_sbml_model("../models/enhanced_model_ecoli.xml")

        gapfiller = GapFiller(model,
                              Model(),
                              demand_reactions=True,
                              exchange_reactions=True,
                              integer_threshold=1e-300)

        solution = gapfiller.fill(iterations=1)
        print(solution)
        model.add_reactions(solution[0])

        print(model.optimize().objective_value)

        cobra.io.write_sbml_model(model, "enhanced_model_ecoli2.xml")
        cobra.io.save_json_model(model, "enhanced_model_ecoli.json")
예제 #6
0
파일: gapfill.py 프로젝트: maringos/gapseq
def checkProduction(model, metabolite, fill=True, addMets=False):
    modtmp = set_medium(model, minmed, verbose=False)
    
    if addMets:
        newM = []
        for m in refmod.metabolites:
            if m not in modtmp.metabolites:
                newM.append(m.copy())
        modtmp.add_metabolites(newM)
    
    rea1 = Reaction("Refresh_ATP", lower_bound=0, upper_bound=1000)
    rea1.add_metabolites({modtmp.metabolites.cpd00002_c0:-1, modtmp.metabolites.cpd00001_c0:-1, modtmp.metabolites.cpd00008_c0:1,modtmp.metabolites.cpd00009_c0:1, modtmp.metabolites.cpd00067_c0:1})
    modtmp.add_reaction(rea1)

    rea2 = Reaction("Refresh_NADH", lower_bound=0, upper_bound=1000)
    rea2.add_metabolites({modtmp.metabolites.cpd00004_c0:-1, modtmp.metabolites.cpd00067_c0:1, modtmp.metabolites.cpd00003_c0:1})
    modtmp.add_reaction(rea2)
    
    rea3 = Reaction("Refresh_NADPH", lower_bound=0, upper_bound=1000)
    rea3.add_metabolites({modtmp.metabolites.cpd00005_c0:-1, modtmp.metabolites.cpd00067_c0:1, modtmp.metabolites.cpd00006_c0:1})
    modtmp.add_reaction(rea3)

    modtmp.add_boundary(modtmp.metabolites.cpd00012_c0, type='demand') # ppi
    modtmp.add_boundary(modtmp.metabolites.cpd00009_c0, type='demand') # pi
    modtmp.add_boundary(modtmp.metabolites.cpd00067_c0, type='demand') # h+

    #modtmp.add_boundary(modtmp.metabolites.cpd00010_c0, type='exchange', lb=-1000)

    #rea4 = Reaction("Refresh_Pi", lower_bound=0, upper_bound=1000)
    #rea4.add_metabolites({modtmp.metabolites.cpd00009_c0:-1})
    #modtmp.add_reaction(rea4)


    m = modtmp.metabolites.get_by_id(metabolite)
    modtmp.objective = modtmp.add_boundary(m, type='demand')
    #sol = modtmp.slim_optimize()
    sol = modtmp.optimize()
    if round(sol.objective_value,12) > 0:
        print m.id, m.name, "can be produced:", sol.objective_value
        return
    else:
        print m.id, m.name, "CANNOT be produced:", sol.objective_value
        print "\t --> try to find reactions for gapfilling"
        #print gapfill(modtmp, refmod)   
        try:
            gapsol = GapFiller(modtmp, refmod, integer_threshold=1e-32).fill()
        except RuntimeError:
            print "\t => Runtime error: lowering the integer_threshold?"
            return
        except:
            print "\t => failed:", sys.exc_info()[0]
            return
        if len(gapsol[0]) > 0:
            print "\t => could be fixed:", ",".join([r.id for r in gapsol[0]])
            if fill:
                model.add_reactions([r for r in gapsol[0] if r not in model.reactions])
예제 #7
0
def checkBiomass(model, fill_gaps=True):
    modmin = set_medium(model, minmed)
    #modmin = model.copy()
    if fill_gaps:
        modnew = model.copy()  # will be returned
    newM = []
    for m in refmod.metabolites:
        if m not in modmin.metabolites:
            newM.append(m.copy())
    # add all metabolites from reference (needed for gapfilling => otherwise reactions sometimes not found!)
    modmin.add_metabolites(newM)

    Call = 0
    Cwork = 0
    Cfix = 0
    fixLater = []
    fail = []
    biomass = [r.id for r in model.reactions
               if r.objective_coefficient != 0][0]
    allMet = model.reactions.get_by_id(biomass).reactants
    for m in allMet:
        if m.formula in ignore:  # ignore minerals, etc
            continue
        Call += 1
        modtmp = modmin.copy()
        modtmp.objective = modtmp.add_boundary(m, type='demand')
        obj = modtmp.slim_optimize()
        if obj > 0:
            #print "\t => could be produced:"
            Cwork += 1
        elif fill_gaps:  # gapfilling
            print obj, m.id, m.name
            try:
                #gapsol = gapfill(modtmp, refmod) # integer_threshold=1e-06
                gapsol = GapFiller(modtmp, refmod,
                                   integer_threshold=1e-16).fill()
            except RuntimeError:
                print "\t => Runtime error: lowering the integer_threshold?"
                fixLater.append(m)
                continue
            except:
                print "\t => failed:", sys.exc_info()[0]
                fail.append(m)
                continue
            if len(gapsol[0]) > 0:
                Cfix += 1
                print "\t => could be fixed:", ",".join(
                    [r.id for r in gapsol[0]])
                modnew.add_reactions(
                    [r for r in gapsol[0] if r not in modnew.reactions])
    print "\nTotal compounds:", Call, "\t can be produced:", Cwork, "\t could be fixed", Cfix, "\t altogether:", round(
        100 * float(Cwork + Cfix) / Call,
        1), "%", " (before:", round(100 * float(Cwork) / Call, 1), "% )"
    if fill_gaps:
        return (modnew)
예제 #8
0
            if len(gapsol[0]) > 0:
                Cfix += 1
                print "\t => could be fixed:", ",".join(
                    [r.id for r in gapsol[0]])
                modnew.add_reactions(
                    [r for r in gapsol[0] if r not in modnew.reactions])
    print "\nTotal compounds:", Call, "\t can be produced:", Cwork, "\t could be fixed", Cfix, "\t altogether:", round(
        100 * float(Cwork + Cfix) / Call,
        1), "%", " (before:", round(100 * float(Cwork) / Call, 1), "% )"
    if fill_gaps:
        return (modnew)


mod.add_reactions([ex for ex in refmod.exchanges if ex not in mod.reactions])
checkProduction(mod, "atp[c]")
sol = mod.optimize()
if sol.status != "optimal" or round(sol.objective_value, 6) == 0:
    print "no biomass production possible try to fix"
    tmpmod = mod.copy()
    for ex in tmpmod.exchanges:
        ex.lower_bound = -1000
    gapsol = GapFiller(tmpmod,
                       refmod,
                       demand_reactions=False,
                       integer_threshold=1e-16).fill()
    print gapsol

modnew = checkBiomass(mod, fill_gaps=True)
fileID = os.path.splitext(os.path.basename(sys.argv[1]))[0]
write_sbml_model(modnew, filename=fileID + "_gapfilled.xml")
예제 #9
0
def test_gapfilling(salmonella):
    """Test Gapfilling."""
    m = Model()
    m.add_metabolites([Metabolite(m_id) for m_id in ["a", "b", "c"]])
    exa = Reaction("EX_a")
    exa.add_metabolites({m.metabolites.a: 1})
    b2c = Reaction("b2c")
    b2c.add_metabolites({m.metabolites.b: -1, m.metabolites.c: 1})
    dmc = Reaction("DM_c")
    dmc.add_metabolites({m.metabolites.c: -1})
    m.add_reactions([exa, b2c, dmc])
    m.objective = 'DM_c'

    universal = Model()
    a2b = Reaction("a2b")
    a2d = Reaction("a2d")
    universal.add_reactions([a2b, a2d])
    a2b.build_reaction_from_string("a --> b", verbose=False)
    a2d.build_reaction_from_string("a --> d", verbose=False)

    # # GrowMatch
    # result = gapfilling.growMatch(m, universal)[0]
    result = gapfill(m, universal)[0]
    assert len(result) == 1
    assert result[0].id == "a2b"

    # # SMILEY
    # result = gapfilling.SMILEY(m, "b", universal)[0]
    with m:
        m.objective = m.add_boundary(m.metabolites.b, type='demand')
        result = gapfill(m, universal)[0]
        assert len(result) == 1
        assert result[0].id == "a2b"

    # # 2 rounds of GrowMatch with exchange reactions
    # result = gapfilling.growMatch(m, None, ex_rxns=True, iterations=2)
    result = gapfill(m, None, exchange_reactions=True,
                     iterations=2)
    assert len(result) == 2
    assert len(result[0]) == 1
    assert len(result[1]) == 1
    assert {i[0].id for i in result} == {"EX_b", "EX_c"}

    # # Gapfilling solution adds metabolites not present in original model
    # test for when demand = T
    # a demand reaction must be added to clear new metabolite
    universal_noDM = Model()
    a2b = Reaction("a2b")
    universal_noDM.add_reactions([a2b])
    a2b.build_reaction_from_string("a --> b + d", verbose=False)
    result = gapfill(m, universal_noDM,
                     exchange_reactions=False,
                     demand_reactions=True)[0]
    # add reaction a2b and demand reaction to clear met d
    assert len(result) == 2
    assert "a2b" in [x.id for x in result]

    # test for when demand = False
    # test for when metabolites are added to the model and
    # must be cleared by other reactions in universal model
    # (i.e. not necessarily a demand reaction)
    universal_withDM = universal_noDM.copy()
    d_dm = Reaction("d_dm")
    universal_withDM.add_reactions([d_dm])
    d_dm.build_reaction_from_string("d -->", verbose=False)
    result = gapfill(m, universal_withDM,
                     exchange_reactions=False,
                     demand_reactions=False)[0]
    assert len(result) == 2
    assert "a2b" in [x.id for x in result]

    # somewhat bigger model
    universal = Model("universal_reactions")
    with salmonella as model:
        for i in [i.id for i in model.metabolites.f6p_c.reactions]:
            reaction = model.reactions.get_by_id(i)
            universal.add_reactions([reaction.copy()])
            model.remove_reactions([reaction])
        gf = GapFiller(model, universal,
                       penalties={'TKT2': 1e3},
                       demand_reactions=False)
        solution = gf.fill()
        assert 'TKT2' not in {r.id for r in solution[0]}
        assert gf.validate(solution[0])
예제 #10
0
                       set(s1).difference(set(s2)))  # add exchange reactions
Nfix = 0
for cs in csources:
    csname = tmpmod.reactions.get_by_id(cs).metabolites.keys()[0].name
    med = minmed + [cs]
    tmpmod = set_medium(tmpmod, med, verbose=False)
    sol = tmpmod.slim_optimize()
    if round(sol, 6) > 0:
        pass
        print csname, "can be used:", sol
    else:
        print csname, "CANNOT be used:", sol
        print "\t --> try to find reactions for gapfilling"
        try:
            #gapsol = GapFiller(tmpmod, refmod, demand_reactions=False, integer_threshold=1e-16).fill()
            gapsol = GapFiller(tmpmod, refmod, demand_reactions=False).fill()
        except RuntimeError:
            print "\t => Runtime error: lowering the integer_threshold?"
            if (cs in s1):
                newmod.remove_reactions(
                    cs
                )  # remove exchange reaction for compounds that cannot be used
            continue
        except:
            print "\t => failed:", sys.exc_info()[0]
            if (cs in s1):
                newmod.remove_reactions(
                    cs
                )  # remove exchange reaction for compounds that cannot be used
            continue
        if len(gapsol[0]) > 0:
예제 #11
0
파일: expand.py 프로젝트: opencobra/Medusa
def gapfill_to_ensemble(model,
                        iterations=1,
                        universal=None,
                        lower_bound=0.05,
                        penalties=None,
                        exchange_reactions=False,
                        demand_reactions=False,
                        integer_threshold=1e-6):
    """
    Performs gapfilling on model, pulling reactions from universal.
    Any existing constraints on base_model are maintained during gapfilling, so
    these should be set before calling gapfill_to_ensemble (e.g. secretion of
    metabolites, choice of objective function etc.).

    Currently, only iterative solutions are supported with accumulating
    penalties (i.e. after each iteration, the penalty for each reaction
    doubles).

    Parameters
    ----------
    model : cobra.Model
        The model to perform gap filling on.
    universal : cobra.Model
        A universal model with reactions that can be used to complete the
        model.
    lower_bound : float, 0.05
        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.
    integer_threshold : float, 1e-6
        The threshold at which a value is considered non-zero (aka
        integrality threshold). If gapfilled models fail to validate,
        you may want to lower this value. However, picking a threshold that is
        too low may also result in reactions being added that are not essential
        to meet the imposed constraints.
    exchange_reactions : bool, False
        Consider adding exchange (uptake) reactions for all metabolites
        in the model.
    demand_reactions : bool, False
        Consider adding demand reactions for all metabolites.

    Returns
    -------
    ensemble : medusa.core.Ensemble
        The ensemble object created from the gapfill solutions.
    """
    gapfiller = GapFiller(model,
                          universal=universal,
                          lower_bound=lower_bound,
                          penalties=penalties,
                          demand_reactions=demand_reactions,
                          exchange_reactions=exchange_reactions,
                          integer_threshold=integer_threshold)
    solutions = gapfiller.fill(iterations=iterations)
    print("finished gap-filling. Constructing ensemble...")
    ensemble = _build_ensemble_from_gapfill_solutions(model,
                                                      solutions,
                                                      universal=universal)

    return ensemble
예제 #12
0
def test_gapfilling(salmonella: Model) -> None:
    """Test Gapfilling."""
    m = Model()
    m.add_metabolites([Metabolite(m_id) for m_id in ["a", "b", "c"]])
    exa = Reaction("EX_a")
    exa.add_metabolites({m.metabolites.a: 1})
    b2c = Reaction("b2c")
    b2c.add_metabolites({m.metabolites.b: -1, m.metabolites.c: 1})
    dmc = Reaction("DM_c")
    dmc.add_metabolites({m.metabolites.c: -1})
    m.add_reactions([exa, b2c, dmc])
    m.objective = "DM_c"

    universal = Model()
    a2b = Reaction("a2b")
    a2d = Reaction("a2d")
    universal.add_reactions([a2b, a2d])
    a2b.build_reaction_from_string("a --> b", verbose=False)
    a2d.build_reaction_from_string("a --> d", verbose=False)

    # # GrowMatch
    # result = gapfilling.growMatch(m, universal)[0]
    result = gapfill(m, universal)[0]
    assert len(result) == 1
    assert result[0].id == "a2b"

    # # SMILEY
    # result = gapfilling.SMILEY(m, "b", universal)[0]
    with m:
        m.objective = m.add_boundary(m.metabolites.b, type="demand")
        result = gapfill(m, universal)[0]
        assert len(result) == 1
        assert result[0].id == "a2b"

    # # 2 rounds of GrowMatch with exchange reactions
    # result = gapfilling.growMatch(m, None, ex_rxns=True, iterations=2)
    result = gapfill(m, None, exchange_reactions=True, iterations=2)
    assert len(result) == 2
    assert len(result[0]) == 1
    assert len(result[1]) == 1
    assert {i[0].id for i in result} == {"EX_b", "EX_c"}

    # # Gapfilling solution adds metabolites not present in original model
    # test for when demand = T
    # a demand reaction must be added to clear new metabolite
    universal_noDM = Model()
    a2b = Reaction("a2b")
    universal_noDM.add_reactions([a2b])
    a2b.build_reaction_from_string("a --> b + d", verbose=False)
    result = gapfill(m,
                     universal_noDM,
                     exchange_reactions=False,
                     demand_reactions=True)[0]
    # add reaction a2b and demand reaction to clear met d
    assert len(result) == 2
    assert "a2b" in [x.id for x in result]

    # test for when demand = False
    # test for when metabolites are added to the model and
    # must be cleared by other reactions in universal model
    # (i.e. not necessarily a demand reaction)
    universal_withDM = universal_noDM.copy()
    d_dm = Reaction("d_dm")
    universal_withDM.add_reactions([d_dm])
    d_dm.build_reaction_from_string("d -->", verbose=False)
    result = gapfill(m,
                     universal_withDM,
                     exchange_reactions=False,
                     demand_reactions=False)[0]
    assert len(result) == 2
    assert "a2b" in [x.id for x in result]

    # somewhat bigger model
    universal = Model("universal_reactions")
    with salmonella as model:
        for i in [i.id for i in model.metabolites.f6p_c.reactions]:
            reaction = model.reactions.get_by_id(i)
            universal.add_reactions([reaction.copy()])
            model.remove_reactions([reaction])
        gf = GapFiller(model,
                       universal,
                       penalties={"TKT2": 1e3},
                       demand_reactions=False)
        solution = gf.fill()
        assert "TKT2" not in {r.id for r in solution[0]}
        assert gf.validate(solution[0])
예제 #13
0
파일: gapfill.py 프로젝트: maringos/gapseq
def checkBiomass(model, fill_gaps=True, addMets=False):
    #modmin = set_medium(model, minmed, verbose=False)
    if fill_gaps:
        modnew = model.copy() # will be returned
    
        
    if addMets: # add all metabolites from reference (needed for gapfilling => otherwise reactions sometimes not found!)
        newM = []
        for m in refmod.metabolites:
            if m not in modnew.metabolites:
                newM.append(m.copy())
        #modmin.add_metabolites(newM) 
        modnew.add_metabolites(newM) 
    
    Call=0; Cwork=0; Cfix=0
    fixLater = []
    fail = []
    #relMet = ["cpd00288_c0"]
    allMet = model.reactions.bio1.reactants #+ [modmin.metabolites.get_by_id(m) for m in relMet]
    #allMet = model.reactions.Biomass.reactants # vmh
    #bioaa = [m for m in model.metabolites if m.name.startswith("L_") and m in model.reactions.bio1.metabolites]
    #for m in bioaa:
    for m in allMet:
        if m.formula in ignore: # ignore minerals, etc
            continue
            print m.id, m.name, m.formula
        Call += 1
        
        #modtmp = modmin.copy()
        modtmp = set_medium(modnew, minmed, verbose=False)
    
#        rea1 = Reaction("Refresh_ATP", lower_bound=0, upper_bound=1000)
#        rea1.add_metabolites({modtmp.metabolites.cpd00002_c0:-1, modtmp.metabolites.cpd00001_c0:-1, modtmp.metabolites.cpd00008_c0:1,modtmp.metabolites.cpd00009_c0:1, modtmp.metabolites.cpd00067_c0:1})
#        modtmp.add_reaction(rea1)
#
#        rea2 = Reaction("Refresh_NADH", lower_bound=0, upper_bound=1000)
#        rea2.add_metabolites({modtmp.metabolites.cpd00004_c0:-1, modtmp.metabolites.cpd00067_c0:1, modtmp.metabolites.cpd00003_c0:1})
#        modtmp.add_reaction(rea2)
#        
#        rea3 = Reaction("Refresh_NADPH", lower_bound=0, upper_bound=1000)
#        rea3.add_metabolites({modtmp.metabolites.cpd00005_c0:-1, modtmp.metabolites.cpd00067_c0:1, modtmp.metabolites.cpd00006_c0:1})
#        modtmp.add_reaction(rea3)
#
#        modtmp.add_boundary(modtmp.metabolites.cpd00012_c0, type='demand') # ppi
#        modtmp.add_boundary(modtmp.metabolites.cpd00009_c0, type='demand') # pi
#        modtmp.add_boundary(modtmp.metabolites.cpd00067_c0, type='demand') # h+

        modtmp.objective = modtmp.add_boundary(m, type='demand')
        obj = modtmp.slim_optimize()
        if round(obj,6) > 0:
            print obj, m.id, m.name
            Cwork += 1
        elif fill_gaps: # gapfilling
            print obj, m.id, m.name
            try:
                #gapsol = gapfill(modtmp, refmod) # integer_threshold=1e-06
                gapsol = GapFiller(modtmp, refmod, integer_threshold=1e-16).fill()
            except RuntimeError:
                print "\t => Runtime error: lowering the integer_threshold?"
                fixLater.append(m)
                continue
            except:
                print "\t => failed:", sys.exc_info()[0]
                fail.append(m)
                continue
            if len(gapsol[0]) > 0:
                Cfix += 1
                print "\t => could be fixed:", ",".join([r.id for r in gapsol[0]])
                modnew.add_reactions([r for r in gapsol[0] if r not in modnew.reactions])
    print "\nTotal compounds:", Call, "\t can be produced:", Cwork, "\t could be fixed", Cfix, "\t altogether:", round(100*float(Cwork+Cfix)/Call,1), "%", " (before:",round(100*float(Cwork)/Call,1),"% )"
    print "Could not synthesis:", ",".join([m.id for m in fixLater+fail])
    print "Could not synthesis:", ",".join([m.name for m in fixLater+fail])
    if fill_gaps:
        return(modnew)