def init_people(self, seed_infections=1): ''' Create the people ''' self.people = sc.odict() # Dictionary for storing the people self.off_ship = sc.odict() # For people who've been moved off the ship guests = [0] * self['n_ppl'] class_size = 15 conned = { 's1': class_size, 's2': class_size, 's3': class_size, 'c': class_size } # generate contacts contacts_all = make_network.make_hybrid_contacts(self['n_ppl'], conned) nu = -1 for is_crew in guests: # Loop over each person nu += 1 person = Person( contacts=contacts_all[0][nu], uid=nu) # Create the person, gives the correct contacts self.people[person.uid] = person # Save them to the dictionary # Create the seed infections for i in range(seed_infections): person = self.people[i] person.susceptible = False person.exposed = True person.infectious = True person.date_exposed = 0 person.date_infectious = 0 person.exposed_type = "seeded" return
def init_people(self, seed_infections=1): ''' Create the people ''' self.people = sc.odict() # Dictionary for storing the people self.off_ship = sc.odict() # For people who've been moved off the ship guests = [0] * self['n_guests'] crew = [1] * self['n_crew'] for is_crew in crew + guests: # Loop over each person age, sex = cova_pars.get_age_sex(is_crew) if is_crew: contacts = self['contacts_crew'] else: contacts = self['contacts_guest'] person = Person(age=age, sex=sex, crew=is_crew, contacts=contacts) # Create the person self.people[person.uid] = person # Save them to the dictionary # Create the seed infections for i in range(seed_infections): person = self.people[i] person.susceptible = False person.exposed = True person.infectious = True person.date_exposed = 0 person.date_infectious = 0 return
def handle_to_plot(kind, to_plot, n_cols, sim, check_ready=True): ''' Handle which quantities to plot ''' # Check that results are ready if check_ready and not sim.results_ready: errormsg = 'Cannot plot since results are not ready yet -- did you run the sim?' raise RuntimeError(errormsg) # If not specified or specified as a string, load defaults if to_plot is None or isinstance(to_plot, str): to_plot = cvd.get_default_plots(to_plot, kind=kind, sim=sim) # If a list of keys has been supplied if isinstance(to_plot, list): to_plot_list = to_plot # Store separately to_plot = sc.odict() # Create the dict reskeys = sim.result_keys() for reskey in to_plot_list: name = sim.results[reskey].name if reskey in reskeys else sim.results['strain'][reskey].name to_plot[name] = [reskey] # Use the result name as the key and the reskey as the value to_plot = sc.odict(sc.dcp(to_plot)) # In case it's supplied as a dict # Handle rows and columns -- assume 5 is the most rows we would want n_plots = len(to_plot) if n_cols is None: max_rows = 4 # Assumption -- if desired, the user can override this by setting n_cols manually n_cols = int((n_plots-1)//max_rows + 1) # This gives 1 column for 1-4, 2 for 5-8, etc. n_rows,n_cols = sc.get_rows_cols(n_plots, ncols=n_cols) # Inconsistent naming due to Covasim/Matplotlib conventions return to_plot, n_cols, n_rows
def handle_to_plot(which, to_plot, n_cols, sim): ''' Handle which quantities to plot ''' # If not specified or specified as a string, load defaults if to_plot is None or isinstance(to_plot, str): if which == 'sim': to_plot = cvd.get_sim_plots(to_plot) elif which == 'scens': to_plot = cvd.get_scen_plots(to_plot) else: errormsg = f'"which" must be "sim" or "scens", not "{which}"' raise NotImplementedError(errormsg) # If a list of keys has been supplied if isinstance(to_plot, list): to_plot_list = to_plot # Store separately to_plot = sc.odict() # Create the dict for reskey in to_plot_list: to_plot[sim.results[reskey].name] = [ reskey ] # Use the result name as the key and the reskey as the value to_plot = sc.odict(sc.dcp(to_plot)) # In case it's supplied as a dict # Handle rows and columns -- assume 5 is the most rows we would want n_plots = len(to_plot) if n_cols is None: max_rows = 4 # Assumption -- if desired, the user can override this by setting n_cols manually n_cols = int((n_plots - 1) // max_rows + 1) # This gives 1 column for 1-4, 2 for 5-8, etc. n_rows = int(np.ceil(n_plots / n_cols)) # Number of subplot rows to have return to_plot, n_cols, n_rows
def handle_to_plot(kind, to_plot, n_cols, sim, check_ready=True): ''' Handle which quantities to plot ''' # Allow default kind to be overwritten by to_plot -- used by msim.plot() if isinstance(to_plot, tuple): kind, to_plot = to_plot # Split the tuple # Check that results are ready if check_ready and not sim.results_ready: errormsg = 'Cannot plot since results are not ready yet -- did you run the sim?' raise RuntimeError(errormsg) # If it matches a result key, convert to a list reskeys = sim.result_keys('main') varkeys = sim.result_keys('variant') allkeys = reskeys + varkeys if to_plot in allkeys: to_plot = sc.tolist(to_plot) # If not specified or specified as another string, load defaults if to_plot is None or isinstance(to_plot, str): to_plot = cvd.get_default_plots(to_plot, kind=kind, sim=sim) # If a list of keys has been supplied or constructed if isinstance(to_plot, list): to_plot_list = to_plot # Store separately to_plot = sc.odict() # Create the dict invalid = sc.autolist() for reskey in to_plot_list: if reskey in allkeys: name = sim.results[ reskey].name if reskey in reskeys else sim.results[ 'variant'][reskey].name to_plot[name] = [ reskey ] # Use the result name as the key and the reskey as the value else: invalid += reskey if len(invalid): errormsg = f'The following key(s) are invalid:\n{sc.strjoin(invalid)}\n\nValid main keys are:\n{sc.strjoin(reskeys)}\n\nValid variant keys are:\n{sc.strjoin(varkeys)}' raise sc.KeyNotFoundError(errormsg) to_plot = sc.odict(sc.dcp(to_plot)) # In case it's supplied as a dict # Handle rows and columns -- assume 5 is the most rows we would want n_plots = len(to_plot) if n_cols is None: max_rows = 5 # Assumption -- if desired, the user can override this by setting n_cols manually n_cols = int((n_plots - 1) // max_rows + 1) # This gives 1 column for 1-4, 2 for 5-8, etc. n_rows, n_cols = sc.get_rows_cols( n_plots, ncols=n_cols ) # Inconsistent naming due to Covasim/Matplotlib conventions return to_plot, n_cols, n_rows
def items(self, pattern=None): ''' Return all found items in an odict ''' output = sc.odict() keys = self.keys(pattern=pattern) for key in keys: output[key] = self.get(key) return output
def test_beds(do_plot=False, do_show=True, do_save=False, fig_path=None): sc.heading('Test of bed capacity estimation') sc.heading('Setting up...') sc.tic() n_runs = 3 verbose = 1 basepars = {'n': 1000} metapars = {'n_runs': n_runs} sim = cv.Sim() # Define the scenarios scenarios = { 'baseline': { 'name': 'No bed constraints', 'pars': { 'n_infected': 100 } }, 'bedconstraint': { 'name': 'Only 10 beds available', 'pars': { 'n_infected': 100, 'n_beds': 10, } }, 'bedconstraint2': { 'name': 'Only 1 bed available, people are 10x more likely to die if not hospitalized', 'pars': { 'n_infected': 100, 'n_beds': 1, 'OR_no_treat': 10., } }, } scens = cv.Scenarios(sim=sim, basepars=basepars, metapars=metapars, scenarios=scenarios) scens.run(verbose=verbose, debug=debug) if do_plot: to_plot = sc.odict({ 'cum_deaths': 'Cumulative deaths', # 'bed_capacity': 'People needing beds / beds', 'n_severe': 'Number of cases requiring hospitalization', 'n_critical': 'Number of cases requiring ICU', }) scens.plot(to_plot=to_plot, do_save=do_save, do_show=do_show, fig_path=fig_path) return scens
def __init__(self, name=None, project=None, filename=None, folder=None): if name is None: name = 'Default' self.projectref = sc.Link(project) # Store pointer for the project self.name = sc.uniquename( name, namelist=self.projectref().burdensets.keys( )) # Name of the parameter set, e.g. 'default' self.uid = sc.uuid() # ID self.created = sc.now() # Date created self.modified = sc.now() # Date modified # Define hard-coded column names self.colnames = sc.odict([ ('active', 'Active'), #('code', 'Code'), ('cause', 'Cause'), ('dalys', 'DALYs'), ('deaths', 'Deaths'), ('prevalence', 'Prevalence') ]) # Load data, if provided self.data = None if filename is not None: self.loaddata(filename=filename, folder=folder) return None
def test_repr(): n_entries = 300 qq = sc.odict() for i in range(n_entries): key = f'key{i:03d}' qq[key] = i**2 print(qq)
def get_sim_plots(): ''' Specify which quantities to plot; used in sim.py ''' plots = sc.odict({ 'Total counts': [ 'cum_infections', 'cum_diagnoses', 'cum_recoveries', # 'cum_tests', 'n_susceptible', # 'n_infectious', 'cum_symptomatic', ], 'Daily counts': [ 'new_infections', 'new_diagnoses', 'new_recoveries', 'new_deaths', ], 'Health outcomes': [ 'cum_severe', 'cum_critical', 'cum_deaths', 'n_symptomatic', # 'n_severe', # 'n_critical', ] }) return plots
def get_sim_plots(which='default'): ''' Specify which quantities to plot; used in sim.py. Args: which (str): either 'default' or 'overview' ''' if which in [None, 'default']: plots = sc.odict({ 'Total counts': [ 'cum_infections', 'n_infectious', 'cum_diagnoses', ], 'Daily counts': [ 'new_infections', 'new_diagnoses', ], 'Health outcomes': [ 'cum_severe', 'cum_critical', 'cum_deaths', ], }) elif which == 'overview': plots = sc.dcp(overview_plots) else: errormsg = f'The choice which="{which}" is not supported' raise ValueError(errormsg) return plots
def finalize(self, verbose=None): self.results['cum_exposed'].values = pl.cumsum( self.results['new_infections'].values) + self[ 'n_infected'] # Include initially infected people self.results['cum_tested'].values = pl.cumsum( self.results['new_tests'].values) self.results['cum_diagnosed'].values = pl.cumsum( self.results['new_diagnoses'].values) self.results['cum_deaths'].values = pl.cumsum( self.results['new_deaths'].values) self.results['cum_recoveries'].values = pl.cumsum( self.results['new_recoveries'].values) # Add in the results from the interventions for intervention in self['interventions']: intervention.finalize(self) # Execute any post-processing # Scale the results for reskey in self.reskeys: if self.results[reskey].scale: self.results[reskey].values *= self['scale'] # Perform calculations on results self.compute_doubling() self.compute_r_eff() self.likelihood() # Convert to an odict to allow e.g. sim.people[25] later, and results to an objdict to allow e.g. sim.results.diagnoses self.people = sc.odict(self.people) self.results = sc.objdict(self.results) self.results_ready = True return
def test_each(): sc.heading('From each:') z = sc.odict({'a': np.array([1, 2, 3, 4]), 'b': np.array([5, 6, 7, 8])}) f = z.fromeach(2) # Returns array([3,7]) g = z.fromeach( ind=[1, 3], asdict=True) # Returns sc.odict({'a':array([2,4]), 'b':array([6,8])}) printexamples([f, g]) sc.heading('To each:') z = sc.odict({'a': [1, 2, 3, 4], 'b': [5, 6, 7, 8]}) z.toeach(2, [10, 20]) # z is now sc.odict({'a':[1,2,10,4], 'b':[5,6,20,8]}) z.toeach( ind=3, val=666) # z is now sc.odict({'a':[1,2,10,666], 'b':[5,6,20,666]}) printexamples([z])
def test_insert(): sc.heading('Insert:') z = sc.odict() z['foo'] = 1492 z.insert(1604) z.insert(0, 'ganges', 1444) z.insert(2, 'midway', 1234) printexamples([z])
def __init__(self, func, x, xmin, xmax, fittable=None, mp=None, maxiters=None, optimum=None, func_args=None, parallel_args=None, parallelize=None, verbose=None): self.func = func self.x = np.array(x, dtype=float) self.xmin = np.array(xmin, dtype=float) self.xmax = np.array( xmax, dtype=float) # TODO: refactor how defaults are handled self.fittable = np.array( fittable) if fittable is not None else np.ones( len(x)) # Set everything to be fittable by default self.maxiters = maxiters if maxiters is not None else 10 # Set iterations to be 10 by default self.func_args = func_args if func_args is not None else {} self.parallel_args = parallel_args if parallel_args is not None else {} self.parallelize = parallelize if parallelize is not None else True self.verbose = verbose if verbose is not None else 2 self.optimum = optimum if optimum is not None else 'max' self.set_mp( mp ) # mp = metaparameters; can be None, 'sphere', 'shell', or a dict of values self.samples = None self.results = None self.iteration = 0 self.relstepsize = 1.0 # The current relative step size self.allcenters = sc.odict({ self.key: self.x }) # Clunky way of creating a dict with a string key the iteration self.allsamples = sc.odict( ) # Initialize storing the value of x on each iteration self.allresults = sc.odict( ) # Initialize storing the results for each iteration self.fvals = np.zeros( (self.maxiters + 1, self.mp.N)) # Store all function evaluations return
def test_map(): sc.heading('Map:') cat = sc.odict({'a': [1, 2], 'b': [3, 4]}) def myfunc(mylist): return [i**2 for i in mylist] dog = cat.map(myfunc) # Returns sc.odict({'a':[1,4], 'b':[9,16]}) printexamples([cat, dog])
def getinfo(self): ''' Return an odict with basic information about the project''' info = sc.odict() for attr in [ 'name', 'version', 'created', 'modified', 'gitbranch', 'gitversion', 'uid' ]: info[attr] = getattr(self, attr) # Populate the dictionary return info
def __init__(self, days, *args, **kwargs): super().__init__(**kwargs) # Initialize the Intervention object days = sc.promotetolist(days) # Combine multiple days days.extend(args) # Include additional arguments, if present self.days = days # Converted to integer representations self.dates = None # String representations self.start_day = None # Store the start date of the simulation self.snapshots = sc.odict() # Store the actual snapshots return
def init_people(self, seed_infections=1): ''' Create the people ''' self.people = sc.odict() # Dictionary for storing the people self.off_ship = sc.odict() # For people who've been moved off the ship guests = [0] * self['n_ppl'] for is_crew in guests: # Loop over each person person = Person(contacts=0) # Create the person self.people[person.uid] = person # Save them to the dictionary # Create the seed infections for i in range(seed_infections): person = self.people[i] person.susceptible = False person.exposed = True person.infectious = True person.date_exposed = 0 person.date_infectious = 0 return
def init_people(self, seed_infections=1): ''' Create the people ''' self.people = sc.odict() # Dictionary for storing the people self.off_ship = sc.odict() # For people who've been moved off the ship guests = [0] * self['n_guests'] crew = [1] * self['n_crew'] for is_crew in crew + guests: # Loop over each person age, sex = cov_pars.get_age_sex(is_crew) person = Person(self.pars, age=age, sex=sex, crew=is_crew) # Create the person self.people[person.uid] = person # Save them to the dictionary # Create the seed infections for i in range(seed_infections): self.people[i].exposed = True self.people[i].infectious = True self.people[i].date_exposed = 0 self.people[i].date_infectious = 0 return
def test_datastore(url): # Reset the database (check flushing works) ds = sw.make_datastore(url) ds.flushdb() ds = sw.make_datastore(url) assert len(ds.keys()) == 1 # There should be a datastore settings key present # Basic CRUD functionality # CREATE key_in = 'testkey' data_in = sc.odict({'foo':[1,2,3], 'bar':[4,5,6]}) key_out = ds.saveblob(obj=data_in, key=key_in) # READ data_out = ds.loadblob(key_in) assert key_in == key_out assert data_in == data_out assert ds.get('nonexistent') is None with pytest.raises(KeyError): ds.get('nonexistent', notnone=True) # UPDATE data_in['foo'][0] = 2 ds.saveblob(obj=data_in, key=key_in) # This should result in an in-place update data_out = ds.loadblob(key_in) assert data_out['foo'][0] == 2 # DELETE ds.delete(key_in) assert 'foo' not in ds.keys() # Check it was successfully deleted ds.delete('nonexistent') # If a key doesn't exist, an error should not occur # TEST KEY LISTING AND FILTERING ds.saveblob(obj='teststr', key='foo') ds.saveblob(obj='teststr', key='bar') assert {'foo','bar'}.issubset(set(ds.keys())) assert set(ds.keys('f*')) == {'foo'} assert set(ds.keys('bar')) == {'bar'} # TEST EXISTENCE assert ds.exists('foo') assert not ds.exists('nonexistent') # Tidy up cleanup = {db_file:os.remove, db_folder:shutil.rmtree} for fn,func in cleanup.items(): try: func(fn) print('Removed %s' % fn) except: pass
def check_contacts(sim, check=False, verbose=True): ''' Store the number of contacts in the sim ''' if check: contacts = {} for lkey in ['h', 'w', 's', 'c']: contacts[lkey] = len(sim.people.contacts[lkey]) if not hasattr(sim, 'n_contacts'): sim.n_contacts = sc.odict() sim.n_contacts[sim.date(sim.t)] = contacts if verbose: print(f'>>> On day {sim.t}, there were {contacts} contacts') return
def handle_to_plot(which, to_plot, n_cols, sim): ''' Handle which quantities to plot ''' if to_plot is None: if which == 'sim': to_plot = cvd.get_sim_plots() elif which =='scens': to_plot = cvd.get_scen_plots() else: errormsg = f'"which" must be "sim" or "scens", not "{which}"' raise NotImplementedError(errormsg) elif isinstance(to_plot, list): # If a list of keys has been supplied to_plot_list = to_plot # Store separately to_plot = sc.odict() # Create the dict for reskey in to_plot_list: to_plot[sim.results[reskey].name] = [reskey] # Use the result name as the key and the reskey as the value to_plot = sc.odict(sc.dcp(to_plot)) # In case it's supplied as a dict n_rows = np.ceil(len(to_plot)/n_cols) # Number of subplot rows to have return to_plot, n_rows
def getoptions(tojson=True): options = sc.odict([ ('Advertising', 'advert'), ('Education', 'educat'), ('Small business', 'smallbiz'), ('Travel', 'travel'), ('Unemployment', 'unempl'), ]) if tojson: output = sc.sanitizejson(options.keys(), tostring=False) else: output = options return output
def get_scen_plots(): ''' Default scenario plots -- used in run.py ''' plots = sc.odict({ 'Cumulative infections': [ 'cum_infections', ], 'Number of people currently infectious': [ 'n_infectious', ], 'Number of people requiring hospitalization': [ 'n_severe', ] }) return plots
def __init__(self, name='Default', burdenfile=None, interventionsfile=None, country=None, makepackage=True, verbose=2): ''' Initialize the project ''' ## Define the structure sets self.burdensets = sc.odict() self.intervsets = sc.odict() self.packagesets = sc.odict() ## Define other quantities self.name = name self.country = country self.uid = sc.uuid() self.created = sc.now() self.modified = sc.now() self.version = hp.version self.gitinfo = sc.gitinfo(__file__) self.filename = None # File path, only present if self.save() is used ## Load burden spreadsheet, if available if burdenfile: self.loadburden(filename=burdenfile, verbose=verbose) ## Load interventions spreadsheet, if available if interventionsfile: self.loadinterventions(filename=interventionsfile, verbose=verbose) ## Combine into health package, if available if makepackage and burdenfile and interventionsfile: self.makepackage() return None
def __init__(self, days=None, states=None, edges=None, datafile=None, sim=None, **kwargs): super().__init__(**kwargs) # Initialize the Intervention object self.days = days # To be converted to integer representations self.edges = edges # Edges of age bins self.states = states # States to save self.datafile = datafile # Data file to load self.bins = None # Age bins, calculated from edges self.dates = None # String representations of dates self.start_day = None # Store the start date of the simulation self.data = None # Store the loaded data self.hists = sc.odict() # Store the actual snapshots self.window_hists = None # Store the histograms for individual windows -- populated by compute_windows() if sim is not None: # Process a supplied simulation self.from_sim(sim) return
def test_make(): sc.heading('Make:') a = sc.odict().make( 5 ) # Make an odict of length 5, populated with Nones and default key names b = sc.odict().make( 'foo', 34) # Make an odict with a single key 'foo' of value 34 c = sc.odict().make(['a', 'b']) # Make an odict with keys 'a' and 'b' d = sc.odict().make( ['a', 'b'], 0) # Make an odict with keys 'a' and 'b', initialized to 0 e = sc.odict().make(keys=['a', 'b'], vals=[1, 2]) # Make an odict with 'a':1 and 'b':2 f = sc.odict({ 'a': 34, 'b': 58 }).make(['c', 'd'], [99, 45]) # Add extra keys to an exising odict g = sc.odict().make(keys=['a', 'b', 'c'], keys2=['A', 'B', 'C'], keys3=['x', 'y', 'z'], vals=0) # Make a triply nested odict printexamples([a, b, c, d, e, f, g]) sc.heading('Make from:') a = 'cat' b = 'dog' o = sc.odict().makefrom(source=locals(), keys=[ 'a', 'b' ]) # Make use of fact that variables are stored in a dictionary d = { 'a': 'cat', 'b': 'dog' } p = sc.odict().makefrom(d) # Same as sc.odict(d) l = ['cat', 'monkey', 'dog'] q = sc.odict().makefrom(source=l, keys=[0, 2], keynames=['a', 'b']) printexamples([o, p, q])
def generate_scenarios(): ''' Generate scenarios (dictionaries of parameters) for the school intervention ''' # Create a single sim to get parameters (make_pars is close, but not quite) sim = cs.create_sim({'rand_seed':0}, pop_size=pop_size) base_beta_s = sim.pars['beta_layer']['s'] scns = sc.odict() remote = { 'start_day': '2020-09-01', 'schedule': 'remote', 'screen_prob': 0, 'test_prob': 0, 'trace_prob': 0, 'ili_prob': 0, 'beta_s': 0 } base = { 'start_day': '2020-09-01', 'schedule': 'full', 'screen_prob': 0, 'test_prob': 0.5, 'trace_prob': 0.5, 'ili_prob': 0.002, # Daily ili probability equates to about 10% incidence over the first 3 months of school 'beta_s': base_beta_s # No NPI } scns['as_normal'] = scenario(es=base, ms=base, hs=base) # Add screening and NPI screening = sc.dcp(base) screening['screen_prob'] = 0.9 screening['beta_s'] = 0.75 * base_beta_s # 25% reduction due to NPI scns['with_screening'] = scenario(es=screening, ms=screening, hs=screening) scns['ES_MS_inperson_HS_remote'] = scenario(es=screening, ms=screening, hs=remote) scns['ES_inperson_MS_HS_remote'] = scenario(es=screening, ms=remote, hs=remote) # Add hybrid scheduling hybrid = sc.dcp(screening) hybrid['schedule'] = 'hybrid' scns['all_hybrid'] = scenario(es=hybrid, ms=hybrid, hs=hybrid) scns['ES_hybrid'] = scenario(es=hybrid, ms=remote, hs=remote) # All remote scns['all_remote'] = scenario(es=remote, ms=remote, hs=remote) return scns
def pairplotpars(data, inds=None, color_column=None, bounds=None, cmap='parula', bins=None, edgecolor='w', facecolor='#F8A493', figsize=(20, 16)): ''' Plot scatterplots, histograms, and kernel densities ''' import seaborn as sns # Optional import data = sc.odict(sc.dcp(data)) # Create the dataframe df = pd.DataFrame.from_dict(data) if inds is not None: df = df.iloc[inds, :].copy() # Choose the colors if color_column: colors = sc.vectocolor(df[color_column].values, cmap=cmap) else: colors = [facecolor for i in range(len(df))] df['color_column'] = [sc.rgb2hex(rgba[:-1]) for rgba in colors] # Make the plot grid = sns.PairGrid(df) grid = grid.map_lower(pl.scatter, **{'facecolors': df['color_column']}) grid = grid.map_diag(pl.hist, bins=bins, edgecolor=edgecolor, facecolor=facecolor) grid = grid.map_upper(sns.kdeplot) grid.fig.set_size_inches(figsize) grid.fig.tight_layout() # Set bounds if bounds: for ax in grid.axes.flatten(): xlabel = ax.get_xlabel() ylabel = ax.get_ylabel() if xlabel in bounds: ax.set_xlim(bounds[xlabel]) if ylabel in bounds: ax.set_ylim(bounds[ylabel]) return grid