networks

library.networks

Additional network types: household, spatial, and theoretical.

HouseholdNet builds households from DHS-style survey data; DiskNet connects agents that are spatially close; ErdosRenyiNet and NullNet are useful for theoretical work and debugging. Core network classes (ss.RandomNet, ss.MFNet, ss.StaticNet, etc.) live in starsim.networks.

Classes

Name Description
DiskNet Disk graph in which edges are made between agents located within a user-defined radius.
ErdosRenyiNet In the Erdos-Renyi network, every possible edge has a probability, p, of
HouseholdNet A household contact network built from DHS-style survey data.
NullNet A convenience class for a network of size n that only has self-connections with a weight of 0.

DiskNet

library.networks.DiskNet(key_dict=None, pars=None, **kwargs)

Disk graph in which edges are made between agents located within a user-defined radius.

Interactions take place within a square with edge length of 1. Agents are initialized to have a random position and orientation within this square. On each time step, agents advance v*dt in the direction they are pointed. When encountering a wall, agents are reflected.

Edges are formed between two agents if they are within r distance of each other.

Parameters

Name Type Description Default
r float radius within which edges are formed required
v freq speed at which agents move required

Attributes

Name Type Description
x FloatArr x position, in [0, 1]
y FloatArr y position, in [0, 1]
theta FloatArr direction of travel, in radians

Examples

import starsim as ss
import starsim.library as ssl

sim = ss.Sim(diseases='sis', networks=ssl.DiskNet(r=0.05))
sim.run()

Methods

Name Description
add_pairs Generate contacts
add_pairs
library.networks.DiskNet.add_pairs()

Generate contacts

ErdosRenyiNet

library.networks.ErdosRenyiNet(key_dict=None, pars=None, **kwargs)

In the Erdos-Renyi network, every possible edge has a probability, p, of being created on each time step.

The degree of each node will have a binomial distribution, considering each of the N-1 possible edges connection this node to the others will be created with probability p.

Please be careful with the dur parameter. When set to 0, new edges will be created on each time step. If positive, edges will persist for dur years. Note that the existence of edges from previous time steps will not prevent or otherwise alter the creation of new edges on each time step, edges will accumulate over time.

Warning: this network is quite slow compared to ss.RandomNet.

Parameters

Name Type Description Default
p float probability that each possible edge is created per timestep required
dur dur / Dist how long edges persist; 0 means new edges each timestep required

Examples

import starsim as ss
import starsim.library as ssl

sim = ss.Sim(diseases='sis', networks=ssl.ErdosRenyiNet(p=0.01))
sim.run()

Methods

Name Description
add_pairs Generate contacts
add_pairs
library.networks.ErdosRenyiNet.add_pairs()

Generate contacts

HouseholdNet

library.networks.HouseholdNet(
    pars=None,
    dhs_data=None,
    dynamic=True,
    prob_move_out=_,
    update_freq=_,
    **kwargs,
)

A household contact network built from DHS-style survey data.

When initialized, this network overrides the age (and optionally sex) of all agents in the sim and assigns each agent a household ID. Use with caution if other modules depend upon or alter age and sex.

Households are created by selecting a random household from the provided data and setting the age and sex of agents to match, repeating until all agents have been assigned to a household. Ages in the data are typically in integer years; a random fractional year is added so agents don’t share exact ages.

This network assumes only one mother per household. Births are automatically added to their mother’s household network.

Parameters

Name Type Description Default
dhs_data DataFrame / str A pandas or Sciris dataframe with columns hh_id and ages. Optionally also sexes. The ages column should contain comma-separated age strings (e.g. "72, 17, 30"). If sexes is included, it should contain comma-separated values using DHS convention (1 = male, 2 = female) with the same number of entries as ages. Pass 'default' to use synthetic data (see make_default_data()), e.g. for demos and testing. None
dynamic bool If True (default), households evolve over time: one female is assigned as head of each household, pregnant non-head females may move out to form new households, and births are added to the mother’s household. Requires the Pregnancy module. If False, the network is static and step() is a no-op. True
prob_move_out float Probability a non-head female moves out to start her own household, evaluated once at the start of each pregnancy. Default 0.7. Only used when dynamic=True. _
update_freq int How often (in timesteps) to update the network. Default 1. Only used when dynamic=True. _

The expected dataframe format is::

    hh_id                ages          sexes
0       0          72, 17, 30        1, 1, 2
1       1                  37              2
2       2          13, 55, 36        2, 1, 2
3       3  52, 13, 12, 64, 53     1, 2, 1, 2
4       4              30, 66           1, 1

Data in this format can be obtained from the DHS Program <https://dhsprogram.com>_. To prepare a DHS household dataset:

  1. Register and request access at https://dhsprogram.com

  2. Download a Household Recode (HR) dataset in Stata format (e.g. XXHR7xDT.zip)

  3. Use HouseholdNet.load_dhs() to extract the data::

    import starsim as ss; import starsim.library as ssl dhs_data = ssl.networks.HouseholdNet.load_dhs(‘XXHR7xDT/XXHR7xFL.DTA’) sim = ss.Sim(networks=ssl.networks.HouseholdNet(dhs_data=dhs_data)) sim.run()

If real data are not available, synthetic data can be constructed::

import numpy as np
import sciris as sc
import starsim as ss; import starsim.library as ssl

n = 1000
age_strings = []
for i in range(n):
    household_size = np.random.randint(1, 6)
    ages = np.random.randint(0, 80, household_size)
    age_strings.append(sc.strjoin(ages))
dhs_data = sc.dataframe(hh_id=np.arange(n), ages=age_strings)

household = ssl.networks.HouseholdNet(dhs_data=dhs_data)
sim = ss.Sim(diseases='sis', networks=household)
sim.run()
sim.plot()

Methods

Name Description
add_pairs Generate contacts by assigning agents to households sampled from the data.
create_new_households Find females that are pregnant and not a head of household.
load_dhs Load a DHS Household Recode (HR) Stata file and return a dataframe
make_default_data Generate synthetic household data, used when dhs_data='default'.
add_pairs
library.networks.HouseholdNet.add_pairs()

Generate contacts by assigning agents to households sampled from the data.

Households are drawn uniformly at random (with replacement) until they cover the whole population, exactly as the reference algorithm, but sampling, age/sex assignment, edge creation, and head-of-household selection are all vectorized rather than looped per household. Results are statistically equivalent but not bit-identical to the loop version (the random draws differ).

create_new_households
library.networks.HouseholdNet.create_new_households()

Find females that are pregnant and not a head of household. Move them and a randomly sampled male partner to a new household.

load_dhs
library.networks.HouseholdNet.load_dhs(path)

Load a DHS Household Recode (HR) Stata file and return a dataframe suitable for use with HouseholdNet.

Reads the wide-format HR file, extracts per-member age (HV105) and sex (HV104) columns, filters to valid entries (age <= 95 and sex in [1, 2]), and returns a dataframe with columns hh_id, ages, and sexes.

Parameters
Name Type Description Default
path str / Path Path to a DHS Household Recode Stata file (e.g. XXHR7xFL.DTA). required
Returns
Name Type Description
sc.dataframe: A dataframe with columns hh_id, ages, and
sexes ready for use with HouseholdNet(dhs_data=...).
Examples
import starsim as ss; import starsim.library as ssl
dhs_data = ssl.networks.HouseholdNet.load_dhs('ZZHR62FL.DTA')
sim = ss.Sim(networks=ssl.networks.HouseholdNet(dhs_data=dhs_data))
sim.run()
make_default_data
library.networks.HouseholdNet.make_default_data(n=1000, seed=1)

Generate synthetic household data, used when dhs_data='default'.

Creates n households of 1-5 members with ages uniformly distributed between 0 and 80. Intended for demos and testing when real DHS data are not available; see load_dhs() for loading actual survey data.

Parameters
Name Type Description Default
n int number of synthetic households to generate 1000
seed int random seed for reproducibility 1
Returns
Name Type Description
sc.dataframe: A dataframe with columns hh_id and ages ready for
use with HouseholdNet(dhs_data=...).

NullNet

library.networks.NullNet(n_people=None, **kwargs)

A convenience class for a network of size n that only has self-connections with a weight of 0. This network can be useful for debugging purposes or as a placeholder network during development for conditions that require more complex network mechanisms.

Guarantees there’s one (1) contact per agent (themselves), and that their connection weight is zero.

For an empty network (ie, no edges) use >> import starsim as ss >> import networkx as nx >> empty_net_static = ss.StaticNet(nx.empty_graph) >> empty_net_rand = ss.RandomNet(n_contacts=0)

Parameters

Name Type Description Default
n_people int number of agents in the network; defaults to the sim’s n_agents None

Methods

Name Description
step Not used for NullNet
step
library.networks.NullNet.step()

Not used for NullNet