Source code for emodpy_malaria.demographics.MalariaDemographics

"""
This module contains the classes and functions for creating demographics files
for malaria simulations. For more information on |EMOD_s| demographics files,
see :doc:`emod/software-demographics`. 
"""
import os
import emod_api.demographics.Demographics as Demog
from emod_api.demographics import DemographicsTemplates as DT
import emod_api.config.default_from_schema_no_validation as dfs


[docs] class MalariaDemographics(Demog.Demographics): """ This class is derived from :py:class:`emod_api:emod_api.demographics.Demographics.Demographics` and sets certain defaults for malaria in construction. Args: nodes: The number of nodes to create. idref: Method describing how the latitude and longitude values are created for each of the nodes in a simulation. "Gridded world" values use a grid overlaid across the globe at some arcsec resolution. You may also generate the grid using another tool or coordinate system. For more information, see :ref:`demo-metadata`. base_file: A basic demographics file used as a starting point for creating more complicated demographics files. For example, using a single node file to create a multi-node file for spatial simulations. init_prev: The initial malaria prevalence of the population. Defaults to 0%. include_biting_heterogeneity: variable biting rates. Defaults to on. Returns: None """ def __init__(self, nodes, idref="Gridded world grump2.5arcmin", base_file=None, init_prev=0.0, include_biting_heterogeneity=True): super().__init__(nodes, idref, base_file) super().SetDefaultNodeAttributes(birth=True) if init_prev > 0: # Do constant intial prevalence as uniform with same min and max. super().SetInitPrevFromUniformDraw(init_prev, init_prev, f"Constant Initial Prevalence ({init_prev})") if include_biting_heterogeneity: self.set_risk_lowmedium() # lognormal, default=1.6
[docs] def set_risk_lowmedium(self): """ Set initial risk for low-medium transmission settings per: https://wiki.idmod.org/display/MAL/Heterogeneous+biting+risk+in+simulations+vs+data. """ super().SetHeteroRiskLognormalDist(mean=0.0, sigma=1.6)
[docs] def set_risk_high(self): """ Set initial risk for high transmission settings per: https://wiki.idmod.org/display/MAL/Heterogeneous+biting+risk+in+simulations+vs+data. """ super().SetHeteroRiskExponDist(mean=1.0) # 1.0 is placeholder
[docs] def add_larval_habitat_multiplier(self, schema, hab_type, multiplier, species="ALL_SPECIES", node_id=0): """ Add LarvalHabitatMultiplier to node(s). Args: schema: Path to schema.json. hab_type: Habitat type. multiplier: Multiplier or Factor. species: Specific species (defaults to ALL). node_id: Nodes for this LHM. Defaults to all. Returns: Nothing. """ lhm = dfs.schema_to_config_subnode(schema, ["idmTypes", "idmType:LarvalHabitatMultiplierSpec"]) lhm.parameters.Factor = multiplier lhm.parameters.Habitat = hab_type lhm.parameters.Species = species lhm.parameters.finalize() # set params if node_id == 0: if "LarvalHabitatMultiplier" in self.raw['Defaults']['NodeAttributes']: lhm_dict = self.raw['Defaults']['NodeAttributes']["LarvalHabitatMultiplier"] else: lhm_dict = [] lhm_dict.append(lhm.parameters) self.SetNodeDefaultFromTemplate({"LarvalHabitatMultiplier": lhm_dict}, setter_fn=None) else: if self.get_node(node_id).node_attributes.larval_habitat_multiplier: lhm_dict = self.get_node(node_id).node_attributes.larval_habitat_multiplier else: lhm_dict = [] lhm_dict.append(lhm.parameters) self.get_node(node_id).node_attributes.larval_habitat_multiplier = lhm_dict
[docs] def add_initial_vectors_per_species(self, init_vector_species, node_ids=None): """ Add an InitialVectorsForSpecies configuration for all nodes or just a set of nodes. Args: init_vector_species: Dictionary of vector species (strings) to initial populations. There is no checking for coherence of species named in other input settings. node_ids: Array of node ids. Defaults to None for all nodes. Returns: N/A. """ if node_ids is None: ivs_dict = dict() ivs_dict["InitialVectorsPerSpecies"] = init_vector_species self.SetNodeDefaultFromTemplate(ivs_dict, setter_fn=None) else: for node_id in node_ids: self.get_node(node_id).node_attributes.add_parameter("InitialVectorsPerSpecies", init_vector_species)
# no implicits
[docs] def add_initial_vectors_per_species_from_csv(self, csv_path): """ Add initial vector species population to 'demographics' nodes from a csv file. Args: csv_path: Path to CSV file with the initial vector species populations for each node. Returns: N/A. """ import csv if not os.path.exists(csv_path): raise ValueError(f"File not found at {csv_path}.") with open(csv_path) as csv_file: reader = csv.DictReader(csv_file) for line in reader: # collect all the initial vector species values for a given node. node = int(line["node_id"]) ivps = dict() for species in line: if species != "node_id": ivps[species] = int(line[species]) self.add_initial_vectors_per_species(ivps, [node])
[docs] def from_template_node(lat=0, lon=0, pop=1e6, name=1, forced_id=1, init_prev=0.2, include_biting_heterogeneity=True): """ Create a single-node :py:class:`~emodpy_malaria.demographics.MalariaDemographics` instance from the parameters you supply. Args: lat: Latitude of the centroid of the node to create. lon: Longitude of the centroid of the node to create. pop: Human population of the node. name: The name of the node. This may be a characteristic of the node, such as "rural" or "urban", or an identifying integer. forced_id: The node ID for the single node. init_prev: The initial malaria prevalence of the node. Returns: A :py:class:`~emodpy_malaria.demographics.MalariaDemographics` instance. """ new_nodes = [Demog.Node(lat=lat, lon=lon, pop=pop, name=name, forced_id=forced_id)] return MalariaDemographics(nodes=new_nodes, init_prev=init_prev, include_biting_heterogeneity=include_biting_heterogeneity)
[docs] def from_pop_csv(pop_filename_in, pop_filename_out="spatial_gridded_pop_dir", site="No_Site"): """ Create a multi-node :py:class:`~emodpy_malaria.demographics.MalariaDemographics` instance from a CSV file describing a population. Args: pop_filename_in: The path to the demographics file to ingest. pop_filename_out: The path to the file to output. site: A string to identify the country, village, or trial site. Returns: A :py:class:`~emodpy_malaria.demographics.MalariaDemographics` instance """ if not os.path.exists(pop_filename_in): raise ValueError(f"Can't find input data file {pop_filename_in}") generic_demog = Demog.from_pop_csv(pop_filename_in=pop_filename_in, res=1/120, id_ref="from_pop_csv", pop_filename_out=pop_filename_out, site=site) nodes = generic_demog._nodes return MalariaDemographics(nodes=nodes, idref=site)
[docs] def from_csv(input_file, res=30 / 3600, id_ref="from_csv", init_prev=0.0, include_biting_heterogeneity=True): """ Create a multi-node :py:class:`~emodpy_malaria.demographics.MalariaDemographics` instance from a CSV file describing a population. Args: input_file: The path to the csv file to ingest. res: Resolution. id_ref: A string to identify the file, needs to match other input files. init_prev: The initial malaria prevalence of the population. Defaults to 0%. include_biting_heterogeneity: variable biting rates. Defaults to on. Returns: A :py:class:`~emodpy_malaria.demographics.MalariaDemographics` instance """ if os.path.exists(input_file) == False: raise ValueError(f"Can't find input data file {input_file}") generic_demog = Demog.from_csv(input_file, res, id_ref) nodes = generic_demog._nodes return MalariaDemographics(nodes=nodes, idref=id_ref, init_prev=init_prev, include_biting_heterogeneity=include_biting_heterogeneity)
[docs] def from_params(tot_pop=1e6, num_nodes=100, frac_rural=0.3, id_ref="from_params"): """ Creates nodes with following logic: First node is the urban node, which contains tot_pop * (1-frac_rural) of the population, the rest of the nodes splip the left-over population with less and less people in each node. Create a multi-node :py:class:`~emodpy_malaria.demographics.MalariaDemographics` instance as a synthetic population based on a few parameters. Args: tot_pop: The total human population in the node. num_nodes: The number of nodes to create. frac_rural: The fraction of the population that will be distributed between nodes 2 and higher id_ref: Method describing how the latitude and longitude values are created for each of the nodes in a simulation. "Gridded world" values use a grid overlaid across the globe at some arcsec resolution. You may also generate the grid using another tool or coordinate system. For more information, see :ref:`demo-metadata`. Returns: A :py:class:`~emodpy_malaria.demographics.MalariaDemographics` instance. """ generic_demog = Demog.from_params(tot_pop, num_nodes, frac_rural, id_ref) nodes = generic_demog.nodes return MalariaDemographics(nodes=nodes, idref=id_ref)