Developer tutorial: Analyzers#

Reporting results#

Each Starsim module can have its own results, which get added to the full list of results in the Sim object. For example, the ss.Pregnancy module adds results like sim.results.pregnancy.pregnant, and the ss.HIV module adds results like sim.results.hiv.new_infections. If you are writing your own module, you can add whatever custom results you want. However, another option is to create an Analyzer to store results that you might need for one particular analysis but won’t need all the time. An Analyzer is very similar to other Starsim modules in its structure, but the general idea of an analyzer is that it gets called at the end of a timestep, and reports of the state of things after everything else has been updated without changing any of the module states itself.

Suppose we wanted to create an analyzer that would report on the number of new HIV infections in pregnant women:

[1]:
import starsim as ss
import pandas as pd

class HIV_in_pregnancy(ss.Analyzer):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.requires = [ss.HIV, ss.Pregnancy]
        self.name = 'hiv_in_pregnancy'
        return

    def init_pre(self, sim):
        super().init_pre(sim)
        npts = self.sim.npts
        self.results += [
            ss.Result(self.name, 'new_infections_pregnancy', npts, dtype=float, scale=True),
        ]
        return

    def apply(self, sim):
        ti = sim.ti
        hiv = sim.diseases.hiv
        pregnant = sim.demographics.pregnancy.pregnant
        newly_infected = hiv.ti_infected == ti
        self.results['new_infections_pregnancy'][ti] = len((newly_infected & pregnant).uids)
        return

pregnancy = ss.Pregnancy(pars=dict(fertility_rate=pd.read_csv('test_data/nigeria_asfr.csv')))
hiv = ss.HIV(beta={'mfnet':[0.5,0.25]})
sim = ss.Sim(diseases=hiv, networks='mfnet', demographics=pregnancy, analyzers=HIV_in_pregnancy())
sim.run()
print(f'Total infections among pregnant women: {sim.results.hiv_in_pregnancy.new_infections_pregnancy.sum()}')

Starsim 1.0.0 (2024-07-10) — © 2023-2024 by IDM
Initializing sim with 10000 agents
  Running 2000.0 ( 0/51) (0.31 s)  ———————————————————— 2%
  Running 2010.0 (10/51) (0.45 s)  ••••———————————————— 22%
  Running 2020.0 (20/51) (0.64 s)  ••••••••———————————— 41%
  Running 2030.0 (30/51) (0.87 s)  ••••••••••••———————— 61%
  Running 2040.0 (40/51) (1.12 s)  ••••••••••••••••———— 80%
  Running 2050.0 (50/51) (1.39 s)  •••••••••••••••••••• 100%

Total infections among pregnant women: 97.0

Analyzers are ideal for adding custom results, and because they get added to the sim in the same way as any other result, they also get automatically exported in the same format, e.g. using sim.export_df().

Here’s a plot of the results from our HIV in pregnancy analyzer:

[2]:
import matplotlib.pyplot as plt

res = sim.results

plt.figure()
plt.plot(res.yearvec, res.hiv_in_pregnancy.new_infections_pregnancy)
plt.title('HIV infections acquired during pregnancy')
plt.show();
../_images/tutorials_dev_tut_analyzers_4_0.png