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)
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()
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
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
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
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
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
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
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
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
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
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)
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
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}")
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
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
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)
def save(self): pars_calib = self.get_best_pars() sc.savejson(f'calibrated_parameters_{self.until}_{self.state}.json', pars_calib)