diff --git a/tests/models/animals/test_scaling_functions.py b/tests/models/animals/test_scaling_functions.py index fa0337149..4118c7a17 100644 --- a/tests/models/animals/test_scaling_functions.py +++ b/tests/models/animals/test_scaling_functions.py @@ -89,78 +89,6 @@ def test_metabolic_rate(mass, temperature, terms, metabolic_type, met_rate): assert testing_rate == pytest.approx(met_rate, rel=1e-6) -@pytest.mark.parametrize( - "mass, muscle, terms", - [ - pytest.param(0.0, 0.0, (1.0, 0.38), id="zero_mass"), - pytest.param(1.0, 380.0, (1.0, 0.38), id="small_mass"), - pytest.param(1000.0, 380000.0, (1.0, 0.38), id="large_mass"), - ], -) -def test_muscle_mass_scaling(mass, muscle, terms): - """Testing muscle mass scaling for various body-masses.""" - - from virtual_ecosystem.models.animal.scaling_functions import muscle_mass_scaling - - gains = muscle_mass_scaling(mass, terms) - assert gains == pytest.approx(muscle, rel=1e-6) - - -@pytest.mark.parametrize( - "mass, fat, terms", - [ - pytest.param(0.0, 0.0, (1.19, 0.02), id="zero_mass"), - pytest.param(1.0, 74.307045, (1.19, 0.02), id="low_mass"), - pytest.param(1000.0, 276076.852920, (1.19, 0.02), id="large_mass"), - ], -) -def test_fat_mass_scaling(mass, fat, terms): - """Testing fat mass scaling for various body-masses.""" - - from virtual_ecosystem.models.animal.scaling_functions import fat_mass_scaling - - gains = fat_mass_scaling(mass, terms) - assert gains == pytest.approx(fat, rel=1e-6) - - -@pytest.mark.parametrize( - "mass, energy, muscle_terms, fat_terms", - [ - pytest.param(0.0, 0.0, (1.0, 0.38), (1.19, 0.02), id="zerp_mass"), - pytest.param(1.0, 3180149.320736, (1.0, 0.38), (1.19, 0.02), id="low_mass"), - pytest.param( - 1000.0, 4592537970.444037, (1.0, 0.38), (1.19, 0.02), id="high_mass" - ), - ], -) -def test_energetic_reserve_scaling(mass, energy, muscle_terms, fat_terms): - """Testing energetic reserve scaling for various body-masses.""" - - from virtual_ecosystem.models.animal.scaling_functions import ( - energetic_reserve_scaling, - ) - - gains = energetic_reserve_scaling(mass, muscle_terms, fat_terms) - assert gains == pytest.approx(energy, rel=1e-6) - - -@pytest.mark.parametrize( - "mass, intake_rate, terms", - [ - pytest.param(0.0, 0.0, (0.71, 0.63), id="zero_mass"), - pytest.param(1.0, 0.3024, (0.71, 0.63), id="low_mass"), - pytest.param(1000.0, 40.792637, (0.71, 0.63), id="high_mass"), - ], -) -def test_intake_rate_scaling(mass, intake_rate, terms): - """Testing intake rate scaling for various body-masses.""" - - from virtual_ecosystem.models.animal.scaling_functions import intake_rate_scaling - - test_rate = intake_rate_scaling(mass, terms) - assert test_rate == pytest.approx(intake_rate, rel=1e-6) - - def test_herbivore_prey_group_selection(): """Test for herbivore diet type selection.""" from virtual_ecosystem.models.animal.scaling_functions import ( @@ -214,48 +142,6 @@ def test_prey_group_selection_mass_and_terms_impact(): assert result_default == result_diff_mass == result_diff_terms -@pytest.mark.parametrize( - "mass, terms, expected, error_type", - [ - pytest.param(1.0, (0.25, 0.05), 0.2055623, None, id="low_mass_valid"), - pytest.param(1000.0, (0.01, 0.1), 0.1018162, None, id="high_mass_valid"), - pytest.param( - 0.0, - (0.71, 0.63), - None, - ZeroDivisionError, - id="zero_mass_error", - ), - pytest.param( - -1.0, - (0.71, 0.63), - None, - TypeError, - id="negative_mass_error", - ), - pytest.param( - 1.0, - (0.71,), - None, - IndexError, - id="invalid_terms_error", - ), - ], -) -def test_natural_mortality_scaling(mass, terms, expected, error_type): - """Testing natural mortality scaling for various body-masses.""" - from virtual_ecosystem.models.animal.scaling_functions import ( - natural_mortality_scaling, - ) - - if error_type: - with pytest.raises(error_type): - natural_mortality_scaling(mass, terms) - else: - result = natural_mortality_scaling(mass, terms) - assert result == pytest.approx(expected, rel=1e-6) - - @pytest.mark.parametrize( "input_value, expected_output", [ diff --git a/virtual_ecosystem/models/animal/animal_cohorts.py b/virtual_ecosystem/models/animal/animal_cohorts.py index ea46e304a..2c2f45f20 100644 --- a/virtual_ecosystem/models/animal/animal_cohorts.py +++ b/virtual_ecosystem/models/animal/animal_cohorts.py @@ -68,12 +68,6 @@ def __init__( """The amount of time [days] since reaching adult body-mass.""" self.reproductive_mass: float = 0.0 """The pool of biomass from which the material of reproduction is drawn.""" - - self.intake_rate: float = sf.intake_rate_scaling( - self.functional_group.adult_mass, self.functional_group.intake_rate_terms - ) - """The individual rate of plant mass consumption over an 8hr foraging day - [kg/day].""" self.prey_groups = sf.prey_group_selection( self.functional_group.diet, self.functional_group.adult_mass, diff --git a/virtual_ecosystem/models/animal/constants.py b/virtual_ecosystem/models/animal/constants.py index ea58d0efb..4e5c3e5c4 100644 --- a/virtual_ecosystem/models/animal/constants.py +++ b/virtual_ecosystem/models/animal/constants.py @@ -53,30 +53,6 @@ class AnimalConsts(ConstantsDataclass): } ) - fat_mass_terms: dict[TaxaType, tuple[float, float]] = field( - default_factory=lambda: { - TaxaType.MAMMAL: (1.19, 0.02), # Scaling of mammalian herbivore fat mass - TaxaType.BIRD: (1.19, 0.05), # Toy Values - TaxaType.INSECT: (1.19, 0.05), # Toy Values - } - ) - - muscle_mass_terms: dict[TaxaType, tuple[float, float]] = field( - default_factory=lambda: { - TaxaType.MAMMAL: (1.0, 0.38), # Scaling of mammalian herbivore muscle mass - TaxaType.BIRD: (1.0, 0.40), # Toy Values - TaxaType.INSECT: (1.0, 0.40), # Toy Values - } - ) - - intake_rate_terms: dict[TaxaType, tuple[float, float]] = field( - default_factory=lambda: { - TaxaType.MAMMAL: (0.71, 0.63), # Mammalian maximum intake rate - TaxaType.BIRD: (0.7, 0.50), # Toy Values - TaxaType.INSECT: (0.7, 0.50), # Toy Values - } - ) - energy_density: dict[str, float] = field( default_factory=lambda: { "meat": 7000.0, # Energy of mammal meat [J/g] @@ -110,14 +86,6 @@ class AnimalConsts(ConstantsDataclass): } ) - longevity_scaling_terms: dict[TaxaType, tuple[float, float]] = field( - default_factory=lambda: { - TaxaType.MAMMAL: (0.25, 0.02), # Toy values - TaxaType.BIRD: (0.25, 0.05), # Toy values - TaxaType.INSECT: (0.25, 0.05), # Toy values - } - ) - birth_mass_threshold: float = 1.5 # Threshold for reproduction flow_to_reproductive_mass_threshold: float = ( 1.0 # Threshold of trophic flow to reproductive mass diff --git a/virtual_ecosystem/models/animal/functional_group.py b/virtual_ecosystem/models/animal/functional_group.py index c2dd99220..f81765fef 100644 --- a/virtual_ecosystem/models/animal/functional_group.py +++ b/virtual_ecosystem/models/animal/functional_group.py @@ -84,12 +84,6 @@ def __init__( """The coefficient and exponent of metabolic rate.""" self.damuths_law_terms = self.constants.damuths_law_terms[self.taxa][self.diet] """The coefficient and exponent of damuth's law for population density.""" - self.muscle_mass_terms = self.constants.muscle_mass_terms[self.taxa] - """The coefficient and exponent of muscle mass allometry.""" - self.fat_mass_terms = self.constants.fat_mass_terms[self.taxa] - """The coefficient and exponent of fat mass allometry.""" - self.intake_rate_terms = self.constants.intake_rate_terms[self.taxa] - """The coefficient and exponent of intake allometry.""" self.conversion_efficiency = self.constants.conversion_efficiency[self.diet] """The conversion efficiency of the functional group based on diet.""" self.mechanical_efficiency = self.constants.mechanical_efficiency[self.diet] @@ -98,8 +92,6 @@ def __init__( self.taxa ] """The predator-prey mass ratio scaling relationship.""" - self.longevity_scaling = self.constants.longevity_scaling_terms[self.taxa] - """The coefficient and exponent for lifespan allometry.""" def import_functional_groups( diff --git a/virtual_ecosystem/models/animal/protocols.py b/virtual_ecosystem/models/animal/protocols.py index cebc0ca72..deaca524f 100644 --- a/virtual_ecosystem/models/animal/protocols.py +++ b/virtual_ecosystem/models/animal/protocols.py @@ -11,7 +11,6 @@ class Consumer(Protocol): """This is the protocol for defining consumers (currently just AnimalCohort).""" - intake_rate: float functional_group: FunctionalGroup individuals: int diff --git a/virtual_ecosystem/models/animal/scaling_functions.py b/virtual_ecosystem/models/animal/scaling_functions.py index 49a32d30f..f299eb993 100644 --- a/virtual_ecosystem/models/animal/scaling_functions.py +++ b/virtual_ecosystem/models/animal/scaling_functions.py @@ -94,94 +94,6 @@ def metabolic_rate( raise ValueError("Invalid metabolic type: {metabolic_type}") -def muscle_mass_scaling(mass: float, terms: tuple) -> float: - """The function to set the amount of muscle mass on individual in an AnimalCohort. - - Currently, this scaling relationship is only accurate for terrestrial mammals. - This will later be updated for additional functional types. - - TODO: Remove if unused. - - Args: - mass: The body-mass [kg] of an AnimalCohort. - terms: The tuple of muscle scaling terms used. - - Returns: - The mass [g] of muscle on an individual of the animal cohort. - - """ - - return terms[1] * (mass * 1000) ** terms[0] - - -def fat_mass_scaling(mass: float, terms: tuple) -> float: - """The function to set the amount of fat mass on individual in an AnimalCohort. - - Currently, this scaling relationship is only accurate for terrestrial mammals. - This will later be updated for additional functional types. - - TODO: Remove if unused. - - Args: - mass: The body-mass [kg] of an AnimalCohort. - terms: The tuple of fat scaling terms used. - - Returns: - The mass [g] of fat on an individual of the animal cohort. - - """ - - return terms[1] * (mass * 1000) ** terms[0] - - -def energetic_reserve_scaling( - mass: float, muscle_terms: tuple, fat_terms: tuple -) -> float: - """The function to set the energetic reserve of an individual in an AnimalCohort. - - Currently, this scaling relationship is only accurate for terrestrial mammals. - This will later be updated for additional functional types. - - TODO: Remove if unused. - - Args: - mass: The body-mass [kg] of an AnimalCohort. - muscle_terms: The tuple of muscle scaling terms used. - fat_terms: The tuple of fat scaling terms used. - - Returns: - The energetic reserve [J] of an individual of the animal cohort. - - """ - return ( - muscle_mass_scaling(mass, muscle_terms) + fat_mass_scaling(mass, fat_terms) - ) * 7000.0 # j/g - - -def intake_rate_scaling(mass: float, terms: tuple) -> float: - """The function to set the intake rate of an individual in an AnimalCohort. - - Currently, this scaling relationship is only accurate for terrestrial - herbivorous mammals interacting with plant foods. This will later be updated - for additional functional types and interactions. - - The function form converts the original g/min rate into a kg/day rate, where a - day is an 8hr foraging window. - - TODO: Remove if unused. - - Args: - mass: The body-mass [kg] of an AnimalCohort. - terms: The tuple of intake rate terms used. - - Returns: - The intake rate [kg/day] of an individual of the animal cohort. - - """ - - return terms[1] * mass ** terms[0] * 480 * (1 / 1000) - - def prey_group_selection( diet_type: DietType, mass: float, terms: tuple ) -> dict[str, tuple[float, float]]: @@ -221,37 +133,6 @@ def prey_group_selection( raise ValueError("Invalid diet type: {diet_type}") -def natural_mortality_scaling(mass: float, terms: tuple) -> float: - """Determine the natural mortality rate of animal cohorts. - - Relationship from: Dureuil & Froese 2021 - - M = - ln(P) / tmax (annual, year^-1, instantaneous rate) - tmax = mean maximum age - P = 0.015 # proportion surviving to tmax - - Transform yearly rate to daily rate - transform daily rate to daily probability - prob = 1 - e^-M - - TODO: Remove if unused. - - Args: - mass: The body-mass [kg] of an AnimalCohort. - terms: The terms of the mean maximum age equation. - - Returns: - The allometric natural mortality rate as a daily probability of death. - - """ - tmax = terms[1] * mass ** terms[0] - annual_mortality_rate = -log(0.015) / tmax - daily_mortality_rate = annual_mortality_rate / 365.0 - daily_mortality_prob = 1 - exp(-daily_mortality_rate) - - return daily_mortality_prob - - def background_mortality(u_bg: float) -> float: """Constant background rate of wastebasket mortality.