def test_calib(): entry = sc.loadjson(calibfile)[0] params = sc.dcp(entry['pars']) params['rand_seed'] = int(entry['index']) scen = generate_scenarios()['all_remote'] testing = generate_testing()['None'] #testing[0]['delay'] = 0 for stype, spec in scen.items(): if spec is not None: spec['testing'] = testing scen['testing'] = testing scen['es']['verbose'] = scen['ms']['verbose'] = scen['hs'][ 'verbose'] = debug sim = cs.create_sim(params, pop_size=pop_size, folder=folder) sm = cvsch.schools_manager(scen) sim['interventions'] += [sm] sim.run(keep_people=debug) stats = evaluate_sim(sim) print(stats) if debug: sim.plot(to_plot='overview') #t = sim.make_transtree() else: sim.plot() cv.savefig('sim.png') return sim
def make_safegraph(sim): ''' Create interventions representing SafeGraph data ''' # Load data.values fn = safegraph_file df = pd.read_csv(fn) week = df['week'] s = df['p.tot.schools'].values w = df['p.tot.no.schools'].values c = sc.dcp(w) # Not different enough to warrant different values # Do processing days = sim.day(week.values.tolist()) last_day = days[-1] + 1 i_days = np.arange(days[0], last_day) s = np.interp(i_days, days, s) w = np.interp(i_days, days, w) c = np.interp(i_days, days, c) days = i_days # Create interventions interventions = [ cv.clip_edges(days=days, changes=s, layers='s', label='clip_s'), cv.clip_edges(days=days, changes=w, layers='w', label='clip_w'), cv.clip_edges(days=days, changes=c, layers='c', label='clip_c'), ] return interventions
def get_household_head_ages_by_size(pop): """ Calculate the count of households by size and the age of the head of the household, assuming the minimal household members id is the id of the head of the household. Args: pop (sp.Pop) : population object Returns: np.ndarray: An array with rows as household size and columns as household head age brackets. """ popdict = pop.popdict loc_pars = sc.dcp(pop.loc_pars) loc_pars.location = None hha_brackets = spdata.get_head_age_brackets(**loc_pars) # temporarily location should be None until data json work will automatically search up when data are not available # hha_index use age as key and bracket index as value hha_index = spb.get_index_by_brackets(hha_brackets) uids = get_household_heads(popdict=popdict) d = {} # construct tables for each houldhold head for uid in uids.values(): d[popdict[uid]['hhid']] = {'hhid': popdict[uid]['hhid'], 'age': popdict[uid]['age'], 'family_size': len(popdict[uid]['contacts']['H']) + 1, 'hh_age_bracket': hha_index[popdict[uid]['age']]} df_household_age = pd.DataFrame.from_dict(d, orient="index") # aggregate by age_bracket (column) and family_size (row) df_household_age = df_household_age.groupby(['hh_age_bracket', 'family_size'], as_index=False).count()\ .pivot(index='family_size', columns='hh_age_bracket', values='hhid').fillna(0) return np.array(df_household_age.values)
def keys(self): ''' Get the keys that have been set ''' curr_keys = self.__dict__.keys() new_keys = [k for k in self._keys if k in curr_keys ] # Remove any keys that have been removed self._keys = new_keys # Trim any that were removed return sc.dcp(new_keys)
def make_random_contacts(pop_size, contacts, overshoot=1.2): ''' Make random static contacts ''' # Preprocessing pop_size = int(pop_size) # Number of people contacts = sc.dcp(contacts) layer_keys = list(contacts.keys()) contacts_list = [] # Precalculate contacts n_across_layers = np.sum(list(contacts.values())) n_all_contacts = int( pop_size * n_across_layers * overshoot ) # The overshoot is used so we won't run out of contacts if the Poisson draws happen to be higher than the expected value all_contacts = cvu.choose_r(max_n=pop_size, n=n_all_contacts) # Choose people at random p_counts = {} for lkey in layer_keys: p_counts[lkey] = np.array( (cvu.n_poisson(contacts[lkey], pop_size) / 2.0).round(), dtype=cvd.default_int ) # Draw the number of Poisson contacts for this person # Make contacts count = 0 for p in range(pop_size): contact_dict = {} for lkey in layer_keys: n_contacts = p_counts[lkey][p] contact_dict[lkey] = all_contacts[count:count + n_contacts] # Assign people count += n_contacts contacts_list.append(contact_dict) return contacts_list, layer_keys
def combine(self, output=False): ''' Combine multiple sims into a single sim with scaled results ''' n_runs = len(self) combined_sim = sc.dcp(self.sims[0]) combined_sim.parallelized = { 'parallelized': True, 'combined': True, 'n_runs': n_runs } # Store how this was parallelized combined_sim['pop_size'] *= n_runs # Record the number of people for s, sim in enumerate(self.sims[1:]): # Skip the first one if combined_sim.people: combined_sim.people += sim.people for key in sim.result_keys(): this_res = sim.results[key] combined_sim.results[key].values += this_res.values # For non-count results (scale=False), rescale them for key in combined_sim.result_keys(): if not combined_sim.results[key].scale: combined_sim.results[key].values /= n_runs self.orig_base_sim = self.base_sim self.base_sim = combined_sim self.results = combined_sim.results self.which = 'combined' if output: return self.base_sim else: return
def reduce(self, quantiles=None, output=False): ''' Combine multiple sims into a single sim with scaled results ''' if quantiles is None: quantiles = self.quantiles if not isinstance(quantiles, dict): try: quantiles = { 'low': float(quantiles[0]), 'high': float(quantiles[1]) } except Exception as E: errormsg = f'Could not figure out how to convert {quantiles} into a quantiles object: must be a dict with keys low, high or a 2-element array ({str(E)})' raise ValueError(errormsg) # Store information on the sims n_runs = len(self) reduced_sim = sc.dcp(self.sims[0]) reduced_sim.parallelized = { 'parallelized': True, 'combined': False, 'n_runs': n_runs } # Store how this was parallelized # Perform the statistics raw = {} reskeys = reduced_sim.result_keys() for reskey in reskeys: raw[reskey] = np.zeros((reduced_sim.npts, len(self.sims))) for s, sim in enumerate(self.sims): vals = sim.results[reskey].values if len(vals) != reduced_sim.npts: errormsg = f'Cannot reduce sims with inconsistent numbers of days: {reduced_sim.npts} vs. {len(vals)}' raise ValueError(errormsg) raw[reskey][:, s] = vals for reskey in reskeys: reduced_sim.results[reskey].values[:] = np.quantile( raw[reskey], q=0.5, axis=1) # Changed from median to mean for smoother plots reduced_sim.results[reskey].low = np.quantile(raw[reskey], q=quantiles['low'], axis=1) reduced_sim.results[reskey].high = np.quantile(raw[reskey], q=quantiles['high'], axis=1) # Compute and store final results reduced_sim.compute_likelihood() reduced_sim.compute_summary(verbose=False) self.orig_base_sim = self.base_sim self.base_sim = reduced_sim self.results = reduced_sim.results self.summary = reduced_sim.summary self.which = 'reduced' if output: return self.base_sim else: return
def optimize(D, country_data, c): country = country_data['name'][c] print(f' Working on {country} ({c+1}/{len(country_data)})...') D[country].makepackage(verbose=False) meta = country_data.findrow(country, asdict=True) alloc = [] dalys = [] for spend in spendings: D[country].package().optimize(budget=spend*meta['population']) df = D[country].package().data alloc.append(sc.dcp(df['opt_spend'][:])) dalys.append(sc.dcp(df['opt_dalys_averted'][:])) meta['interv_names'] = sc.dcp(df['shortname'][:]) result = sc.odict({'meta':meta, 'alloc':pl.array(alloc), 'dalys':pl.array(dalys), 'package':D[country].package()}) return result
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 get_asymmetric_matrix(symmetric_matrix, aggregate_ages): """ Get the contact matrix for the average individual in each age bracket. Args: symmetric_matrix (np.ndarray) : A symmetric age contact matrix. aggregate_ages (dict) : A dictionary mapping single year ages to age brackets. Returns: A contact matrix (``np.ndarray``) whose elements ``M_ij`` describe the contact frequency for the average individual in age bracket ``i`` with all possible contacts in age bracket ``j``. Example ======= :: age_brackets = sp.get_census_age_brackets(sp.datadir,state_location='Washington',country_location='usa') age_by_brackets_dic = sp.get_age_by_brackets_dic(age_brackets) aggregate_age_count = sp.get_aggregate_ages(age_count, age_by_brackets_dic) aggregate_matrix = symmetric_matrix.copy() aggregate_matrix = sp.get_aggregate_matrix(aggregate_matrix, age_by_brackets_dic) asymmetric_matrix = sp.get_asymmetric_matrix(aggregate_matrix, aggregate_age_count) """ M = sc.dcp(symmetric_matrix) for a in aggregate_ages: M[a, :] = M[a, :] / float(aggregate_ages[a]) return M
def test_with_non_teaching_staff(): """ When with_non_teaching_staff is True, each school should be created with non teaching staff. Otherwise when False, there should be no non teaching staff in schools. """ sp.logger.info(f'Testing the effect of the parameter with_non_teaching_staff.') test_pars = sc.dcp(pars) test_pars.with_non_teaching_staff = True pop_1 = sp.Pop(**test_pars) popdict_1 = pop_1.to_dict() test_pars.with_non_teaching_staff = False pop_2 = sp.Pop(**test_pars) popdict_2 = pop_2.to_dict() school_staff_1 = {} for i, person in popdict_1.items(): if person['scid'] is not None: school_staff_1.setdefault(person['scid'], 0) if person['sc_staff']: school_staff_1[person['scid']] += 1 staff_ids_2 = set() for i, person in popdict_2.items(): if person['sc_staff']: staff_ids_2.add(i) # with_non_teaching_staff == True so minimum number of staff per school needs to be 1 assert min(school_staff_1.values()) >= 1, f"with_non_teaching_staff parameter check failed when set to True." # with_non_teaching_staff == False so there should be no one who shows up with sc_staff set to 1 assert len(staff_ids_2) == 0, f"with_non_teaching_staff parameter check failed when set to False."
def __add__(self, people2): ''' Combine two people arrays ''' newpeople = sc.dcp(self) keys = list(self.keys()) for key in keys: npval = newpeople[key] p2val = people2[key] if npval.ndim == 1: newpeople.set(key, np.concatenate([npval, p2val], axis=0), die=False) # Allow size mismatch elif npval.ndim == 2: newpeople.set(key, np.concatenate([npval, p2val], axis=1), die=False) else: errormsg = f'Not sure how to combine arrays of {npval.ndim} dimensions for {key}' raise NotImplementedError(errormsg) # Validate newpeople.pars['pop_size'] += people2.pars['pop_size'] newpeople.validate() # Reassign UIDs so they're unique newpeople.set('uid', np.arange(len(newpeople))) return newpeople
def populate_households(pop, households, age_by_uid): """ Populate all of the households. Store each household at the index corresponding to it's hhid. Args: pop (sp.Pop) : population households (list) : list of lists where each sublist represents a household and contains the ids of the household members age_by_uid (dict) : dictionary mapping each person's id to their age """ # initialize an empty set of households # if previously you had 10 households and now you want to repopulate with # this method and only supply 5 households, this method will overwrite the list to produce only 5 households initialize_empty_households(pop, len(households)) log.debug("Populating households.") # now populate households for nh, hh in enumerate(households): kwargs = dict( hhid=nh, member_uids=hh, reference_uid=hh[ 0], # by default, the reference person is the first in the household in synthpops - with vital dynamics this may change reference_age=age_by_uid[hh[0]]) household = Household() household.set_layer_group(**kwargs) pop.households[household['hhid']] = sc.dcp(household) pop.populate = True return
def __init__(self, school, testing, sim): ''' Initialize testing. ''' self.school = school self.testing = [] if testing is None else sc.dcp(testing) for test in self.testing: if 'is_antigen' not in test: test['is_antigen'] = False self.n_tested = {'PCR': 0, 'Antigen': 0} for test in self.testing: # Determine from test start_day and repeat which sim times to test on start_t = sim.day(test['start_date']) if test['repeat'] == None: # Easy - one time test test['t_vec'] = [start_t] else: test['t_vec'] = list( range(start_t, sim.pars['n_days'], test['repeat'])) # Determine uids to include uids = [] ppl = sim.people if 'students' in test['groups']: uids.append(cv.itruei(ppl.student_flag, self.school.uids)) if 'staff' in test['groups']: uids.append(cv.itruei(ppl.staff_flag, self.school.uids)) if 'teachers' in test['groups']: uids.append(cv.itruei(ppl.teacher_flag, self.school.uids)) test['uids'] = np.concatenate(uids)
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 save_new_project(proj, username=None, uid=None): """ If we're creating a new project, we need to do some operations on it to make sure it's valid for the webapp. """ # Preliminaries new_project = sc.dcp(proj) # Copy the project, only save what we want... new_project.uid = sc.uuid(uid) # Get unique name user = get_user(username) current_project_names = [] for project_key in user.projects: proj = load_project(project_key) current_project_names.append(proj.name) new_project_name = sc.uniquename(new_project.name, namelist=current_project_names) new_project.name = new_project_name # Ensure it's a valid webapp project if not hasattr(new_project, 'webapp'): new_project.webapp = sc.prettyobj() new_project.webapp.username = username # If we ever use Celery with HealthPrior: new_project.webapp.tasks = [] new_project.webapp.username = username # Make sure we have the current username # Save all the things key = save_project(new_project) if key not in user.projects: # Let's not allow multiple copies user.projects.append(key) datastore.saveuser(user) return key, new_project
def test_ltcf_resident_ages(do_show=False): """ Compare the ltcf resident ages generated with those expected for the location. """ sp.logger.info(f"Testing that ltcf resident ages align with the expected resident ages for the location.") test_pars = sc.dcp(pars) # to actually match decently, you need to model a higher population size, but for regular # test purposes, large sizes will be quite a lot to test on every merge test_pars['n'] = settings.pop_sizes.large pop = sp.Pop(**test_pars) pop_dict = pop.to_dict() ltcf_resident_rates_by_age = sp.get_long_term_care_facility_use_rates(sp.settings.datadir, country_location=pop.country_location, state_location=pop.state_location, ) expected_ltcf_rates = ltcf_resident_rates_by_age.values() ltcf_resident_ages = dict.fromkeys(ltcf_resident_rates_by_age.keys(), 0) age_count = pop.count_pop_ages() for i, person in pop_dict.items(): if person['ltcf_res']: ltcf_resident_ages[person['age']] += 1 gen_ltcf_rates = {a: ltcf_resident_ages[a] / age_count[a] for a in ltcf_resident_ages} fig, ax = sppl.plot_array(expected_ltcf_rates, generated=gen_ltcf_rates.values(), do_show=False, binned=True) ax.set_xlabel('LTCF Resident Ages') ax.set_title('LTCF Resident Use Rates by Age') ax.set_ylim(0., 1.) ax.set_xlim(0., 100) if do_show: plt.show()
def make_random_contacts(pop_size, contacts, overshoot=1.2): ''' Make random static contacts ''' # Preprocessing pop_size = int(pop_size) # Number of people contacts = sc.dcp(contacts) layer_keys = list(contacts.keys()) contacts_list = [] # Precalculate contacts n_across_layers = np.prod(list(contacts.values())) n_all_contacts = int(pop_size * n_across_layers * overshoot) all_contacts = cvu.choose_r(max_n=pop_size, n=n_all_contacts) # Choose people at random p_counts = {} for lkey in layer_keys: p_counts[lkey] = cvu.n_poisson( contacts[lkey], pop_size) # Draw the number of Poisson contacts for this person # Make contacts count = 0 for p in range(pop_size): contact_dict = {} for lkey in layer_keys: n_contacts = p_counts[lkey][p] contact_dict[lkey] = all_contacts[count:count + n_contacts] # Assign people count += n_contacts contacts_list.append(contact_dict) return contacts_list, layer_keys
def make_detailed(self, people, reset=False): ''' Construct a detailed transmission tree, with additional information for each person ''' if self.detailed is None or reset: # Reset to look like the line list, but with more detail self.detailed = [None]*len(self) for transdict in self.linelist: if transdict is not None: # Pull out key quantities ddict = sc.dcp(transdict) # For "detailed dictionary" source = ddict['source'] target = ddict['target'] date = ddict['date'] # Only need to check against the date, since will return False if condition is false (NaN) if source is not None: # This information is only available for people infected by other people, not e.g. importations ddict['s_age'] = people.age[source] ddict['t_age'] = people.age[target] ddict['s_symp'] = people.date_symptomatic[source] <= date ddict['s_diag'] = people.date_diagnosed[source] <= date ddict['s_quar'] = people.date_quarantined[source] <= date ddict['s_sev'] = people.date_severe[source] <= date ddict['s_crit'] = people.date_critical[source] <= date ddict['t_quar'] = people.date_quarantined[target] <= date ddict['s_asymp'] = np.isnan(people.date_symptomatic[source]) ddict['s_presymp'] = ~ddict['s_asymp'] and ~ddict['s_symp'] # Not asymptomatic and not currently symptomatic self.detailed[target] = ddict return
def test_pop_n(): sp.logger.info("Testing when n is None.") test_pars = sc.dcp(pars) test_pars['n'] = None pop = sp.Pop(**test_pars) assert pop.n == sp.defaults.default_pop_size, 'Check failed.' print('Check passed')
def populate_workplaces(pop, workplaces): """ Populate all of the workplaces. Store each workplace at the index corresponding to it's wpid. Args: pop (sp.Pop) : population workplaces (list) : list of lists where each sublist represents a workplace and contains the ids of the workplace members Notes: If number of workplaces (n) is fewer than existing workplaces, it will only replace the first n workplaces. Otherwise the existing workplaces will be overwritten by the input workplaces. """ # make sure there are enough workplaces initialize_empty_workplaces(pop, len(workplaces)) log.debug("Populating workplaces.") # now populate workplaces for nw, wp in enumerate(workplaces): kwargs = dict(wpid=nw, member_uids=wp, ) workplace = Workplace() workplace.set_layer_group(**kwargs) pop.workplaces[workplace['wpid']] = sc.dcp(workplace) 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 finalize_figure(fig, plkwargs, **new_plkwargs): """ Update any parameters and then return figpath. Args: fig (matplotlib.Figure) : figure plkwargs (plotting_kwargs) : plotting kwargs class new_plkwargs (dict) : dictionary of new plotting kwargs to update with Returns: Matplotlib figure. """ plkwargs = sc.dcp(plkwargs) plkwargs.update(new_plkwargs) if plkwargs.do_save: plkwargs.figpath = sc.makefilepath(filename=plkwargs.figname, folder=plkwargs.figdir, ext=plkwargs.format) fig.savefig(plkwargs.figpath, format=plkwargs.format, dpi=plkwargs.save_dpi) if plkwargs.do_show: plt.show() return fig
def initialize(self, sim): ''' Fix the dates and store the vaccinations ''' # Handle days self.start_day = sim.day(self.start_day) self.end_day = sim.day(self.end_day) self.days = [self.start_day, self.end_day] # Handle priority days if self.priority_days is None: self.priority_days = [self.start_day] else: self.priority_days = [sim.day(d) for d in self.priority_days] self.priority_days = sc.promotetoarray(self.priority_days) assert (len(self.priority_days) == len(self.age_priority)) assert (self.priority_days[0] == self.start_day) # Process daily data self.daily_vaccines = process_daily_data(self.daily_vaccines, sim, self.start_day) # Ensure we have the dose scheduler flag = True for intv in sim['interventions']: if isinstance(intv, dose_scheduler): flag = False if flag: sim['interventions'] += [dose_scheduler()] # Save self.orig_rel_trans = sc.dcp( sim.people.rel_trans ) # Keep a copy of pre-vaccination transmission self.orig_symp_prob = sc.dcp( sim.people.symp_prob) # ...and symptom probability # Initialize vaccine info self.vaccinations = np.zeros(sim.n, dtype=cvd.default_int) self.vaccine_take = np.zeros(sim.n, dtype=np.bool) self.vaccination_dates = [ [] for p in range(sim.n) ] # Store the dates when people are vaccinated sim.results['new_doses'] = cvb.Result(name='New Doses', npts=sim['n_days'] + 1, color='#ff00ff') self.initialized = True return
def make_synthpop(sim): ''' Make a population using synthpops, including contacts ''' import synthpops as sp # Optional import pop_size = sim['pop_size'] population = sp.make_population(n=pop_size) uids, ages, sexes, contacts = [], [], [], [] for uid, person in population.items(): uids.append(uid) ages.append(person['age']) sexes.append(person['sex']) # Replace contact UIDs with ints... uid_mapping = {uid: u for u, uid in enumerate(uids)} key_mapping = { 'H': 'h', 'S': 's', 'W': 'w', 'C': 'c' } # Remap keys from old names to new names for uid in uids: person = population.pop(uid) uid_contacts = sc.dcp(person['contacts']) int_contacts = {} for key in uid_contacts.keys(): new_key = key_mapping[key] int_contacts[new_key] = [] for uid in uid_contacts[key]: int_contacts[new_key].append(uid_mapping[uid]) int_contacts[new_key] = np.array(int_contacts[new_key], dtype=cvd.default_int) contacts.append(int_contacts) # Add community contacts c_contacts, _ = make_random_contacts(pop_size, {'c': sim['contacts']['c']}) for i in range(pop_size): contacts[i]['c'] = c_contacts[i][ 'c'] # Copy over community contacts -- present for everyone # Finalize popdict = {} popdict['uid'] = sc.dcp(uids) popdict['age'] = np.array(ages) popdict['sex'] = np.array(sexes) popdict['contacts'] = sc.dcp(contacts) layer_keys = list(key_mapping.values()) return popdict, layer_keys
def run_sim(index, scenpars=None, label=None, runinfo=None, do_shrink=True, from_cache=True, verbose=True): ''' Load, modify, and run the simulation ''' if scenpars is None: print('WARNING, loading default parameters!') scenpars = sc.dcp(d_pars) if label is None: label = f'full_sim_trial{index}_nolabel' # Run sim or load up until scenarios start sim_loaded = 0 filename = f'./simcache/projection_trial{index}.sim' if from_cache and os.path.exists(filename): tries = 0 while not sim_loaded and tries < 3: try: print(f'run_sim(): Loading sim from cache ({filename})...') sim = cv.load(filename) assert isinstance( sim, cv.Sim ) # Sometimes unpickling fails, but can reload locally tn = sim.get_interventions('tn') tn.subtarget = test_num_subtarg sim_loaded = 1 except Exception as E: print(f'Loading failed on try {tries}! {E}') string = '\n\n'.join([ f'Index {index}', filename, f'Try {tries}', str(E), sc.traceback() ]) fn = f'simcache_exception_index{index}_try{tries}.err' sc.savetext(fn, string) tries += 1 sc.timedsleep(0.5) if not sim_loaded: print(f'run_sim(): Creating new sim (and saving to {filename})...') sim = create_sim(index, verbose=verbose) sim.run(until=sim.sceninfo.calib_end) sim.save(filename, keep_people=True) # Modify the sim with these scenario values sim = modify_sim(sim, scenpars=scenpars, label=label, runinfo=runinfo) # Rerun till the end and optionally shrink sim.run(restore_pars=False) # So we can see the changes made if do_shrink: sim.shrink() return sim sc.toc(T)
def show_locations(location=None, output=False): ''' Print a list of available locations. Args: location (str): if provided, only check if this location is in the list output (bool): whether to return the list (else print) **Examples**:: sp.people.show_locations() # Print a list of valid locations sp.people.show_locations('lithuania') # Check if Lithuania is a valid location sp.people.show_locations('Viet-Nam') # Check if Viet-Nam is a valid location New in version 1.10.0. ''' country_json = sc.dcp(cad.data) state_json = sc.dcp(sad.data) aliases = get_country_aliases() age_data = sc.mergedicts(state_json, country_json, aliases) # Countries will overwrite states, e.g. Georgia household_data = sc.dcp(hsd.data) loclist = sc.objdict() loclist.age_distributions = sorted(list(age_data.keys())) loclist.household_size_distributions = sorted(list(household_data.keys())) if location is not None: age_available = location.lower() in [v.lower() for v in loclist.age_distributions] hh_available = location.lower() in [v.lower() for v in loclist.household_size_distributions] age_sugg = '' hh_sugg = '' age_sugg = f'(closest match: {sc.suggest(location, loclist.age_distributions)})' if not age_available else '' hh_sugg = f'(closest match: {sc.suggest(location, loclist.household_size_distributions)})' if not hh_available else '' print(f'For location "{location}":') print(f' Population age distribution is available: {age_available} {age_sugg}') print(f' Household size distribution is available: {hh_available} {hh_sugg}') return if output: return loclist else: print(f'There are {len(loclist.age_distributions)} age distributions and {len(loclist.household_size_distributions)} household size distributions.') print('\nList of available locations (case insensitive):\n') sc.pp(loclist) return
def copy_burden(project_id, intervkey, index): proj = load_project(project_id) data = proj.burdensets[intervkey].data value = sc.dcp(data[index]) value[1] += ' (copy)' data.insert(row=index, value=value) save_project(proj) return None
def process_age_tables(): """Function to preprocess age tables.""" file_path = os.path.join(dir_path, 'Series A. Population Tables.xlsx') df = pd.read_excel(file_path, sheet_name='A5', header=1, skiprows=[2, 3], skipfooter=303) ages = df['Age in single Years'].values[1:] age_count = np.array(df['National'].values[1:]) age_range = np.arange(len(ages)) age_dist = age_count / age_count.sum() age_dist_mapping = dict(zip(age_range, age_dist)) data = dict(age_min=sc.dcp(age_range), age_max=sc.dcp(age_range), age_dist=age_dist) data['age_max'][-1] = 100 new_df = pd.DataFrame.from_dict(data) new_file_path = os.path.join(dir_path, 'Malawi_national_ages.csv') new_df.to_csv(new_file_path, index=False) census_age_brackets = sp.get_census_age_brackets( sp.settings.datadir, location='seattle-metro', state_location='Washington', country_location='usa', nbrackets=16) census_age_by_brackets = sp.get_age_by_brackets(census_age_brackets) agg_ages = sp.get_aggregate_ages(age_dist_mapping, census_age_by_brackets) agg_data = dict() agg_data['age_min'] = np.array( [census_age_brackets[b][0] for b in census_age_brackets]) agg_data['age_max'] = np.array( [census_age_brackets[b][-1] for b in census_age_brackets]) agg_data['age_dist'] = np.array( [agg_ages[b] for b in sorted(census_age_brackets.keys())]) agg_df = pd.DataFrame.from_dict(agg_data) print(agg_df) agg_path = os.path.join(dir_path, 'Malawi_national_ages_16.csv') agg_df.to_csv(agg_path, index=False)
def copy_intervention(project_id, intervkey, index): proj = load_project(project_id) data = proj.intervsets[intervkey].data value = sc.dcp(data[index]) value[1] += ' (copy)' # This is the name -- warning, hard-coded! data.insert(row=index, value=value) save_project(proj) return None