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

Feature #247

Merged
merged 65 commits into from
Nov 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
7d8657a
Initial commit
mghosh00 Nov 15, 2023
3eea911
Added household id
mghosh00 Nov 15, 2023
34db412
Added set_id
abbie-evans Nov 15, 2023
3f25185
Added ID for person and households
abbie-evans Nov 15, 2023
12e0e9b
Added some tests and a regex check
mghosh00 Nov 16, 2023
ffdb83f
Merge conflict
abbie-evans Nov 16, 2023
a6039b0
Merge branch 'feature-id' of github.com:SABS-R3-Epidemiology/epiabm i…
abbie-evans Nov 16, 2023
830988c
Resolved circular import errors
KCGallagher Nov 16, 2023
55e5337
Merge branch 'feature-id' of github.com:SABS-R3-Epidemiology/epiabm i…
abbie-evans Nov 16, 2023
7322f07
Ensure unique cell ids for toy pop
KCGallagher Nov 16, 2023
71d6d68
Merge branch 'feature-id' of github.com:SABS-R3-Epidemiology/epiabm i…
abbie-evans Nov 16, 2023
da3669e
Removed print statement
abbie-evans Nov 16, 2023
bed0a99
Updated ID definition
abbie-evans Nov 16, 2023
4be6a4e
Updated test for ID
abbie-evans Nov 16, 2023
38b302c
Updated household id
abbie-evans Nov 17, 2023
8226f46
Updated set_id test
abbie-evans Nov 17, 2023
2f4f2db
Updated regex
mghosh00 Nov 17, 2023
c9ce368
Merge branch 'feature-id' of github.com:SABS-R3-Epidemiology/epiabm i…
mghosh00 Nov 17, 2023
5f9782f
self.id added
abbie-evans Nov 17, 2023
f4406b2
Updated set_id test
abbie-evans Nov 17, 2023
0a98755
Update add_household
abbie-evans Nov 17, 2023
a572114
Updated add_household test
abbie-evans Nov 17, 2023
537bf21
Merge branch 'feature-id' of github.com:SABS-R3-Epidemiology/epiabm i…
mghosh00 Nov 18, 2023
6d90677
Changed cell id to a string to match the other types, and fixed error…
mghosh00 Nov 19, 2023
839a713
Fixed line lengths
mghosh00 Nov 22, 2023
666afea
Import arrangement
abbie-evans Nov 22, 2023
c718a9f
Updated set_id tests
abbie-evans Nov 22, 2023
8c0d697
Merge branch 'feature-id' of github.com:SABS-R3-Epidemiology/epiabm i…
abbie-evans Nov 22, 2023
3df1187
Added checks for duplicates
mghosh00 Nov 22, 2023
3807cc6
Merge remote-tracking branch 'origin/feature-id' into feature-id
mghosh00 Nov 22, 2023
9e2bef6
Style changes
mghosh00 Nov 22, 2023
e46a784
Fixed error and changed make_pop
mghosh00 Nov 22, 2023
a983def
Added tests for uniqueness of id
abbie-evans Nov 22, 2023
182cdb6
Fixes of duplicate ids
mghosh00 Nov 22, 2023
2b2263d
Merge remote-tracking branch 'origin/feature-id' into feature-id
mghosh00 Nov 22, 2023
18a666d
Fixes of duplicate ids
mghosh00 Nov 22, 2023
6a8ddd6
Checked that the actual dataframe in test_file_population_config matc…
mghosh00 Nov 22, 2023
ecea0bd
Pandas version check
mghosh00 Nov 22, 2023
e21a57d
Fixed error
mghosh00 Nov 22, 2023
b8bde2c
Added duplicates test for cells
mghosh00 Nov 22, 2023
8027168
Added duplicates test for cells
mghosh00 Nov 22, 2023
705d114
Update set_id test for duplicates
abbie-evans Nov 22, 2023
1cbc7bb
Added argument cells for use of cells set_id
abbie-evans Nov 22, 2023
c7532d5
Attempt fix of indent error
abbie-evans Nov 22, 2023
ec76924
Style fixes
abbie-evans Nov 23, 2023
98eda4f
Merge branch 'main' into feature-id
abbie-evans Nov 23, 2023
48a98d2
Changed csv read so that cell and microcell ids are read as integers,…
mghosh00 Nov 23, 2023
7d8b8b0
Fixed some errors
mghosh00 Nov 23, 2023
e3eb42c
Updated error message
abbie-evans Nov 24, 2023
da8895a
Removed parameter chaining in the mock_read
mghosh00 Nov 27, 2023
89806cb
Modified add_household so that person id is only set if person does n…
mghosh00 Nov 29, 2023
8345e24
Added change_id parameter to the add_household function so that we ca…
mghosh00 Nov 29, 2023
f2074a7
Error fix
mghosh00 Nov 29, 2023
d326166
Style fixes
abbie-evans Nov 29, 2023
14cc1d2
Updated add_household to have a default value
mghosh00 Nov 30, 2023
a4f85ed
Merge remote-tracking branch 'origin/feature-id' into feature-id
mghosh00 Nov 30, 2023
63aad23
Made changes travel_sweep to ensure that the ids of travellers are set
mghosh00 Nov 30, 2023
15978f3
Update for loop in add_household
abbie-evans Nov 30, 2023
ea0a512
Changed add_household to have an override_person_id boolean attribute…
mghosh00 Nov 30, 2023
18c76fb
Merge remote-tracking branch 'origin/feature-id' into feature-id
mghosh00 Nov 30, 2023
3c2f5ce
Added further logging
mghosh00 Nov 30, 2023
4d13e6c
Update pyEpiabm/pyEpiabm/intervention/travel_isolation.py
mghosh00 Nov 30, 2023
84d5a46
Made changes
mghosh00 Nov 30, 2023
da35973
Merge remote-tracking branch 'origin/feature-id' into feature-id
mghosh00 Nov 30, 2023
3edfb19
Flake8 fix
mghosh00 Nov 30, 2023
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: 3 additions & 3 deletions pyEpiabm/pyEpiabm/core/_compartment_counter.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

from pyEpiabm.property import InfectionStatus

import pyEpiabm.core
from .parameters import Parameters


class _CompartmentCounter:
Expand All @@ -28,9 +28,9 @@ def __init__(self, identifier: str):
# Identifier
self._identifier = identifier
# Number of age groups
if pyEpiabm.core.Parameters.instance().use_ages:
if Parameters.instance().use_ages:
self.nb_age_groups =\
len(pyEpiabm.core.Parameters.instance().age_proportions)
len(Parameters.instance().age_proportions)
else:
self.nb_age_groups = 1

Expand Down
27 changes: 22 additions & 5 deletions pyEpiabm/pyEpiabm/core/cell.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@

import typing
import numpy as np
import re
from queue import Queue
from numbers import Number

from pyEpiabm.core import Parameters
from pyEpiabm.property import InfectionStatus
from pyEpiabm.utility import DistanceFunctions

from .microcell import Microcell
from .parameters import Parameters
from .person import Person
from ._compartment_counter import _CompartmentCounter

Expand All @@ -31,7 +32,7 @@ def __init__(self, loc: typing.Tuple[float, float] = (0, 0)):

"""
self.location = loc
self.id = hash(self)
self.id = str(hash(self))
self.microcells = []
self.persons = []
self.places = []
Expand Down Expand Up @@ -70,15 +71,31 @@ def add_microcells(self, n):
for _ in range(n):
self.microcells.append(Microcell(self))

def set_id(self, id: float):
"""Updates ID of cell (i.e. for input from file).
def set_id(self, id: str, cells: typing.List):
"""Updates id of current cell (i.e. for input from file).

Parameters
----------
id : float
id : str
Identity of cell
cells : list
List of all current cells

"""
# Ensure id is a string
if not isinstance(id, str):
raise TypeError("Provided id must be a string")

# This regex will match on any string which has 1 or more digits
if not re.match("^\\d+$", id):
raise ValueError(f"Invalid id: {id}. id must be of the form 'i' "
f"where i is an integer")

# Finally, check for duplicates
cell_ids = [cell.id for cell in cells]
if id in cell_ids:
raise ValueError(f"Duplicate id: {id}.")

self.id = id

def enqueue_person(self, person: Person):
Expand Down
33 changes: 33 additions & 0 deletions pyEpiabm/pyEpiabm/core/household.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

import typing
from numbers import Number
import re

from pyEpiabm.property import InfectionStatus

Expand Down Expand Up @@ -37,6 +38,7 @@ def __init__(self, microcell, loc: typing.Tuple[float, float],
self.cell = microcell.cell
self.microcell = microcell
self.isolation_location = False
self.id = self.microcell.id + "." + str(len(self.microcell.households))

if not (len(loc) == 2 and isinstance(loc[0], Number) and
isinstance(loc[1], Number)):
Expand Down Expand Up @@ -104,3 +106,34 @@ def remove_household(self):
"""
self.microcell.households.remove(self)
self.cell.households.remove(self)

def set_id(self, id: str):
"""Updates id of current household (i.e. for input from file).
Format of id - for example 3.1.2 represents household 2 within
microcell 1 within cell 3. The id will only be changed if it has the
correct expression.

Parameters
----------
id : str
Identity of household

"""

# Ensure id is a string
if not isinstance(id, str):
raise TypeError("Provided id must be a string")

# This regex will match on any string which takes the form "i.j.k"
# where i, j and k are integers
if not re.match("^\\d+\\.\\d+\\.\\d+$", id):
raise ValueError(f"Invalid id: {id}. id must be of the form "
f"'i.j.k' where i, j, k are integers")

# Finally, check for duplicates
household_ids = [household.id
for household in self.microcell.households]
if id in household_ids:
raise ValueError(f"Duplicate id: {id}.")

self.id = id
53 changes: 42 additions & 11 deletions pyEpiabm/pyEpiabm/core/microcell.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import typing
from numbers import Number
import logging
import re

from pyEpiabm.property import InfectionStatus

Expand All @@ -24,6 +25,7 @@ class Microcell:
An instance of :class:`Cell`

"""

def __init__(self, cell):
"""Constructor Method.

Expand All @@ -33,12 +35,12 @@ def __init__(self, cell):
Microcell's parent :class:`Cell` instance

"""
self.id = hash(self)
self.persons = []
self.places = []
self.households = []
self.cell = cell
self.location = cell.location
self.id = self.cell.id + "." + str(len(self.cell.microcells))
self.compartment_counter = _CompartmentCounter(
f"Microcell {id(self)}")

Expand All @@ -52,17 +54,33 @@ def __repr__(self):

"""
return f"Microcell with {len(self.persons)} people" + \
f" at location {self.location}."
f" at location {self.location}."

def set_id(self, id):
"""Updates ID of microcell (i.e. for input from file).
"""Updates id of current microcell (i.e. for input from file).

Parameters
----------
id : float
id : str
Identity of microcell

"""

# Ensure id is a string
if not isinstance(id, str):
raise TypeError("Provided id must be a string")

# This regex will match on any string which takes the form "i.j" where
# i and j are integers
if not re.match("^\\d+\\.\\d+$", id):
raise ValueError(f"Invalid id: {id}. id must be of the form 'i.j' "
f"where i, j are integers")

# Finally, check for duplicates
microcell_ids = [microcell.id for microcell in self.cell.microcells]
if id in microcell_ids:
raise ValueError(f"Duplicate id: {id}.")

self.id = id

def add_person(self, person):
Expand Down Expand Up @@ -123,27 +141,40 @@ def add_place(self, n: int, loc: typing.Tuple[float, float],
self.cell.places.append(p)
self.places.append(p)

def add_household(self, people: list):
def add_household(self, people: list, update_person_id: bool = True):
"""Adds a default :class:`Household` to Microcell and fills it with
a number of :class:`Person` s.

Parameters
----------
people : list
List of :class:`People` to add to household
update_person_id : bool
Boolean representing whether we wish to update the id of the
people of the household when the function is called or not

"""
if len(people) != 0:
household = Household(self, loc=self.location)
for person in people:
for i, person in enumerate(people):
household.add_person(person)

if update_person_id:
person.set_id(household.id + "." + str(i))
else:
# If the person already has a household, then do not change
# their id
logging.info(f"Person {person.id} has moved to "
f"household {household.id} but has "
f"not changed id")

else:
logging.info("Cannot create an empty household")

def notify_person_status_change(
self,
old_status: InfectionStatus,
new_status: InfectionStatus,
self,
old_status: InfectionStatus,
new_status: InfectionStatus,
age_group) -> None:
"""Notify Microcell that a person's status has changed.

Expand Down Expand Up @@ -177,8 +208,8 @@ def set_location(self, loc: typing.Tuple[float, float]):

def count_icu(self):
return sum(map(lambda person: person.infection_status ==
InfectionStatus.InfectICU, self.persons))
InfectionStatus.InfectICU, self.persons))

def count_infectious(self):
return sum(map(lambda person: person.is_infectious() is
True, self.persons))
True, self.persons))
40 changes: 37 additions & 3 deletions pyEpiabm/pyEpiabm/core/person.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#

import random
import re

from pyEpiabm.property import InfectionStatus

Expand Down Expand Up @@ -54,6 +55,8 @@ def __init__(self, microcell, age_group=None):
self.key_worker = False
self.date_positive = None
self.is_vaccinated = False
self.id = self.microcell.id + "." + "." + \
str(len(self.microcell.persons))

self.set_random_age(age_group)

Expand Down Expand Up @@ -110,7 +113,7 @@ def is_susceptible(self):
Whether person is currently susceptible

"""
return self.infection_status == InfectionStatus.\
return self.infection_status == InfectionStatus. \
Susceptible

def __repr__(self):
Expand Down Expand Up @@ -214,12 +217,43 @@ def remove_person(self):
Used to remove travellers from the population.

"""
self.microcell.cell.compartment_counter.\
self.microcell.cell.compartment_counter. \
_increment_compartment(-1, self.infection_status,
self.age_group)
self.microcell.compartment_counter.\
self.microcell.compartment_counter. \
_increment_compartment(-1, self.infection_status,
self.age_group)
self.microcell.cell.persons.remove(self)
self.microcell.persons.remove(self)
self.household.persons.remove(self)

def set_id(self, id: str):
"""Updates id of current person (i.e. for input from file).
id format: 4.3.2.1 represents cell 4, microcell 3 within this cell,
household 2 within this microcell, and person 1 within this
household. The id will only be changed if it is of the correct format.

Parameters
----------
id : str
Identity of person

"""

# Ensure id is a string
if not isinstance(id, str):
raise TypeError("Provided id must be a string")

# This regex will match on any string which takes the form "i.j.k.l"
# where i, j, k and l are integers (k can be empty)
if not re.match("^\\d+\\.\\d+\\.\\d*\\.\\d+$", id):
raise ValueError(f"Invalid id: {id}. id must be of the form "
f"'i.j.k.l' where i, j, k, l are integers (k"
f"can be empty)")

# Finally, check for duplicates
person_ids = [person.id for person in self.microcell.persons]
if id in person_ids:
raise ValueError(f"Duplicate id: {id}.")

self.id = id
3 changes: 2 additions & 1 deletion pyEpiabm/pyEpiabm/core/population.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,10 @@ def add_cells(self, n):
Number of empty :class:`Cell` s to add

"""
base_num = len(self.cells)
for i in range(n):
self.cells.append(Cell())
self.cells[i].set_id(i)
self.cells[i + base_num].set_id(str(i + base_num), self.cells)

def total_people(self):
"""Returns the total number of people in the population.
Expand Down
12 changes: 9 additions & 3 deletions pyEpiabm/pyEpiabm/intervention/travel_isolation.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#
# Travel isolation Class
#

import logging
import random

from pyEpiabm.core import Parameters
Expand Down Expand Up @@ -75,6 +75,11 @@ def __call__(self, time):
selected_household = random.choice(
existing_households)
selected_household.add_person(person)
logging.info(f"Person {person.id} has "
f"finished isolating and "
f"has moved to household "
KCGallagher marked this conversation as resolved.
Show resolved Hide resolved
f"{selected_household.id}")

else:
person.household.isolation_location = \
False
Expand All @@ -91,9 +96,10 @@ def __call__(self, time):
if len(person.household.persons) > 1:
# Remove from old household
person.household.persons.remove(person)
# Put in new household
# Move to temporary household
# N.B Person ID is not changed
person.microcell.add_household([
person])
person], update_person_id=False)
person.household.isolation_location = \
True
else:
Expand Down
Loading
Loading