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

Animal - Feature/multi grid occupancy #530

Merged
merged 38 commits into from
Dec 4, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
9b88fe0
Basic outline of an Animal Territories class.
TaranRallings Jul 10, 2024
b963654
Added methods for initialize territory, territory size, updating terr…
TaranRallings Jul 10, 2024
e988161
Revised initialize_territory to use breadth-first search.
TaranRallings Jul 11, 2024
4b64df3
Merge branch 'develop' into feature/multi_grid_occupancy
TaranRallings Jul 11, 2024
11a8326
Added a Territory protocol to avoid circular reference.
TaranRallings Jul 11, 2024
0286b62
Added calls to initialize_territory to birth, migration, and metamorp…
TaranRallings Jul 11, 2024
0e3d2a3
Changed initialize_territory to use dynamic importing.
TaranRallings Jul 11, 2024
58a32a5
Added testing for AnimalTerritory.
TaranRallings Jul 11, 2024
67e0997
Refactored initialize_territory so that bfs_territory is a stand alon…
TaranRallings Jul 12, 2024
195417b
Added test for bfs_territory.
TaranRallings Jul 12, 2024
0aa128f
Added test for initialize_territory.
TaranRallings Jul 12, 2024
49ae8bb
Merge branch 'develop' into feature/multi_grid_occupancy
TaranRallings Jul 15, 2024
54639cb
Fixed test_calculate_potential_consumed_mass.
TaranRallings Jul 15, 2024
4c7fe4c
Reworking of types and protocols.
TaranRallings Jul 16, 2024
1766d88
Updated defecate for all pools in territory.
TaranRallings Jul 16, 2024
24f0c47
Merge branch 'develop' into feature/multi_grid_occupancy
TaranRallings Jul 17, 2024
aaa75e5
Many small changes to get typing to work between files/classes. This …
TaranRallings Jul 18, 2024
4ceba3c
die_individual now calls update_carcass_pools.
TaranRallings Jul 18, 2024
bb70dfb
Updated excrete for multi-grid.
TaranRallings Jul 18, 2024
1e93fc4
Added a community.occupancy attribute to track cohorts partially in a…
TaranRallings Jul 19, 2024
a896d0f
Added abandon_communities method to animal territory.
TaranRallings Jul 19, 2024
56ee5d0
Added a reinitialize_territory method and modified migrate.
TaranRallings Jul 19, 2024
d6313bf
Updated test_animal_territories.
TaranRallings Jul 22, 2024
6798997
Updated tests for animal_cohorts.
TaranRallings Jul 23, 2024
1eba4f2
Added all_occupying_cohorts method and revised test_forage_community.
TaranRallings Jul 24, 2024
1f85190
Revised test_inflict_non_predation_mortality.
TaranRallings Jul 25, 2024
af6bb16
Fully revised test_animal_communities for multi-grid.
TaranRallings Jul 25, 2024
c68a9e7
Updated animal model tests.
TaranRallings Jul 25, 2024
81cd1f4
Finished revising all animal tests for multi grid occupancy.
TaranRallings Jul 25, 2024
5b5708d
Merge branch 'develop' into feature/multi_grid_occupancy
TaranRallings Jul 26, 2024
4dbb2d8
Added temporary solution to problem with plant data and ve_run testing.
TaranRallings Jul 26, 2024
4efee34
Added test for reinitialize territory.
TaranRallings Jul 26, 2024
a777fc2
Small docstring fix in animal communities.
TaranRallings Jul 29, 2024
fbae47b
Added a mass check on forage_cohort.
TaranRallings Jul 30, 2024
dddfa6b
Adjusted defecate docstring to fix doc build errors.
TaranRallings Jul 30, 2024
1908f0a
Modified test_generate_animal_model to deal with stochastic warnings.
TaranRallings Jul 30, 2024
8c68c14
Fixed defecate docstring bug.
TaranRallings Jul 30, 2024
b979702
Merge branch 'develop' into feature/multi_grid_occupancy
TaranRallings Aug 2, 2024
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
Prev Previous commit
Next Next commit
Updated test_animal_territories.
  • Loading branch information
TaranRallings committed Jul 22, 2024
commit d6313bfabe01ca4dd035c55d0c04acf11fd251dc
4 changes: 2 additions & 2 deletions tests/models/animals/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ def functional_group_list_instance(shared_datadir, constants_instance):

@pytest.fixture
def animal_model_instance(
data_instance,
animal_data_for_community_instance,
fixture_core_components,
functional_group_list_instance,
constants_instance,
Expand All @@ -163,7 +163,7 @@ def animal_model_instance(
from virtual_ecosystem.models.animal.animal_model import AnimalModel

return AnimalModel(
data=data_instance,
data=animal_data_for_community_instance,
core_components=fixture_core_components,
functional_groups=functional_group_list_instance,
model_constants=constants_instance,
Expand Down
106 changes: 90 additions & 16 deletions tests/models/animals/test_animal_territories.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,32 +21,46 @@ def animal_territory_instance(self, get_community_by_key):
from virtual_ecosystem.models.animal.animal_territories import AnimalTerritory

return AnimalTerritory(
grid_cell_keys=[1, 2, 3], get_community_by_key=get_community_by_key
centroid=0,
grid_cell_keys=[1, 2, 3],
get_community_by_key=get_community_by_key,
)

def test_update_territory(
self, mocker, animal_territory_instance, herbivore_cohort_instance
):
"""Test for update_territory method."""
mock_get_prey = mocker.patch.object(
animal_territory_instance, "get_prey", return_value=[]
)
mock_get_plant_resources = mocker.patch.object(
@pytest.fixture
def mock_get_plant_resources(self, mocker, animal_territory_instance):
"""Mock get_plant_resources method."""
return mocker.patch.object(
animal_territory_instance, "get_plant_resources", return_value=[]
)
mock_get_excrement_pools = mocker.patch.object(

@pytest.fixture
def mock_get_excrement_pools(self, mocker, animal_territory_instance):
"""Mock get_excrement_pools method."""
return mocker.patch.object(
animal_territory_instance, "get_excrement_pools", return_value=[]
)
mock_get_carcass_pool = mocker.patch.object(
animal_territory_instance, "get_carcass_pool", return_value=[]

@pytest.fixture
def mock_get_carcass_pools(self, mocker, animal_territory_instance):
"""Mock get_carcass_pools method."""
return mocker.patch.object(
animal_territory_instance, "get_carcass_pools", return_value=[]
)

def test_update_territory(
self,
animal_territory_instance,
herbivore_cohort_instance,
mock_get_plant_resources,
mock_get_excrement_pools,
mock_get_carcass_pools,
):
"""Test for update_territory method."""
animal_territory_instance.update_territory(herbivore_cohort_instance)

mock_get_prey.assert_called_once_with(herbivore_cohort_instance)
mock_get_plant_resources.assert_called_once()
mock_get_excrement_pools.assert_called_once()
mock_get_carcass_pool.assert_called_once()
mock_get_carcass_pools.assert_called_once()

def test_get_prey(
self,
Expand Down Expand Up @@ -83,15 +97,75 @@ def test_get_excrement_pools(self, animal_territory_instance):
for excrement in excrement_pools:
assert isinstance(excrement, ExcrementPool)

def test_get_carcass_pool(self, animal_territory_instance):
def test_get_carcass_pools(self, animal_territory_instance):
"""Test for get carcass pool method."""
from virtual_ecosystem.models.animal.decay import CarcassPool

carcass_pools = animal_territory_instance.get_carcass_pool()
carcass_pools = animal_territory_instance.get_carcass_pools()
assert len(carcass_pools) == len(animal_territory_instance.grid_cell_keys)
for carcass in carcass_pools:
assert isinstance(carcass, CarcassPool)

@pytest.fixture
def mock_carcass_pool(self, mocker):
"""Fixture for a mock CarcassPool."""
mock_pool = mocker.Mock()
mock_pool.scavengeable_energy = 10000.0
mock_pool.decomposed_energy = 0.0
return mock_pool
Comment on lines +88 to +94
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why mock it? It's a small enough resource that it looks like you can simply use:

from virtual_ecosystem.models.animal.decay import CarcassPool
return CarcassPool(scavengeable_energy=10000.0, decomposed_energy=0)


@pytest.fixture
def mock_community(self, mocker, mock_carcass_pool):
"""Fixture for a mock AnimalCommunity with a carcass pool."""
community_mock = mocker.Mock()
community_mock.carcass_pool = mock_carcass_pool
return community_mock

@pytest.fixture
def mock_get_community_by_key(self, mocker, mock_community):
"""Fixture for get_community_by_key, returning a mock community."""
return mocker.Mock(side_effect=lambda key: mock_community)

@pytest.fixture
def animal_territory_instance_1(self, mock_get_community_by_key):
"""Fixture for the first animal territory with mock get_community_by_key."""
from virtual_ecosystem.models.animal.animal_territories import AnimalTerritory

return AnimalTerritory(
centroid=0,
grid_cell_keys=[1, 2, 3],
get_community_by_key=mock_get_community_by_key,
)

@pytest.fixture
def animal_territory_instance_2(self, mock_get_community_by_key):
"""Fixture for the second animal territory with mock get_community_by_key."""
from virtual_ecosystem.models.animal.animal_territories import AnimalTerritory

return AnimalTerritory(
centroid=1,
grid_cell_keys=[2, 3, 4],
get_community_by_key=mock_get_community_by_key,
)

def test_find_intersecting_carcass_pools(
self,
animal_territory_instance_1,
animal_territory_instance_2,
mock_carcass_pool,
):
"""Test for find_intersecting_carcass_pools method."""
intersecting_pools = (
animal_territory_instance_1.find_intersecting_carcass_pools(
animal_territory_instance_2
)
)
Comment on lines +108 to +141
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
@pytest.fixture
def animal_territory_instance_1(self, mock_get_community_by_key):
"""Fixture for the first animal territory with mock get_community_by_key."""
from virtual_ecosystem.models.animal.animal_territories import AnimalTerritory
return AnimalTerritory(
centroid=0,
grid_cell_keys=[1, 2, 3],
get_community_by_key=mock_get_community_by_key,
)
@pytest.fixture
def animal_territory_instance_2(self, mock_get_community_by_key):
"""Fixture for the second animal territory with mock get_community_by_key."""
from virtual_ecosystem.models.animal.animal_territories import AnimalTerritory
return AnimalTerritory(
centroid=1,
grid_cell_keys=[2, 3, 4],
get_community_by_key=mock_get_community_by_key,
)
def test_find_intersecting_carcass_pools(
self,
animal_territory_instance_1,
animal_territory_instance_2,
mock_carcass_pool,
):
"""Test for find_intersecting_carcass_pools method."""
intersecting_pools = (
animal_territory_instance_1.find_intersecting_carcass_pools(
animal_territory_instance_2
)
)
@pytest.fixture
def animal_territory_instances(self, mock_get_community_by_key):
"""Fixture for the first animal territory with mock get_community_by_key."""
from virtual_ecosystem.models.animal.animal_territories import AnimalTerritory
return (
AnimalTerritory(
centroid=0,
grid_cell_keys=[1, 2, 3],
get_community_by_key=mock_get_community_by_key,
),
AnimalTerritory(
centroid=1,
grid_cell_keys=[2, 3, 4],
get_community_by_key=mock_get_community_by_key,
)
)
def test_find_intersecting_carcass_pools(
self,
animal_territory_instances,
mock_carcass_pool,
):
"""Test for find_intersecting_carcass_pools method."""
t1, t2 = animal_territory_instances
intersecting_pools = t1.find_intersecting_carcass_pools(t2)

It might even be making the fixture in the conftest.py provide these two and just reuse it. You can always ditch one when it isn't needed: t1, _ = animal_community_instances


# Since the same mock object is returned, we need to repeat it for the
# expected value.
expected_pools = [mock_carcass_pool, mock_carcass_pool]
assert intersecting_pools == expected_pools


@pytest.mark.parametrize(
"centroid_key, target_cell_number, cell_nx, cell_ny, expected",
Expand Down
9 changes: 6 additions & 3 deletions virtual_ecosystem/models/animal/animal_communities.py
Original file line number Diff line number Diff line change
Expand Up @@ -213,8 +213,9 @@ def populate_community(self) -> None:
def migrate(self, migrant: AnimalCohort, destination: AnimalCommunity) -> None:
"""Function to move an AnimalCohort between AnimalCommunity objects.

This function should take a cohort and a destination community and then pop the
cohort from this community to the destination.
This function takes a cohort and a destination community, changes the
centroid of the cohort's territory to be the new community, and then
reinitializes the territory around the new centroid.

TODO: travel distance should be a function of body-size or locomotion once
multi-grid occupancy is integrated.
Expand All @@ -236,7 +237,7 @@ def migrate(self, migrant: AnimalCohort, destination: AnimalCommunity) -> None:
)

def migrate_community(self) -> None:
"""This handles migrating all cohorts in a community.
"""This handles migrating all cohorts with a centroid in the community.

This migration method initiates migration for two reasons:
1) The cohort is starving and needs to move for a chance at resource access
Expand Down Expand Up @@ -399,6 +400,8 @@ def collect_prey(
This is a helper function for territory.get_prey, it filters suitable prey from
the total list of animal cohorts across the territory.

TODO: possibly moved to be a territory method

Args:
consumer_cohort: The AnimalCohort for which a prey list is being collected

Expand Down
4 changes: 2 additions & 2 deletions virtual_ecosystem/models/animal/animal_territories.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def __init__(
"""A list of grid cells present in the territory."""
self.get_community_by_key = get_community_by_key
"""A list of animal communities present in the territory."""
self.territory_prey: Sequence[Consumer] = []
# self.territory_prey: Sequence[Consumer] = []
"""A list of animal prey present in the territory."""
self.territory_plants: Sequence[Resource] = []
"""A list of plant resources present in the territory."""
Expand All @@ -60,7 +60,7 @@ def update_territory(self, consumer_cohort: Consumer) -> None:

"""

self.territory_prey = self.get_prey(consumer_cohort)
# self.territory_prey = self.get_prey(consumer_cohort)
self.territory_plants = self.get_plant_resources()
self.territory_excrement = self.get_excrement_pools()
self.territory_carcasses = self.get_carcass_pools()
Expand Down