import emodpy_malaria.demographics.MalariaDemographics as Demographics
import emod_api.demographics.PreDefinedDistributions as Distributions
def build_demog():
"""
This function builds a demographics input file for the DTK using emod_api.
"""
= Demographics.from_template_node(lat=1.00, lon=1.00, pop=1000, name="Example_Site_Name", forced_id=1, init_prev=0.1)
demog
# Add equal birth and mortality rates
demog.SetEquilibriumVitalDynamics()
# Call and add age distribution
= Distributions.AgeDistribution_SSAfrica
age_distribution
demog.SetAgeDistribution(age_distribution)
return demog
Creating Demographics Files
Create a Demographics Files
The demographics file is a required input file for EMOD that specifies characteristics of the population in a simulation. This includes aspects like the population size, birth rates, non-malaria mortality rates, age structure, initial prevalence, and more. Full documentation on the demographics file and its parameters/structure are available in the malaria model documentation.
Parts of a demographics file
A demographics file is a JSON file organized into 4 main sections:
- Metadata
- NodeProperties
- Defaults
- Parameters applied to all nodes in the simulation
- Nodes: each node is a simulated location. Transmission within a node is well-mixed, and nodes are connected by human and/or vector migration.
- Allows node-specific parameters
- Specified parameters override values in ‘Defaults’
# Structure of Demographics File for a simulation with 1 node
{"Metadata": {
"DateCreated": "dateTime",
"Tool": "scriptUsedToGenerate",
"Author": "author",
"IdReference": "Gridded world grump2.5arcmin",
"NodeCount": "1"
},"NodeProperties": [
{...}
],"Defaults": {
"NodeAttributes": {
..."BirthRateSource": "World Bank",
"CountryBirthRate": 31.047,
"World Bank Year": "2016",
...
},"IndividualAttributes": {...},
"IndividualProperties": {...}
},"Nodes": [{
"NodeID": 1,
"NodeAttributes": {
"BirthRate": 0.1190,
"InitialPopulation": 1400,
"Village": "Obom"
},"IndividualAttributes": {...},
"IndividualProperties": {...}
}] }
Single-node simulations
The emod-api package contains most of the major functionality to create a demographics file. It is supported by emodpy-malaria
to add parameters that are more specific to the malaria workflow, imported as Demographics
in the code chunk below. For single node, non-spatial simulations the from_template_node
command is most commonly used; however, you may also choose to read in pre-made json files for these types of simulations. We include this command in our demographics builder with it’s basic parameters: - latitude - longitude - population size - site name - forced node ID (if desired) - initial prevalence value (if desired)
With this saved as the demog
item, we can add additional complexity as needed. This may include things like setting equilibrium vital dynamics so birth and mortality rates are equal, producing a relatively stable population size, or an age distribution for our population. In this example, we pull the age distribution of all of Sub-Saharan Africa from the emod-api
and then apply it to our demographics item. You may also add complexity through individual properties and other specific parameters as desired.
Fixed birth rate and age equilibrium
The example above is based on the assumption that you set the population dynamic, controlled by Birth_Rate_Dependence
to POPULATION_DEP_RATE
(the default). However, in the situation where you want to use FIXED_BIRTH_RATE
, then setting as above will cause the birth to be near zero, because birth rate in the POPULATION_DEP_RATE
is read as probability of birth per person in the model per day. In the FIXED_BIRTH_RATE
setting, birth rate is read as probability of birth per day.
As a result, it is recommended that you choose a crude birth rate that works for you (birth per 1000 population per year), and create your demographic this way:
import emodpy_malaria.demographics.MalariaDemographics as Demographics
from emod_api.demographics.DemographicsTemplates import CrudeRate
def build_demog():
"""
This function builds a demographics input file for the DTK using emod_api.
"""
= 1000
pop = 38.92
crude_rate
= Demographics.from_template_node(lat=1.00, lon=1.00, pop=pop, name="Example_Site_Name", forced_id=1, init_prev=0.1)
demog
# Set Birth and Death Rate
*pop))
demog.SetBirthRate(CrudeRate(crude_rate
demog.SetMortalityRate(CrudeRate(crude_rate))
# Set age distribution to equilibrium
demog.SetEquilibriumAgeDistFromBirthAndMortRates(CrudeRate(crude_rate),
CrudeRate(crude_rate))
return demog
Basically, the birth rate needs to be set differently to account for the difference between using FIXED_BIRTH_RATE
and POPULATION_DEP_RATE
. Note that in this example, the mortality rate is also set to the birth rate to ensure that the population is stable and at equilibrium. Finally, we use the SetEquilibriumAgeDistFromBirthAndMortRates
to make sure the age distribution is already at equilibrium given the birth and death rates right from the beginning. You might notice that this means the age distribution in the model is not the same as the “real world”. The actual age distribution in the model can only be achieved if you supply the birth and death (by age) rates over the years of simulations. With constant birth rate and equilibrium vital dynamics, the age distribution will move into a fixed shape even if you start off with a different age distribution.