-
Notifications
You must be signed in to change notification settings - Fork 2
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
Feature/stoichiometry for Animals #726
base: develop
Are you sure you want to change the base?
Conversation
… functional groups, explicitly tracked elemental masses in cohorts, and a grow() cohort-method for constraining mass gain.
…lantresources, and decay for working with stoichiometric dictionaries.
… grow inside of the eat method.
…f stoichiometry explicitly.
…y testing rework.
…el with soil and data.
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## develop #726 +/- ##
===========================================
- Coverage 94.70% 94.40% -0.30%
===========================================
Files 73 73
Lines 4946 5059 +113
===========================================
+ Hits 4684 4776 +92
- Misses 262 283 +21 ☔ View full report in Codecov by Sentry. |
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.
I've looked at the exchanges with the litter/soil model and I am happy that information will still get passed into my models in the format I want it in. I'm not approving as I don't feel well placed to give feedback on the overall structure/approach.
I had one specific comment which directly contradicts what I told you on teams earlier, sorry!
self.leaf_waste_pools[cell_id].mass_cnp["carbon"] | ||
/ self.leaf_waste_pools[cell_id].mass_cnp["phosphorus"] | ||
if self.leaf_waste_pools[cell_id].mass_cnp["phosphorus"] > 0 | ||
else 0.0 |
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.
Sorry despite what I said earlier using 0.0 here doesn't really work, but obviously using inf
for the divide by zero case would break the downstream calculations. Not 100% sure what the best approach is here, I guess this is a value that you should never expect, so maybe we just accept this as a weird edge case?
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.
Okay actually think you want to add the following between the if and the else
elif self.leaf_waste_pools[cell_id].mass_cnp["carbon"] > 0 np.inf```
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.
(the above might not be valid, but you get the idea)
This means that if there is a carbon flow with no associated nitrogen/phosphorus an infinite value gets returned (which then raises an error downstream). And this makes sense because biological matter always contains N and P.
But this handles the "there's no phosphorus because there's no organic matter at all" case gracefully
efficiency = detritivore.functional_group.mechanical_efficiency | ||
actual_consumed_mass = actually_available_mass * efficiency | ||
|
||
# Avoid division by zero in nutrient fractions calculation |
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.
You actually take a step to avoid division errors here, is there a reason not to do this in the plant waste products case above?
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.
I have not gone into the detail of the code, but don't have much time today and wanted to give you some early feedback. This very much calls for a dedicated class in which to put together all the cnp
related manipulations. Something like the following will also facilitate manipulation and type checks:
@dataclass
class CNP:
carbon: float
nitrogen: float
phosphorus: float
@property
def total(self) -> float:
return self.carbon + self.nitrogen + self.phosphorus
def __getitem__(self, key):
"""In case you want dictionary-style access."""
return getattr(self, key)
Or, conversely, you can make it inherit from dict and add properties, as needed:
class CNP(dict):
@property
def carbon(self) -> float:
return self["carbon"]
@property
def nitrogen(self) -> float:
return self["nitrogen"]
@property
def phosphorus(self) -> float:
return self["phosphorus"]
@property
def total(self) -> float:
return sum(self.values())
Given that CNP
is something that seems to have some entity as a group, I think it deserves to be treated as such in the code, also facilitating its documentation.
@dalonsoa This is a really good idea and I'm annoyed that I didn't think of it! I'll make the adjustments. |
Description
This PR contains the transition from a purely carbon mass system to a carbon, nitrogen, phosphorus (cnp) system.
Key Changes:
Fixes # (issue)
Type of change
Key checklist
pre-commit
checks:$ pre-commit run -a
$ poetry run pytest
Further checks