Skip to content

Commit

Permalink
update values repr
Browse files Browse the repository at this point in the history
  • Loading branch information
cliffckerr committed Mar 25, 2020
1 parent b5f2b6e commit c407adb
Showing 3 changed files with 50 additions and 16 deletions.
8 changes: 7 additions & 1 deletion covasim/base.py
Original file line number Diff line number Diff line change
@@ -64,7 +64,7 @@ def update_pars(self, pars, create=False):
return


class Result(sc.prettyobj):
class Result(object):
'''
Stores a single result -- by default, acts like an array.
@@ -89,6 +89,12 @@ def __init__(self, name=None, values=None, npts=None, scale=True, ispercentage=F
self.values = np.array(values, dtype=float) # Ensure it's an array
return

def __repr__(self, *args, **kwargs):
''' Use pretty repr, like sc.prettyobj, but displaying full values '''
output = sc.prepr(self, skip='values')
output += 'values:\n' + repr(self.values)
return output

def __getitem__(self, *args, **kwargs):
return self.values.__getitem__(*args, **kwargs)

56 changes: 42 additions & 14 deletions covasim/model.py
Original file line number Diff line number Diff line change
@@ -331,9 +331,10 @@ def init_people(self, verbose=None, id_len=6):
return


def apply_testing(self, t, test_probs, n_diagnoses, verbose):
def apply_testing(self, t, n_diagnoses, verbose):
''' Perform testing '''
test_sensitivity = self['sensitivity']
test_probs = self.test_probs
if t<len(self['daily_tests']): # Don't know how long the data is, ensure we don't go past the end
n_tests = self['daily_tests'][t] # Number of tests for this day
if n_tests and not pl.isnan(n_tests): # There are tests this day
@@ -349,6 +350,7 @@ def apply_testing(self, t, test_probs, n_diagnoses, verbose):
tested_person.diagnosed = True
tested_person.date_diagnosed = t
sc.printv(f' Person {tested_person.uid} was diagnosed at timestep {t}!', 2, verbose)

return n_diagnoses


@@ -427,14 +429,12 @@ def run(self, initialize=True, do_plot=False, verbose=None, **kwargs):
else:
print(string)

test_probs = {} # Store the probability of each person getting tested
# Initialise testing -- assign equal testing probabilities initially, these will get adjusted later
self.test_probs = dict.fromkeys(self.uids, 1.0) # Store the probability of each person getting tested

# Update each person
for person in self.people.values():

# Initialise testing -- assign equal testing probabilities initially, these will get adjusted later
test_probs[person.uid] = 1.0

# Count susceptibles
if person.susceptible:
n_susceptible += 1
@@ -517,14 +517,14 @@ def run(self, initialize=True, do_plot=False, verbose=None, **kwargs):
# Adjust testing probability based on what's happened to the person
# NB, these need to be separate if statements, because a person can be both diagnosed and infectious/symptomatic
if person.symptomatic:
test_probs[person.uid] *= sympt_test # They're symptomatic
self.test_probs[person.uid] *= sympt_test # They're symptomatic
if person.known_contact:
test_probs[person.uid] *= trace_test # They've had contact with a known positive
self.test_probs[person.uid] *= trace_test # They've had contact with a known positive
if person.diagnosed:
test_probs[person.uid] = 0.0
self.test_probs[person.uid] = 0.0

# Implement testing -- this is outside of the loop over people, but inside the loop over time
self.apply_testing(t, test_probs, n_diagnoses, verbose)
self.apply_testing(t, n_diagnoses, verbose)

# Implement interventions
self.apply_interventions(t, verbose)
@@ -554,7 +554,7 @@ def run(self, initialize=True, do_plot=False, verbose=None, **kwargs):

# Perform calculations on results
self.compute_doubling()
# self.compute_r_eff()
self.compute_r_eff()
self.likelihood()

# Tidy up
@@ -565,8 +565,9 @@ def run(self, initialize=True, do_plot=False, verbose=None, **kwargs):
if do_plot:
self.plot(**kwargs)

# Convert to an odict to allow e.g. sim.people[25] later
# Convert to an odict to allow e.g. sim.people[25] later, and results to an objdict to allow e.g. sim.results.diagnoses
self.people = sc.odict(self.people)
self.results = sc.objdict(self.results)

return self.results

@@ -600,9 +601,36 @@ def compute_doubling(self, window=None, max_doubling_time=100):


def compute_r_eff(self):
# Effective reproductive number based on number still susceptible -- TODO: use data instead
# self.results['r_eff'][t] = self.calculated['r_0']*self.results['n_susceptible'][t]/self['n']
raise NotImplementedError
''' Effective reproductive number based on number still susceptible -- TODO: use data instead '''

# Initialize arrays to hold sources and targets infected each day
sources = np.zeros(self.npts)
targets = np.zeros(self.npts)

# Loop over each person to pull out the transmission
for person in self.people.values():
if person.date_exposed is not None: # Skip people who were never exposed
if person.date_recovered is not None:
outcome_date = person.date_recovered
elif person.date_died is not None:
outcome_date = person.date_died
else:
errormsg = f'No outcome (death or recovery) can be determined for the following person:\n{person}'
raise ValueError(errormsg)

if outcome_date is not None and outcome_date<self.npts:
outcome_date = int(outcome_date)
sources[outcome_date] += 1
targets[outcome_date] += len(person.infected)
else:
# print(f'Person {person.uid} is NOT exposed')
pass

# Populate the array -- to avoid divide-by-zero, skip indices that are 0
inds = sc.findinds(sources>0)
r_eff = targets[inds]/sources[inds]
self.results['r_eff'].values[inds] = r_eff
return


def likelihood(self, verbose=None):
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
sciris>=0.16.3
sciris>=0.16.4
scirisweb>=0.16.0
matplotlib>=2.2.2
numpy>=1.10.1

0 comments on commit c407adb

Please sign in to comment.