Skip to main content

run

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 (see ss.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 runs
plot
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 it
shrink
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 merge
summarize
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 run
to_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 run
  • until and verbose: as for sim.run()
  • shrink: whether to shrink each sim after it runs, to save memory (see sim.shrink())
  • par_args: passed to sc.Parallel()
  • run_args: passed to each sim.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 beta

restart_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