Skip to content
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

Adding non-predation mortality and semelparity to the Animal Module. #422

Merged
merged 18 commits into from
May 31, 2024
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,41 +191,47 @@ def fixture_config():
taxa = "bird"
diet = "carnivore"
metabolic_type = "endothermic"
reproductive_type = "iteroparous"
birth_mass = 0.1
adult_mass = 1.0
[[animals.functional_groups]]
name = "herbivorous_bird"
taxa = "bird"
diet = "herbivore"
metabolic_type = "endothermic"
reproductive_type = "iteroparous"
birth_mass = 0.05
adult_mass = 0.5
[[animals.functional_groups]]
name = "carnivorous_mammal"
taxa = "mammal"
diet = "carnivore"
metabolic_type = "endothermic"
reproductive_type = "iteroparous"
birth_mass = 4.0
adult_mass = 40.0
[[animals.functional_groups]]
name = "herbivorous_mammal"
taxa = "mammal"
diet = "herbivore"
metabolic_type = "endothermic"
reproductive_type = "iteroparous"
birth_mass = 1.0
adult_mass = 10.0
[[animals.functional_groups]]
name = "carnivorous_insect"
taxa = "insect"
diet = "carnivore"
metabolic_type = "ectothermic"
reproductive_type = "semelparous"
birth_mass = 0.001
adult_mass = 0.01
[[animals.functional_groups]]
name = "herbivorous_insect"
taxa = "insect"
diet = "herbivore"
metabolic_type = "ectothermic"
reproductive_type = "iteroparous"
birth_mass = 0.0005
adult_mass = 0.005
"""
Expand Down
6 changes: 6 additions & 0 deletions tests/core/data/all_config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ diet = "carnivore"
metabolic_type = "endothermic"
birth_mass = 0.1
adult_mass = 1.0
reproductive_type = "iteroparous"

[[animals.functional_groups]]
name = "herbivorous_bird"
Expand All @@ -44,6 +45,7 @@ diet = "herbivore"
metabolic_type = "endothermic"
birth_mass = 0.05
adult_mass = 0.5
reproductive_type = "iteroparous"

[[animals.functional_groups]]
name = "carnivorous_mammal"
Expand All @@ -52,6 +54,7 @@ diet = "carnivore"
metabolic_type = "endothermic"
birth_mass = 4.0
adult_mass = 40.0
reproductive_type = "iteroparous"

[[animals.functional_groups]]
name = "herbivorous_mammal"
Expand All @@ -60,6 +63,7 @@ diet = "herbivore"
metabolic_type = "endothermic"
birth_mass = 1.0
adult_mass = 10.0
reproductive_type = "iteroparous"

[[animals.functional_groups]]
name = "carnivorous_insect"
Expand All @@ -68,6 +72,7 @@ diet = "carnivore"
metabolic_type = "ectothermic"
birth_mass = 0.001
adult_mass = 0.01
reproductive_type = "iteroparous"

[[animals.functional_groups]]
name = "herbivorous_insect"
Expand All @@ -76,3 +81,4 @@ diet = "herbivore"
metabolic_type = "ectothermic"
birth_mass = 0.0005
adult_mass = 0.005
reproductive_type = "semelparous"
16 changes: 9 additions & 7 deletions tests/models/animals/data/example_functional_group_import.csv
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
name,taxa,diet,metabolic_type,birth_mass,adult_mass
carnivorous_bird,bird,carnivore,endothermic,0.1,1.0
herbivorous_bird,bird,herbivore,endothermic,0.05,0.5
carnivorous_mammal,mammal,carnivore,endothermic,4.0,40.0
herbivorous_mammal,mammal,herbivore,endothermic,1.0,10.0
carnivorous_insect,insect,carnivore,ectothermic,0.001,0.01
herbivorous_insect,insect,herbivore,ectothermic,0.0005,0.005
name,taxa,diet,metabolic_type,reproductive_type,birth_mass,adult_mass
carnivorous_bird,bird,carnivore,endothermic,iteroparous,0.1,1.0
herbivorous_bird,bird,herbivore,endothermic,iteroparous,0.05,0.5
carnivorous_mammal,mammal,carnivore,endothermic,iteroparous,4.0,40.0
herbivorous_mammal,mammal,herbivore,endothermic,iteroparous,1.0,10.0
carnivorous_insect_iteroparous,insect,carnivore,ectothermic,iteroparous,0.001,0.01
herbivorous_insect_iteroparous,insect,herbivore,ectothermic,iteroparous,0.0005,0.005
carnivorous_insect_semelparous,insect,carnivore,ectothermic,semelparous,0.001,0.01
herbivorous_insect_semelparous,insect,herbivore,ectothermic,semelparous,0.0005,0.005
128 changes: 128 additions & 0 deletions tests/models/animals/test_animal_cohorts.py
Original file line number Diff line number Diff line change
Expand Up @@ -1015,3 +1015,131 @@ def test_migrate_juvenile_probability(
assert (
probability_of_dispersal == expected_probability
), "The probability calculated did not match the expected probability."

@pytest.mark.parametrize(
"is_mature, u_bg, lambda_se, t_to_maturity, t_since_maturity, lambda_max, J_st,"
"zeta_st, mass_current, mass_max, dt, expected_dead",
[
pytest.param(
True,
0.001,
0.003,
365,
30,
1.0,
0.6,
0.05,
600,
600,
30,
13,
id="mature_with_all_mortalities",
),
pytest.param(
False,
0.001,
0.003,
365,
30,
1.0,
0.6,
0.05,
600,
600,
30,
4,
id="immature_without_senescence",
),
],
)
def test_inflict_non_predation_mortality(
self,
mocker,
is_mature,
u_bg,
lambda_se,
t_to_maturity,
t_since_maturity,
lambda_max,
J_st,
zeta_st,
mass_current,
mass_max,
dt,
expected_dead,
predator_cohort_instance,
carcass_pool_instance,
):
"""Test the calculation of total non-predation mortality in a cohort."""
from math import ceil, exp

import virtual_ecosystem.models.animals.scaling_functions as sf

# Use the predator cohort instance and set initial individuals to 100
cohort = predator_cohort_instance
cohort.individuals = 100 # Set initial individuals count
cohort.is_mature = is_mature
cohort.mass_current = mass_current
cohort.time_to_maturity = t_to_maturity
cohort.time_since_maturity = t_since_maturity
cohort.functional_group.adult_mass = mass_max

# Mocking the mortality functions to return predefined values
mocker.patch(
"virtual_ecosystem.models.animals.scaling_functions.background_mortality",
return_value=u_bg,
)
mocker.patch(
"virtual_ecosystem.models.animals.scaling_functions.senescence_mortality",
return_value=(
lambda_se * exp(t_since_maturity / t_to_maturity) if is_mature else 0.0
),
)
mocker.patch(
"virtual_ecosystem.models.animals.scaling_functions.starvation_mortality",
return_value=(
lambda_max
/ (1 + exp((mass_current - J_st * mass_max) / (zeta_st * mass_max)))
),
)

# Diagnostics
print(f"Initial individuals: {cohort.individuals}")

# Run the method
cohort.inflict_non_predation_mortality(dt, carcass_pool_instance)

# Calculate expected number of deaths inside the test
u_bg_value = sf.background_mortality(u_bg)
u_se_value = (
sf.senescence_mortality(lambda_se, t_to_maturity, t_since_maturity)
if is_mature
else 0.0
)
u_st_value = sf.starvation_mortality(
lambda_max, J_st, zeta_st, mass_current, mass_max
)
u_t = u_bg_value + u_se_value + u_st_value

number_dead = ceil(100 * (1 - exp(-u_t * dt)))

# Diagnostics
print(
f"background: {u_bg_value},"
f"senescence: {u_se_value},"
f"starvation: {u_st_value}"
)
print(f"Calculated total mortality rate: {u_t}")
print(
f"Calculated number dead: {number_dead},"
f"Expected number dead: {expected_dead}"
)
print(
f"Remaining individuals: {cohort.individuals},"
f"Expected remaining: {100 - expected_dead}"
)

# Verify
assert (
cohort.individuals == 100 - expected_dead
), "The calculated number of dead individuals doesn't match the expected value."
Loading
Loading