-
Notifications
You must be signed in to change notification settings - Fork 212
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
refactor: transform production envelope to wide format with multiple carbon sources #587
Conversation
On 2, being used to ggplot's interface, I find long format much more convenient as the column names remain fixed and then easier to write general plotting code. But, I guess that may be somewhat niche case and that wide format feels more familiar. |
Actually, even for ggplot2 I find the wide variant more convenient because I opted to use ggplot2::ggplot(total_df, ggplot2::aes(x = biomass,
ymin = flux_minimum,
ymax = flux_maximum,
color = label,
fill = label)) +
ggplot2::geom_ribbon(alpha=0.3) +
ggplot2::scale_color_brewer(name = "Model", palette = "Set1") +
ggplot2::scale_fill_brewer(name = "Model", palette = "Set1") +
ggplot2::labs(x = expression(paste("Growth [", g[DW], h^{-1}, "]")),
y = expression(paste("Flux [", mmol, g[DW]^{-1}, h^{-1}, "]"))) Which can produce something like the following plot, for example. |
Sure that works as well, I find it easiest to know the right format when having tried to implement many different plots which I didn't do yet (e.g. to recycle code with plotting e.g. fva, however that should be done the best way.). Something to think of when implementing overall better plot functions for cobra. In the mean time, switch to wide format here totally fine with me. |
Any other ideas that should be included here? I think testing could be expanded for sure. |
Codecov Report
@@ Coverage Diff @@
## devel #587 +/- ##
==========================================
+ Coverage 71.43% 71.45% +0.01%
==========================================
Files 65 65
Lines 8778 8784 +6
Branches 1483 1491 +8
==========================================
+ Hits 6271 6277 +6
Misses 2239 2239
Partials 268 268
Continue to review full report at Codecov.
|
results['carbon_source'] = carbon_io[0].id | ||
return results | ||
with model: | ||
model.solver.objective.direction = sense |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't use context manager, perhaps better formulate as model.objective = ..
? Otherwise I guess will exit with objective changed to max if starting with min..
for rxn in reactions: | ||
point = grid.at[i, rxn.id] | ||
rxn.bounds = point, point | ||
model.slim_optimize() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
perhaps obj_value = model.slim_optimize()
and then use obj_value
below
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed.
model.slim_optimize() | ||
if model.solver.status != OPTIMAL: | ||
continue | ||
if abs(model.solver.objective.value) < \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
how about making the tolerance an optional argument and have thereby have this clipping documented?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea.
try: | ||
return carbon_output_flux / carbon_input_flux | ||
except ZeroDivisionError: | ||
return nan | ||
|
||
|
||
def mass_yield(c_input_output): | ||
"""Gram product divided by gram of carbon input source | ||
def reaction_components(reaction, atom='C'): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
element
not atom.. And since you add this, perhaps do it all the way and allow user to calculate any element yield by having e.g. yield_element='N'
as argument to production_envelope
? Or do later and remove parametrisation here..
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removing parametrization here for now. It's a little annoying with column naming so unless there is a need for it I'd skip it.
a0f25a6
to
d4c81e7
Compare
This PR is now based on #588 and the new |
01329b2
to
f292c28
Compare
f292c28
to
7777ea7
Compare
grid.at[i, 'carbon_yield_{}'.format(direction)] = \ | ||
total_yield([rxn.flux for rxn in c_input], | ||
input_components, | ||
model.solver.objective.value, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
obj_val
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Absolutely!
fix #582
So far this PR re-organizes the code for
production_envelope
a little bit and catches the potentialZeroDivisionError
inmass_yield
. However, I suggest the following further changes which is why I marked this PR as WIP.