# Starsim v3.7.0

> A fast, flexible agent-based disease modeling framework

- Starsim is an agent-based modeling framework for simulating disease spread among agents via dynamic transmission networks, including co-transmission of multiple diseases and the effect of interventions.
- Everything in the core package is available from the top level: `import starsim as ss`, then e.g. `ss.Sim()`. Do not import submodules directly.
- Example and reference modules (e.g. `ssl.Cholera`) are in the library: `import starsim.library as ssl`. They are illustrative rather than validated.
- Signatures are as introspected from the current version; summaries are the first paragraph of each docstring.
- Module arguments default to `None` in the signature; the actual defaults are listed as "Default pars", and can be overridden by keyword or via `pars=dict(...)`.
- Aliases are alternative names for the same object; the canonical name is the one listed, and is the one to prefer when writing new code.

This file lists all 195 public Starsim functions and classes. It is generated from the source by `python make_api.py`; do not edit it by hand.

## Links

- [Documentation](https://docs.starsim.org): tutorials, user guide, and API reference
- [Source](https://github.com/starsimhub/starsim): the Starsim repository
- [Style guide](https://github.com/starsimhub/styleguide): the Starsim style guide
- [Sciris](https://docs.sciris.org/llms.txt): the equivalent index for Sciris (`sc`), which Starsim uses extensively

## Simulations (ss.sim)

- `ss.AlreadyRunError(*args, **kwargs)`: Raised if trying to re-run an already-run sim without re-initializing
- `ss.check_sims_match(*args, full=False)`: Shortcut to using ss.diff_sims() to check if multiple sims match

  ```python
  s1 = ss.Sim(diseases='sir', networks='random').run()
  s2 = ss.Sim(pars=dict(diseases='sir', networks='random')).run()
  s3 = ss.Sim(diseases=ss.SIR(), networks=ss.RandomNet()).run()
  assert ss.check_sims_match(s1, s2, s3)
  ```

- `ss.demo(run=True, plot=True, summary=True, show=True, **kwargs)`: Create a simple demo simulation for Starsim

  ```python
  ss.demo() # Run, plot, and show results
  ss.demo(diseases='hiv', networks='mf') # Run with different defaults
  ```

- `ss.diff_sims(sim1, sim2, skip_key_diffs=False, skip=None, full=False, output=False, die=False)`: Compute the difference of the summaries of two simulations, and print any values which differ.

  ```python
  s1 = ss.Sim(rand_seed=1).run()
  s2 = ss.Sim(rand_seed=2).run()
  ss.diff_sims(s1, s2)
  ```

- `ss.Sim(pars=None, label=None, people=None, demographics=None, connectors=None, networks=None, diseases=None, interventions=None, analyzers=None, custom=None, modules=None, copy_inputs=True, data=None, **kwargs)`: The Sim object
  - Default pars: `label=''`, `verbose=0.1`, `n_agents=10000.0`, `total_pop=None`, `pop_scale=None`, `rescale=False`, `rescale_threshold=0.05`, `rescale_factor=1.2`, `people_results=True`, `start=None`, `stop=None`, `dur=None`, `dt=None`, `rand_seed=1`, `birth_rate=None`, `death_rate=None`, `use_aging=None`, `people=None`, `custom=ss.ndict()`, `demographics=ss.ndict()`, `connectors=ss.ndict()`, `networks=ss.ndict()`, `interventions=ss.ndict()`, `diseases=ss.ndict()`, `analyzers=ss.ndict()`, `modules=ss.ndict()`

  ```python
  sim = ss.Sim(diseases='sir', networks='random') # Simplest Starsim sim; equivalent to ss.demo()
  sim = ss.Sim(diseases=ss.SIR(), networks=ss.RandomNet()) # Equivalent using objects instead of strings
  sim = ss.Sim(diseases=['sir', ss.SIS()], networks=['random', 'mf']) # Example using list inputs; can mix and match types
  sim = ss.Sim(modules=[ss.SIR(), ss.RandomNet()]) # Can supply multiple types of module with the 'modules' argument
  ```


## People (ss.people)

- `ss.People(n_agents, age_data=None, extra_states=None, mock=False)`: A class to perform all the operations on the people This class is usually created automatically by the sim. The only required input argument is the population size, but typically the full parameters dictionary will get passed instead since it will be needed before the People object is initialized.

  ```python
  ppl = ss.People(2000)
  ```

- `ss.Person(*args, **kwargs)`: A simple class to hold all attributes of a person

  ```python
  sim = ss.Sim(diseases='sir', networks='random', n_agents=100).run()
  print(sim.people.person(5)) # The 5th agent in the simulation
  ```


## Modules (ss.modules)

- `ss.Base()`: The parent class for Sim and Module objects
- `ss.find_modules(key=None, flat=False, verbose=False)`: Find all subclasses of Module present in Starsim, divided by type
- `ss.Module(name=None, label=None, **kwargs)`: The main base class for all Starsim modules: diseases, networks, interventions, etc.

  ```python
  class SIR(ss.Module):
      def __init__(self, pars=_, beta=_, init_prev=_, p_death=_, **kwargs):
          super().__init__() # Call this first with no arguments
          self.define_pars( # Then define the parameters, including their default value
              beta = ss.peryear(0.1),
              init_prev = ss.bernoulli(p=0.01),
              p_death = ss.bernoulli(p=0.3),
          )
          self.update_pars(pars, **kwargs) # Update with any user-supplied parameters, and raise an exception if trying to set a parameter that wasn't defined in define_pars()
          return
  ```

- `ss.module_map(key=None)`: Map modules to standard types
- `ss.module_types()`: Return a list of known module types; based on `module_map()`
- `ss.register_modules(*args)`: Register custom modules with Starsim so they can be referred to by string.

  ```python
  # Standard use case, register modules automatically
  import my_custom_disease_model as mcdm
  ss.register_modules(mcdm)
  ss.Sim(diseases='mydisease', networks='random').run() # This will work if mcdm.MyDisease() is defined

  # Manual usage
  my_modules = [mcdm.MyDisease, mcdm.MyNetwork]
  ss.register_modules(my_modules)
  ss.Sim(diseases='mydisease', networks='mynetwork').run()
  ```

- `ss.required(val=True)`: Decorator to mark module methods as required.

  ```python
  class CustomSIS(ss.SIS):

      def step(self):
          super().step()
          self.custom_step() # Will raise an exception if this line is not here
          return

      @ss.required() # Mark this method as required on run
      def custom_step(self):
          pass
  ```


## Diseases (ss.diseases)

- `ss.Disease(pars=None, **kwargs)`: Base module class for diseases.
- `ss.Infection(pars=None, **kwargs)`: Base class for infectious diseases used in Starsim
  - Default pars: `init_prev=None`
- `ss.InfectionLog(disease=None, networks=None)`: Record infections
- `ss.NCD(pars=None, initial_risk=None, dur_risk=None, prognosis=None, **kwargs)`: Example non-communicable disease
  - Default pars: `initial_risk=ss.bernoulli(p=0.3)`, `dur_risk=ss.expon(scale=10)`, `prognosis=ss.weibull(c=2, loc=0.0, scale=5)`
- `ss.SEIR(pars=None, dur_exp=None, **kwargs)`: Example SEIR model
  - Default pars: `init_prev=ss.bernoulli(p=0.01)`, `beta=ss.peryear(0.1)`, `dur_inf=ss.lognorm_ex(mean=6, std=1.0)`, `p_death=ss.bernoulli(p=0.01)`, `dur_exp=ss.lognorm_ex(mean=0.5, std=1.0)`
- `ss.SIR(pars=None, beta=None, init_prev=None, dur_inf=None, p_death=None, **kwargs)`: Example SIR model
  - Default pars: `init_prev=ss.bernoulli(p=0.01)`, `beta=ss.peryear(0.1)`, `dur_inf=ss.lognorm_ex(mean=6, std=1.0)`, `p_death=ss.bernoulli(p=0.01)`
- `ss.SIS(pars=None, beta=None, init_prev=None, dur_inf=None, waning=None, imm_boost=None, **kwargs)`: Example SIS model
  - Default pars: `init_prev=ss.bernoulli(p=0.01)`, `beta=ss.peryear(0.05)`, `dur_inf=ss.lognorm_ex(mean=10, std=1.0)`, `waning=ss.peryear(0.05)`, `imm_boost=1.0`

## Networks (ss.networks)

- `ss.AgeGroup(low, high, do_cache=True)`: A simple age-based filter that returns uids of agents that match the criteria
- `ss.BreastfeedingNet(pars=None, **kwargs)`: Network for breastfeeding transmission
  - Default pars: `dur=None`
- `ss.ClusterNet(pars=None, cluster_size=None, age_range=None, beta=None, dynamic=None, **kwargs)`: Fully connected clusters of agents, e.g. households, schools, or workplaces
  - Default pars: `cluster_size=ss.poisson(lam=4)`, `age_range=None`, `beta=1.0`, `dynamic=False`

  ```python
  households = ss.ClusterNet(name='households', cluster_size=ss.poisson(3))
  sim = ss.Sim(diseases='sis', networks=households)
  sim.run()
  ```

- `ss.DynamicNetwork(pars=None, edges=None, **kwargs)`: A network where partnerships update dynamically
- `ss.HybridNet(pars=None, household_size=None, contacts=None, beta=None, school_ages=None, work_ages=None, dynamic=None, **kwargs)`: Covasim v3's "hybrid" population: households, schools, workplaces, and community
  - Default pars: `household_size=ss.poisson(lam=2.0)`, `contacts={'s': 20, 'w': 16, 'c': 20}`, `beta={'h': 3.0, 's': 0.6, 'w': 0.6, 'c': 0.3}`, `school_ages=[6, 22]`, `work_ages=[22, 65]`, `dynamic=False`

  ```python
  sim = ss.Sim(diseases='sis', networks=ss.HybridNet())
  sim.run()
  print(sim.networks.keys()) # ['h', 's', 'w', 'c']

  # Larger households and smaller schools; contacts and beta can be partial
  hybrid = ss.HybridNet(household_size=ss.poisson(3), contacts=dict(s=10))
  ```

- `ss.MaternalNet(pars=None, edges=None, **kwargs)`: Alias for `PrenatalNet`, kept for backwards compatibility
- `ss.MFNet(pars=None, duration=None, debut=None, acts=None, participation=None, rel_part_rates=None, **kwargs)`: This network is built by **randomly pairing** males and female with variable relationship durations.
  - Default pars: `duration=ss.lognorm_ex(mean=15, std=1)`, `debut=ss.normal(loc=16, scale=1.0)`, `acts=ss.poisson(lam=80)`, `participation=ss.bernoulli(p=0.9)`, `rel_part_rates=1.0`
- `ss.MixingPool(pars=None, diseases=None, src=None, dst=None, beta=None, n_contacts=None, **kwargs)`: Define a single mixing pool; can be used as a drop-in replacement for a network.
  - Default pars: `diseases=[]`, `src=None`, `dst=None`, `beta=1.0`, `n_contacts=ss.constant(v=10)`

  ```python
  import starsim as ss

  # Set the parameters
  mp_pars = dict(
      src = lambda sim: sim.people.male, # only males are infectious
      dst = None, # all agents are susceptible
      beta = 0.2,
      n_contacts = ss.poisson(lam=4),
  )

  # Seed 5% of the male population
  def p_init(self, sim, uids):
  # [...]
  ```

- `ss.MixingPools(pars=None, diseases=None, src=None, dst=None, beta=None, n_contacts=None, **kwargs)`: A container for creating a rectangular array of MixingPool instances

  ```python
  import starsim as ss
  mps = ss.MixingPools(
      diseases = 'sis',
      beta = 0.1,
      src = {'0-15': ss.AgeGroup(0, 15), '15+': ss.AgeGroup(15, None)},
      dst = {'0-15': ss.AgeGroup(0, 15), '15+': ss.AgeGroup(15, None)},
      n_contacts = [[2.4, 0.49], [0.91, 0.16]],  # Illustrative contact matrix
  )
  sim = ss.Sim(diseases='sis', networks=mps).run()
  sim.plot()
  ```

- `ss.MSMNet(pars=None, duration=None, debut=None, acts=None, participation=None, **kwargs)`: A network that randomly pairs males
  - Default pars: `duration=ss.lognorm_ex(mean=2, std=1)`, `debut=ss.normal(loc=16, scale=2)`, `acts=ss.lognorm_ex(mean=80, std=20)`, `participation=ss.bernoulli(p=0.1)`
- `ss.Network(pars=None, edges=None, **kwargs)`: A class holding a single network of contact edges (connections) between people as well as methods for updating these. Networks mediate disease transmission between agents in `ss.People`; see `ss.Disease` for how transmission uses network edges, and `ss.RandomNet`, `ss.MFNet`, `ss.PrenatalNet` for […]

  ```python
  # Generate an average of 10 contacts for 1000 people
  n_contacts_pp = 10
  n_people = 1000
  n = n_contacts_pp * n_people
  p1 = np.random.randint(n_people, size=n)
  p2 = np.random.randint(n_people, size=n)
  beta = np.ones(n)
  network = ss.Network(p1=p1, p2=p2, beta=beta, label='rand')
  network = ss.Network(edges=dict(p1=p1, p2=p2, beta=beta), label='rand') # Alternate method

  # Convert one network to another with extra columns
  index = np.arange(n)
  # [...]
  ```

- `ss.PostnatalNet(pars=None, dur=None, **kwargs)`: Network to track postnatal processes
  - Default pars: `dur=None`
- `ss.PrenatalNet(pars=None, edges=None, **kwargs)`: Prenatal transmission network
- `ss.RandomExactNet(pars=None, n_contacts=None, dur=None, beta=None, age_range=None, dynamic=None, **kwargs)`: Random connectivity between agents
  - Default pars: `n_contacts=ss.constant(v=10)`, `dur=ss.years(0)`, `beta=1.0`, `age_range=None`, `dynamic=True`

  ```python
  # Static network with Poisson-distributed contacts among adults, as in Covasim v3
  net = ss.RandomNet(n_contacts=ss.poisson(20), age_range=[18, 65], dynamic=False)
  ```

- `ss.RandomNet(pars=None, n_contacts=None, dur=None, beta=None, age_range=None, dynamic=None, **kwargs)`: A faster, approximate version of `ss.RandomExactNet`
  - Default pars: `n_contacts=ss.constant(v=10)`, `dur=ss.years(0)`, `beta=1.0`, `age_range=None`, `dynamic=True`
- `ss.RandomSafeNet(pars=None, n_edges=None, dur=None, beta=None, **kwargs)`: Create a CRN-safe, O(N) random network
  - Default pars: `n_edges=5`, `dur=ss.years(0)`, `beta=1.0`
- `ss.Route(name=None, label=None, **kwargs)`: A transmission route -- e.g., a network, mixing pool, environmental transmission, etc.
- `ss.SexualNetwork(pars=None, edges=None, **kwargs)`: Base class for all sexual networks
- `ss.StaticNet(graph=None, pars=None, **kwargs)`: A network class of static partnerships converted from a networkx graph. There's no formation of new partnerships and initialized partnerships only end when one of the partners dies. The networkx graph can be created outside Starsim if population size is known. Or the graph can be created by passing […]
  - Default pars: `seed=True`, `p=None`, `n_contacts=10`

  ```python
  # Generate a networkx graph and pass to Starsim
  import networkx as nx
  import starsim as ss
  g = nx.scale_free_graph(n=10000)
  ss.StaticNet(graph=g)

  # Pass a networkx graph generator to Starsim
  ss.StaticNet(graph=nx.erdos_renyi_graph, p=0.0001, seed=True)
  ```


## Demographics (ss.demographics)

- `ss.Births(pars=None, birth_rate=None, rel_birth=None, rate_units=None, metadata=None, **kwargs)`: Create births based on rates, rather than based on pregnancy.
  - Default pars: `birth_rate=ss.peryear(20)`, `rel_birth=1`, `rate_units=0.001`
- `ss.Deaths(pars=None, rel_death=None, death_rate=None, rate_units=None, metadata=None, **kwargs)`: Configure disease-independent "background" deaths.
  - Default pars: `rel_death=1`, `death_rate=ss.peryear(10)`, `rate_units=0.001`
- `ss.Demographics(name=None, label=None, **kwargs)`: Base class for demographic modules.
- `ss.Pregnancy(pars=None, fertility_rate=None, rel_fertility=None, p_infertile=None, min_age=None, max_age=None, rate_units=None, dur_pregnancy=None, dur_breastfeed=None, p_breastfeed=None, rr_ptb=None, rr_ptb_age=None, p_maternal_death=None, p_survive_maternal_death=None, sex_ratio=None, burnin=None, slot_scale=None, min_slots=None, trimesters=None, metadata=None, **kwargs)`: Create births via pregnancies for each agent.
  - Default pars: `fertility_rate=ss.peryear(100)`, `rel_fertility=1`, `p_infertile=ss.bernoulli(p=0)`, `min_age=15`, `max_age=50`, `rate_units=0.001`, `dur_pregnancy=ss.choice(a=[32 33 34 35 36 37 38 39 40 41 42], p=[0.001 0.002 0.005 0.012 0.026 […]`, `dur_breastfeed=ss.lognorm_ex(mean=0.75, std=0.5)`, `p_breastfeed=ss.bernoulli(p=1)`, `embryos_per_pregnancy=ss.choice(a=[1 2], p=[1. 0.], replace=True)`, `rr_ptb=ss.normal(loc=1, scale=0.1)`, `rr_ptb_age=array([[ 18. , 35. , 1000. ], [ 1.2, 1. , 1.2]])`, `p_maternal_death=ss.bernoulli(p=0)`, `p_survive_maternal_death=ss.bernoulli(p=0)`, `p_loss=ss.bernoulli(p=0)`, `loss_threshold=ss.weeks(20)`, `sex_ratio=ss.bernoulli(p=0.5)`, `slot_scale=100`, `min_slots=100`, `preterm_threshold=ss.weeks(37)`, `very_preterm_threshold=ss.weeks(32)`, `burnin=True`, `trimesters=[weeks(13), weeks(26)]`
- `ss.PregnancyPars(**kwargs)`: Pregnancy parameters and default values

## Interventions (ss.interventions)

- `ss.BaseScreening(product=None, prob=None, eligibility=None, **kwargs)`: Base class for screening.
- `ss.BaseTest(product=None, prob=None, eligibility=None, **kwargs)`: Base class for screening and triage.
- `ss.BaseTreatment(product=None, prob=None, eligibility=None, **kwargs)`: Base treatment class.
- `ss.BaseTriage(product=None, prob=None, eligibility=None, **kwargs)`: Base class for triage.
- `ss.BaseVaccination(*args, product=None, prob=None, label=None, **kwargs)`: Base vaccination class for determining who will receive a vaccine.
- `ss.campaign_screening(product=None, prob=None, eligibility=None, **kwargs)`: Campaign screening - an instance of base screening combined with campaign delivery. See base classes for a description of input arguments.

  ```python
  screen1 = ss.campaign_screening(product=my_prod, prob=0.2, years=2030) # Screen 20% of the eligible population in 2020
  screen2 = ss.campaign_screening(product=my_prod, prob=0.02, years=[2025,2030]) # Screen 20% of the eligible population in 2025 and again in 2030
  ```

- `ss.campaign_triage(product=None, prob=None, eligibility=None, **kwargs)`: Campaign triage - an instance of base triage combined with campaign delivery. See base classes for a description of input arguments.

  ```python
  # Example: In 2030, triage all positive screens into confirmatory testing
  screened_pos = lambda sim: sim.interventions.screening.outcomes['positive']
  triage1 = ss.campaign_triage(product=my_triage, eligibility=screen_pos, prob=0.9, years=2030)
  ```

- `ss.campaign_vx(*args, product=None, prob=None, label=None, **kwargs)`: Campaign vaccination - an instance of base vaccination combined with campaign delivery. See base classes for a description of input arguments.
- `ss.CampaignDelivery(*args, years=None, prob=None, **kwargs)`: Base class for any intervention that uses campaign delivery; delivers only at the specified years.
- `ss.Intervention(*args, eligibility=None, **kwargs)`: Base class for interventions.
- `ss.routine_screening(product=None, prob=None, eligibility=None, **kwargs)`: Routine screening - an instance of base screening combined with routine delivery. See base classes for a description of input arguments.

  ```python
  screen1 = ss.routine_screening(product=my_prod, prob=0.02) # Screen 2% of the eligible population every year
  screen2 = ss.routine_screening(product=my_prod, prob=0.02, start_year=2020) # Screen 2% every year starting in 2020
  screen3 = ss.routine_screening(product=my_prod, prob=np.linspace(0.005,0.025,5), years=np.arange(2020,2025)) # Scale up screening over 5 years starting in 2020
  ```

- `ss.routine_triage(product=None, prob=None, eligibility=None, **kwargs)`: Routine triage - an instance of base triage combined with routine delivery. See base classes for a description of input arguments.

  ```python
  # Example: Triage positive screens into confirmatory testing
  screened_pos = lambda sim: sim.interventions.screening.outcomes['positive']
  triage = ss.routine_triage(product=my_triage, eligibility=screen_pos, prob=0.9, start_year=2030)
  ```

- `ss.routine_vx(*args, product=None, prob=None, label=None, **kwargs)`: Routine vaccination - an instance of base vaccination combined with routine delivery. See base classes for a description of input arguments.
- `ss.RoutineDelivery(*args, years=None, start_year=None, end_year=None, prob=None, annual_prob=True, **kwargs)`: Base class for any intervention that uses routine delivery; handles interpolation of input years.
- `ss.treat_num(max_capacity=None, **kwargs)`: Treat a fixed number of people each timestep.

## Products (ss.products)

- `ss.Dx(df=None, hierarchy=None, *args, **kwargs)`: Generic class for diagnostics
- `ss.Product(name=None, label=None, **kwargs)`: Generic product base class; subclasses implement administer().
- `ss.simple_vx(**kwargs)`: Create a simple vaccine product that affects the probability of infection.
  - Default pars: `efficacy=0.9`, `leaky=True`, `disease=None`
- `ss.Tx(df=None, *args, **kwargs)`: Treatment products change fundamental properties about People, including their prognoses and infectiousness.
- `ss.Vx(diseases=None, *args, **kwargs)`: Vaccine product; subclasses implement administer() to apply immunity.

## Connectors (ss.connectors)

- `ss.Connector(name=None, label=None, **kwargs)`: Base class for Connectors, which mediate interactions between disease (or other) modules
- `ss.seasonality(**kwargs)`: Example connector -- apply sine-wave seasonality of transmission to one or more diseases
  - Default pars: `diseases=None`, `scale=0.2`, `shift=0.0`

  ```python
  import starsim as ss

  pars = dict(
      n_agents = 10_000,
      start = '2020-01-01',
      stop = '2023-01-01',
      dt = ss.weeks(1.0),
      diseases = dict(
          type = 'sis',
          beta = ss.perweek(0.05),
          dur_inf = ss.weeks(5),
          waning = ss.perweek(0.1),
  # [...]
  ```


## Analyzers (ss.analyzers)

- `ss.Analyzer(name=None, label=None, **kwargs)`: Base class for Analyzers. Analyzers are used to provide more detailed information about a simulation than is available by default -- for example, pulling states out of sim.people on a particular timestep before they get updated on the next step.
- `ss.dynamics_by_age(state, age_bins=(0, 20, 40, 100))`: Example analyzer: track dynamics of a state by age.

  ```python
  by_age = ss.dynamics_by_age('sis.infected')

  sim = ss.Sim(diseases='sis', networks='random', analyzers=by_age)
  sim.run()
  sim.analyzers[0].plot() # Note: if Sim(copy_inputs=False), we can also use by_age.plot()
  ```

- `ss.infection_log(**kwargs)`: Log infections -- see `ss.InfectionLog` for detail

  ```python
  import starsim as ss
  sim = ss.Sim(n_agents=1000, dt=0.2, dur=15, diseases='sir', networks='random', analyzers='infection_log')
  sim.run()
  sim.analyzers[0].plot()
  ```


## Time, durations, and rates (ss.time)

- `ss.date(*args, day_round=True, allow_zero=None, **kwargs)`: Define a point in time, based on `pd.Timestamp`

  ```python
  ss.date(2020) # Returns <2020-01-01>
  ss.date(year=2020) # Returns <2020-01-01>
  ss.date(year=2024.75) # Returns <2024-10-01>
  ss.date('2024-04-04') # Returns <2024-04-04>
  ss.date(year=2024, month=4, day=4) # Returns <2024-04-04>
  ```

- `ss.DateArray(arr=None, unit=None)`: Lightweight wrapper for an array of dates
- `ss.datedur(*args, **kwargs)`: Date based duration e.g., if requiring a week to be 7 calendar days later
- `ss.days(value=None, base=None, **kwargs)`: Construct a value-based duration
- `ss.dur(value=None, base=None, **kwargs)`: Base class for durations
- `ss.freq(value, unit=None)`: Class for the number of events (rather than probability) in a specified period
- `ss.freqperday(value, unit=None)`: Subclass of `ss.freq`; see that entry for details.
- `ss.freqpermonth(value, unit=None)`: Subclass of `ss.freq`; see that entry for details.
- `ss.freqperweek(value, unit=None)`: Subclass of `ss.freq`; see that entry for details.
- `ss.freqperyear(value, unit=None)`: Subclass of `ss.freq`; see that entry for details.
- `ss.months(value=None, base=None, **kwargs)`: Construct a value-based duration
- `ss.per(value, unit=None)`: A `per` represents an instantaneous rate of an event occurring. Rates must be non-negative, but need not be less than 1.
- `ss.perday(value, unit=None)`: Subclass of `ss.per`; see that entry for details.
- `ss.permonth(value, unit=None)`: Subclass of `ss.per`; see that entry for details.
- `ss.perweek(value, unit=None)`: Subclass of `ss.per`; see that entry for details.
- `ss.peryear(value, unit=None)`: Subclass of `ss.per`; see that entry for details.
- `ss.prob(value=None, unit=None, rate=None)`: `prob` represents the probability of an event occurring during a specified period of time.
- `ss.probperday(value=None, unit=None, rate=None)`: Subclass of `ss.prob`; see that entry for details.
- `ss.probpermonth(value=None, unit=None, rate=None)`: Subclass of `ss.prob`; see that entry for details.
- `ss.probperweek(value=None, unit=None, rate=None)`: Subclass of `ss.prob`; see that entry for details.
- `ss.probperyear(value=None, unit=None, rate=None)`: Subclass of `ss.prob`; see that entry for details.
- `ss.Rate(value, unit=None)`: Store a value per unit time e.g., 2 per day - self.value - the numerator (e.g., 2) - a scalar float - self.unit - the denominator (e.g., 1 day) - a dur object
- `ss.rate(value, unit=None)`: Backwards compatibility function for Rate
- `ss.rate_prob(value, unit=None)`: Backwards compatibility function for per
- `ss.time_prob(value, unit=None)`: Backwards compatibility function for prob
- `ss.TimePar(*args, **kwargs)`: Parent class for all TimePars -- dur, Rate, etc.
- `ss.weeks(value=None, base=None, **kwargs)`: Construct a value-based duration
- `ss.years(value=1, base=None)`: Subclass of `ss.dur`; see that entry for details.

## Timelines (ss.timeline)

- `ss.Timeline(start=None, stop=None, dt=None, dur=None, name=None, init=None, sim=None)`: Handle time vectors and sequencing ("timelines") for both simulations and modules.

  ```python
  t1 = ss.Timeline(start=2000, stop=2020, dt=1.0)
  t2 = ss.Timeline(start='2021-01-01', stop='2021-04-04', dt=ss.days(2))
  ```


## Distributions (ss.distributions)

- `ss.bernoulli(p=0.5, **kwargs)`: Bernoulli distribution: return True or False with the specified probability (which can be an array)
- `ss.beta_dist(a=1.0, b=1.0, **kwargs)`: Beta distribution
- `ss.beta_mean(mean=0.5, var=0.05, force=False, **kwargs)`: Beta distribution paramterized by the mean
- `ss.choice(a=2, p=None, replace=True, **kwargs)`: Random choice between discrete options (note: dynamic parameters not supported)

  ```python
  # Simulate 10 die rolls
  ss.choice(6, strict=False)(10) + 1

  # Choose between specified options each with a specified probability (must sum to 1)
  ss.choice(a=[30, 70], p=[0.3, 0.7], strict=False)(10)
  ```

- `ss.choose_n(n=1, weights=None, die=False, **kwargs)`: Choose exactly n agents (without replacement) from a set of candidate UIDs

  ```python
  # Seed exactly 20 infections
  sir = ss.SIR(init_prev=ss.choose_n(20))

  # Choose 5 agents, weighted by age
  chooser = ss.choose_n(5, weights=lambda self, sim, uids: sim.people.age[uids])
  ```

- `ss.constant(v=0.0, **kwargs)`: Constant (delta) distribution: equivalent to np.full()
- `ss.Dist(dist=None, distname=None, name=None, unit=None, round=False, seed=None, offset=None, strict=True, auto=True, sim=None, module=None, mock=False, debug=False, **kwargs)`: Base class for tracking one random number generator associated with one distribution, i.e. one decision per timestep.

  ```python
  # Create a Bernoulli distribution
  p_death = ss.bernoulli(p=0.1).init(force=True)
  p_death.rvs(50) # Create 50 draws

  # Create a normal distribution that's also a timepar
  dur_infection = ss.normal(loc=12, scale=2, unit='years')
  dur_infection = ss.years(ss.normal(loc=12, scale=2)) # Same as above
  dur_infection = ss.normal(loc=ss.years(12), scale=2) # Same as above
  dur_infection = ss.normal(loc=ss.years(12), scale=ss.months(24)) # Same as above, perform time unit conversion internally
  dur_infection.init(force=True).plot_hist() # Show results

  # Create a duration that is rounded to the nearest whole number of days
  # [...]
  ```

- `ss.Dists(obj=None, *args, base_seed=None, sim=None)`: Class for managing a collection of Dist objects
- `ss.expon(scale=1.0, **kwargs)`: Exponential distribution
- `ss.gamma(a=1.0, loc=0.0, scale=1.0, **kwargs)`: Gamma distribution (specifically, scipy.stats.gamma)
- `ss.histogram(values=None, bins=None, density=False, data=None, **kwargs)`: Sample from a histogram with defined bins

  ```python
  # Sample from an age distribution
  age_bins = [0,    10,  20,  40,  65, 100]
  age_vals = [0.1, 0.1, 0.3, 0.3, 0.2]
  h1 = ss.histogram(values=age_vals, bins=age_bins, strict=False)
  h1.plot_hist()

  # Create a histogram from data
  data = np.random.randn(10_000)*2+5
  h2 = ss.histogram(data=data, strict=False)
  h2.plot_hist(bins=100)
  ```

- `ss.link_dists(obj, sim, module=None, overwrite=False, init=False, **kwargs)`: Link distributions to the sim and the module; used in module.init() and people.init()
- `ss.lognorm_ex(mean=1.0, std=1.0, **kwargs)`: Lognormal distribution, parameterized in terms of the "explicit" (lognormal) distribution, with mean=mean and std=std for this distribution (see lognorm_im for comparison). Note that a mean ≤ 0.0 is impossible, since this is the parameter of the distribution after the log transform.

  ```python
  ss.lognorm_ex(mean=2, std=1, strict=False).rvs(1000).mean() # Should be close to 2
  ```

- `ss.lognorm_im(mean=0.0, sigma=1.0, **kwargs)`: Lognormal distribution, parameterized in terms of the "implicit" (normal) distribution, with mean=loc and std=scale (see lognorm_ex for comparison).

  ```python
  ss.lognorm_im(mean=2, sigma=1, strict=False).rvs(1000).mean() # Should be roughly 10
  ```

- `ss.make_dist(pars=None, **kwargs)`: Make a distribution from a dictionary
- `ss.multi_random(names, *args, crn=None, **kwargs)`: A class for holding two or more ss.random() distributions, and generating random numbers linked to each of them. Useful for e.g. pairwise transmission probabilities.
- `ss.nbinom(n=1, p=0.5, **kwargs)`: Negative binomial distribution
- `ss.normal(loc=0.0, scale=1.0, **kwargs)`: Normal distribution
- `ss.poisson(lam=1.0, **kwargs)`: Poisson distribution
- `ss.rand_raw(**kwargs)`: Directly sample raw integers (uint64) from the random number generator. Typicaly only used with ss.combine_rands().
- `ss.randint(*args, low=None, high=None, dtype=None, **kwargs)`: Random integer distribution, on the interval [low, high)
- `ss.random(**kwargs)`: Random distribution, with values on the interval (0, 1)
- `ss.scale_types(*args, **kwargs)`: Define how distributions scale
- `ss.uniform(low=None, high=None, **kwargs)`: Uniform distribution, values on interval (low, high)
- `ss.weibull(c=1.0, loc=0.0, scale=1.0, **kwargs)`: Weibull distribution (specifically, scipy.stats.weibull_min)

## Parameters (ss.parameters)

- `ss.Pars(pars=None, **kwargs)`: Dict-like container of parameters
- `ss.SimPars(pars=None, create=True, **kwargs)`: Create the parameters for the simulation. Typically, this function is used internally rather than called by the user; e.g. typical use would be to do sim = ss.Sim() and then inspect sim.pars, rather than calling this function directly.

## Results (ss.results)

- `ss.Result(name=None, label=None, dtype=<class 'float'>, shape=None, scale=True, auto_plot=True, module=None, values=None, timevec=None, low=None, high=None, summarize_by=None, columns=None, **kwargs)`: Array-like container for holding sim results.

  ```python
  res = ss.Result('new_infections', columns=['wild', 'alpha'], shape=10)
  res[3] = [20, 5] # Set the values for timestep 3
  res['alpha'][4] = 8 # Set one value for timestep 4
  res['alpha'].label # Returns 'new_infections (alpha)'
  ```

- `ss.Results(module, *args, strict=True, **kwargs)`: Container for storing results

## Running multiple simulations (ss.run)

- `ss.multi_run(sim, n_runs=4, reseed=None, iterpars=None, shrink=None, run_args=None, sim_args=None, par_args=None, do_run=True, parallel=True, n_cpus=None, copy_sim=False, verbose=None, **kwargs)`: For running multiple sims in parallel. If the first argument is a list of sims rather than a single sim, exactly these will be run and most other arguments will be ignored.

  ```python
  import starsim as ss
  sim = ss.Sim()
  sims = ss.multi_run(sim, n_runs=6)
  ```

- `ss.MultiSim(sims=None, base_sim=None, label=None, n_runs=4, initialize=False, inplace=True, debug=False, **kwargs)`: Class for running multiple copies of a simulation in parallel.

  ```python
  import starsim as ss

  s1 = ss.Sim(networks='random', diseases=ss.SIS(beta=0.02), label='Low transmission')
  s2 = ss.Sim(networks='random', diseases=ss.SIS(beta=0.05), label='Medium transmission')
  s3 = ss.Sim(networks='random', diseases=ss.SIS(beta=0.10), label='High transmission')

  msim = ss.MultiSim(sims=[s1, s2, s3])
  msim.run()

  # Plot individual sims
  msim.plot()

  # [...]
  ```

- `ss.parallel(*args, **kwargs)`: A shortcut to `ss.MultiSim()`, allowing the quick running of multiple simulations at once.

  ```python
  s1 = ss.Sim(n_agents=1000, label='Small', diseases='sis', networks='random')
  s2 = ss.Sim(n_agents=2000, label='Large', diseases='sis', networks='random')
  ss.parallel(s1, s2).plot()
  msim = ss.parallel([s1, s2], shrink=False)
  ```

- `ss.single_run(sim, ind=0, reseed=True, shrink=True, run_args=None, sim_args=None, verbose=None, do_run=True, copy_sim=False, **kwargs)`: Convenience function to perform a single simulation run. Mostly used for parallelization, but can also be used directly.

  ```python
  import starsim as ss
  sim = ss.Sim() # Create a default simulation
  sim = ss.single_run(sim) # Run it, equivalent(ish) to sim.run()
  ```


## Calibration (ss.calibration)

- `ss.BetaBinomial(name, expected, extract_fn, conform, weight=1, include_fn=None, n_boot=None, combine_reps=None)`: Beta-binomial negative log-likelihood component for count data with overdispersion
- `ss.Binomial(name, expected, extract_fn, conform, weight=1, include_fn=None, n_boot=None, combine_reps=None)`: Binomial negative log-likelihood component for count data with a known number of trials
- `ss.CalibComponent(name, expected, extract_fn, conform, weight=1, include_fn=None, n_boot=None, combine_reps=None)`: A class to compare a single channel of observed data with output from a simulation. The Calibration class can use several CalibComponent objects to form an overall understanding of how will a given simulation reflects observed data.
- `ss.Calibration(sim, calib_pars, n_workers=None, total_trials=None, reseed=True, build_fn=None, build_kw=None, eval_fn=None, eval_kw=None, components=None, prune_fn=None, label=None, study_name=None, db_name=None, keep_db=None, continue_db=None, storage=None, sampler=None, die=False, debug=False, verbose=True)`: A class to handle calibration of Starsim simulations. Uses the Optuna hyperparameter optimization library (optuna.org).
- `ss.DirichletMultinomial(name, expected, extract_fn, conform, weight=1, include_fn=None, n_boot=None, combine_reps=None)`: Dirichlet-multinomial negative log-likelihood component for compositional count data
- `ss.GammaPoisson(*args, **kwargs)`: Gamma-Poisson (negative binomial) negative log-likelihood component for overdispersed count data
- `ss.linear_accum(expected, actual)`: Interpolate in the cumulative sum, then difference. Use for incident data (flows) like incidence or new_deaths. The accumulation is done between 't' and 't1', both of which must be present in the index of expected and actual dataframes.
- `ss.linear_interp(expected, actual)`: Simply interpolate, use for prevalent (stock) data like prevalence
- `ss.Normal(name, expected, extract_fn, conform, weight=1, sigma2=None, **kwargs)`: Normal (Gaussian) negative log-likelihood component for continuous data
- `ss.step_containing(expected, actual)`: Find the step containing the the timepoint. Use for prevalent data like prevalence where you want to match a specific time point rather than interpolate.

## Samples (ss.samples)

- `ss.Dataset(folder=None, results=None, *args, **kwargs)`: Store the results and provide options for filtering
- `ss.Samples(fname, memory_buffer=True, preload=False)`: Stores CSV outputs and summary dataframes

## Arrays and agent indexing (ss.arrays)

- `ss.Arr(name=None, dtype=None, default=None, nan=None, label=None, raw=None, skip_init=False, people=None, mock=None, columns=None)`: Store a state of the agents (e.g. age, infection status, etc.) as an array.

  ```python
  # Create a standalone Arr for quick testing
  age = ss.Arr('age', default=0, mock=5) # 5 = length if not supplying a real People object
  age[:] = [20, 30, 40, 50, 60]
  age.mean()  # Returns 40.0

  # Use within a simulation
  sim = ss.Sim(n_agents=100).init()
  sim.people.age.mean()  # Mean age of active agents

  # Create a 2D array, e.g. immunity to each of 3 variants
  imm = ss.FloatArr('imm', default=0, columns=3, mock=5)
  imm[ss.uids([0, 1]), 2] = 0.8 # Set immunity to variant 2 for agents 0 and 1
  # [...]
  ```

- `ss.BaseArr(values, *args, **kwargs)`: An object that acts exactly like a NumPy array, except stores the values in self.values.
- `ss.BoolArr(name=None, **kwargs)`: Subclass of `ss.Arr` with defaults for booleans.

  ```python
  # Create a standalone BoolArr
  infected = ss.BoolArr('infected', mock=5)
  infected[ss.uids([0, 2, 4])] = True
  infected.count()  # Returns 3
  infected.uids     # Returns ss.uids([0, 2, 4])
  ```

- `ss.BoolState(name=None, **kwargs)`: A boolean array being used as a state.
- `ss.FloatArr(name=None, **kwargs)`: Subclass of `ss.Arr` with defaults for floats and ints.
- `ss.IndexArr(name=None, label=None)`: A special class of Arr used for UIDs and RNG IDs; not to be used as a general integer array (for that, use IntArr)
- `ss.IntArr(name=None, **kwargs)`: Subclass of `ss.Arr` with defaults for ints.
- `ss.uids(arr=None)`: Class to specify that integers should be interpreted as UIDs.

  ```python
  a = ss.uids([1, 2, 3])
  b = ss.uids([3, 4, 5])
  a + b   # Concatenate: uids([1, 2, 3, 3, 4, 5])
  a | b   # Union:       uids([1, 2, 3, 4, 5])
  a & b   # Intersect:   uids([3])
  a - b   # Difference:  uids([1, 2])
  ```


## Integration loop (ss.loop)

- `ss.Loop(sim)`: Define the integration loop

## Utilities (ss.utils)

- `ss.apply_age_range(age_string, arr)`: Return a boolean mask for values in `arr` that fall within the age range.
- `ss.find_contacts(p1, p2, inds)`: Variation on Network.find_contacts() that avoids sorting.
- `ss.load(filename, **kwargs)`: Alias to Sciris `sc.loadany()`
- `ss.ndict(*args, nameattr='name', type=None, strict=True, overwrite=False, **kwargs)`: A dictionary-like class that provides additional functionalities for handling named items.

  ```python
  networks = ss.ndict(ss.MFNet(), ss.PrenatalNet())
  networks = ss.ndict([ss.MFNet(), ss.PrenatalNet()])
  networks = ss.ndict({'mf':ss.MFNet(), 'prenatal':ss.PrenatalNet()})
  ```

- `ss.parse_age_range(age_string) -> tuple`: Parse an age range string into lower and upper bounds.
- `ss.plot_args(kwargs=None, _debug=False, **defaults)`: Process known plotting kwargs.

  ```python
  kw = ss.plot_args(kwargs, fig_kw=dict(figsize=(10,10)) # Explicit way to set figure size, passed to `plt.figure()` eventually
  kw = ss.plot_args(kwargs, figsize=(10,10)) # Shortcut since known keyword
  ```

- `ss.return_fig(fig, **kwargs)`: Do postprocessing on the figure: by default, don't return if in Jupyter, but show instead; not for the user
- `ss.save(filename, obj, **kwargs)`: Alias to Sciris `sc.save()`
- `ss.show(**kwargs)`: Shortcut for matplotlib.pyplot.show()
- `ss.shrink(obj=None, attrs=None, verbose=False)`: Replace one or more object attributes in-place with an `ss.utils.Shrunk()` placeholder.

  ```python
  # "Shrink" (remove) the People object
  sim = ss.Sim()
  ss.shrink(sim, 'people')

  # Equivalent behavior, used manually
  sim.people = ss.shrink()
  ```

- `ss.standardize_data(data=None, metadata=None, min_year=1800, out_of_range=0, default_age=0, default_year=2024)`: Standardize formats of input data
- `ss.standardize_netkey(key)`: Standardize network key names
- `ss.validate_sim_data(data=None, die=None)`: Validate data intended to be compared to the sim outputs, e.g. for calibration
- `ss.warn(msg, category=None, verbose=None, die=None)`: Helper function to handle warnings -- shortcut to warnings.warn

## Debugging tools (ss.debugtools)

- `ss.check_requires(sim, requires, *args)`: Check that the module's requirements (of other modules) are met
- `ss.check_version(expected, die=False, warn=True)`: Check the expected Starsim version with the one actually installed. The expected version string may optionally start with '>=' or '<=' (== is implied otherwise), but other operators (e.g. ~=) are not supported. Note that '>' and '<' are interpreted to mean '>=' and '<='; '>' and '<' are not […]

  ```python
  ss.check_version('>=3.0.0', die=True) # Will raise an exception if an older version is used
  ```

- `ss.Debugger(*args, func, skip=None, verbose=True, die=True, run=False)`: Step through one or more sims and pause or raise an exception when a condition is met

  ```python
  ## Example 1: Identical sims are identical
  import starsim as ss

  s1 = ss.Sim(pars=dict(diseases='sis', networks='random'), n_agents=250)
  s2 = s1.copy()
  s3 = s1.copy()
  db = ss.Debugger(s1, s2, s3, func='equal')
  db.run()

  ## Example 2: Pause when sim results diverge
  import sciris as sc
  import starsim as ss
  # [...]
  ```

- `ss.Diagnostics(sim, rvs=True, states=True, detailed=False)`: Helper class for storing detailed diagnostic information; see sim.set_diagnostics() for usage; not to be used directly
- `ss.metadata(comments=None)`: Store metadata; like `sc.metadata()`, but optimized for speed
- `ss.mock_module(dur=10, **kwargs)`: Create a minimal mock "Module" object; kwargs are passed to `ss.mock_time()`
- `ss.mock_people(n_agents=100, min_age=0, max_age=70, age_seed=1)`: Create a minimal mock "People" object with ages
- `ss.mock_sim(n_agents=100, **kwargs)`: Create a minimal mock "Sim" object to initialize objects that require it
- `ss.mock_time(dt=1.0, dur=10, start=2000)`: Create a minimal mock "Time" object
- `ss.Profile(sim, follow=None, do_run=True, plot=True, verbose=True, **kwargs)`: Class to profile the performance of a simulation

  ```python
  import starsim as ss

  net = ss.RandomNet()
  sis = ss.SIS()
  sim = ss.Sim(networks=net, diseases=sis)
  prof = sim.profile(follow=[net.add_pairs, sis.infect])
  prof.disp()
  ```


## Settings (ss.settings)

- `ss.load_fonts(folder=None, name='Mulish', rebuild=False, verbose=False, **kwargs)`: Helper function to load custom fonts for plotting -- (usually) not for the user.
- `ss.options(*args, **kwargs)`: Set options for Starsim.

  ```python
  ss.options(verbose=True) # Set more verbosity
  ss.options(warnings='error') # Be more strict about warnings
  ```

- `ss.style(style=None, **kwargs)`: Set the style in a with block.

  ```python
  # Create a plot using default Starsim styling
  with ss.style():
      plt.plot()

  # Create a plot using a built-in Matplotlib style
  with ss.style('seaborn-v0_8-whitegrid'):
      plt.plot()

  # Customize the current style
  with ss.style(font='Rosario'):
      plt.plot()
  ```


## Library: diseases (ssl.diseases)

- `ssl.ART(year, coverage, pars=None, **kwargs)`: Scale up antiretroviral therapy over time.

  ```python
  import starsim.library as ssl

  art = ssl.ART(year=[2000, 2010, 2020], coverage=[0, 0.4, 0.8])
  ```

- `ssl.CD4_analyzer(**kwargs)`: Record the CD4 count of every agent at every timestep.
- `ssl.Cholera(pars=None, **kwargs)`: Cholera, with both direct and environmental (waterborne) transmission.
  - Default pars: `init_prev=ss.bernoulli(p=0.005)`, `beta=ss.prob(1/1)`, `p_death=ss.bernoulli(p=0.005)`, `dur_exp=ss.lognorm_ex(mean=2.772, std=4.737)`, `dur_asymp2rec=ss.uniform(low=1, high=10)`, `dur_symp2rec=ss.lognorm_ex(mean=5, std=1.8)`, `dur_symp2dead=ss.lognorm_ex(mean=1, std=0.5)`, `p_symp=ss.bernoulli(p=0.5)`, `asymp_trans=0.01`, `beta_env=ss.prob(0.166667)`, `half_sat_rate=1000000`, `shedding_rate=ss.freqperday(10)`, `decay_rate=ss.perday(0.033)`, `p_env_transmit=ss.bernoulli(p=0)`

  ```python
  import starsim as ss
  import starsim.library as ssl

  sim = ss.Sim(diseases=ssl.Cholera(), networks='random')
  sim.run()
  sim.plot()
  ```

- `ssl.Ebola(pars=None, **kwargs)`: Ebola, including severe disease and transmission from unburied bodies.
  - Default pars: `init_prev=ss.bernoulli(p=0.005)`, `beta=ss.prob(1/1)`, `p_death=ss.bernoulli(p=0.55)`, `dur_exp=ss.lognorm_ex(mean=12.7, std=1.0)`, `sev_factor=2.2`, `unburied_factor=2.1`, `dur_symp2sev=ss.lognorm_ex(mean=6, std=1.0)`, `dur_sev2dead=ss.lognorm_ex(mean=1.5, std=1.0)`, `dur_dead2buried=ss.lognorm_ex(mean=2, std=1.0)`, `dur_symp2rec=ss.lognorm_ex(mean=10, std=1.0)`, `dur_sev2rec=ss.lognorm_ex(mean=10.4, std=1.0)`, `p_sev=ss.bernoulli(p=0.7)`, `p_safe_bury=ss.bernoulli(p=0.25)`

  ```python
  import starsim as ss
  import starsim.library as ssl

  sim = ss.Sim(diseases=ssl.Ebola(), networks='random')
  sim.run()
  sim.plot()
  ```

- `ssl.HIV(pars=None, **kwargs)`: Simple HIV model with CD4 count dynamics and ART.
  - Default pars: `init_prev=ss.bernoulli(p=0.05)`, `beta=0.0`, `cd4_min=100`, `cd4_max=500`, `cd4_rate=5`, `eff_condoms=0.7`, `art_efficacy=0.96`, `death_dist=ss.bernoulli(p=<function HIV.death_prob_func>)`, `p_death=ss.peryear(0.05)`

  ```python
  import starsim as ss
  import starsim.library as ssl

  sim = ss.Sim(
      diseases = ssl.HIV(beta=0.02, init_prev=0.05),
      networks = 'random',
      interventions = ssl.ART(year=[2000, 2020], coverage=[0, 0.8]),
  )
  sim.run()
  sim.plot()
  ```

- `ssl.Measles(pars=None, **kwargs)`: Measles, as an SEIR model.
  - Default pars: `init_prev=ss.bernoulli(p=0.005)`, `beta=ss.peryear(1)`, `dur_inf=ss.normal(loc=11, scale=1.0)`, `p_death=ss.bernoulli(p=0.005)`, `dur_exp=ss.normal(loc=8, scale=1.0)`

  ```python
  import starsim as ss
  import starsim.library as ssl

  sim = ss.Sim(diseases=ssl.Measles(), networks='random')
  sim.run()
  sim.plot()
  ```


## Library: maternal, newborn, and child health (ssl.mnch)

- `ssl.CongenitalDisease(pars=None, **kwargs)`: Simple disease with congenital outcomes via the generic framework.
  - Default pars: `init_prev=ss.bernoulli(p=0.01)`, `beta=ss.peryear(0.1)`, `dur_inf=ss.lognorm_ex(mean=6, std=1.0)`, `p_death=ss.bernoulli(p=0.01)`, `birth_outcome_keys=['stillborn', 'congenital', 'normal']`, `birth_outcomes=#0. 'default': ss.choice(a=3, p=[0.3 0.4 0.3], replace=True)`
- `ssl.fetal_infection(pars=None, **kwargs)`: Connect a disease to fetal health outcomes during pregnancy.
  - Default pars: `timing_shift=ss.lognorm_ex(mean=3.0, std=1.0)`, `growth_penalty=0.15`
- `ssl.FetalHealth(pars=None, **kwargs)`: Track fetal health outcomes during pregnancy.
  - Default pars: `weight_by_ga=array([[ 24., 600.], [ 25., 700.], [ 26., 800.], [ 27., 900.], [ 28., 1000.], [  […]`, `interp_fn=<function interp>`, `sga_ratio=0.87`, `lbw_threshold=2500`, `vlbw_threshold=1500`, `min_ga=ss.weeks(24)`, `percentile_dist=ss.normal(loc=1.0, scale=0.1)`

  ```python
  import starsim as ss

  sim = ss.Sim(
      demographics=[ss.Pregnancy(fertility_rate=10), ss.Deaths(death_rate=10)],
      modules=ssl.mnch.FetalHealth(),
      networks=ss.PrenatalNet(),
  )
  sim.run()
  ```

- `ssl.NeonatalSepsis(pars=None, **kwargs)`: Minimal neonatal sepsis model.
  - Default pars: `init_prev=ss.bernoulli(p=0.3)`, `beta=ss.peryear(0)`, `dur_inf=ss.lognorm_ex(mean=7, std=3)`, `p_death=ss.bernoulli(p=0.5)`
- `ssl.treat_pregnant(disease='sir', start_year=None, end_year=None, pars=None, **kwargs)`: Treat infected pregnant women and partially reverse fetal damage.
  - Default pars: `p_treat=ss.bernoulli(p=0.9)`, `tx_growth_reversal=0.7`, `tx_timing_reversal=0.7`

## Library: networks (ssl.networks)

- `ssl.DiskNet(pars=None, **kwargs)`: Disk graph in which edges are made between agents located within a user-defined radius.
  - Default pars: `r=0.1`, `v=ss.freq(0.05/1)`

  ```python
  import starsim as ss
  import starsim.library as ssl

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

- `ssl.ErdosRenyiNet(pars=None, **kwargs)`: In the Erdos-Renyi network, every possible edge has a probability, p, of being created on each time step.
  - Default pars: `p=0.1`, `dur=ss.years(0)`

  ```python
  import starsim as ss
  import starsim.library as ssl

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

- `ssl.HouseholdNet(pars=None, dhs_data=None, dynamic=True, prob_move_out=None, update_freq=None, **kwargs)`: A household contact network built from DHS-style survey data.
- `ssl.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.

<!-- Generated by `python make_api.py` for Starsim v3.7.0: llms-full.txt -->
