-
Notifications
You must be signed in to change notification settings - Fork 9
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
Add helper functions for PFT geometry and canopy shape. #290
Comments
OK - been playing around with idea on this, and I think a nice API for users on this issue is to extend class Flora():
...
def get_allometries(dbh: NDArray) -> dict[str, NDArray]:
"""Generate T Model predictions for PFTs in Flora for a set of DBH values."""
...
def get_canopy_shape(z: NDArray) -> dict[str, NDArray]:
"""Generate canopy shape predictions for PFTs in Flora for a set of vertical height values."""
... Those aren't methods of If the return values in the dictionary are a set of import numpy as np
from matplotlib import pyplot as plt
from pyrealm.demography.flora import PlantFunctionalType, Flora
# Create flora
pft1 = PlantFunctionalType(name='pft1', h_max=20)
pft2 = PlantFunctionalType(name='pft2', h_max=30)
flora = Flora([pft1, pft2])
# Get allometries for DBH values from 0 to 1 m in 1cm increments
dbh = np.linspace(0, 1, num=101)
allometries = flora.get_allometries(dbh=dbh)
# Plot stem_height vs dbh for both PFTs in one go.
plt(dbh, allometries['stem_height'], label = flora.pft_names) I like that a lot as an API but it immediately provides another angle on why def calculate_heights(h_max: NDArray, a_hd: NDArray, dbh: NDArray) -> NDArray:
return h_max * (1 - np.exp(-a_hd * dbh / h_max))
dbh = np.linspace(0, 1, num=101)
h_max = np.array([20,30])
a_hd = np.array([116.0,116.0])
h = calculate_heights(h_max, a_hd, dbh[:, None]) # turn DBH into a column vector. I think that restructure would be make the functions more flexible and general. I was going to concentrate on expanding functionality through this issue and #289 before thinking about replacing @omarjamil, @MarionBWeinzierl and @j-emberton Thoughts? |
I like this approach, but I would change the implementation slightly so that the end user doesn't need to worry about transposing the array. I would prefer that we handle the transposition inside (perhaps using a generic shape test and conditional transposition helper function) to keep the interface cleaner. Alongside, for this type of broadcasting we might want to enforce checks at runtime to make sure the arrays are broadcastable. Its slightly messy to try and type hint the appropriate relative shapes for all the inputs, so easier just to do it at runtime. But this is secondary to the overall approach which I think is nice. |
I'd agree completely except for the use case where someone wants e.g. a 6x6 output with 6 heights for each of 6 PFTs in a Flora. If the broadcasting is internal, then we can't tell the user intention from the input shapes alone, so we would have to add an intended output shape argument ( And I don't think I'd bother type hinting the shapes - or at least, we've not done it anywhere else, so handling shape checking in a validation function like the ones in #288 seems ok to me. |
This seems like a reasonable approach to me as well. On a broader point, I agree that we should leave the transposition to the user. As long the functions are consistent in how the input arrays are arranged and what is returned, the rest should be left to the user. This would be the easiest to understand and debug. |
Thanks @omarjamil and @j-emberton . So my plan now is to:
|
We need some neat wrappers to make it easier to visualise PFT scaling without having to go through a Community object. This is partly to make the docs easier, but also to allow users to visualise the effects of the PFT settings. We need:
The text was updated successfully, but these errors were encountered: