def run_regression(self, filename, test_prefix, actual_vals, location,
                    state_location, country_location):
     pop = utilities.runpop(resultdir=self.configDir,
                            actual_vals=actual_vals,
                            testprefix=test_prefix,
                            method=sp.make_population)
     # if default sort order is not concerned:
     pop = dict(sorted(pop.items(), key=lambda x: x[0]))
     sc.savejson(filename, pop, indent=2)
     self.get_pop_details(pop, self.resultdir, test_prefix, location,
                          state_location, country_location)
     if not self.generateBaseline:
         unchanged, failed_cases = self.check_result(
             actual_folder=self.resultdir, test_prefix=test_prefix)
         if unchanged:
             print(f'Note: regression unchanged')
         else:
             print(f'Warning, regression changed! Generating report...')
             self.generate_reports(test_prefix=test_prefix,
                                   failedcases=failed_cases)
             errormsg = f"regression test detected changes, " \
                        f"please go to \n{self.pdfDir} " \
                        f"to review report and test results \n " \
                        f"\n\ndelete files in {os.path.join(self.expectedDir, test_prefix)} " \
                        f"and regenerate expected files using cls.generateBaseline=True\n " \
                        f"if you approve this change."
             raise ValueError(errormsg)
Exemple #2
0
    def test_regression_make_population(self):
        #set params, make sure name is identical to param names
        n = 2001
        rand_seed = 1001
        max_contacts = None
        with_industry_code = False
        with_facilities = False
        use_two_group_reduction = False
        average_LTCF_degree = 20
        generate = True
        #
        test_prefix = sys._getframe().f_code.co_name
        filename = os.path.join(self.resultdir,
                                f'pop_{n}_seed{rand_seed}.json')
        actual_vals = locals()
        pop = self.runpop(filename=filename,
                          actual_vals=actual_vals,
                          testprefix=test_prefix)
        # if default sort order is not concerned:
        # pop = dict(sorted(pop.items(), key=lambda x: x[0]))

        sc.savejson(filename, pop, indent=2)
        unchanged = self.check_result(actual_file=filename, prefix=test_prefix)
        if not unchanged:
            self.generate_reports()
Exemple #3
0
    def export_results(self, for_json=True, filename=None, indent=2, *args, **kwargs):
        '''
        Convert results to dict -- see also to_json().

        The results written to Excel must have a regular table shape, whereas
        for the JSON output, arbitrary data shapes are supported.

        Args:
            for_json (bool): if False, only data associated with Result objects will be included in the converted output
            filename (str): filename to save to; if None, do not save
            indent (int): indent (int): if writing to file, how many indents to use per nested level
            args (list): passed to savejson()
            kwargs (dict): passed to savejson()

        Returns:
            resdict (dict): dictionary representation of the results

        '''
        resdict = {}
        resdict['t'] = self.results['t'] # Assume that there is a key for time

        if for_json:
            resdict['timeseries_keys'] = self.result_keys()
        for key,res in self.results.items():
            if isinstance(res, Result):
                resdict[key] = res.values
            elif for_json:
                if key == 'date':
                    resdict[key] = [str(d) for d in res] # Convert dates to strings
                else:
                    resdict[key] = res
        if filename is not None:
            sc.savejson(filename=filename, obj=resdict, indent=indent, *args, **kwargs)
        return resdict
def runpop(resultdir, actual_vals, testprefix, method):
    """
    run any method which create apopulation
    and write args and population to file "{resultdir}/{testprefix}.txt"
    method must be a method which returns population
    and write population file to "{resultdir}/{testprefix}_pop.json"

    args:
      resultdir (str): result folder
      actual_vals (dict): a dictionary with param name and param value
      testprefix (str): test prefix to generate file name
    """
    os.makedirs(resultdir, exist_ok=True)
    params = {}
    args = inspect.getfullargspec(method).args
    for i in range(0, len(args)):
        params[args[i]] = inspect.signature(method).parameters[args[i]].default
    for name in actual_vals:
        if name in params.keys():
            params[name] = actual_vals[name]
    with open(os.path.join(resultdir, f"{testprefix}.txt"), mode="w") as cf:
        for key, value in params.items():
            cf.writelines(str(key) + ':' + str(value) + "\n")

    pop = method(**params)
    sc.savejson(os.path.join(resultdir, f"{testprefix}_pop.json"),
                pop,
                indent=2)
    return pop
Exemple #5
0
 def test_scale(self):
     seed = 1
     # set param
     average_student_teacher_ratio = 22
     average_student_all_staff_ratio = 15
     datadir = self.dataDir
     location = 'seattle_metro'
     state_location = 'Washington'
     country_location = 'usa'
     i = 0
     for n in [2001, 10001]:
         try:
             pop = {}
             sp.set_seed(seed)
             print(seed)
             pop = sp.generate_synthetic_population(n, datadir,average_student_teacher_ratio=average_student_teacher_ratio,
                                                    average_student_all_staff_ratio=average_student_all_staff_ratio,
                                                    return_popdict=True)
             sc.savejson(os.path.join(self.resultdir, f"calltwice_{n}_{i}.json"), pop, indent=2)
             result = utilities.check_teacher_staff_ratio(pop, self.dataDir, f"calltwice_{n}_{i}", average_student_teacher_ratio,
                                                          average_student_all_staff_ratio=average_student_all_staff_ratio, err_margin=2)
             utilities_dist.check_enrollment_distribution(pop, n, datadir, location, state_location, country_location,
                                                     test_prefix=f"calltwice{n}_{i}", skip_stat_check=True, do_close=self.do_close)
             utilities_dist.check_age_distribution(pop, n, datadir, self.resultdir, location, state_location, country_location,
                                              test_prefix=f"calltwice{n}_{i}", do_close=self.do_close)
             i += 1
         except:
             print("check failed, continue...")
     return result
Exemple #6
0
    def export_pars(self, filename=None, indent=2, *args, **kwargs):
        '''
        Return parameters for JSON export -- see also to_json().

        This method is required so that interventions can specify
        their JSON-friendly representation.

        Args:
            filename (str): filename to save to; if None, do not save
            indent (int): indent (int): if writing to file, how many indents to use per nested level
            args (list): passed to savejson()
            kwargs (dict): passed to savejson()

        Returns:
            pardict (dict): a dictionary containing all the parameter values
        '''
        pardict = {}
        for key in self.pars.keys():
            if key == 'interventions':
                pardict[key] = [intervention.to_json() for intervention in self.pars[key]]
            elif key == 'start_day':
                pardict[key] = str(self.pars[key])
            else:
                pardict[key] = self.pars[key]
        if filename is not None:
            sc.savejson(filename=filename, obj=pardict, indent=indent, *args, **kwargs)
        return pardict
Exemple #7
0
def runpop(resultdir, actual_vals, testprefix, method):
    """
    Run any method which creates a population and write args and population to
    file "{resultdir}/{testprefix}.json". The method must be a method which
    returns a population. Write the population file to
    "{resultdir}/{testprefix}.config.json"

    Args:
      resultdir (str)    : result directory
      actual_vals (dict) : a dictionary with param name and param value
      testprefix (str)   : test prefix to generate file name
      method (str)       : method which generates population

    Returns:
        Population dictionary.
    """
    os.makedirs(resultdir, exist_ok=True)
    params = {}
    args = inspect.getfullargspec(method).args
    for arg in args:
        params[arg] = inspect.signature(method).parameters[arg].default
    for name in actual_vals:
        if name in params.keys():
            params[name] = actual_vals[name]
    sc.savejson(os.path.join(resultdir, f"{testprefix}.config.json"),
                params,
                indent=2)
    pop = method(**params)
    sc.savejson(os.path.join(resultdir, f"{testprefix}_pop.json"),
                pop,
                indent=2)
    return pop
def savejson(study):
    dbname = 'calibrated_parameters_UK'

    sc.heading('Making results structure...')
    results = []
    failed_trials = []
    for trial in study.trials:
        data = {'index':trial.number, 'mismatch': trial.value}
        for key,val in trial.params.items():
            data[key] = val
        if data['mismatch'] is None:
            failed_trials.append(data['index'])
        else:
            results.append(data)
    print(f'Processed {len(study.trials)} trials; {len(failed_trials)} failed')

    sc.heading('Making data structure...')
    keys = ['index', 'mismatch'] + pkeys
    data = sc.objdict().make(keys=keys, vals=[])
    for i,r in enumerate(results):
        for key in keys:
            data[key].append(r[key])
    df = pd.DataFrame.from_dict(data)

    order = np.argsort(df['mismatch'])
    json = []
    for o in order:
        row = df.iloc[o,:].to_dict()
        rowdict = dict(index=row.pop('index'), mismatch=row.pop('mismatch'), pars={})
        for key,val in row.items():
            rowdict['pars'][key] = val
        json.append(rowdict)
    sc.savejson(f'{dbname}.json', json, indent=2)

    return
Exemple #9
0
    def get_pop_details(self,
                        pop,
                        dir,
                        title_prefix,
                        location,
                        state_location,
                        country_location,
                        decimal=3):
        os.makedirs(dir, exist_ok=True)
        # want default age brackets and to see that they line up with the average contacts by age bracket created
        age_brackets = spdd.get_census_age_brackets(self.datadir, location,
                                                    state_location,
                                                    country_location)
        age_brackets_labels = [
            str(age_brackets[b][0]) + '-' + str(age_brackets[b][-1])
            for b in sorted(age_brackets.keys())
        ]
        for setting_code in ['H', 'W', 'S']:
            average_contacts = utilities.get_average_contact_by_age(
                pop, self.datadir, setting_code=setting_code, decimal=decimal)
            fmt = f'%.{str(decimal)}f'
            # print(f"expected contacts by age for {code}:\n", average_contacts)
            utilities.plot_array(
                average_contacts,
                datadir=self.figDir,
                testprefix=
                f"{self.n}_seed_{self.seed}_{setting_code}_average_contacts",
                expect_label='Expected' if self.generateBaseline else 'Test',
                names=age_brackets_labels,
                xlabel_rotation=50)
            sc.savejson(os.path.join(
                dir,
                f"{self.n}_seed_{self.seed}_{setting_code}_average_contact.json"
            ),
                        dict(enumerate(average_contacts.tolist())),
                        indent=2)

            for method in ['density', 'frequency']:
                matrix = sp.calculate_contact_matrix(pop, method, setting_code)
                brackets = spdd.get_census_age_brackets(
                    self.datadir, location, state_location, country_location)
                ageindex = spb.get_age_by_brackets_dic(brackets)
                agg_matrix = spb.get_aggregate_matrix(matrix, ageindex)
                textfile = os.path.join(
                    dir,
                    f"{self.n}_seed_{self.seed}_{setting_code}_{method}_contact_matrix.csv"
                )
                np.savetxt(textfile, agg_matrix, delimiter=",", fmt=fmt)
                fig = sp.plot_contacts(pop,
                                       setting_code=setting_code,
                                       density_or_frequency=method,
                                       do_show=False)
                fig.savefig(
                    os.path.join(
                        self.figDir,
                        f"{self.n}_seed_{self.seed}_{setting_code}_{method}_contact_matrix.png"
                    ))
def plot_schools(pop):
    ''' Not a formal test, but a sanity check for school distributions '''
    keys = ['pk', 'es', 'ms', 'hs'] # Exclude universities for this analysis
    ppl_keys = ['all', 'students', 'teachers', 'staff']
    xpeople = np.arange(len(ppl_keys)) # X axis for people
    school_types_by_ind = {}
    for key,vals in pop.school_types.items():
        for val in vals:
            if key in keys:
                school_types_by_ind[val] = key

    results = {}
    for sc_id,sc_type in school_types_by_ind.items():
        thisres = sc.objdict()
        sc_inds = (pop.school_id == sc_id)
        thisres.all = cv.true(sc_inds)
        thisres.students = cv.true(np.array(pop.student_flag) * sc_inds)
        thisres.teachers = cv.true(np.array(pop.teacher_flag) * sc_inds)
        thisres.staff    = cv.true(np.array(pop.staff_flag) * sc_inds)
        results[sc_id] = thisres

    # Do plotting
    fig = pl.figure(figsize=figsize, dpi=dpi)
    pl.subplots_adjust(left=0.05, right=0.95, bottom=0.05, top=0.95, hspace=0.5, wspace=0.5)
    n_schools = len(results)
    n_cols = len(ppl_keys) + 1
    count = 0
    for sc_id in results.keys():
        count += 1
        school_type = school_types_by_ind[sc_id]
        ax = pl.subplot(n_schools, n_cols, count)
        thisres = results[sc_id]
        thisres.people_counts = [len(thisres[k]) for k in ppl_keys]
        ax.bar(xpeople, thisres.people_counts)
        ax.set_xticks(xpeople)
        ax.set_xticklabels(ppl_keys)
        title = f'School ID {sc_id}, school type {school_type}, total size: {len(thisres.all)}'
        ax.set_title(title)

        thisres.ages = sc.objdict()
        for key in ppl_keys:
            count += 1
            ax = pl.subplot(n_schools, n_cols, count)
            thisres.ages[key] = pop.age[thisres[key]]
            pl.hist(thisres.ages[key])
            ax.set_title(f'Ages for {key} in school {sc_id} ({school_type})')

    if do_maximize:
        cv.maximize(fig=fig)

    if to_json:
        sc.savejson(outfile, results, indent=2)

    return results
    def get_pop_details(self,
                        pop,
                        dir,
                        title_prefix,
                        location,
                        state_location,
                        country_location,
                        decimal=3):
        os.makedirs(dir, exist_ok=True)
        for setting_code in ['H', 'W', 'S']:
            average_contacts = utilities.get_average_contact_by_age(
                pop, self.datadir, setting_code=setting_code, decimal=decimal)
            fmt = f'%.{str(decimal)}f'
            # print(f"expected contacts by age for {code}:\n", average_contacts)
            utilities.plot_array(
                average_contacts,
                datadir=self.figDir,
                testprefix=
                f"{self.n}_seed_{self.seed}_{setting_code}_average_contacts",
                expect_label='Expected' if self.generateBaseline else 'Test')
            sc.savejson(os.path.join(
                dir,
                f"{self.n}_seed_{self.seed}_{setting_code}_average_contact.json"
            ),
                        dict(enumerate(average_contacts.tolist())),
                        indent=2)

            for type in ['density', 'frequency']:
                matrix = sp.calculate_contact_matrix(pop, type, setting_code)
                brackets = sp.get_census_age_brackets(self.datadir,
                                                      state_location,
                                                      country_location)
                ageindex = sp.get_age_by_brackets_dic(brackets)
                agg_matrix = sp.get_aggregate_matrix(matrix, ageindex)
                np.savetxt(os.path.join(
                    dir,
                    f"{self.n}_seed_{self.seed}_{setting_code}_{type}_contact_matrix.csv"
                ),
                           agg_matrix,
                           delimiter=",",
                           fmt=fmt)
                fig = plot_age_mixing_matrices.test_plot_generated_contact_matrix(
                    setting_code=setting_code,
                    population=pop,
                    title_prefix=" Expected "
                    if self.generateBaseline else " Test ",
                    density_or_frequency=type)
                # fig.show()
                fig.savefig(
                    os.path.join(
                        self.figDir,
                        f"{self.n}_seed_{self.seed}_{setting_code}_{type}_contact_matrix.png"
                    ))
def objective(trial):
    ''' Define the objective for Optuna '''
    pars = {}
    bounds = cs.define_pars(which='bounds', use_safegraph=use_safegraph)
    for key, bound in bounds.items():
        pars[key] = trial.suggest_uniform(key, *bound)
    pars['rand_seed'] = trial.number
    mismatch = cs.run_sim(pars, use_safegraph=use_safegraph)
    try:
        pars['mismatch'] = mismatch
        sc.savejson(f'./progress/trial{trial.number}_{get_fn()}.pars', pars)
    except Exception as E:
        print(f'Could not save progress file; {str(E)}')
    return mismatch
Exemple #13
0
def git_info(filename=None, check=False, old_info=None, die=False, verbose=True, **kwargs):
    '''
    Get current git information and optionally write it to disk.

    Args:
        filename (str): name of the file to write to or read from
        check (bool): whether or not to compare two git versions
        old_info (dict): dictionary of information to check against
        die (bool): whether or not to raise an exception if the check fails

    **Examples**::

        cv.git_info('covasim_version.json') # Writes to disk
        cv.git_info('covasim_version.json', check=True) # Checks that current version matches saved file
    '''
    info = sc.gitinfo(__file__)
    if not check: # Just get information
        if filename is not None:
            output = sc.savejson(filename, info, **kwargs)
        else:
            output = info
    else:
        if filename is not None:
            old_info = sc.loadjson(filename, **kwargs)
        string = ''
        if info != old_info:
            string = f'Git information differs: {info} vs. {old_info}'
            if die:
                raise ValueError(string)
            elif verbose:
                print(string)
    return output
Exemple #14
0
    def to_json(self, filename=None, tostring=True, indent=2, verbose=False, *args, **kwargs):
        '''
        Export results as JSON.

        Args:
            filename (str): if None, return string; else, write to file

        Returns:
            A unicode string containing a JSON representation of the results,
            or writes the JSON file to disk

        '''
        d = {'t':self.tvec,
             'results':   self.results,
             'basepars':  self.basepars,
             'metapars':  self.metapars,
             'simpars':   self.base_sim.export_pars(),
             'scenarios': self.scenarios
             }
        if filename is None:
            output = sc.jsonify(d, tostring=tostring, indent=indent, verbose=verbose, *args, **kwargs)
        else:
            output = sc.savejson(filename=filename, obj=d, indent=indent, *args, **kwargs)

        return output
Exemple #15
0
    def to_json(self, filename=None, tostring=True, indent=2, *args, **kwargs):
        """
        Export results as JSON.

        Args:
            filename (str): if None, return string; else, write to file

        Returns:
            A unicode string containing a JSON representation of the results,
            or writes the JSON file to disk

        """
        resdict = self._make_resdict()
        pardict = self._make_pardict()
        d = {'results': resdict, 'parameters': pardict}
        if filename is None:
            output = sc.jsonify(d,
                                tostring=tostring,
                                indent=indent,
                                *args,
                                **kwargs)
        else:
            output = sc.savejson(filename=filename, obj=d, *args, **kwargs)

        return output
def git_info(filename=None, check=False, comments=None, old_info=None, die=False, indent=2, verbose=True, frame=2, **kwargs):
    '''
    Get current git information and optionally write it to disk. Simplest usage
    is cv.git_info(__file__)

    Args:
        filename  (str): name of the file to write to or read from
        check    (bool): whether or not to compare two git versions
        comments (dict): additional comments to include in the file
        old_info (dict): dictionary of information to check against
        die      (bool): whether or not to raise an exception if the check fails
        indent    (int): how many indents to use when writing the file to disk
        verbose  (bool): detail to print
        frame     (int): how many frames back to look for caller info
        kwargs   (dict): passed to sc.loadjson() (if check=True) or sc.savejson() (if check=False)

    **Examples**::

        cv.git_info() # Return information
        cv.git_info(__file__) # Writes to disk
        cv.git_info('covasim_version.gitinfo') # Writes to disk
        cv.git_info('covasim_version.gitinfo', check=True) # Checks that current version matches saved file
    '''

    # Handle the case where __file__ is supplied as the argument
    if isinstance(filename, str) and filename.endswith('.py'):
        filename = filename.replace('.py', '.gitinfo')

    # Get git info
    calling_file = sc.makefilepath(sc.getcaller(frame=frame, tostring=False)['filename'])
    cv_info = {'version':cvv.__version__}
    cv_info.update(sc.gitinfo(__file__, verbose=False))
    caller_info = sc.gitinfo(calling_file, verbose=False)
    caller_info['filename'] = calling_file
    info = {'covasim':cv_info, 'called_by':caller_info}
    if comments:
        info['comments'] = comments

    # Just get information and optionally write to disk
    if not check:
        if filename is not None:
            output = sc.savejson(filename, info, indent=indent, **kwargs)
        else:
            output = info
        return output

    # Check if versions match, and optionally raise an error
    else:
        if filename is not None:
            old_info = sc.loadjson(filename, **kwargs)
        string = ''
        old_cv_info = old_info['covasim'] if 'covasim' in old_info else old_info
        if cv_info != old_cv_info: # pragma: no cover
            string = f'Git information differs: {cv_info} vs. {old_cv_info}'
            if die:
                raise ValueError(string)
            elif verbose:
                print(string)
        return
Exemple #17
0
def test_benchmark(do_save=do_save):
    ''' Compare benchmark performance '''

    print('Running benchmark...')
    previous = sc.loadjson(benchmark_filename)

    # Create the sim
    sim = cv.Sim(verbose=0)

    # Time initialization
    t0 = sc.tic()
    sim.initialize()
    t_init = sc.toc(t0, output=True)

    # Time running
    t0 = sc.tic()
    sim.run()
    t_run = sc.toc(t0, output=True)

    # Construct json
    n_decimals = 3
    json = {
        'time': {
            'initialize': round(t_init, n_decimals),
            'run': round(t_run, n_decimals),
        },
        'parameters': {
            'pop_size': sim['pop_size'],
            'pop_type': sim['pop_type'],
            'n_days': sim['n_days'],
        },
    }

    print('Previous benchmark:')
    sc.pp(previous)

    print('\nNew benchmark:')
    sc.pp(json)

    if do_save:
        sc.savejson(filename=benchmark_filename, obj=json, indent=2)

    print('Done.')

    return json
Exemple #18
0
    def to_json(self, filename, indent=2, **kwargs):
        """
        Export to a JSON file.

        **Example**::

            pop.to_json('my-pop.json')
        """
        return sc.savejson(filename, self.popdict, indent=indent, **kwargs)
Exemple #19
0
    def save(self, filename, verbose=True, **kwargs):
        '''
        Save current settings as a JSON file.

        Args:
            filename (str): file to save to
            kwargs (dict): passed to ``sc.savejson()``
        '''
        json = self.to_dict()
        output = sc.savejson(filename=filename, obj=json, **kwargs)
        if verbose: print(f'Settings saved to {filename}')
        return output
Exemple #20
0
    def to_json(self, filename=None, keys=None, tostring=False, indent=2, verbose=False, *args, **kwargs):
        '''
        Export results as JSON.

        Args:
            filename (str): if None, return string; else, write to file
            keys (str or list): attributes to write to json (default: results, parameters, and summary)
            tostring (bool): if not writing to file, whether to write to string (alternative is sanitized dictionary)
            indent (int): if writing to file, how many indents to use per nested level
            verbose (bool): detail to print
            args (list): passed to savejson()
            kwargs (dict): passed to savejson()

        Returns:
            A unicode string containing a JSON representation of the results,
            or writes the JSON file to disk

        **Examples**::

            json = sim.to_json()
            sim.to_json('results.json')
            sim.to_json('summary.json', keys='summary')
        '''

        # Handle keys
        if keys is None:
            keys = ['results', 'pars', 'summary']
        keys = sc.promotetolist(keys)

        # Convert to JSON-compatible format
        d = {}
        for key in keys:
            if key == 'results':
                resdict = self.export_results(for_json=True)
                d['results'] = resdict
            elif key in ['pars', 'parameters']:
                pardict = self.export_pars()
                d['parameters'] = pardict
            elif key == 'summary':
                d['summary'] = dict(sc.dcp(self.summary))
            else:
                try:
                    d[key] = sc.sanitizejson(getattr(self, key))
                except Exception as E:
                    errormsg = f'Could not convert "{key}" to JSON: {str(E)}; continuing...'
                    print(errormsg)

        if filename is None:
            output = sc.jsonify(d, tostring=tostring, indent=indent, verbose=verbose, *args, **kwargs)
        else:
            output = sc.savejson(filename=filename, obj=d, indent=indent, *args, **kwargs)

        return output
def regression_persist(obj, filename, decimal=3):
    # persist files for regression run
    if str(filename).endswith('json'):
        if isinstance(obj, sp.Pop):
            obj.to_json(filename)
        else:
            sc.savejson(filename, obj)
    elif str(filename).endswith('csv') or str(filename).endswith('txt'):
        if isinstance(obj, np.ndarray) or isinstance(obj, list):
            fmt = f'%.{str(decimal)}f'
            np.savetxt(filename, np.array(obj), delimiter=",", fmt=fmt)
        elif isinstance(obj, pd.DataFrame):
            obj.to_csv(filename)
        elif isinstance(obj, str):
            with open(filename, "w") as f:
                f.write(obj)
        else:
            raise ValueError(f"Unrecognized object type: {type(obj)} ")
    else:
        raise ValueError(
            f"Invalid filename: {filename} only json / csv /txt supported!")
    print(f"file saved: {filename}")
Exemple #22
0
def runpop(resultdir, actual_vals, testprefix, method):
    """
    Run any method which creates a population and write args and population to
    file "{resultdir}/{testprefix}.json". The method must be a method which
    returns a population. Write the population file to
    "{resultdir}/{testprefix}.config.json"

    Args:
      resultdir (str)    : result directory
      actual_vals (dict) : a dictionary with param name and param value
      testprefix (str)   : test prefix to generate file name
      method (str)       : method which generates population

    Returns:
        Population dictionary.
    """
    print(
        'NB: calling runpop with "method" is not used, since only make_population() is used'
    )
    os.makedirs(resultdir, exist_ok=True)
    params = {}
    for name in actual_vals:
        if name not in [
                'self', 'test_prefix', 'filename'
        ]:  # Remove automatically generated but invalid parameters
            params[name] = actual_vals[name]
    sc.savejson(os.path.join(resultdir, f"{testprefix}.config.json"),
                params,
                indent=2)
    print(params)
    pop = sp.make_population(**params)
    if do_save:
        sc.savejson(os.path.join(resultdir, f"{testprefix}_pop.json"),
                    pop,
                    indent=2)
    return pop
Exemple #23
0
    pop = sp.make_population(**pars)
    elapsed = sc.toc(T, output=True)

    for person in [6, 66, 666]:
        print(f'\n\nPerson {person}')
        sc.pp(pop[person])
    print('\n\n')
    print(sc.gitinfo(sp.__file__))
    print(sp.version.__version__)

    popkeys = list(pop.keys())
    stridekeys = [popkeys[i] for i in range(0, len(pop), stride)]
    subpop = {k: pop[k] for k in stridekeys}

    if do_save:
        sc.savejson(f'pop_v{sp.version.__version__}.json', subpop, indent=2)

    print('\n\n')
    pps = pars["n"] / elapsed
    print(
        f'Total time: {elapsed:0.3f} s for {pars["n"]} people ({pps:0.0f} people/second)'
    )

    #%% Plotting
    fig, axes = pl.subplots(2, 3, figsize=(32, 18))
    expected = sc.loadjson('expected/pop_2001_seed1001.json')
    expected = {int(key): val for key, val in expected.items()}
    actual = pop
    for c, code in enumerate(['H', 'W', 'S']):
        args = dict(setting_code=code, density_or_frequency='density')
        fig = plotmatrix(population=expected,
def test_benchmark(do_save=do_save):
    ''' Compare benchmark performance '''

    print('Running benchmark...')
    previous = sc.loadjson(benchmark_filename)

    repeats = 5
    t_inits = []
    t_runs  = []

    def normalize_performance():
        ''' Normalize performance across CPUs -- simple Numpy calculation '''
        t_bls = []
        bl_repeats = 5
        n_outer = 10
        n_inner = 1e6
        for r in range(bl_repeats):
            t0 = sc.tic()
            for i in range(n_outer):
                a = np.random.random(int(n_inner))
                b = np.random.random(int(n_inner))
                a*b
            t_bl = sc.toc(t0, output=True)
            t_bls.append(t_bl)
        t_bl = min(t_bls)
        reference = 0.112 # Benchmarked on an Intel i9-8950HK CPU @ 2.90GHz
        ratio = reference/t_bl
        return ratio


    # Test CPU performance before the run
    r1 = normalize_performance()

    # Do the actual benchmarking
    for r in range(repeats):

        # Create the sim
        sim = cv.Sim(verbose=0)

        # Time initialization
        t0 = sc.tic()
        sim.initialize()
        t_init = sc.toc(t0, output=True)

        # Time running
        t0 = sc.tic()
        sim.run()
        t_run = sc.toc(t0, output=True)

        # Store results
        t_inits.append(t_init)
        t_runs.append(t_run)

    # Test CPU performance after the run
    r2 = normalize_performance()
    ratio = (r1+r2)/2
    t_init = min(t_inits)*ratio
    t_run  = min(t_runs)*ratio

    # Construct json
    n_decimals = 3
    json = {'time': {
                'initialize': round(t_init, n_decimals),
                'run':        round(t_run,  n_decimals),
                },
            'parameters': {
                'pop_size': sim['pop_size'],
                'pop_type': sim['pop_type'],
                'n_days':   sim['n_days'],
                },
            'cpu_performance': ratio,
            }

    print('Previous benchmark:')
    sc.pp(previous)

    print('\nNew benchmark:')
    sc.pp(json)

    if do_save:
        sc.savejson(filename=benchmark_filename, obj=json, indent=2)

    print('Done.')

    return json
        'cum_diagnoses', 'new_diagnoses', 'cum_deaths', 'new_deaths'
    ]

    # # Plot initial
    print('Running initial...')
    pars, pkeys = get_bounds()  # Get parameter guesses
    sim = create_sim(pars.best)
    sim.run()
    fig = sim.plot(to_plot=to_plot)
    fig.axes[0].set_title('Initial parameter values')
    objective(pars.best)
    pl.pause(1.0)  # Ensure it has time to render

    # Calibrate
    print('Starting calibration for {state}...')
    T = sc.tic()
    pars_calib = calibrate()
    sc.toc(T)

    # Plot result
    print('Plotting result...')
    x = [pars_calib[k] for k in pkeys]
    sim = create_sim(x)
    sim.run()
    fig = sim.plot(to_plot=to_plot)
    fig.axes[0].set_title('Calibrated parameter values')

    if do_save:
        sc.savejson(f'calibrated_parameters_ny.json', pars_calib)

print('Done.')
sc.heading('Making data structure...')
keys = ['index', 'mismatch'] + pkeys
print(keys)
data = sc.objdict().make(keys=keys, vals=[])
for i, r in enumerate(results):
    for key in keys:
        if key not in r:
            print(
                f'Warning! Key {key} is missing from trial {i}, replacing with default'
            )
            r[key] = best[key]
        data[key].append(r[key])
df = pd.DataFrame.from_dict(data)

sc.heading('Saving...')

# Save data to JSON
order = np.argsort(df['mismatch'])
json = []
for o in order:
    row = df.iloc[o, :].to_dict()
    rowdict = dict(index=row.pop('index'),
                   mismatch=row.pop('mismatch'),
                   pars={})
    for key, val in row.items():
        rowdict['pars'][key] = val
    json.append(rowdict)
sc.savejson(f'{state}-processed.json', json, indent=2)
saveobj = False
Exemple #27
0
        if data['mismatch'] is None:
            failed_trials.append(data['index'])
        else:
            results.append(data)
    print(f'Processed {len(study.trials)} trials; {len(failed_trials)} failed')

    sc.heading('Making data structure...')
    keys = ['index', 'mismatch'] + list(best.keys())
    data = sc.objdict().make(keys=keys, vals=[])
    for i, r in enumerate(results):
        for key in keys:
            if key not in r:
                print(f'Warning! Key {key} is missing from trial {i}, replacing with default')
                r[key] = best[key]
            data[key].append(r[key])
    df = pd.DataFrame.from_dict(data)

    if save_json:
        order = np.argsort(df['mismatch'])
        json = []
        for o in order:
            row = df.iloc[o,:].to_dict()
            rowdict = dict(index=row.pop('index'), mismatch=row.pop('mismatch'), pars={})
            for key,val in row.items():
                rowdict['pars'][key] = val
            json.append(rowdict)
        sc.savejson(f'{name}.json', json, indent=2)
        saveobj = False
        if saveobj: # Smaller file, but less portable
            sc.saveobj(f'{name}.obj', json)
Exemple #28
0
 def save(self):
     pars_calib = self.get_best_pars()
     sc.savejson(f'calibrated_parameters_{self.until}_{self.state}.json',
                 pars_calib)