run
Running many sims: ss.parallel() and ss.MultiSim
These exist so that a model can be run many times, across seeds, parameter values, or scenarios, with the results gathered in one place for comparing and plotting.
Used with: agents and compartments; declared and coded modules
Classes
| Name | Description |
|---|---|
| Branching | What came of the runs of a branching process together (msim.branching): see sim.branching for one run |
| ByScenario | For the sims of a MultiSim: keys() and items() by scenario, as a dict of them would have (each scenario’s sim, or a list of them if it has several runs) |
| DifferentTimes | In place of msim.results, for sims with different time points (e.g. different steps): any use of it raises an error saying why, and what to do instead |
| MultiResults | The results of the runs of a MultiSim: the results of a sim, each with a run axis first |
| MultiSim | The runs of one or more sims: every result of the sims with a run axis first, and the sims that were run |
| RestartedSims | The sim of each run of sims that were restarted for their runs (see restart_runs()), made when it is first asked for |
| Sims | The sims of the runs of a MultiSim: a list, which can also be indexed by scenario (msim.sims['Vaccine'], msim.sims.items(); see MultiSim.sims) |
Branching
run.Branching(runs)What came of the runs of a branching process together (msim.branching): see sim.branching for one run
Attributes
| Name | Type | Description |
|---|---|---|
| sizes | array |
the people infected in each run, the seeds included |
| outcomes | array |
each run’s outcome: 'extinct', 'stopped' (by until=), or 'ongoing' |
| p_extinct | float |
the fraction of the runs that went extinct, and p_extinct_ci its 95% interval (Wilson’s) |
| lengths | array |
as agents, the most generations of each run’s chain |
| offspring | array |
as agents, the number each person infected, of everyone infected long enough before the end that their offspring are all counted (see sim.branching); only if no run was stopped by until=, since where a run stops depends on its offspring |
| R, | k (float | as agents, the mean of the offspring and their dispersion, as a negative binomial fitted by maximum likelihood (k is infinite for offspring no more variable than a Poisson’s); None if a run was stopped by until=, so to estimate them, run for a fixed dur instead |
Example
sir = ss.SIR(beta=ss.perday(0.3), dur_inf=ss.days(10), init_n=dict(I=1))
sim = ss.Sim(diseases=sir, total_pop=1e6, branching=True, solver='gillespie', unit='day', dur=ss.days(365))
msim = ss.parallel(sim, n_runs=200, until=sir.I.n + sir.R.n >= 200)
msim.branching.p_extinct # About 1/R0 = 1/3
msim.branching.plot()Methods
| Name | Description |
|---|---|
| fit_offspring | The mean of some offspring counts, and the dispersion k of a negative binomial with that mean fitted to them by maximum likelihood (infinite if they are no more variable than a Poisson’s) |
| plot | The distribution of the chains’ sizes (and, as agents, of their lengths in generations) |
fit_offspring
run.Branching.fit_offspring(counts)The mean of some offspring counts, and the dispersion k of a negative binomial with that mean fitted to them by maximum likelihood (infinite if they are no more variable than a Poisson’s)
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| counts | array |
the number of offspring of each case | required |
plot
run.Branching.plot(**kwargs)The distribution of the chains’ sizes (and, as agents, of their lengths in generations)
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| kwargs | dict |
passed to ss.plot_args() |
ByScenario
run.ByScenario()For the sims of a MultiSim: keys() and items() by scenario, as a dict of them would have (each scenario’s sim, or a list of them if it has several runs)
Methods
| Name | Description |
|---|---|
| items | Each scenario, and its sim (or a list of them, if it has several runs) |
| keys | The scenarios, in order |
items
run.ByScenario.items()Each scenario, and its sim (or a list of them, if it has several runs)
keys
run.ByScenario.keys()The scenarios, in order
DifferentTimes
run.DifferentTimes(sims)In place of msim.results, for sims with different time points (e.g. different steps): any use of it raises an error saying why, and what to do instead
MultiResults
run.MultiResults(module=None, *args, **kwargs)The results of the runs of a MultiSim: the results of a sim, each with a run axis first
Each result is an ss.Result (see there for what one across runs does), e.g. msim.results.sir.I.quantiles().
Methods
| Name | Description |
|---|---|
| build | The results of many runs, each with a run axis first: the one constructor that every way of running many sims ends in |
| concat | The results of several sets of runs, one after the other (each result that all of them have) |
| diff | The difference of every result from the baseline scenario: a dict by scenario, then module, then result |
| from_sims | Every result that every sim has (with the same shape), across the sims: one run per sim |
| take | The results of some of the runs, by position |
| to_df | Every result across the runs, as a long dataframe with columns for the module and result: one row per run and time (see ss.Result.to_df()), or with quantiles=, per scenario, quantile, and time |
build
run.MultiResults.build(arrays, runs, timevec=None, order=None)The results of many runs, each with a run axis first: the one constructor that every way of running many sims ends in
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| arrays | dict |
for each result, by (module, key), with the module None for the sim’s own results: the result of one run it is like (like, for its name, kind, label, time points, and dimensions), its values (runs by time points), and if it is kept by group, strata and denom (runs by rows by groups) and group_ti (see ss.solvers.group_rows()) |
required |
| runs | dataframe |
one row per run: its scenario, and the values of any parameters swept | required |
| timevec | array |
the sim’s time points | None |
| order | Results | the results of a sim, whose order the results keep (e.g. the modules’ results before the sim’s own, as in sim.summarize()); results it doesn’t have go last |
None |
concat
run.MultiResults.concat(results)The results of several sets of runs, one after the other (each result that all of them have)
diff
run.MultiResults.diff(baseline)The difference of every result from the baseline scenario: a dict by scenario, then module, then result
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| baseline | str |
the name of the baseline scenario | required |
from_sims
run.MultiResults.from_sims(sims, runs)Every result that every sim has (with the same shape), across the sims: one run per sim
take
run.MultiResults.take(inds)The results of some of the runs, by position
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| inds | array |
the positions of the runs | required |
to_df
run.MultiResults.to_df(quantiles=None, **kwargs)Every result across the runs, as a long dataframe with columns for the module and result: one row per run and time (see ss.Result.to_df()), or with quantiles=, per scenario, quantile, and time
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| quantiles | tuple |
the quantiles to compute, from 0 to 1 (default: one row per run) | None |
| kwargs | dict |
passed to ss.Result.to_df() |
MultiSim
run.MultiSim(
sims=None,
label=None,
n_runs=None,
pars=None,
priors=False,
inplace=True,
**kwargs,
)The runs of one or more sims: every result of the sims with a run axis first, and the sims that were run
Made and run by ss.parallel(), the way to run many sims; ss.MultiSim(...) with the same arguments, then msim.run(), does the same (and is the class to subclass). Each sim is run once unless n_runs, pars, or priors is given: a single sim, ss.MultiSim(sim), is one run, where in Starsim 3 it was run four times by default (ss.parallel(sim, n_runs=4) for that). To make and initialize the sim of each run without running them, use msim.init_sims().
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| sims | Sim / list / dict |
a single sim, a list/tuple of sims, a dict of sims by label, or another MultiSim (or list of MultiSims); the first is msim.base_sim, whose label and settings the MultiSim shows |
None |
| label | str |
the name of the multisim | None |
| n_runs | int |
the number of runs of each sim, each with its own seed (by default, 1) | None |
| pars | dict / list |
sets of values of parameters to run each sim with; see ss.parallel() |
None |
| priors | bool / dict |
draw n_runs sets of values from the priors of the parameters, or the draws to run; see ss.parallel() |
False |
| inplace | bool |
whether to update sims that are run as they are (with no n_runs or pars) with their results (default True) |
True |
| kwargs | dict |
how to run the sims, as for ss.parallel(): workers (the number of worker processes: by default one per CPU; 1 runs them one after another in this process), until and verbose (as for sim.run()), shrink, par_args, and run_args |
By default (verbose not given: the sims’ own verbose, if they share one, else ss.options.verbose) the runs print nothing of their own, and the MultiSim shows their progress: nothing for runs that are done within a second, a bar for each run if there are up to 10 that each take more than 10 seconds, and otherwise one bar with the number of runs done (to a file, a line every tenth); then a line on what was run.
Once run, a MultiSim has:
results: every result with a run axis first (seess.Result), e.g.msim.results.sir.I.quantiles();runs: one row per run, with its scenario (the label of its sim), the values of any parameters swept or drawn, and its seed (rand_seed);sims: the sims that were run (for runs restarted from one compartmental sim, that sim, as it was after its last run).
len(msim) is the number of runs.
A subclass changes the sim of each run by overriding make_run(), and can take options of its own for it by adding them to run_options (see the last example).
Examples
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='High transmission')
msim = ss.parallel(s1, s2, n_runs=5)
msim.plot() # The median and a 95% interval of each scenario
msim.results.sis.prevalence.select(scenario='Low transmission').median()
class NoisyMultiSim(ss.MultiSim): # Each run with its own beta, drawn around 0.05
run_options = ss.MultiSim.run_options + ['noise']
def make_run(self, sim, values, seed, noise=0.1):
beta = 0.05*np.exp(noise*np.random.default_rng(seed).normal())
return super().make_run(sim, dict(values or {}, beta=beta), seed)
msim = NoisyMultiSim(s1, n_runs=10, noise=0.2).run()Attributes
| Name | Description |
|---|---|
| branching | For the runs of a branching process (ss.Sim(branching=True)): what came of them together, as an ss.run.Branching; None if the runs are not branching processes (see sim.branching for one run) |
| run_pars | The values of the parameters swept (or drawn) in each run, as a dataframe (or None if there are none) |
| sims | The sim of each run, by position (msim.sims[0]) or by scenario (msim.sims['Vaccine']: its sim, or a list of them if it has several runs; and msim.sims.items()), each labeled by its scenario |
Methods
| Name | Description |
|---|---|
| collect | Put the results of the sims together as runs (msim.results), if they have the same time points (msim._same_times) |
| combine | Combine the sims into a single sim, whose results are those of one population made of all of them, e.g. to treat several smaller sims as one larger population |
| copy | A deep copy of the MultiSim, its sims included |
| diff | The difference of each scenario from a baseline, for every result they share, run by run |
| disp | Print every attribute of the MultiSim |
| init_sims | Make the sim of each run, and initialize them without running them |
| make_run | The sim of one run: a new one (see sim.new()), with a seed and values of model parameters |
| marks | When the interventions of each scenario act, for marking on plots (see plot()): those of every scenario by None, the others by their scenario; spans as their starts unless fill=True |
| merge | Merge several MultiSims into one, with the runs of each, one after the other; msim.split() separates them again. |
| plot | Plot the results across the runs: the median and a 95% interval of each scenario, or every run if lines=True |
| plot_each | Plot each run on its own time axis, for sims with different time points (see plot()): each scenario in a color of its own |
| run | Run the sims, each n_runs times with its own seed and with each set of values of pars, and collect their results; see ss.parallel() |
| show | A moderate length summary of the MultiSim: its runs, scenarios, and sims. See also print(msim) (one line) |
| shrink | Shrink each sim, to save memory (e.g. before saving the MultiSim), keeping the results across runs; see sim.shrink() |
| split | Split one MultiSim into several, each with some of its runs; the reverse of ss.MultiSim.merge(). |
| summarize | A table of each result over the whole of each run, across the runs: the median, an interval, the mean, and the standard deviation |
| to_df | Every result across the runs; see ss.run.MultiResults.to_df() for the arguments |
collect
run.MultiSim.collect(sims)Put the results of the sims together as runs (msim.results), if they have the same time points (msim._same_times)
Sims with different time points (e.g. different steps) are kept as they are: each can be plotted on its own time axis (msim.plot()), but their results can’t be put together, so what combines the runs raises an error.
combine
run.MultiSim.combine()Combine the sims into a single sim, whose results are those of one population made of all of them, e.g. to treat several smaller sims as one larger population
Only the output is combined. Results that scale with population size (res.scale=True, e.g. counts) are summed; other results (e.g. prevalence) are averaged, weighted by each sim’s total_pop. The population sizes (n_agents and total_pop) are summed, and pop_scale is updated to match. The people are not joined: the combined sim keeps the people (if any) of the first sim, so it is not a larger population of agents that interact, and cannot be run again as one. To keep the runs as runs, see ss.MultiSim.merge().
Returns
| Name | Type | Description |
|---|---|---|
| The combined sim |
Examples
msim = ss.MultiSim(ss.Sim(n_agents=1e3, diseases='sis', networks='random'), n_runs=4)
msim.run()
sim = msim.combine() # Equivalent to a single sim with n_agents=4e3
sim.plot()copy
run.MultiSim.copy(die=True)A deep copy of the MultiSim, its sims included
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| die | bool |
whether to raise an exception if the copy fails (else, make a shallow copy) | True |
diff
run.MultiSim.diff(baseline)The difference of each scenario from a baseline, for every result they share, run by run
For sims run with ss.parallel({'baseline': sim1, 'vaccine': sim2}, n_runs=...). Returns a dict by scenario, then module, then result; each entry has one row per run.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| baseline | str |
the label of the baseline scenario | required |
Examples
sims = ss.parallel({'baseline': base, 'vaccine': vx}, n_runs=10)
averted = -sims.diff('baseline').vaccine.sir.infection.cum.median()[-1]disp
run.MultiSim.disp()Print every attribute of the MultiSim
init_sims
run.MultiSim.init_sims(**kwargs)Make the sim of each run, and initialize them without running them
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| kwargs | dict |
the same arguments as msim.run() |
make_run
run.MultiSim.make_run(sim, values, seed)The sim of one run: a new one (see sim.new()), with a seed and values of model parameters
A subclass can override this to change the sim of each run, e.g. to add noise to a parameter; the options it adds to run_options are passed to it as keywords.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| sim | Sim | the sim of the scenario | required |
| values | dict |
the values of parameters for this run (from pars=), or None; rand_seed among them is the seed |
required |
| seed | int |
the seed of this run | required |
marks
run.MultiSim.marks(sims, fill=False)When the interventions of each scenario act, for marking on plots (see plot()): those of every scenario by None, the others by their scenario; spans as their starts unless fill=True
merge
run.MultiSim.merge(*args)Merge several MultiSims into one, with the runs of each, one after the other; msim.split() separates them again.
Unlike msim.combine(), which adds up the sims as one population, the runs stay separate runs.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| args | MultiSim | the MultiSims to merge (either a list, or separate arguments) |
Returns
| Name | Type | Description |
|---|---|---|
| A new MultiSim |
Examples
m1 = ss.MultiSim(ss.Sim(diseases='sis', networks='random', label='SIS'), n_runs=3).run()
m2 = ss.MultiSim(ss.Sim(diseases='sis', networks='random', label='SIS 2'), n_runs=3).run()
msim = ss.MultiSim.merge(m1, m2) # 6 runsplot
run.MultiSim.plot(
key=None,
fig=None,
legend=True,
lines=False,
show_data=True,
show_interventions=True,
**kwargs,
)Plot the results across the runs: the median and a 95% interval of each scenario, or every run if lines=True
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| key | str / list |
the result (e.g. 'sir.I') or results to plot; by default, those that sim.plot() shows |
None |
| fig | Figure |
if provided, plot results into an existing figure | None |
| legend | bool |
whether to label the scenarios, if there is more than one | True |
| lines | bool |
plot every run instead of the median and interval | False |
| show_data | bool |
plot the data of the first sim that has any, as sim.plot() does (a flow with data at a longer period than the step is shown as its totals over the data’s periods) |
True |
| show_interventions | bool / str |
mark when interventions act, as sim.plot() does ('fill' to shade the span they’re active): in gray those of every scenario, and in a scenario’s color those of that scenario alone |
True |
| **kwargs | dict |
known arguments (e.g. figsize, font) split between the plotting dicts; see ss.plot_args() for all valid options |
plot_each
run.MultiSim.plot_each(
key=None,
fig=None,
legend=True,
show_data=True,
log=False,
**kwargs,
)Plot each run on its own time axis, for sims with different time points (see plot()): each scenario in a color of its own
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| key | str / list |
the result or results to plot (default: as for plot()) |
None |
| fig | Figure |
the figure to plot on | None |
| legend | bool |
whether to show a legend | True |
| show_data | bool |
whether to show the sim’s data, if any | True |
| log | bool |
whether to use a log scale for the y-axis | False |
| kwargs | dict |
passed to ss.plot_args() |
run
run.MultiSim.run(**kwargs)Run the sims, each n_runs times with its own seed and with each set of values of pars, and collect their results; see ss.parallel()
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| kwargs | dict |
change the arguments the MultiSim was made with, e.g. n_runs=10 or workers=1 |
Returns
| Name | Type | Description |
|---|---|---|
| The MultiSim, with its results |
show
run.MultiSim.show(**kwargs)A moderate length summary of the MultiSim: its runs, scenarios, and sims. See also print(msim) (one line) and msim.disp() (every attribute).
Returns
| Name | Type | Description |
|---|---|---|
| text | ss.display.Text |
the summary, which shows itself at a prompt or in a notebook, as describe() does; it is a string (print(text), str(text)) |
Examples
msim = ss.MultiSim(ss.demo(run=False), label='Example multisim', n_runs=4)
msim.run()
msim.show() # Shows moderate length output
text = msim.show() # And returns it, e.g. to save itshrink
run.MultiSim.shrink(**kwargs)Shrink each sim, to save memory (e.g. before saving the MultiSim), keeping the results across runs; see sim.shrink()
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| kwargs | dict |
passed to sim.shrink() for each sim |
split
run.MultiSim.split(inds=None, chunks=None)Split one MultiSim into several, each with some of its runs; the reverse of ss.MultiSim.merge().
Specify either the positions of the runs for each new MultiSim (inds), or consecutive chunks (chunks). For a merged MultiSim, neither is needed.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| inds | list |
a list of lists of positions, with each list turned into a MultiSim | None |
| chunks | int / list |
if an int, split the MultiSim into that many equal chunks; if a list, the number of runs in each chunk | None |
Returns
| Name | Type | Description |
|---|---|---|
| A list of MultiSims |
Examples
msim = ss.MultiSim(ss.Sim(diseases='sis', networks='random'), n_runs=6).run()
m1, m2 = msim.split(inds=[[0,2,4], [1,3,5]])
m1, m2 = msim.split(chunks=[2,4]) # Equivalent to inds=[[0,1], [2,3,4,5]]
m1, m2 = msim.split(chunks=2) # Equivalent to inds=[[0,1,2], [3,4,5]]
m1, m2 = ss.MultiSim.merge(m1, m2).split() # Use the chunks from the mergesummarize
run.MultiSim.summarize(
key=None,
interval=0.95,
how=None,
baseline=None,
each=False,
t=None,
)A table of each result over the whole of each run, across the runs: the median, an interval, the mean, and the standard deviation
Each result is first summarized over each run by its summarize_by (see sim.summarize()): a flow (e.g. infections) by its total, a stock (e.g. the number recovered) by its final value, and a ratio (e.g. prevalence) by its mean. Results that are 0 throughout are kept, so the tables of different runs (and of sim.summarize()) line up row for row.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| key | str |
if given, only this result (e.g. 'sir_infection' or 'sir.infection'), as msim.summarize().loc[key]: its row (or a row per scenario, if there are several) |
None |
| interval | float |
the fraction of runs the interval holds (default 0.95: from the 2.5th to the 97.5th percentile), as msim.plot() shows |
0.95 |
| how | str / dict |
how to summarize each result over each run: ‘mean’, ‘median’, ‘sum’, ‘last’, ‘max’, ‘min’, or a function, or a dict of these by result key, as for sim.summarize() |
None |
| baseline | str |
the label of a scenario to compare with: each other scenario’s difference from it, run by run (the runs are paired by position, as in msim.diff()), so the interval is of the paired differences |
None |
| each | bool |
if True, a column for each run (labeled by its scenario), with its own value of each result, rather than the statistics across the runs | False |
| t | int / str / date |
if given, each result’s value at this time point (a timestep index, or a date, the nearest time point to it) rather than over the whole run | None |
Returns
| Name | Type | Description |
|---|---|---|
A dataframe with a row for each result (and scenario, if there are several), and the columns median, low, high, mean, and std (or value, if each scenario was run once; or a column for each run, with each=True); with key, the rows of that result |
Example
msim = ss.parallel(sim, n_runs=20)
msim.summarize() # Every result
msim.summarize('sir_infection') # The total infections
msim.summarize(how=dict(sir_I='max')) # The peak number infectious in each run, over the runs
msim.summarize(baseline='No intervention') # Each scenario's difference from the baseline, e.g. the infections averted (negative)
msim.summarize(each=True) # The scenarios side by side, a column for each run
msim.summarize(each=True, t='2030-01-01') # The value of each result on that date, in each runto_df
run.MultiSim.to_df(**kwargs)Every result across the runs; see ss.run.MultiResults.to_df() for the arguments
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| kwargs | dict |
passed to ss.run.MultiResults.to_df(), e.g. quantiles=(0.025, 0.5, 0.975) |
RestartedSims
run.RestartedSims(runners, sets, n_runs, seeds, given=False)The sim of each run of sims that were restarted for their runs (see restart_runs()), made when it is first asked for
The runs are kept as results, so the sim of a run is made again only when it is asked for: a copy of its scenario’s sim, restarted with the run’s seed and values and run. runners are the sims (one per scenario) that were restarted.
Sims
run.Sims()The sims of the runs of a MultiSim: a list, which can also be indexed by scenario (msim.sims['Vaccine'], msim.sims.items(); see MultiSim.sims)
Functions
| Name | Description |
|---|---|
| base_values | The values of the parameters named in keys that the sim was built with, or None if one can’t be found this way (e.g. a value for one level) |
| by_scenario | For msim.sims['Vaccine']: the sim of the scenario, or a list of them if it has several runs |
| check_run_options | A clear error for a keyword that is not an option for running many sims: one of Starsim 3’s, a sim given by keyword, or an unknown one; call is the (class, method) it was given to, as ss.v3_deprecations.check() takes them |
| labeled | The sims of a dict by label, each labeled by its key, e.g. {'Baseline': s1, 'Vaccine': s2} |
| own_disease | The name of a sim’s one disease: the one it made or named, else its only disease (see ss.Sim.init_results()); None if it has several, or none |
| par_sets | A list of sets of parameter values, from a list of dicts or a dict of lists (one value per set) |
| parallel | Run many sims: different sims, each sim many times with its own seed, or with sets of values of its parameters |
| restart_runs | Run each sim a number of times, each with its own seed, by building it once and restarting it |
| run_each | Run each of a list of sims: in parallel, with a worker process per CPU (or workers of them), or with workers=1, one after another in this process |
| run_row | The row of a run in msim.runs: its scenario, its values, and its seed; a set of swept values is a scenario of its own, and a draw or a seed swept is a run of its sim’s scenario |
| run_seed | The seed of run i of set of values j (p) of a sim with this seed: the seed given in the set (plus i), if it has one; otherwise |
| same_times | Whether the sims have the same time points, so that their results can be put together as runs |
| single_run | Run one sim, as run_each() does: labeled by its position if it has no label, and shrunk afterwards if shrink |
base_values
run.base_values(sim, keys)The values of the parameters named in keys that the sim was built with, or None if one can’t be found this way (e.g. a value for one level)
by_scenario
run.by_scenario(sims, key)For msim.sims['Vaccine']: the sim of the scenario, or a list of them if it has several runs
check_run_options
run.check_run_options(kwargs, options=run_options, call=(None, 'parallel'))A clear error for a keyword that is not an option for running many sims: one of Starsim 3’s, a sim given by keyword, or an unknown one; call is the (class, method) it was given to, as ss.v3_deprecations.check() takes them
labeled
run.labeled(sims)The sims of a dict by label, each labeled by its key, e.g. {'Baseline': s1, 'Vaccine': s2}
own_disease
run.own_disease(sim)The name of a sim’s one disease: the one it made or named, else its only disease (see ss.Sim.init_results()); None if it has several, or none
par_sets
run.par_sets(pars)A list of sets of parameter values, from a list of dicts or a dict of lists (one value per set)
parallel
run.parallel(*args, n_runs=None, pars=None, priors=False, **kwargs)Run many sims: different sims, each sim many times with its own seed, or with sets of values of its parameters
This is the one way to run many sims (sim.run() runs one, and returns it). Every way of running ends in the same results: each result with a run axis first.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| args | list |
the sims to run, or a dict of them by label (e.g. {'No intervention': s1, 'Vaccine': s2}) |
|
| n_runs | int |
if provided, run each sim this many times, each with its own seed (the sim’s seed, plus 1, 2, …) | None |
| pars | dict / list |
sets of values of parameters to run each sim with, to compare them (a sweep): a dict with a list of values for each parameter (dict(beta=[0.2, 0.3])), or a list of dicts; see below |
None |
| priors | bool / dict |
True to draw n_runs sets of values from the priors of the parameters, to carry the uncertainty in them into a projection; or the draws themselves (e.g. from a posterior); see below |
False |
| kwargs | dict |
how to run them; see below |
With pars=, each set of values is run n_runs times (default 1), with the same seeds for every set, and each set is a scenario of its own. The values are in msim.runs (and can be selected, e.g. res.select(beta=0.2)), with each run’s rand_seed. Seeds can be given too, e.g. pars=dict(rand_seed=[1, 5, 9]), as runs of the scenario rather than scenarios.
With priors=True, n_runs sets of values are drawn from the priors of the parameters (ss.par(prior=...), or uniform over its bounds), on a Latin hypercube, and each is run once; draws can also be given, as for pars= (as fit.project() passes those of a posterior). Unlike a sweep with pars=, the draws are runs of their sim’s scenario, each with a seed of its own (the sim’s seed, plus 1, 2, …), so quantiles over a scenario’s runs include both the draws and chance.
How to run them, by keyword (see also ss.MultiSim):
workers: the number of worker processes (by default, one per CPU); 1 runs them one after another in this process, e.g. on a shared machine, or to debug a rununtilandverbose: as forsim.run()shrink: whether to shrink each sim after it runs, to save memory (seesim.shrink())par_args: passed tosc.Parallel()run_args: passed to eachsim.run()
Returns
| Name | Type | Description |
|---|---|---|
A run MultiSim. Each result is available across the runs, with the label of each sim as its scenario, e.g. msim.results.sir.I.quantiles([0.025, 0.5, 0.975]). |
Examples
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)
msim = ss.parallel(s1, n_runs=10) # Ten runs of one sim
msim = ss.parallel(s1, n_runs=10, workers=1) # The same, one after another in this process
msim = ss.parallel({'Baseline': s1, 'With vaccine': s2}, n_runs=10) # Two scenarios; see msim.diff('Baseline')
msim = ss.parallel(sim, pars=dict(beta=np.linspace(0.1, 0.5, 100))) # One run with each value of betarestart_runs
run.restart_runs(sims, n_runs, pars=None, draws=False, starts=None)Run each sim a number of times, each with its own seed, by building it once and restarting it
Only for sims that are nothing but compartments (see ss.Sim.restart()), where this is many times faster than running copies. Returns None if any of the sims is not. Otherwise returns the sim of each run (RestartedSims, which makes each one when it is asked for), the results of every run (ss.run.MultiResults), and a dataframe of the runs.
With pars= (see ss.parallel()), each set of values is run n_runs times (as runs of their sim’s scenario if they are draws). An ODE with sim.jax = True (and JAX installed) takes them all in one call to JAX (see ss.gradients), which is faster than the kernels for tens of thousands of runs, once JAX has started.
With starts, one for each set of values: where its runs start, by the name of the module that runs the compartments (each a start of ss.solvers.Compartmental.run_many()), for the runs to continue from (e.g. from the runs drawn with a posterior: see ss.fitting.Fit.project()); a module without one starts at the start. The sims of the runs are then not available, only their results.
run_each
run.run_each(
sims,
workers=None,
par_args=None,
shrink=None,
verbose=None,
run_args=None,
progress=None,
)Run each of a list of sims: in parallel, with a worker process per CPU (or workers of them), or with workers=1, one after another in this process
With progress (an ss.display.RunsProgress), each run puts how far it has got in a dict shared with this process (Sciris’ globaldict), from which the progress is drawn ten times a second.
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| sims | list |
the sims to run | required |
| workers | int |
the number of worker processes to use (default: one per CPU); 1 runs the sims one after another in this process | None |
| par_args | dict |
passed to sc.parallelize() |
None |
| shrink | bool |
whether to shrink each sim after it runs | None |
| verbose | float |
how much to print | None |
| run_args | dict |
passed to sim.run() |
None |
| progress | ss.display.RunsProgress |
the progress to draw | None |
Returns the list of run sims (copies, as they are pickled to run in parallel).
run_row
run.run_row(sim, p, seed, draws=False)The row of a run in msim.runs: its scenario, its values, and its seed; a set of swept values is a scenario of its own, and a draw or a seed swept is a run of its sim’s scenario
run_seed
run.run_seed(seed, p, j, i, n_runs, draws=False)The seed of run i of set of values j (p) of a sim with this seed: the seed given in the set (plus i), if it has one; otherwise seed + i, the same for every set swept (so they are compared with the same chance events), or for draws, a seed of each draw’s own, since the draws of a posterior are runs of a scenario, and so differ by chance as well as by their values
same_times
run.same_times(sims)Whether the sims have the same time points, so that their results can be put together as runs
single_run
run.single_run(
sim,
ind=0,
shrink=True,
run_args=None,
verbose=None,
copy_sim=False,
track=False,
globaldict=None,
show=None,
)Run one sim, as run_each() does: labeled by its position if it has no label, and shrunk afterwards if shrink
Parameters
| Name | Type | Description | Default |
|---|---|---|---|
| sim | Sim | the sim to run | required |
| ind | int |
its position among the sims | 0 |
| shrink | bool |
whether to shrink the sim after it has run | True |
| run_args | dict |
arguments passed to sim.run() |
None |
| verbose | int |
detail to print | None |
| copy_sim | bool |
whether to run a copy of the sim (as pickling gives when running in parallel) | False |
| track | bool |
whether to put how far the run has got in globaldict, by ind (see ss.display.RunsProgress) |
False |
| globaldict | dict |
a dict shared with the other runs (given by sc.parallelize(), or by run_each() when run in a loop) |
None |
| show | func |
what shows the progress, when run in this process | None |