Skip to content

HIV

Bases: BaseExposure

Source code in titan/exposures/hiv.py
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
class HIV(base_exposure.BaseExposure):
    name: str = "hiv"
    stats: List[str] = ["hiv", "hiv_dx", "hiv_aids", "hiv_new", "hiv_dx_new"]
    """
        HIV collects the following stats:

        * hiv - number of agents with active hiv
        * hiv_dx - number of agents with diagnosed hiv
        * hiv_aids - number of agents with aids
        * hiv_new - number of agents converted to hiv this timestep
        * hiv_dx_new - number of agents with diagnosed with hiv this timestep
    """

    dx_counts: Dict[str, Dict[str, int]] = {}
    """Counts of diagnosed agents by race and sex_type"""

    agents: Set["agent.Agent"] = set()
    """Agents with active hiv"""

    def __init__(self, agent: "agent.Agent"):
        super().__init__(agent)

        self.active = False
        self.time: Optional[int] = None
        self.dx = False
        self.dx_time: Optional[int] = None
        self.aids = False

    @classmethod
    def init_class(cls, params):
        """
        Initialize any diagnosis counts and the agents set.

        args:
            params: parameters for this population
        """
        cls.dx_counts = {
            race: {so: 0 for so in params.classes.sex_types}
            for race in params.classes.races
        }
        cls.agents = set()

    def init_agent(self, pop: "population.Population", time: int):
        """
        Initialize the agent for this exposure during population initialization (`Population.create_agent`).  Called on only exposures that are enabled per the params.

        Based on demographic params for the agent, stochastically determine if hiv is active, and if active, at what past time point was the agent converted, if the agent is diagnosed, and if the agent has aids.

        args:
            pop: the population this agent is a part of
            time: the current time step
        """
        agent_params = (
            self.agent.location.params.demographics[self.agent.race]
            .sex_type[self.agent.sex_type]
            .drug_type[self.agent.drug_type]
        )

        # HIV
        if (
            pop.pop_random.random() < agent_params.hiv.init
            and time >= pop.params.hiv.start_time
        ):
            self.active = True

            # if HIV, when did the agent convert? Random sample
            self.time = utils.safe_random_int(
                time - self.agent.location.params.hiv.max_init_time,
                time,
                pop.pop_random,
            )

            if pop.pop_random.random() < agent_params.hiv.aids.init:
                self.aids = True

            if pop.pop_random.random() < agent_params.hiv.dx.init:
                self.dx = True
                # agent was diagnosed at a random time between conversion and now
                self.dx_time = utils.safe_random_int(self.time, time, pop.pop_random)

            # add agent to class
            self.add_agent(self.agent)

    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`. Agent level updates are done after population level updates.   Called on only exposures that are enabled per the params.

        If the agent is hiv+ and the model time is past the hiv start_time, determine if the agent becomes diagnosed if not yet diagnosed, and if the agent has progressed to aids.

        args:
            model: the instance of TITAN currently being run
        """
        if self.active and model.time >= model.params.hiv.start_time:
            if not self.dx:
                test_prob = (
                    self.agent.location.params.demographics[self.agent.race]
                    .sex_type[self.agent.sex_type]
                    .drug_type[self.agent.drug_type]
                    .hiv.dx.prob
                )

                # Rescale based on calibration param
                test_prob *= model.calibration.test_frequency

                if model.run_random.random() < test_prob:
                    self.diagnose(model)

            self.progress_to_aids(model)

    @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.

        Add the agent to the `agents` set and if the agent is diagnosed, updated the `dx_counts`

        args:
            agent: the agent to add to the class attributes
        """
        cls.agents.add(agent)

        if agent.hiv.dx:  # type: ignore[attr-defined]
            cls.dx_counts[agent.race][agent.sex_type] += 1

    @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.

        Remove the agent from the `agents` set and decrement the `dx_counts` if the agent was diagnosed.

        args:
            agent: the agent to remove from the class attributes
        """
        cls.agents.remove(agent)

        if agent.hiv.dx:  # type: ignore[attr-defined]
            cls.dx_counts[agent.race][agent.sex_type] -= 1

    def set_stats(self, stats: Dict[str, int], time: int):
        if self.active:
            stats["hiv"] += 1
            if self.time == time:
                stats["hiv_new"] += 1
            if self.aids:
                stats["hiv_aids"] += 1
            if self.dx:
                stats["hiv_dx"] += 1
                if self.dx_time == time:
                    stats["hiv_dx_new"] += 1

    @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 of a specific interaction type.  Typically, this is determining if the exposure can cause conversion/change in one of the agents, then if so determining the probability of that and then converting the succeptible agent.

        For hiv, one agent must be active and the other not for an exposure to cause conversion.

        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
        """
        # Agent 1 is HIV+, Agent 2 is not, Agent 2 is succept
        if rel.agent1.hiv.active and not rel.agent2.hiv.active:  # type: ignore[attr-defined]
            agent = rel.agent1
            partner = rel.agent2
        # If Agent 2 is HIV and Agent 1 is not, Agent 1 is succept
        elif not rel.agent1.hiv.active and rel.agent2.hiv.active:  # type: ignore[attr-defined]
            agent = rel.agent2
            partner = rel.agent1
        else:  # neither agent is HIV or both are
            return

        p = agent.hiv.get_transmission_probability(  # type: ignore[attr-defined]
            model, interaction, partner, num_acts
        )

        if model.run_random.random() < p:
            # if agent HIV+ partner becomes HIV+
            partner.hiv.convert(model)  # type: ignore[attr-defined]

    def get_transmission_probability(
        self,
        model: "model.TITAN",
        interaction: str,
        partner: "agent.Agent",
        num_acts: int,
    ) -> float:
        """
        Determines the probability of an hiv transmission event from agent to partner based on
            interaction type and numer of acts. For sex acts, transmission probability is a
            function of the acquisition probability of the HIV- agent's sex role
            and the HIV+ agent's haart adherence, acute status, and dx risk reduction

        args:
            model: The running model
            interaction : "injection" or "sex"
            partner: HIV- Agent
            num_acts: The number of exposure interactions the agents had this time step

        returns:
            probability of transmission from agent to partner
        """
        # if this isn't an interaction where hiv can transmit, return 0% prob
        if interaction not in ("injection", "sex"):
            return 0.0

        # Logic for if needle or sex type interaction
        p: float

        # get baseline probabilities
        if interaction == "injection":
            p = model.params.partnership.injection.transmission.base
        elif interaction == "sex":
            agent_sex_role = self.agent.sex_role
            partner_sex_role = partner.sex_role

            # get partner's sex role during acts
            if partner_sex_role == "versatile":  # versatile partner takes
                # "opposite" position of agent
                if agent_sex_role == "insertive":
                    partner_sex_role = "receptive"
                elif agent_sex_role == "receptive":
                    partner_sex_role = "insertive"
                else:
                    partner_sex_role = "versatile"  # if both versatile, can switch
                    # between receptive and insertive by act

            # get probability of sex acquisition given HIV- partner's position
            p = partner.location.params.partnership.sex.acquisition[partner.sex_type][
                partner_sex_role
            ]

        # feature specific risk adjustment
        for feature in model.features:
            agent_feature = getattr(self.agent, feature.name)
            p *= agent_feature.get_transmission_risk_multiplier(self.time, interaction)

            partner_feature = getattr(partner, feature.name)
            p *= partner_feature.get_acquisition_risk_multiplier(self.time, interaction)

        # Scaling parameter for acute HIV infections
        if self.get_acute_status(model.time):
            p *= self.agent.location.params.hiv.acute.infectivity

        # Scaling parameter for positively identified HIV agents
        if self.dx:
            p *= 1 - self.agent.location.params.hiv.dx.risk_reduction[interaction]

        # Racial calibration parameter to attain proper race incidence disparity
        p *= partner.location.params.demographics[partner.race].hiv.transmission

        # Scaling parameter for per act transmission.
        p *= model.calibration.acquisition

        return utils.total_probability(p, num_acts)

    def convert(self, model: "model.TITAN"):
        """
        Agent becomes HIV agent. Update all appropriate attributes, sets and dictionaries.

        args:
            model: The model being run
        """
        if not self.active:
            self.active = True
            self.time = model.time
            self.agent.vaccine.active = False  # type: ignore[attr-defined]
            self.add_agent(self.agent)

        if self.agent.prep.active:  # type: ignore[attr-defined]
            self.agent.prep.progress(model, force=True)  # type: ignore[attr-defined]

    def diagnose(self, model: "model.TITAN"):
        """
        Mark the agent as diagnosed.

        args:
             model: the running model
        """
        self.dx = True
        self.dx_time = model.time
        self.add_agent(self.agent)

    # ============================ HELPER METHODS ==============================

    def get_acute_status(self, time: int) -> bool:
        """
        Get acute status of agent at time

        args:
            time: The current time step

        returns:
            whether an agent is acute
        """
        if self.active and self.time is not None:
            hiv_duration = time - self.time

            if self.agent.location.params.hiv.acute.duration >= hiv_duration >= 0:
                return True

        return False

    def progress_to_aids(self, model: "model.TITAN"):
        """
        Model the progression of HIV agents to AIDS agents

        args:
             model: the running model
        """
        aids_prob = self.agent.location.params.hiv.aids.prob
        p = self.agent.haart.aids_scale()  # type: ignore[attr-defined]

        if model.run_random.random() < p * aids_prob:
            self.aids = True

agents: Set[agent.Agent] = set() class-attribute instance-attribute

Agents with active hiv

dx_counts: Dict[str, Dict[str, int]] = {} class-attribute instance-attribute

Counts of diagnosed agents by race and sex_type

stats: List[str] = ['hiv', 'hiv_dx', 'hiv_aids', 'hiv_new', 'hiv_dx_new'] class-attribute instance-attribute

HIV collects the following stats:

  • hiv - number of agents with active hiv
  • hiv_dx - number of agents with diagnosed hiv
  • hiv_aids - number of agents with aids
  • hiv_new - number of agents converted to hiv this timestep
  • hiv_dx_new - number of agents with diagnosed with hiv this timestep

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.

Add the agent to the agents set and if the agent is diagnosed, updated the dx_counts

Parameters:

Name Type Description Default
agent Agent

the agent to add to the class attributes

required
Source code in titan/exposures/hiv.py
119
120
121
122
123
124
125
126
127
128
129
130
131
132
@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.

    Add the agent to the `agents` set and if the agent is diagnosed, updated the `dx_counts`

    args:
        agent: the agent to add to the class attributes
    """
    cls.agents.add(agent)

    if agent.hiv.dx:  # type: ignore[attr-defined]
        cls.dx_counts[agent.race][agent.sex_type] += 1

convert(model)

Agent becomes HIV agent. Update all appropriate attributes, sets and dictionaries.

Parameters:

Name Type Description Default
model TITAN

The model being run

required
Source code in titan/exposures/hiv.py
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
def convert(self, model: "model.TITAN"):
    """
    Agent becomes HIV agent. Update all appropriate attributes, sets and dictionaries.

    args:
        model: The model being run
    """
    if not self.active:
        self.active = True
        self.time = model.time
        self.agent.vaccine.active = False  # type: ignore[attr-defined]
        self.add_agent(self.agent)

    if self.agent.prep.active:  # type: ignore[attr-defined]
        self.agent.prep.progress(model, force=True)  # type: ignore[attr-defined]

diagnose(model)

Mark the agent as diagnosed.

Parameters:

Name Type Description Default
model TITAN

the running model

required
Source code in titan/exposures/hiv.py
290
291
292
293
294
295
296
297
298
299
def diagnose(self, model: "model.TITAN"):
    """
    Mark the agent as diagnosed.

    args:
         model: the running model
    """
    self.dx = True
    self.dx_time = model.time
    self.add_agent(self.agent)

expose(model, interaction, rel, num_acts) staticmethod

Expose a relationship to the exposure for a number of acts of a specific interaction type. Typically, this is determining if the exposure can cause conversion/change in one of the agents, then if so determining the probability of that and then converting the succeptible agent.

For hiv, one agent must be active and the other not for an exposure to cause conversion.

Parameters:

Name Type Description Default
model TITAN

The running model

required
interaction str

The type of interaction (e.g. sex, injection)

required
rel 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/hiv.py
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
@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 of a specific interaction type.  Typically, this is determining if the exposure can cause conversion/change in one of the agents, then if so determining the probability of that and then converting the succeptible agent.

    For hiv, one agent must be active and the other not for an exposure to cause conversion.

    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
    """
    # Agent 1 is HIV+, Agent 2 is not, Agent 2 is succept
    if rel.agent1.hiv.active and not rel.agent2.hiv.active:  # type: ignore[attr-defined]
        agent = rel.agent1
        partner = rel.agent2
    # If Agent 2 is HIV and Agent 1 is not, Agent 1 is succept
    elif not rel.agent1.hiv.active and rel.agent2.hiv.active:  # type: ignore[attr-defined]
        agent = rel.agent2
        partner = rel.agent1
    else:  # neither agent is HIV or both are
        return

    p = agent.hiv.get_transmission_probability(  # type: ignore[attr-defined]
        model, interaction, partner, num_acts
    )

    if model.run_random.random() < p:
        # if agent HIV+ partner becomes HIV+
        partner.hiv.convert(model)  # type: ignore[attr-defined]

get_acute_status(time)

Get acute status of agent at time

Parameters:

Name Type Description Default
time int

The current time step

required

Returns:

Type Description
bool

whether an agent is acute

Source code in titan/exposures/hiv.py
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
def get_acute_status(self, time: int) -> bool:
    """
    Get acute status of agent at time

    args:
        time: The current time step

    returns:
        whether an agent is acute
    """
    if self.active and self.time is not None:
        hiv_duration = time - self.time

        if self.agent.location.params.hiv.acute.duration >= hiv_duration >= 0:
            return True

    return False

get_transmission_probability(model, interaction, partner, num_acts)

Determines the probability of an hiv transmission event from agent to partner based on interaction type and numer of acts. For sex acts, transmission probability is a function of the acquisition probability of the HIV- agent's sex role and the HIV+ agent's haart adherence, acute status, and dx risk reduction

Parameters:

Name Type Description Default
model TITAN

The running model

required
interaction

"injection" or "sex"

required
partner Agent

HIV- Agent

required
num_acts int

The number of exposure interactions the agents had this time step

required

Returns:

Type Description
float

probability of transmission from agent to partner

Source code in titan/exposures/hiv.py
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
def get_transmission_probability(
    self,
    model: "model.TITAN",
    interaction: str,
    partner: "agent.Agent",
    num_acts: int,
) -> float:
    """
    Determines the probability of an hiv transmission event from agent to partner based on
        interaction type and numer of acts. For sex acts, transmission probability is a
        function of the acquisition probability of the HIV- agent's sex role
        and the HIV+ agent's haart adherence, acute status, and dx risk reduction

    args:
        model: The running model
        interaction : "injection" or "sex"
        partner: HIV- Agent
        num_acts: The number of exposure interactions the agents had this time step

    returns:
        probability of transmission from agent to partner
    """
    # if this isn't an interaction where hiv can transmit, return 0% prob
    if interaction not in ("injection", "sex"):
        return 0.0

    # Logic for if needle or sex type interaction
    p: float

    # get baseline probabilities
    if interaction == "injection":
        p = model.params.partnership.injection.transmission.base
    elif interaction == "sex":
        agent_sex_role = self.agent.sex_role
        partner_sex_role = partner.sex_role

        # get partner's sex role during acts
        if partner_sex_role == "versatile":  # versatile partner takes
            # "opposite" position of agent
            if agent_sex_role == "insertive":
                partner_sex_role = "receptive"
            elif agent_sex_role == "receptive":
                partner_sex_role = "insertive"
            else:
                partner_sex_role = "versatile"  # if both versatile, can switch
                # between receptive and insertive by act

        # get probability of sex acquisition given HIV- partner's position
        p = partner.location.params.partnership.sex.acquisition[partner.sex_type][
            partner_sex_role
        ]

    # feature specific risk adjustment
    for feature in model.features:
        agent_feature = getattr(self.agent, feature.name)
        p *= agent_feature.get_transmission_risk_multiplier(self.time, interaction)

        partner_feature = getattr(partner, feature.name)
        p *= partner_feature.get_acquisition_risk_multiplier(self.time, interaction)

    # Scaling parameter for acute HIV infections
    if self.get_acute_status(model.time):
        p *= self.agent.location.params.hiv.acute.infectivity

    # Scaling parameter for positively identified HIV agents
    if self.dx:
        p *= 1 - self.agent.location.params.hiv.dx.risk_reduction[interaction]

    # Racial calibration parameter to attain proper race incidence disparity
    p *= partner.location.params.demographics[partner.race].hiv.transmission

    # Scaling parameter for per act transmission.
    p *= model.calibration.acquisition

    return utils.total_probability(p, num_acts)

init_agent(pop, time)

Initialize the agent for this exposure during population initialization (Population.create_agent). Called on only exposures that are enabled per the params.

Based on demographic params for the agent, stochastically determine if hiv is active, and if active, at what past time point was the agent converted, if the agent is diagnosed, and if the agent has aids.

Parameters:

Name Type Description Default
pop Population

the population this agent is a part of

required
time int

the current time step

required
Source code in titan/exposures/hiv.py
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
def init_agent(self, pop: "population.Population", time: int):
    """
    Initialize the agent for this exposure during population initialization (`Population.create_agent`).  Called on only exposures that are enabled per the params.

    Based on demographic params for the agent, stochastically determine if hiv is active, and if active, at what past time point was the agent converted, if the agent is diagnosed, and if the agent has aids.

    args:
        pop: the population this agent is a part of
        time: the current time step
    """
    agent_params = (
        self.agent.location.params.demographics[self.agent.race]
        .sex_type[self.agent.sex_type]
        .drug_type[self.agent.drug_type]
    )

    # HIV
    if (
        pop.pop_random.random() < agent_params.hiv.init
        and time >= pop.params.hiv.start_time
    ):
        self.active = True

        # if HIV, when did the agent convert? Random sample
        self.time = utils.safe_random_int(
            time - self.agent.location.params.hiv.max_init_time,
            time,
            pop.pop_random,
        )

        if pop.pop_random.random() < agent_params.hiv.aids.init:
            self.aids = True

        if pop.pop_random.random() < agent_params.hiv.dx.init:
            self.dx = True
            # agent was diagnosed at a random time between conversion and now
            self.dx_time = utils.safe_random_int(self.time, time, pop.pop_random)

        # add agent to class
        self.add_agent(self.agent)

init_class(params) classmethod

Initialize any diagnosis counts and the agents set.

Parameters:

Name Type Description Default
params

parameters for this population

required
Source code in titan/exposures/hiv.py
38
39
40
41
42
43
44
45
46
47
48
49
50
@classmethod
def init_class(cls, params):
    """
    Initialize any diagnosis counts and the agents set.

    args:
        params: parameters for this population
    """
    cls.dx_counts = {
        race: {so: 0 for so in params.classes.sex_types}
        for race in params.classes.races
    }
    cls.agents = set()

progress_to_aids(model)

Model the progression of HIV agents to AIDS agents

Parameters:

Name Type Description Default
model TITAN

the running model

required
Source code in titan/exposures/hiv.py
321
322
323
324
325
326
327
328
329
330
331
332
def progress_to_aids(self, model: "model.TITAN"):
    """
    Model the progression of HIV agents to AIDS agents

    args:
         model: the running model
    """
    aids_prob = self.agent.location.params.hiv.aids.prob
    p = self.agent.haart.aids_scale()  # type: ignore[attr-defined]

    if model.run_random.random() < p * aids_prob:
        self.aids = True

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.

Remove the agent from the agents set and decrement the dx_counts if the agent was diagnosed.

Parameters:

Name Type Description Default
agent Agent

the agent to remove from the class attributes

required
Source code in titan/exposures/hiv.py
134
135
136
137
138
139
140
141
142
143
144
145
146
147
@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.

    Remove the agent from the `agents` set and decrement the `dx_counts` if the agent was diagnosed.

    args:
        agent: the agent to remove from the class attributes
    """
    cls.agents.remove(agent)

    if agent.hiv.dx:  # type: ignore[attr-defined]
        cls.dx_counts[agent.race][agent.sex_type] -= 1

update_agent(model)

Update the agent for this exposure for a time step. Called once per time step in TITAN.update_all_agents. Agent level updates are done after population level updates. Called on only exposures that are enabled per the params.

If the agent is hiv+ and the model time is past the hiv start_time, determine if the agent becomes diagnosed if not yet diagnosed, and if the agent has progressed to aids.

Parameters:

Name Type Description Default
model TITAN

the instance of TITAN currently being run

required
Source code in titan/exposures/hiv.py
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
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`. Agent level updates are done after population level updates.   Called on only exposures that are enabled per the params.

    If the agent is hiv+ and the model time is past the hiv start_time, determine if the agent becomes diagnosed if not yet diagnosed, and if the agent has progressed to aids.

    args:
        model: the instance of TITAN currently being run
    """
    if self.active and model.time >= model.params.hiv.start_time:
        if not self.dx:
            test_prob = (
                self.agent.location.params.demographics[self.agent.race]
                .sex_type[self.agent.sex_type]
                .drug_type[self.agent.drug_type]
                .hiv.dx.prob
            )

            # Rescale based on calibration param
            test_prob *= model.calibration.test_frequency

            if model.run_random.random() < test_prob:
                self.diagnose(model)

        self.progress_to_aids(model)