Overview
Agent Exposures
Exposures (transmissible items such as HIV and knowledge) from params.exposures
are implemented in standalone files that implement the interface from exposures.BaseExposure
. This allows for all of the logic related to an exposure to be consolidated in one place and additionally makes incorporating a new exposure into the model as simple as possible.
To add a new exposure:
- Add the param to
param.exposures
- Add a file to
exposures/
which creates a class that is a sub-class ofBaseExposure
- Implement the methods of
BaseExposure
which are needed for this exposure - Not all methods are needed for all exposures (see below for details on the methods)
- Implement the methods of
- Re-export the exposure from
exposures/__init__.py
- Add tests in
tests/exposures/
- Add it to the docs in
docs/api/exposures/
and to the nav inmkdocs.yml
The TITAN
, Population
, and Agent
classes all use sub-classes of BaseFeature
to initialize the object/call methods as appropriate.
BaseExposure
name: str
Name of exposure in the params file. Also used to name the attribute in Agent
stats: List[str]
List of names of stats that come from this exposure (e.g. hiv.dx)
add_agent(agent)
classmethod
Add an agent to the class (not instance). This can be useful if tracking population level statistics or groups, such as counts or newly active agents.
This method is not called from anywhere in the model, but creates a cohesive api with remove_agent
, which is called from Population.remove_agent
.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
agent |
agent.Agent |
the agent to add to the class attributes |
required |
Source code in titan/exposures/base_exposure.py
@classmethod
def add_agent(cls, agent: "agent.Agent"):
"""
Add an agent to the class (not instance). This can be useful if tracking population level statistics or groups, such as counts or newly active agents.
This method is not called from anywhere in the model, but creates a cohesive api with `remove_agent`, which is called from `Population.remove_agent`.
args:
agent: the agent to add to the class attributes
"""
pass
convert(self, model)
Convert the agent to the exposure (i.e. become active).
Parameters:
Name | Type | Description | Default |
---|---|---|---|
model |
model.TITAN |
The running model |
required |
Source code in titan/exposures/base_exposure.py
def convert(self, model: "model.TITAN"):
"""
Convert the agent to the exposure (i.e. become active).
args:
model: The running model
"""
pass
diagnose(self, model)
Diagnose the agent with the exposure (if applicable).
Parameters:
Name | Type | Description | Default |
---|---|---|---|
model |
model.TITAN |
The running model |
required |
Source code in titan/exposures/base_exposure.py
def diagnose(self, model: "model.TITAN"):
"""
Diagnose the agent with the exposure (if applicable).
args:
model: The running model
"""
pass
expose(model, interaction, rel, num_acts)
staticmethod
Expose a relationship to the exposure for a number of acts for a specific interaction type. Typically, this determines if the exposure can cause conversion/change in one of the agents, then if so, determines the probability of that and then converts the succeptible agent.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
model |
model.TITAN |
The running model |
required |
interaction |
str |
The type of interaction (e.g. sex, injection) |
required |
rel |
agent.Relationship |
The relationship where the interaction is occuring |
required |
num_acts |
int |
The number of acts of that interaction |
required |
Source code in titan/exposures/base_exposure.py
@staticmethod
def expose(
model: "model.TITAN",
interaction: str,
rel: "agent.Relationship",
num_acts: int,
):
"""
Expose a relationship to the exposure for a number of acts for a specific interaction type. Typically, this determines if the exposure can cause conversion/change in one of the agents, then if so, determines the probability of that and then converts the succeptible agent.
args:
model: The running model
interaction: The type of interaction (e.g. sex, injection)
rel: The relationship where the interaction is occuring
num_acts: The number of acts of that interaction
"""
pass
get_transmission_probability(self, model, interaction, partner, num_acts)
Determines the probability of a transmission event from agent to partner based on interaction type.
This is not called from anywhere else in the model, but is recommended as a way to structure the exposure method into getting the transmission probability, then doing the conversion.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
model |
model.TITAN |
The running model |
required |
interaction |
str |
The type of interaction (e.g. |
required |
partner |
agent.Agent |
The agent's partner |
required |
num_acts |
int |
The number of acts where exposure occured |
required |
Returns:
Type | Description |
---|---|
float |
probability of transmission from agent to partner |
Source code in titan/exposures/base_exposure.py
def get_transmission_probability(
self,
model: "model.TITAN",
interaction: str,
partner: "agent.Agent",
num_acts: int,
) -> float:
"""
Determines the probability of a transmission event from agent to partner based on
interaction type.
This is not called from anywhere else in the model, but is recommended as a way to structure the exposure method into getting the transmission probability, then doing the conversion.
args:
model: The running model
interaction : The type of interaction (e.g. `sex`, `injection`)
partner: The agent's partner
num_acts: The number of acts where exposure occured
returns:
probability of transmission from agent to partner
"""
return 0.0
init_agent(self, pop, time)
Initialize the agent for this exposure during population initialization (Population.create_agent
). Called only on exposures that are enabled per the params.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
pop |
population.Population |
the population this agent is a part of |
required |
time |
int |
the current time step |
required |
Source code in titan/exposures/base_exposure.py
def init_agent(self, pop: "population.Population", time: int):
"""
Initialize the agent for this exposure during population initialization (`Population.create_agent`). Called only on exposures that are enabled per the params.
args:
pop: the population this agent is a part of
time: the current time step
"""
pass
init_class(params)
classmethod
Initialize any class level attributes (such as setting counters to zero). Called on every active exposure on population initialization.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
params |
|
parameters for this population |
required |
Source code in titan/exposures/base_exposure.py
@classmethod
def init_class(cls, params):
"""
Initialize any class level attributes (such as setting counters to zero). Called on every active exposure on population initialization.
args:
params: parameters for this population
"""
pass
remove_agent(agent)
classmethod
Remove an agent from the class (not instance). This can be useful if tracking population level statistics or groups, such as counts.
This method is called from Population.remove_agent
, but may also need to be called within the feature if an agent transitions from active == True
to active == False
.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
agent |
agent.Agent |
the agent to remove from the class attributes |
required |
Source code in titan/exposures/base_exposure.py
@classmethod
def remove_agent(cls, agent: "agent.Agent"):
"""
Remove an agent from the class (not instance). This can be useful if tracking population level statistics or groups, such as counts.
This method is called from `Population.remove_agent`, but may also need to be called within the feature if an agent transitions from `active == True` to `active == False`.
args:
agent: the agent to remove from the class attributes
"""
pass
set_stats(self, stats, time)
Update the stats
dictionary passed for this agent. Called from output.get_stats
for each enabled exposure in the model.
The stats to be updated must be declared in the class attribute stats
to make sure the dictionary has the expected keys/counter value initialized.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
stats |
Dict[str, int] |
the dictionary to update with this agent's feature statistics |
required |
time |
int |
the time step of the model when the stats are set |
required |
Source code in titan/exposures/base_exposure.py
def set_stats(self, stats: Dict[str, int], time: int):
"""
Update the `stats` dictionary passed for this agent. Called from `output.get_stats` for each enabled exposure in the model.
The stats to be updated must be declared in the class attribute `stats` to make sure the dictionary has the expected keys/counter value initialized.
args:
stats: the dictionary to update with this agent's feature statistics
time: the time step of the model when the stats are set
"""
pass
update_agent(self, model)
Update the agent for this exposure for a time step. Called once per time step in TITAN.update_all_agents
.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
model |
model.TITAN |
the instance of TITAN currently being run |
required |
Source code in titan/exposures/base_exposure.py
def update_agent(self, model: "model.TITAN"):
"""
Update the agent for this exposure for a time step. Called once per time step in `TITAN.update_all_agents`.
args:
model: the instance of TITAN currently being run
"""
pass