Beispiel #1
0
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
Beispiel #3
0
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)
Beispiel #5
0
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
Beispiel #6
0
    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
Beispiel #7
0
    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
Beispiel #9
0
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
Beispiel #10
0
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)
Beispiel #15
0
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
Beispiel #16
0
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
Beispiel #17
0
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()
Beispiel #18
0
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
Beispiel #19
0
    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
Beispiel #20
0
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')
Beispiel #21
0
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
Beispiel #22
0
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
Beispiel #23
0
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
Beispiel #24
0
    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
Beispiel #25
0
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
Beispiel #28
0
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
Beispiel #29
0
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)
Beispiel #30
0
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