Skip to content

Modelling extinction in spatialized context. #188

Description

@iago-lito

It is not yet time to implement spatial patches, but I think it's good to think ahead, and I find that modelling extinction in this context seems not super straightforward. I think it is worth discussing now.

Today we can consider that our simulations are held within a single patch A. Whenever a species biomass SA falls below our given ext = extinction_threshold, we consider it extinct, record an "extinction event" and then have the variable SA stick to zero for the remainder of the simulation.

Now if we add two other spatial patches B and C, connected together by migration but disconnected from A. Then we are effectively adding two variables SB and SC to represent species biomasses within these extra patches.

One idea behind migration is that it can alleviate extinction because SB becoming extinct may be salvaged by incoming biomass from SC. But how do we define extinction then?

Approach 1

We fire an extinction event as soon as SB reaches below ext, and then have SB stick to zero forever, just like for SA.
This is consistent, but we are effectively forbiding that incoming migration from SC ever salvages SB. Biomass will be lost on the C -> B path.

Approach 2

We allow SB and SC to temporarily, and independently, reach below ext and then rise up again, and only fire a joint extinction event when both reach below ext at the same time (..or their sum?).
This enables salvaging from migration, but it makes the model allow for long periods of SB fluctuating below ext before rising again, which is what the extinction threshold was meant to disallow in the first place.

Approach <X>

.. any other idea?

I am currently leaning towards approach 2 because it is a strict generalization of our current model. In a nutshell, it does not consider that migrants are zombies. But I think this is worth discussing anyway. What do you think?

Activity

  1. alaindanet commented on Apr 22, 2026

    @alaindanet
    Collaborator

    Thank you @iago-lito for pointing out the problem and present it so clearly.

    As I understand and trying to translate this ecologically:

    • Approach 1 would be to implement permanent local extinction, preventing recolonisation/rescue from another patch. As you said yourself, I do not think this is an option.
    • Approach 2 would be to discard local extinction and keep only regional extinction, for example as you suggested, when the regional biomass (the sum of SA, SB, SC) falls below a threshold.

    May be I can give my opinion of what ecological processes would be great to have in the spatial model... A reversible local extinction.
    What meta-community theory models is that local extinction only exists (Approach 1), and that regional extinction (Approach 2) is not explicitly modeled but emerges instead from local extinctions, when all the local populations are (locally) extinct (SA, SB, SC are all inferior to ext).

    I can think of another Approach:

    Having local extinction (Approach 1), but reversible. Species in patch A (SA) stays extinct until the sum of immigrants of the species S from the other patches is above ext.
    I think that it would be most plausible ecological mechanisms and I guess it would be possible to design such callback right? The callback would keep the SX to 0 except if the immigration biomass or the updated biomass goes back above ext?

    Thanks again and please tell me if I was not clear.

  2. iago-lito commented on Apr 23, 2026

    @iago-lito
    CollaboratorAuthor

    Hi @alaindanet and thank you for input :) I like the naming "regional extinction" because it enforces that we are looking for a generalization of the current status. Today when S0 falls below ext, we call it "extinction" but we can also consider it a "regional extinction" for a region that just happens to be only one patch.
    Generalizing this is then just a matter of defining:

    • A region: a connected component within a network of patches.
    • A regional extinction. I can see two options there :
      • Happens when all(S[i] < ext for i in region). This makes sense because ext is thought to be "the biomass of one individual" (is it?). But I think we can do better.
      • Happens when sum(S[i] for i in region) < ext. This is what you are suggesting. It doesn't make sense if ext is thought to be "the biomass of one individual", but I still like it because it allows for a nice definition of your "reversible extinction" phenomenon (see below).

    IIUC you would like being able to define/count/study particular events called "rescue", informally defined as "the species has gone extinct within a patch but it is successfully reintroduced by migration". I understand why these events are interesting. Now how to properly define/model them?

    I am not sure I understand the definition you are offering:

    Species in patch A (SA) stays extinct until the sum of immigrants of the species S from the other patches is above ext

    keep the SX to 0 except if the immigration biomass or the updated biomass goes back above ext

    Are you suggesting that for every biomass variable SX representing the local species biomass, we should introduce another variable SX_foreign to represent that "sum of immigrants" or "immigration biomass"? I am worried that such a variable is rather difficult (or maybe impossible) to define, and that it would require adding more derivatives to the ODE.

    I also have another concern regarding rescue events. They are bound to extinction events, which today do require some runtime interruption logic, and maybe even more tomorrow. But unlike extinction events today, they can happen multiple times during the simulation. In particular, if a species is dying in a patch and blooming in another patch, I expect that it may even flicker, as in extinction/rescue events could fire on and off very fast for a long period of time as the biomass wander around the ext value. In such situations, I am worried that modelling rescue events using extinction events would be disastrous for simulation performance.

    But maybe we can decouple them if we stick to the second definition of a "regional extinction" above. We could define:

    • A regional extinction event: the sum of biomasses in the region falls below ext.
    • A local rescue: the local biomass in a patch rises above ext.

    Regional extinction impacts simulation in that species need to be removed / forced to zero. But it can only happen once per species per region.

    Local rescue does not impact simulation in that local species biomasses can vary above and below ext without consequences, as long as the overall region biomass is still above ext. We can just record the date any time we observe S[t] < ext && S[t + dt] >= ext. Or we can even leave local rescue analysis to post-processing utils.

    There is no such thing as "local extinction": this event is not defined. There is nothing we can call a "local extinction" as long as the species is still live within the region.

    There is no such thing as "regional rescue": this event is not defined. When the species goes extinct at the regional level, then it cannot be rescued anymore.

    What do you think?

  3. iago-lito commented on Apr 23, 2026

    @iago-lito
    CollaboratorAuthor

    Then again.. maybe we could define some "local extinction" event as "whenever we observe local S[t] >= ext && S[t + dt] < ext". But then, like a local rescue, it is a lightweight event that doesn't imply that we remove S or force it to zero at all, as long as the species is still live within other patches in the region.

    In the end, this means we would only have to focus on regions and regional extinctions events during the simulation, and leave local extinctions / local rescues analysis for downstream trajectory post-processing. ext becomes the regional threshold r_ext, and it may even differ from the local threshold l_ext used to determine local extinction / local rescue events later.

  4. alaindanet commented on Apr 27, 2026

    @alaindanet
    Collaborator

    Hey @iago-lito, thank you so much for the neat response, it clarifies a lot. I hope to be able to do the same.

    I agree with you that regional extinction as sum(S[i] for i in region) < ext does not make sense ecologically if there is no local extinction, like as you underlined, in the case there are some patches with less than one individually, but I guess it is something we can live with. But my preference would be to have local (reversible) extinction only (so regional extinction is a consequence of local extinctions).

    ## Rescue

    I will try to clarify. SX representing the local species biomass of species S at the patch X.

    We do not need to compute another variable for immigrants on top of the ODEs, because it will be already present in the ODEs:
    Spatial ODEs will contain one equation for each species and patch, so that the sum of immigrants arriving in each time step will like be something in that flavor: dBS[i] = .... + sum(m[j]*S[j] for j in region_minus_focal) - sum(e[j]*S[i]for j in region_minus_focal) (this sum being S_net_immigrant for latter below), m[j] being the immigration rates of species S from patch j to patch i (i being the focal patch) and S[j] being the biomass of species S in patch j. The sum following minus - is for emigration from patch i to the j patches.

    I understand your concern about colinisation/extinction firing on and off but I would not be surprised that, in absence of stochasticity, species biomass will converge at local scale (and so at regional scale) at a given steady state.

    In sum, I think that ideally the definition of regional extinction should be just sum(S[i] for i in region) == 0, meaning that the species is locally extinct everywhere, the local extinction being S[t] < ext, the local rescue being S_net_immigrant > ext.

    Does that sound clear?

    Then again.. maybe we could define some "local extinction" event as "whenever we observe local S[t] >= ext && S[t + dt] < ext". But then, like a local rescue, it is a lightweight event that doesn't imply that we remove S or force it to zero at all, as long as the species is still live within other patches in the region.

    In the end, this means we would only have to focus on regions and regional extinctions events during the simulation, and leave local extinctions / local rescues analysis for downstream trajectory post-processing. ext becomes the regional threshold r_ext, and it may even differ from the local threshold l_ext used to determine local extinction / local rescue events later.

    So my preference (aside performance issues) would be toward defining local extinction & rescue rather than regional extinction alone.

  5. iago-lito commented on Apr 27, 2026

    @iago-lito
    CollaboratorAuthor

    I understand your concern about colinisation/extinction firing on and off but I would not be surprised that, in absence of stochasticity, species biomass will converge at local scale (and so at regional scale) at a given steady state.

    Well, this is a bet, right? Deterministic dynamics can also cycle or chaos indefinitely. If the cost of firing off/on is to interrupt the solver and produce an intermediate checkpoint model, then I'd rather not take that bet ^ ^" I can expect performances to depend on species number and the complexity of dudt!, but not quite on the phase space structure.

    This being said, I still don't think we need to make these structural events reversible, because we are sort of converging towards a consensual approach (🤞). Let's state that, when species biomass starts being forced to zero, then it stays forced to zero forever. There is no coming back. Now "local extinction" and "rescue" may occur, even several times, prior to this happening.

    In sum, I think that ideally the definition of regional extinction should be just sum(S[i] for i in region) == 0, meaning that the species is locally extinct everywhere, the local extinction being S[t] < ext, the local rescue being S_net_immigrant > ext.

    I'm sorry I am struggling to make sense of this 8)
    For one: S_net_immigrant > ext is not homogeneous. S_net_immigrant is part of a derivative (biomass/time) whereas ext is in units of biomass. So I don't think they can even compare. If we wanted to compare net immigration against a biomass threshold, then we would need to accumulate it over some period of time that still remains to be defined and motivated.
    For another: sum(S[i] for i in region) == 0 implies that all S[i] == 0, which can only occur if all of them have been forced to zero. But if any of them is being forced to zero then there is no way we could have rescued it. I fail to see a consistent procedure where we both allow rescue and yet still expect true regional zero to trigger regional extinction.

    But I can think of another representation (most of it is just rephrasing the above to better demonstrate how I think it does fit both our expectations, but it's maybe worth it):

    • region: a connected component of patches.
    • local extinction threshold l_ext: local biomasses are considered extinct when reaching below this threshold, they are considered rescued when they reach above. May represent e.g. individual biomass.
    • local extinction event: any observed t where S[t] >= l_ext but S[t+dt] < l_ext. We can record the event but we don't force S to zero yet because rescue remains possible.
    • local rescue event: any observed t where S[t] < l_ext but S[t+dt] >= l_ext. We can record the event but we still let S evolve freely according to the interactions DEs.
    • regional extinction threshold r_ext: regional biomass is considered extinct when reaching below this threshold. It cannot be rescued then. May represent e.g. minimal propagule size for (re-)colonization.
    • regional extinction event: fired once per region when sum(S[i] for i in region) < r_ext is first observed. All S[i] are forced to zero from this point on and without any opportunity for being rescued.
    • regional rescue event: undefined, never happens. zombies. bad.

    We can have l_ext = r_ext = ext of course if we find this meaningful.
    Under the hood, we let all S[i] freely evolve however close/far from zero until regional extinction. S[1] can therefore become extincted and then rescued a thousand times in a cycling or chaotic pattern without the simulation becoming cluttered with checkpoints. Rescue emerges from the natural interactions among species and migratory corridors, as defined in the ODE equations. Only one artefactual discontinuity is ever introduced, and only when regional extinction occur.

    Would that sound better to you than the phrasing above? In particular, local extinctions do exist. And regional extinction remains modelled as "all species are locally too weak to regionally maintain".

    Now (I am scared to ask but) #150 is still real. If we had to re-calculate e.g. consumer preferences on extinction events. I think we should rather do this on regional extinctions events rather than local extinctions events, because as long as regional extinctions events did not happen then species are not completely gone. Migration corridors are still at play. The biomass is still around, trying to recolonize the local patch. It is too early for biorates to update. What do you think?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions