In this example, the person.survtime.logoffset.dist.type
configuration setting is used
to add some randomness to the survival time after infection by HIV. This survival time
is given by
By default, the $x$ parameter is zero, causing a very strict relationship between the survival time and the set-point viral load $V_{\rm sp}$. Using the aforementioned configuration option, one can set the value of $x$ on a per-person basis. This allows for variability in the survival time.
In [1]:
# First we'll load the nesessary modules
%matplotlib inline
import pysimpactcyan
import pandas as pd
import matplotlib.pyplot as plt
import math
import numpy as np
In [2]:
# Create an instance of PySimpactCyan, with which we can run simulations
simpact = pysimpactcyan.PySimpactCyan()
In [3]:
# We'll run a simulation with 1000 men and 1000 women. To make the relation
# above easy to see, we're going to disable treatment by setting the acceptance
# threshold to zero
cfg = { }
cfg["population.simtime"] = 100
cfg["population.nummen"] = 1000
cfg["population.numwomen"] = 1000
cfg["person.art.accept.threshold.dist.type"] = "fixed"
cfg["person.art.accept.threshold.dist.fixed.value"] = 0 # Make sure a person never accepts treatment
r = simpact.run(cfg, "/tmp/simptest")
In [4]:
# Get a value for 'infinity'
inf = float("inf")
# This is the line with t_surv = C/Vsp^(-k), on a log-log plot
C = 1325.0
k = -0.49
logVL = np.linspace(2, 6, 2)
logTS = np.log10(C) + k*logVL
In [5]:
# Read the person log from the simulation output
persons = pd.read_csv(r["logpersons"])
# We're only interested in people that got infected by transmission, not by
# the HIV seeding event (InfectType == 1), in persons who actually have died
# (TOD < inf) and who did not receive treatment (TreatTime == inf, which is
# actually always the case since no person will accept treatment)
filteredPersons = persons[(persons["InfectType"] == 1) &
(persons["TOD"].astype(float) < inf) &
(persons["TreatTime"].astype(float) == inf)]
# The survival time is the difference between the time of death and the time
# infection took place. We're going to take the logarithm of this.
survTime = np.log10(filteredPersons["TOD"].astype(float) - filteredPersons["InfectTime"].astype(float))
# We're going to plot this logarithm of the survival time against the logarithm
# of the set-point viral load
SPVL = filteredPersons["log10SPVL"].astype(float)
plt.plot(SPVL, survTime, 'o')
plt.plot(logVL, logTS); # The green reference line
Out[5]:
In [6]:
# In the plot above, you can see that there are several points below the reference line.
# This is because we didn't specify that we're only interested in people who actually died
# by AIDS related causes: each person also has a regular mortality event scheduled, so it's
# possible that a person dies sooner than from AIDS
In [7]:
# Here, we'll repeat the procedure from above, but we're also going to specify that
# we only want to plot the survival time for people who died from AIDS (AIDSDeath == 1)
filteredPersons = persons[(persons["InfectType"] == 1) &
(persons["TOD"].astype(float) < inf) &
(persons["TreatTime"].astype(float) == inf) &
(persons["AIDSDeath"] == 1)
]
survTime = np.log10(filteredPersons["TOD"].astype(float) - filteredPersons["InfectTime"].astype(float))
SPVL = filteredPersons["log10SPVL"].astype(float)
plt.plot(SPVL, survTime, 'o')
plt.plot(logVL, logTS) # The green reference line
Out[7]:
In [8]:
# In the plot above, all survival times lie precisely on the curve that was used to
# generate them, as expected.
In [9]:
# In the following simulation, we're going to specify that for a specific person
# the 'x' parameter in the formula at the top should be picked from a normal
# distribution with a width of 0.1.
cfg = { }
cfg["population.simtime"] = 100
cfg["population.nummen"] = 1000
cfg["population.numwomen"] = 1000
cfg["person.survtime.logoffset.dist.type"] = "normal"
cfg["person.survtime.logoffset.dist.normal.mu"] = 0
cfg["person.survtime.logoffset.dist.normal.sigma"] = 0.1
cfg["person.art.accept.threshold.dist.type"] = "fixed"
cfg["person.art.accept.threshold.dist.fixed.value"] = 0 # Make sure a person never accepts treatment
r = simpact.run(cfg, "/tmp/simptest")
In [10]:
# If we now create the same plot as before, the survival times will no
# longer lie precisely on a line (in the log-log plot), but will show
# some variation
persons = pd.read_csv(r["logpersons"])
filteredPersons = persons[(persons["InfectType"] == 1) &
(persons["TOD"].astype(float) < inf) &
(persons["TreatTime"].astype(float) == inf) &
(persons["AIDSDeath"] == 1)
]
survTime = np.log10(filteredPersons["TOD"].astype(float) - filteredPersons["InfectTime"].astype(float))
SPVL = filteredPersons["log10SPVL"].astype(float)
plt.plot(SPVL, survTime, 'o')
plt.plot(logVL, logTS); # The green reference line
Out[10]:
In [ ]: