-
Notifications
You must be signed in to change notification settings - Fork 3
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
Sanity checks for simulations: disconnected species, extinct species & disconnected graphs #151
Comments
Thank you @alaindanet. IIUC this would solve a substantial part of #137, right? |
Hi @alaindanet! We've just discussed this with @ismael-lajaaiti this morning and I think we're almost good to go :) Here are the specifications I offer for the feature, which should clarify a few things that need to be clarified first IMO. Don't panic: this is mostly about naming things just to be sure we don't get confused ;) 1. Static checks on the "foodweb graph"The directed graph representing the Foodweb is a static graph, fixed, constant throughout the simulation. As such, if it's connected at As it turns out, checks against this static graph used to be performed but I'm not sure whether they still are. I can suggest a behaviour like the following: julia> fw = Foodweb(A=[...])
ERROR: The given matrix describes a disconnected graph.
This error is meant to protect you from unintentionally working on disconnected foodwebs.
But you can construct disconnected foodwebs by setting `allow_disconnected=true`. IIUC this is slightly out-of-scope for the current issue (because it's not even about simulation), but maybe we can fit it in anyway ;) 2. Dynamics checks on the "biomasses graph"The checks discussed here are performed against another graph that does not exactly represent the foodweb, but the effective interactions between live species. Let's call it the biomass graph (?). The biomass graph is a dynamic graph, as it changes over time, during simulation, depending on the biomasses vector
3. Three different kinds of checks.Since the word disconnected has a precise formal meaning in graph theory, I would warn against using it in the three different situations you describe. Here is how I offer referring to them instead. The "problematic features" to be detected are: DisconnectionThe biomass graph is (or has become) a disconnected graph, meaning that its number of connected components is above 1. For instance, this happens when
Then the resulting biomass graph becomes made of two disconnected components Isolated producersOne or several producers (=
Note The existence of isolated producers does not imply disconnection. For example, in the right situation above, when Starving consumersOne or several consumers (=
Note Again, the existence of starving consumers does not imply disconnection. In the above, the biomass graph remains connected after Warning I understand that the biomass of starving consumers is expected to become zero short-term. However, I have a strong opinion that it would be wrong to force it to become instantaneously zero with anything akin to a 4. Suggested feature
.. or something? |
Thank you so much @iago-lito for the clarification, I agree with your semantic about disconnected graphs. If I understand well, I really like the naming "isolated" and may these are our three rules:
or
Really cool, got it about the non-disconnection of the graph following
I really like the terminology and I agree to go with it! About the killing of disconnected species, I have a less strong opinion than you The middle ground that I could think of is that we provide to kill only isolated I really like that you suggest to return the components because there is not an In the simulation, I think that the message that you suggest is great but may julia> out = simulate(model, ..)
INFO: The biomass graph at the end of simulation contains 3 disconnected
components, 3 isolated producers, 3 starving consumers.
This might affect the meaning of of downstream analyses. For more information,
see: `diagnose()`.
You can silent this message with `show_unusual_biomass_graph_properties=false`.
julia> diagnose(out)
The biomass graph at the end of simulation contains 3 disconnected components:
- Connected component 1:
- 2 producers
- 3 consumers
- 4 trophic links
- Connected component 2:
- 2 producers /!\ including 1 isolated producer /!\
- 1 consumer
- 1 trophic link
- Connected component 3:
- 3 producers /!\ including 2 isolated producers /!\
- 4 consumers /!\ including 3 starving consumers /!\
- 4 trophic links
You can retrieve components with `list_connected_components()` and know more
about the problems with those graphs in the dedicated vignette: https://xxx
julia> list_connected_components(out)
3-element Vector{BiomassConnectedComponent}:
Component(producers = [:A, :B, :C], consumers = [:D, :E])
Component(producers = [:F, :G], consumers = [:H], isolated_producers = [:F])
Component(producers = [:M, :N, :O], consumers = [:I, :J, :K, :L], isolated_producers = [:N, :O], starving_consumers = [:I, :J, :K]) |
Good @alaindanet! I'll start implementing this tomorrow :)
To be clear about should here: there is not much we can do to guarantee that a biomass graph won't be disconnected by the end of a simulation. So I guess you mean "should be connected so as not to trigger the @info message".
This is not equivalent to
So yeah, I would say that there are not two (as you wrote) but three starving consumers in the above:
This is still not equivalent to
This is indeed equivalent to
IIUC you are suggesting that
So, when D dies in the following:
Then we can offer to kill And then when C dies:
Then only we can offer to kill
Sure, whatever, as long as user is warned ;) |
Wops, sorry that is also incorrect. A strongly connected component necessarily contains directed cycles, which excludes producers as they have no outgoing edges. Maybe the only good definition of a starving consumer remains |
That sounds marvelous @iago-lito! Thank you for the clarification about the definition of starving consumers and to have taken the time to explain more 🙏 |
@ismael-lajaaiti @alaindanet I can think of another possible artefact of
If
I hear you are sometimes interested in the "time for the community to reach equilibrium". In the above, the time to reach equilibrium is: But if user chooses to dismiss starving consumers In this situation, does it make sense to use |
Hi @iago-lito, in the case you are describing, I hope that
At the end, |
Hey @alaindanet @iago-lito, |
I totally agree with you @ismael-lajaaiti ! |
It's just that I am afraid of adding a new layer of complexity (that is maybe not crucial, as it seems to be quite specific), while the package is already not so easy to use. However, we could document these cases of starving consumers and suggest how to deal with them? |
Yupe. Whatever the eventual decision here, I guess we'll need B[find_disconnected_starving_consumers(model, B)] = 0 whether we want to do this or not is another matter which I'll let you discuss ^ ^" But I think it's always useful to ease such querying of the model. |
Now, I have a new 🌈 pandora box 🕷️ to open @alaindanet @ismael-lajaaiti: the definitions I have offered for What do these concepts become when there are non-trophic interaction layers? For now, I can just craft something like: julia> find_starving_consumers(model, B)
ERROR: Starving consumers are not yet defined in models with non-trophic interaction layers. ? |
Good. What about nutrients? ^ ^" julia> find_isolated_producers(model, B)
ERROR: Isolated producers are not yet defined in models with explicit nutrient nodes. ? |
My take on that
|
Okay, summary of the current model ;)
Now, on top of that, here are the current definitions for the various concepts discussed here:
What does this sound like? |
I am really happy with those definitions! |
These values describe the model under a topological perspective: nodes and their neibouhring relations. Nodes and edges are typed into various 'compartments'. Nodes can be "removed" from topologies while leaving tombstones to maintain indices validity. This enables various topological analyses of the model network like `disconnected_components()`, `isolated_producers()` or `starving_consumers()`.
These values describe the model under a topological perspective: nodes and their neibouhring relations. Nodes and edges are typed into various 'compartments'. Nodes can be "removed" from topologies while leaving tombstones to maintain indices validity. This enables various topological analyses of the model network like `disconnected_components()`, `isolated_producers()` or `starving_consumers()`.
The goal would be to warn users that the ecological network simulations can have properties that can create problems for interpreting the results or computing output metrics.
Those problematic features are:
Disconnected species:
Disconnected graphs:
Tasks:
simulate
A set of function for disconnected species:
The goal is that
simulate
produces a useful message when there is a disconnected species. For example, in that case when there is a disconnected consumer:On top of sanity checks, we can also provide a snippet in the doc to enable users to run the simulations until there are no more extinct species or disconnected species:
The text was updated successfully, but these errors were encountered: