def test_uuid(): ''' Test UID generation ''' import uuid u0 = uuid.uuid4() u1 = sc.uuid() u2 = sc.uuid() u3 = sc.uuid(length=4) assert u1 != u2 assert isinstance(u1, type(u0)) assert isinstance(u3, str) with pytest.raises(ValueError): sc.uuid(length=400) print(f'UIDs:\n{u0}\n{u1}\n{u2}\n{u3}') return u3
def __init__(self, username=None, password=None, displayname=None, email=None, uid=None, raw_password=None, is_admin=False): # Handle general properties if not username: username = '******' if not password: password = '******' if not displayname: displayname = username if not uid: uid = sc.uuid() # Set user-specific properties self.username = username # Set the username. self.displayname = displayname # Set the displayname (what the browser will show). self.email = email # Set the user's email. self.uid = uid # The user's UID self.is_authenticated = True # Set the user to be authentic. self.is_active = True # Set the account to be active. self.is_anonymous = False # The user is not anonymous. self.is_admin = is_admin # Set whether this user has admin rights. # Handle the password if raw_password is not None: if six.PY3: raw_password = raw_password.encode('utf-8') password = sc.sha(raw_password).hexdigest() self.password = password return None
def plot_people(sim) -> dict: z, states = get_individual_states(sim) fig = go.Figure() for state in states[::-1]: # Reverse order for plotting fig.add_trace(go.Scatter( x=sim.tvec, y=(z == state['value']).sum(axis=0), stackgroup='one', line=dict(width=0.5, color=state['color']), fillcolor=state['color'], hoverinfo="y+name", name=state['name'] )) if sim['interventions']: interv_day = sim['interventions'][0].days[0] if interv_day > 0 and interv_day < sim['n_days']: fig.add_shape(dict(type="line", xref="x", yref="paper", x0=interv_day, x1=interv_day, y0=0, y1=1, name='Intervention', line=dict(width=0.5, dash='dash'))) fig.update_layout(annotations=[dict(x=interv_day, y=1.07, xref="x", yref="paper", text="Intervention start", showarrow=False)]) fig.update_layout(yaxis_range=(0, sim.n)) fig.update_layout(title={'text': 'Numbers of people by health state'}, xaxis_title='Day', yaxis_title='People', autosize=True) output = {'json': fig.to_json(), 'id': str(sc.uuid())} d = json.loads(output['json']) d['config'] = {'responsive': True} output['json'] = json.dumps(d) return output
def save_new_project(proj, username=None, uid=None): """ If we're creating a new project, we need to do some operations on it to make sure it's valid for the webapp. """ # Preliminaries new_project = sc.dcp(proj) # Copy the project, only save what we want... new_project.uid = sc.uuid(uid) # Get unique name user = get_user(username) current_project_names = [] for project_key in user.projects: proj = load_project(project_key) current_project_names.append(proj.name) new_project_name = sc.uniquename(new_project.name, namelist=current_project_names) new_project.name = new_project_name # Ensure it's a valid webapp project if not hasattr(new_project, 'webapp'): new_project.webapp = sc.prettyobj() new_project.webapp.username = username # If we ever use Celery with HealthPrior: new_project.webapp.tasks = [] new_project.webapp.username = username # Make sure we have the current username # Save all the things key = save_project(new_project) if key not in user.projects: # Let's not allow multiple copies user.projects.append(key) datastore.saveuser(user) return key, new_project
def __init__(self, name=None, project=None, filename=None, folder=None): if name is None: name = 'Default' self.projectref = sc.Link(project) # Store pointer for the project self.name = sc.uniquename( name, namelist=self.projectref().burdensets.keys( )) # Name of the parameter set, e.g. 'default' self.uid = sc.uuid() # ID self.created = sc.now() # Date created self.modified = sc.now() # Date modified # Define hard-coded column names self.colnames = sc.odict([ ('active', 'Active'), #('code', 'Code'), ('cause', 'Cause'), ('dalys', 'DALYs'), ('deaths', 'Deaths'), ('prevalence', 'Prevalence') ]) # Load data, if provided self.data = None if filename is not None: self.loaddata(filename=filename, folder=folder) return None
def make_randpop(sim, id_len=6): ''' Make a random population, without contacts ''' # Load age data based on 2018 Seattle demographics age_data = np.array([ [0, 4, 0.0605], [5, 9, 0.0607], [10, 14, 0.0566], [15, 19, 0.0557], [20, 24, 0.0612], [25, 29, 0.0843], [30, 34, 0.0848], [35, 39, 0.0764], [40, 44, 0.0697], [45, 49, 0.0701], [50, 54, 0.0681], [55, 59, 0.0653], [60, 64, 0.0591], [65, 69, 0.0453], [70, 74, 0.0312], [75, 79, 0.02016], # Calculated based on 0.0504 total for >=75 [80, 84, 0.01344], [85, 89, 0.01008], [90, 99, 0.00672], ]) # Handle sex and UID n_people = int(sim['n']) # Number of people uids = sc.uuid(which='ascii', n=n_people, length=id_len) sexes = cvu.rbt(0.5, n_people) # Handle ages age_data_min = age_data[:, 0] age_data_max = age_data[:, 1] + 1 # Since actually e.g. 69.999 age_data_range = age_data_max - age_data_min age_data_prob = age_data[:, 2] age_data_prob /= age_data_prob.sum() # Ensure it sums to 1 age_bins = cvu.mt(age_data_prob, n_people) # Choose age bins ages = age_data_min[age_bins] + age_data_range[age_bins] * np.random.random( n_people) # Uniformly distribute within this age bin # Make contacts contacts = [] for p in range(n_people): n_contacts = cvu.pt( sim['contacts'] ) # Draw the number of Poisson contacts for this person contact_inds = cvu.choose( max_n=n_people, n=n_contacts) # Choose people at random, assigning to household contacts.append(contact_inds) # Store output; data duplicated as per-person and list-like formats for convenience popdict = {} popdict['uid'] = uids popdict['age'] = ages popdict['sex'] = sexes popdict['contacts'] = contacts return popdict
def assign_uids_by_homes(homes, id_len=16, use_int=True): """ Assign IDs to everyone in order by their households. Args: homes (array) : The generated synthetic ages of household members. id_len (int) : The length of the UID. use_int (bool) : If True, use ints for the uids of individuals; otherwise use strings of length 'id_len'. Returns: A copy of the generated households with IDs in place of ages, and a dictionary mapping ID to age. """ age_by_uid_dic = dict() homes_by_uids = [] for h, home in enumerate(homes): home_ids = [] for a in home: if use_int: uid = len(age_by_uid_dic) else: uid = sc.uuid(length=id_len) age_by_uid_dic[uid] = a home_ids.append(uid) homes_by_uids.append(home_ids) return homes_by_uids, age_by_uid_dic
def __init__(self): """ Constructor: create an empty class. """ self.id = sc.uuid() self.teachers = set() self.students = set()
def process_graphs(figs): jsons = [] for fig in sc.promotetolist(figs): fig.update_layout(paper_bgcolor=bgcolor, plot_bgcolor=plotbg) output = {'json': fig.to_json(), 'id': str(sc.uuid())} d = json.loads(output['json']) d['config'] = {'responsive': True} output['json'] = json.dumps(d) jsons.append(output) return jsons
def __init__(self, obj=None, key=None, objtype=None, uid=None, force=True): # Handle input arguments if uid is None: if force: uid = sc.uuid() else: errormsg = 'DataStore: Not creating a new Blob UUID since force is set to False: key=%s, objtype=%s, uid=%s, obj=%s' % ( key, objtype, uid, obj) raise Exception(errormsg) if not key: key = '%s%s%s' % (objtype, default_separator, uid) # Set attributes self.key = key self.objtype = objtype self.uid = uid self.created = sc.now() self.modified = [self.created] self.obj = obj return None
def __init__(self, project=None, name=None, burdenset=None, intervset=None, makepackage=None): self.name = name # Name of the parameter set, e.g. 'default' self.uid = sc.uuid() # ID self.projectref = sc.Link( project) # Store pointer for the project, if available self.created = sc.now() # Date created self.modified = sc.now() # Date modified self.eps = 1e-4 # A nonzero value to help with division self.burdenset = burdenset self.intervset = intervset self.budget = None self.frpwt = None self.equitywt = None self.data = None # The data if makepackage: self.makepackage() return None
def __init__(self, name='Default', burdenfile=None, interventionsfile=None, country=None, makepackage=True, verbose=2): ''' Initialize the project ''' ## Define the structure sets self.burdensets = sc.odict() self.intervsets = sc.odict() self.packagesets = sc.odict() ## Define other quantities self.name = name self.country = country self.uid = sc.uuid() self.created = sc.now() self.modified = sc.now() self.version = hp.version self.gitinfo = sc.gitinfo(__file__) self.filename = None # File path, only present if self.save() is used ## Load burden spreadsheet, if available if burdenfile: self.loadburden(filename=burdenfile, verbose=verbose) ## Load interventions spreadsheet, if available if interventionsfile: self.loadinterventions(filename=interventionsfile, verbose=verbose) ## Combine into health package, if available if makepackage and burdenfile and interventionsfile: self.makepackage() return None
def __init__(self, name=None, project=None, filename=None, folder=None): if name is None: name = 'Default' self.projectref = sc.Link(project) # Store pointer for the project self.name = sc.uniquename(name, namelist=self.projectref().intervsets.keys()) # Name of the parameter set, e.g. 'default' self.uid = sc.uuid() # ID self.created = sc.now() # Date created self.modified = sc.now() # Date modified # Define hard-coded column names self.colnames = sc.odict([('active', 'Active'), ('shortname','Short name'), ('platform', 'Platform'), ('burdencov','Causes of burden (max coverage)'), ('icer', 'ICER'), ('unitcost', 'Unit cost'), ('spend', 'Spending'), ('frp', 'FRP'), ('equity', 'Equity'), ]) self.data = None if filename is not None: self.loaddata(filename=filename, folder=folder) return None
def run_sim(sim_pars=None, epi_pars=None, intervention_pars=None, datafile=None, show_animation=False, n_days=90, verbose=True): ''' Create, run, and plot everything ''' err = '' try: # Fix up things that JavaScript mangles orig_pars = cv.make_pars(set_prognoses=True, prog_by_age=False, use_layers=False) defaults = get_defaults(merge=True) web_pars = {} web_pars['verbose'] = verbose # Control verbosity here for key,entry in {**sim_pars, **epi_pars}.items(): print(key, entry) best = defaults[key]['best'] minval = defaults[key]['min'] maxval = defaults[key]['max'] try: web_pars[key] = np.clip(float(entry['best']), minval, maxval) except Exception: user_key = entry['name'] user_val = entry['best'] err1 = f'Could not convert parameter "{user_key}", value "{user_val}"; using default value instead\n' print(err1) err += err1 web_pars[key] = best if die: raise if key in sim_pars: sim_pars[key]['best'] = web_pars[key] else: epi_pars[key]['best'] = web_pars[key] # Convert durations web_pars['dur'] = sc.dcp(orig_pars['dur']) # This is complicated, so just copy it web_pars['dur']['exp2inf']['par1'] = web_pars.pop('web_exp2inf') web_pars['dur']['inf2sym']['par1'] = web_pars.pop('web_inf2sym') web_pars['dur']['crit2die']['par1'] = web_pars.pop('web_timetodie') web_dur = web_pars.pop('web_dur') for key in ['asym2rec', 'mild2rec', 'sev2rec', 'crit2rec']: web_pars['dur'][key]['par1'] = web_dur # Add n_days web_pars['n_days'] = n_days # Add the intervention web_pars['interventions'] = [] switcher = { 'social_distance': map_social_distance, 'school_closures': map_school_closures, 'symptomatic_testing': map_symptomatic_testing, 'contact_tracing': map_contact_tracing } if intervention_pars is not None: for key,scenario in intervention_pars.items(): func = switcher.get(key) func(scenario, web_pars) # Handle CFR -- ignore symptoms and set to 1 web_pars['prognoses'] = sc.dcp(orig_pars['prognoses']) web_pars['rel_symp_prob'] = 1e4 # Arbitrarily large web_pars['rel_severe_prob'] = 1e4 web_pars['rel_crit_prob'] = 1e4 web_pars['prognoses']['death_probs'][0] = web_pars.pop('web_cfr') if web_pars['rand_seed'] == 0: web_pars['rand_seed'] = None web_pars['timelimit'] = max_time # Set the time limit web_pars['pop_size'] = int(web_pars['pop_size']) # Set data type web_pars['contacts'] = int(web_pars['contacts']) # Set data type except Exception as E: err2 = f'Parameter conversion failed! {str(E)}\n' print(err2) err += err2 if die: raise # Create the sim and update the parameters try: sim = cv.Sim(pars=web_pars,datafile=datafile) except Exception as E: err3 = f'Sim creation failed! {str(E)}\n' print(err3) err += err3 if die: raise if verbose: print('Input parameters:') print(web_pars) # Core algorithm try: sim.run(do_plot=False) except TimeoutError: day = sim.t err4 = f"The simulation stopped on day {day} because run time limit ({sim['timelimit']} seconds) was exceeded. Please reduce the population size and/or number of days simulated." err += err4 if die: raise except Exception as E: err4 = f'Sim run failed! {str(E)}\n' print(err4) err += err4 if die: raise # Core plotting graphs = [] try: to_plot = sc.dcp(cv.default_sim_plots) for p,title,keylabels in to_plot.enumitems(): fig = go.Figure() for key in keylabels: label = sim.results[key].name this_color = sim.results[key].color y = sim.results[key][:] fig.add_trace(go.Scatter(x=sim.results['t'][:], y=y, mode='lines', name=label, line_color=this_color)) if sim.data is not None and key in sim.data: data_t = (sim.data.index-sim['start_day'])/np.timedelta64(1,'D') print(sim.data.index, sim['start_day'], np.timedelta64(1,'D'), data_t) ydata = sim.data[key] fig.add_trace(go.Scatter(x=data_t, y=ydata, mode='markers', name=label + ' (data)', line_color=this_color)) if sim['interventions']: interv_day = sim['interventions'][0].days[0] if interv_day > 0 and interv_day < sim['n_days']: fig.add_shape(dict(type="line", xref="x", yref="paper", x0=interv_day, x1=interv_day, y0=0, y1=1, name='Intervention', line=dict(width=0.5, dash='dash'))) fig.update_layout(annotations=[dict(x=interv_day, y=1.07, xref="x", yref="paper", text="Intervention start", showarrow=False)]) fig.update_layout(title={'text':title}, xaxis_title='Day', yaxis_title='Count', autosize=True) output = {'json': fig.to_json(), 'id': str(sc.uuid())} d = json.loads(output['json']) d['config'] = {'responsive': True} output['json'] = json.dumps(d) graphs.append(output) graphs.append(plot_people(sim)) if show_animation: graphs.append(animate_people(sim)) except Exception as E: err5 = f'Plotting failed! {str(E)}\n' print(err5) err += err5 if die: raise # Create and send output files (base64 encoded content) files = {} summary = {} try: datestamp = sc.getdate(dateformat='%Y-%b-%d_%H.%M.%S') ss = sim.to_excel() files['xlsx'] = { 'filename': f'covasim_results_{datestamp}.xlsx', 'content': 'data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64,' + base64.b64encode(ss.blob).decode("utf-8"), } json_string = sim.to_json(verbose=False) files['json'] = { 'filename': f'covasim_results_{datestamp}.json', 'content': 'data:application/text;base64,' + base64.b64encode(json_string.encode()).decode("utf-8"), } # Summary output summary = { 'days': sim.npts-1, 'cases': round(sim.results['cum_infections'][-1]), 'deaths': round(sim.results['cum_deaths'][-1]), } except Exception as E: err6 = f'File saving failed! {str(E)}\n' print(err6) err += err6 if die: raise output = {} output['err'] = err output['sim_pars'] = sim_pars output['epi_pars'] = epi_pars output['graphs'] = graphs output['files'] = files output['summary'] = summary return output
def getkey(self, key=None, objtype=None, uid=None, obj=None, fulloutput=None, forcetype=None): ''' Get a valid database key, either from a given key (do nothing), or else from a supplied objtype and uid, or else read them from the object supplied. The idea is for this method to be as forgiving as possible for different possible combinations of inputs. ''' # Handle optional input arguments if fulloutput is None: fulloutput = False if forcetype is None: forcetype = True # Handle different sources for things props = ['key', 'objtype', 'uid'] args = { 'key': key, 'objtype': objtype, 'uid': uid } # These are what have been supplied by the user fromobj = { 'key': None, 'objtype': None, 'uid': None } # This is from the object final = { 'key': None, 'objtype': None, 'uid': None } # These will eventually be the output values -- copy of args # Look for missing properties from the object if obj: if hasattr(obj, 'key'): fromobj['key'] = obj.key if hasattr(obj, 'objtype'): fromobj['objtype'] = obj.objtype if hasattr(obj, 'uid'): fromobj['uid'] = obj.uid # Populate all non-None entries from the input arguments for p in props: if args[p]: final[p] = sc.flexstr( args[p] ) # Convert to string since you don't know what crazy thing might be passed (using flexstr since str can't handle bytes) # Populate what we can from the object, if it hasn't already been populated for p in props: if fromobj[p] and not final[p]: final[p] = fromobj[p] # If the key is supplied but other things aren't, try to create them now if final['key'] and (not final['objtype'] or not final['uid']): splitkey = final['key'].split(self.separator) if len(splitkey) == 2: # Check that the key split properly if not final['objtype']: final['objtype'] = splitkey[0] if not final['uid']: final['uid'] = splitkey[1] # If we're still stuck, try making a new uid if not final['key'] and not final['uid']: final['uid'] = str(sc.uuid()) # If everything is supplied except the key, create it if not final['key']: if final['objtype'] and final[ 'uid']: # Construct a key from the object type and UID final['key'] = self.makekey(objtype=final['objtype'], uid=final['uid']) elif not final['objtype'] and final[ 'uid']: # Otherwise, just use the UID final['key'] = final['uid'] # Check that it's found, and if not, treat the key as a UID and try again keyexists = self.exists( final['key']) # Check to see whether a match has been found if not keyexists: # If not, treat the key as a UID instead newkey = self.makekey(objtype=final['objtype'], uid=final['key']) newkeyexists = self.exists( newkey) # Check to see whether a match has been found if newkeyexists: final['key'] = newkey # Finally, force the type if requested if forcetype and final['objtype']: splitkey = final['key'].split(self.separator, 1) if splitkey[0] != final['objtype']: final['key'] = self.makekey(objtype=final['objtype'], uid=final['key']) if len(final['key']) > max_key_length: raise Exception('Key is too long') # Return what we need to return if fulloutput: return final['key'], final['objtype'], final['uid'] else: return final['key']
def main_plots(sim): ''' Main simulation results ''' plots = [] to_plot = sc.dcp(cv.default_sim_plots) for p, title, keylabels in to_plot.enumitems(): fig = go.Figure() for key in keylabels: label = sim.results[key].name this_color = sim.results[key].color y = sim.results[key][:] fig.add_trace( go.Scatter(x=sim.results['t'][:], y=y, mode='lines', name=label, line_color=this_color)) if sim.data is not None and key in sim.data: data_t = (sim.data.index - sim['start_day']) / np.timedelta64( 1, 'D') print(sim.data.index, sim['start_day'], np.timedelta64(1, 'D'), data_t) ydata = sim.data[key] fig.add_trace( go.Scatter(x=data_t, y=ydata, mode='markers', name=label + ' (data)', line_color=this_color)) if sim['interventions']: for interv in sim['interventions']: if hasattr(interv, 'days'): for interv_day in interv.days: if interv_day > 0 and interv_day < sim['n_days']: fig.add_shape( dict(type="line", xref="x", yref="paper", x0=interv_day, x1=interv_day, y0=0, y1=1, name='Intervention', line=dict(width=0.5, dash='dash'))) fig.update_layout(annotations=[ dict(x=interv_day, y=1.07, xref="x", yref="paper", text="Intervention change", showarrow=False) ]) fig.update_layout(title={'text': title}, xaxis_title='Day', yaxis_title='Count', autosize=True, paper_bgcolor=bgcolor, plot_bgcolor=plotbg) output = {'json': fig.to_json(), 'id': str(sc.uuid())} d = json.loads(output['json']) d['config'] = {'responsive': True} output['json'] = json.dumps(d) plots.append(output) return plots
def run_sim(sim_pars=None, epi_pars=None, show_animation=False, verbose=True): ''' Create, run, and plot everything ''' err = '' try: # Fix up things that JavaScript mangles orig_pars = cv.make_pars() defaults = get_defaults(merge=True) web_pars = {} web_pars['verbose'] = verbose # Control verbosity here for key, entry in {**sim_pars, **epi_pars}.items(): print(key, entry) best = defaults[key]['best'] minval = defaults[key]['min'] maxval = defaults[key]['max'] try: web_pars[key] = np.clip(float(entry['best']), minval, maxval) except Exception: user_key = entry['name'] user_val = entry['best'] err1 = f'Could not convert parameter "{user_key}", value "{user_val}"; using default value instead\n' print(err1) err += err1 web_pars[key] = best if key in sim_pars: sim_pars[key]['best'] = web_pars[key] else: epi_pars[key]['best'] = web_pars[key] # Convert durations web_pars['dur'] = sc.dcp( orig_pars['dur']) # This is complicated, so just copy it web_pars['dur']['exp2inf']['par1'] = web_pars.pop('web_exp2inf') web_pars['dur']['inf2sym']['par1'] = web_pars.pop('web_inf2sym') web_pars['dur']['crit2die']['par1'] = web_pars.pop('web_timetodie') web_dur = web_pars.pop('web_dur') for key in ['asym2rec', 'mild2rec', 'sev2rec', 'crit2rec']: web_pars['dur'][key]['par1'] = web_dur # Add the intervention web_pars['interventions'] = [] if web_pars['web_int_day'] is not None: web_pars['interventions'] = cv.change_beta( days=web_pars.pop('web_int_day'), changes=(1 - web_pars.pop('web_int_eff'))) # Handle CFR -- ignore symptoms and set to 1 prog_pars = cv.get_default_prognoses(by_age=False) web_pars['rel_symp_prob'] = 1.0 / prog_pars.symp_prob web_pars['rel_severe_prob'] = 1.0 / prog_pars.severe_prob web_pars['rel_crit_prob'] = 1.0 / prog_pars.crit_prob web_pars['rel_death_prob'] = web_pars.pop( 'web_cfr') / prog_pars.death_prob except Exception as E: err2 = f'Parameter conversion failed! {str(E)}\n' print(err2) err += err2 # Create the sim and update the parameters try: sim = cv.Sim() sim['prog_by_age'] = False # So the user can override this value sim['timelimit'] = max_time # Set the time limit if web_pars['seed'] == 0: web_pars['seed'] = None # Reset sim.update_pars(web_pars) except Exception as E: err3 = f'Sim creation failed! {str(E)}\n' print(err3) err += err3 if verbose: print('Input parameters:') print(web_pars) # Core algorithm try: sim.run(do_plot=False) except Exception as E: err4 = f'Sim run failed! {str(E)}\n' print(err4) err += err4 if sim.stopped: try: # Assume it stopped because of the time, but if not, don't worry day = sim.stopped['t'] time_exceeded = f"The simulation stopped on day {day} because run time limit ({sim['timelimit']} seconds) was exceeded. Please reduce the population size and/or number of days simulated." err += time_exceeded except: pass # Core plotting graphs = [] try: to_plot = sc.dcp(cv.default_sim_plots) for p, title, keylabels in to_plot.enumitems(): fig = go.Figure() for key in keylabels: label = sim.results[key].name this_color = sim.results[key].color y = sim.results[key][:] fig.add_trace( go.Scatter(x=sim.results['t'][:], y=y, mode='lines', name=label, line_color=this_color)) if sim['interventions']: interv_day = sim['interventions'][0].days[0] if interv_day > 0 and interv_day < sim['n_days']: fig.add_shape( dict(type="line", xref="x", yref="paper", x0=interv_day, x1=interv_day, y0=0, y1=1, name='Intervention', line=dict(width=0.5, dash='dash'))) fig.update_layout(annotations=[ dict(x=interv_day, y=1.07, xref="x", yref="paper", text="Intervention start", showarrow=False) ]) fig.update_layout(title={'text': title}, xaxis_title='Day', yaxis_title='Count', autosize=True) output = {'json': fig.to_json(), 'id': str(sc.uuid())} d = json.loads(output['json']) d['config'] = {'responsive': True} output['json'] = json.dumps(d) graphs.append(output) graphs.append(plot_people(sim)) if show_animation: graphs.append(animate_people(sim)) except Exception as E: err5 = f'Plotting failed! {str(E)}\n' print(err5) err += err5 # Create and send output files (base64 encoded content) files = {} summary = {} try: datestamp = sc.getdate(dateformat='%Y-%b-%d_%H.%M.%S') ss = sim.to_xlsx() files['xlsx'] = { 'filename': f'COVASim_results_{datestamp}.xlsx', 'content': 'data:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;base64,' + base64.b64encode(ss.blob).decode("utf-8"), } json_string = sim.to_json() files['json'] = { 'filename': f'COVASim_results_{datestamp}.txt', 'content': 'data:application/text;base64,' + base64.b64encode(json_string.encode()).decode("utf-8"), } # Summary output summary = { 'days': sim.npts - 1, 'cases': round(sim.results['cum_infections'][-1]), 'deaths': round(sim.results['cum_deaths'][-1]), } except Exception as E: err6 = f'File saving failed! {str(E)}\n' print(err6) err += err6 output = {} output['err'] = err output['sim_pars'] = sim_pars output['epi_pars'] = epi_pars output['graphs'] = graphs output['files'] = files output['summary'] = summary return output
return P def heading(string, style=None): divider = '=' * 60 sc.blank() if style == 'big': string = '\n'.join([divider, string, divider]) sc.colorize('blue', string) return None # Launch app T = sc.tic() app = main.make_app() user = sw.make_default_users(app)[0] proj_id = sc.uuid(tostring=True) # These can all be the same proj = demoproj(proj_id, user.username) ########################################################################### ### Run the tests ########################################################################### string = 'Starting tests for proj = %s' % proj_id heading(string, 'big') if 'project_io' in torun: heading('Running project_io', 'big') uid = rpcs.save_new_project(proj, user.username) P = rpcs.load_project_record(uid) print(P)
def demoproj(proj_id, username): P = hp.demo() P.name = 'RPCs test %s' % proj_id[:6] P.uid = sc.uuid(proj_id) rpcs.save_new_project(P, username, uid=P.uid) # Force a matching uid return P
def animate_people(sim) -> dict: z, states = get_individual_states(sim, order=False) min_color = min(states, key=lambda x: x['value'])['value'] max_color = max(states, key=lambda x: x['value'])['value'] colorscale = [[x['value'] / max_color, x['color']] for x in states] aspect = 3 y_size = int(np.ceil((z.shape[0] / aspect) ** 0.5)) x_size = int(np.ceil(aspect * y_size)) z = np.pad(z, ((0, x_size * y_size - z.shape[0]), (0, 0)), mode='constant', constant_values=np.nan) days = sim.tvec fig_dict = { "data": [], "layout": {}, "frames": [] } fig_dict["layout"]["updatemenus"] = [ { "buttons": [ { "args": [None, {"frame": {"duration": 200, "redraw": True}, "fromcurrent": True}], "label": "Play", "method": "animate" }, { "args": [[None], {"frame": {"duration": 0, "redraw": True}, "mode": "immediate", "transition": {"duration": 0}}], "label": "Pause", "method": "animate" } ], "direction": "left", "pad": {"r": 10, "t": 87}, "showactive": False, "type": "buttons", "x": 0.1, "xanchor": "right", "y": 0, "yanchor": "top" } ] sliders_dict = { "active": 0, "yanchor": "top", "xanchor": "left", "currentvalue": { "font": {"size": 20}, "prefix": "Day: ", "visible": True, "xanchor": "right" }, "transition": {"duration": 200}, "pad": {"b": 10, "t": 50}, "len": 0.9, "x": 0.1, "y": 0, "steps": [] } # make data fig_dict["data"] = [go.Heatmap(z=np.reshape(z[:, 0], (y_size, x_size)), zmin=min_color, zmax=max_color, colorscale=colorscale, showscale=False, )] for state in states: fig_dict["data"].append(go.Scatter(x=[None], y=[None], mode='markers', marker=dict(size=10, color=state['color']), showlegend=True, name=state['name'])) # make frames for i, day in enumerate(days): frame = {"data": [go.Heatmap(z=np.reshape(z[:, i], (y_size, x_size)))], "name": i} fig_dict["frames"].append(frame) slider_step = {"args": [ [i], {"frame": {"duration": 5, "redraw": True}, "mode": "immediate", } ], "label": i, "method": "animate"} sliders_dict["steps"].append(slider_step) fig_dict["layout"]["sliders"] = [sliders_dict] fig = go.Figure(fig_dict) fig.update_layout( autosize=True, xaxis=dict( automargin=True, range=[-0.5, x_size + 0.5], constrain="domain", showgrid=False, showline=False, showticklabels=False, ), yaxis=dict( automargin=True, range=[-0.5, y_size + 0.5], constrain="domain", scaleanchor="x", scaleratio=1, showgrid=False, showline=False, showticklabels=False, ), ) fig.update_layout( plot_bgcolor='#fff' ) fig.update_layout(title={'text': 'Epidemic over time'}) output = {'json': fig.to_json(), 'id': str(sc.uuid())} d = json.loads(output['json']) d['config'] = {'responsive': True} output['json'] = json.dumps(d) return output
def test_uuid(): sc.heading('Test UID generation') import uuid # Create them u = sc.objdict() u.u0 = uuid.uuid4() u.u1 = sc.uuid() u.u2 = sc.uuid() u.u3 = sc.uuid(length=4) u.u4 = sc.uuid(which='ascii', length=16) u.u5 = sc.uuid(n=3) u.u6 = sc.uuid(which='hex', length=20) u.u7 = sc.uuid(which='numeric', length=10, n=5) # Tests assert u.u1 != u.u2 assert isinstance(u.u1, type(u.u0)) assert isinstance(u.u3, str) with pytest.raises(ValueError): sc.uuid(length=400) # UUID is only 16 characters long with pytest.raises(ValueError): sc.uuid(which='numeric', length=2, n=10) # Not enough unique choices print( 'NOTE: This is supposed to print warnings and then raise a (caught) exception\n' ) with pytest.raises(ValueError): sc.uuid(which='numeric', length=2, n=99, safety=1, verbose=True) # Not enough unique choices # Print results print(f'UIDs:') for key, val in u.items(): print(f'{key}: {val}') return u