Hey guys, for the toy model from Figure 2 in Schellenberger et al. I get identical solutions when using nominal FVA vs. loopless FVA (CycleFreeFlux via `loopless=True`

). If I understand the docs right loopless should help me "to avoid getting high flux ranges for reactions that essentially only can reach high fluxes if they are allowed to participate in loops", but instead I get this. This is with Version: 0.6.1 of cobrapy on Python 2.7:

Edit: Just updated to Version 0.6.2, which didn't change this.

This is because you enforce the previous objective value which requires the loop to be active. If you would use the objective value from the loopless solution or use a lower fraction those ranges should drop.

Probably should calculate a loopless initial solution in FVA as well

This is the first time I'm really working with this. How do I go about not enforcing the previous objective value?

I don't understand your response, but I did notice that I had reaction v3 inverted. I fixed that and now maximising "A->C" doesn't depend on the loop (v1, v2) anymore. However, the two FVA solutions are still identical.

Alright, I think I understand what you meant! You we're referring to the

`loopless_solution`

maintaining the exact same objective value from the previous solution. I wasn't exactly sure what that meant in the documentation, but now I get it! Since I'd like to find loops by comparing a the flux distribution of the normal vs a loopless state and I am OK with the objective value changing, I'll try with `add_loopless`

instead. Thanks for your help!
Yes, FVA fixes the objective to it's maximum by default. Since the objective was v3 and this requires traversing the loop to give that particular maximum you basically force FVA to maintain the loop. The loopless option in FVA only gives you the least loopy solution given the set constraints. However I think we should change the objective value in loopless FVA to be the one from a loopless optimization and not from regular FBA as it is done now.

Hi @hredestig. Can you make a label for SBML/IO related issues? Would help to group all the SBML ones etc. :smile:

@ChristianLieven for most models the objective itself does not change when getting a loopless solution. For that it would need to be part of a loop itself which will not be true if it "consumes" any mass which is usually the case.

@ChristianLieven I think what I said about v3 is wrong. Will check what is going on...

@ChristianLieven found the problem. In your example your objective should be "vB" not "v3". "v3" does fall inside the loop so its maximum requires the loop to be active as said before :)

The same example is analyzed in the cobrapy docs in 8.2 (https://cobrapy.readthedocs.io/en/latest/loopless.html)

For the FVA the result you obtained is correct since your "vB" has an upper bound of 1000 so if you maximize for that and run FVA the loopless and normal solution are the same. To force a different solution would have to make the demand saturate before. For instance:

```
In [1]: from cobra import Model, Metabolite, Reaction
In [2]: from cobra.flux_analysis import flux_variability_analysis
In [3]: model = Model()
...: model.add_metabolites([Metabolite(i) for i in "ABC"])
...: model.add_reactions([Reaction(i) for i in ["EX_A", "DM_C", "v1", "v2", "v3"]])
...:
...: model.reactions.EX_A.add_metabolites({"A": 1})
...: model.reactions.DM_C.add_metabolites({"C": -1})
...:
...: model.reactions.v1.add_metabolites({"A": -1, "B": 1})
...: model.reactions.v2.add_metabolites({"B": -1, "C": 1})
...: model.reactions.v3.add_metabolites({"C": -1, "A": 1})
...:
...: model.objective = 'DM_C'
...:
In [4]: model.reactions.DM_C.bounds = 0, 1
In [5]: flux_variability_analysis(model)
Out[5]:
maximum minimum
DM_C 1.0 1.0
EX_A 1.0 1.0
v1 1000.0 1.0
v2 1000.0 1.0
v3 999.0 0.0
In [6]: flux_variability_analysis(model, loopless=True)
Out[6]:
maximum minimum
DM_C 1.0 1.0
EX_A 1.0 1.0
v1 1.0 1.0
v2 1.0 1.0
v3 0.0 0.0
```

(the model in the docs is actually not the model from Schellenberger unless you also bound EX_A and DM_C by 0,1)

Yeah, the way you describe CycleFreeFlux to be implemented I see how having the objective in the loop isn't helpful! However, I chose v3 as the objective as that is the case for the example from Schellenberger . I understand though that when bounding DM_C to 1 and then optimising it I can still use the faster method! This is what I'll do now. Thanks for taking the time to explain and thanks for your help. :)

Wednesday 12th 16 CEST seems like a good time for the next meeting, @pstjohn can you make it then as well or you prefer some other time?

In COBRApy documentation, 4.4 Running pFBA, the documentation says that FBA and pFBA should give approximately the same objective value.

However, when I print out the values, `print (fba_solution)`

and `print (pfba_solution)`

gives drastically different values of *0.874* and *518.422* respectively.

But, when I run

```
abs(fba_solution.fluxes["Biomass_Ecoli_core"] -
pfba_solution.fluxes["Biomass_Ecoli_core"])
```

I get solution of `1.1102230246251565e-16`

, which, given the previously printed values isn't right.

Also, the value I get is half of what is in the documentation.

Could someone help me figure this out?

@hredestig Unfortunately not, I’m actually on CEST for a conference this week and taking a few days off next week. I do realize I was the person who originally suggested the meeting :worried:. That’s ironically almost the exact time I’m scheduled to present.

Ah okay but we can take different time as well? When would be good for you?

@cdiener just made sbml label (you're very welcome to make labels as well, never meant to have monopoly on that (: )

@cdiener what do you think of #535? We use that feature in decaf so wanted to have it in cobrapy directly as thought could be useful for others as well

@BhushanDhamale see opencobra/cobrapy#518. I believe the new pfba function stores the objective value from the second LP involved in parsimonious flux-balance analysis, which is different than the objective function maximized when calling model.optimize().

works for me but thought perhaps not everyone would have time to react, but let's try? 16 CEST?

@ChristianLieven got confused myself so it's definitely not too obvious :) It's possible to also remove loops with CycleFreeFlux if the objective is part of a loop. This is what is actually done in loopless FVA... So maybe something to consider for the future...

Did we ever decide anything regarding the pfba objective? Could make sense to assign the "old" objective value to the solution in

`pfba`

. I think this was also the behavior in cobrapy 0.5...
@hredestig it's more that I have no idea what that "epic" stuff is so I did not want to break it

@hredestig will review it

@BhushanDhamale So if

`Biomass_Ecoli_core`

has an objective coefficient of 1 in both cases, then the expression you posted is the difference between values of identical objective functions. If your objective function has many terms, you would have to consider adding the appropriate objective coefficients and predicted fluxes to the expression you posted above.
@cdiener yeah I know the epics are for our decaf team, sadly they have to be stored in the repo causing some noise. Nothing broken by making more labels

All right, tomorrow at 16:00 CEST for next meeting meet.jit.si/cobrapy

@pstjohn you get up early it seems :smile: so 9:00 for me and Peter I suppose :)

Well actually i’m currently in toulouse for IFAC, so its the late afternoon

Apologies if 9 is too early

I see so I got overpowered by the European time zone people this time :smile: 9:00 is fine just kidding