def __init__(self, school, sim):
        self.school = school

        zero_vec = [0] * sim.npts

        ppl = sim.people
        pop_scale = sim.pars['pop_scale']
        student_uids = cv.itruei(ppl.student_flag, self.school.uids)
        teacher_uids = cv.itruei(ppl.teacher_flag, self.school.uids)
        staff_uids = cv.itruei(ppl.staff_flag, self.school.uids)

        self.num_school_days = 0

        self.num = {
            'students': len(student_uids) * pop_scale,
            'teachers': len(teacher_uids) * pop_scale,
            'staff': len(staff_uids) * pop_scale,
        }

        # Initialize results arrays
        base_result = {
            key: sc.dcp(zero_vec)
            for key in ['students', 'teachers', 'staff']
        }
        self.infectious = sc.dcp(base_result)
        self.infectious_arrive_at_school = sc.dcp(base_result)
        self.infectious_stay_at_school = sc.dcp(base_result)
        self.newly_exposed = sc.dcp(base_result)
        self.scheduled = sc.dcp(base_result)
        self.in_person = sc.dcp(base_result)
    def __init__(self, school, testing, sim):
        ''' Initialize testing. '''

        self.school = school
        self.testing = [] if testing is None else sc.dcp(testing)

        for test in self.testing:
            if 'is_antigen' not in test:
                test['is_antigen'] = False

        self.n_tested = {'PCR': 0, 'Antigen': 0}

        for test in self.testing:
            # Determine from test start_day and repeat which sim times to test on
            start_t = sim.day(test['start_date'])
            if test['repeat'] == None:
                # Easy - one time test
                test['t_vec'] = [start_t]
            else:
                test['t_vec'] = list(
                    range(start_t, sim.pars['n_days'], test['repeat']))

            # Determine uids to include
            uids = []
            ppl = sim.people
            if 'students' in test['groups']:
                uids.append(cv.itruei(ppl.student_flag, self.school.uids))
            if 'staff' in test['groups']:
                uids.append(cv.itruei(ppl.staff_flag, self.school.uids))
            if 'teachers' in test['groups']:
                uids.append(cv.itruei(ppl.teacher_flag, self.school.uids))
            test['uids'] = np.concatenate(uids)
    def antigen_test(self,
                     inds,
                     sym7d_sens=1.0,
                     other_sens=1.0,
                     specificity=1,
                     loss_prob=0.0,
                     sim=None):
        '''
        Adapted from the test() method on sim.people to do antigen testing. Main change is that sensitivity is now broken into those symptomatic in the past week and others.

        Args:
            inds: indices of who to test
            sym7d_sens (float): probability of a true positive in a recently symptomatic individual (7d)
            other_sens (float): probability of a true positive in others
            loss_prob (float): probability of loss to follow-up
            delay (int): number of days before test results are ready
        '''

        ppl = sim.people
        t = sim.t

        inds = np.unique(inds)
        # Antigen tests don't count towards stats (yet)
        #ppl.tested[inds] = True
        #ppl.date_tested[inds] = t # Only keep the last time they tested
        #ppl.date_results[inds] = t + delay # Keep date when next results will be returned

        is_infectious_not_dx = cv.itruei(ppl.infectious * ~ppl.diagnosed, inds)
        symp = cv.itruei(ppl.symptomatic, is_infectious_not_dx)
        recently_symp_inds = symp[t - ppl.date_symptomatic[symp] < 7]

        other_inds = np.setdiff1d(is_infectious_not_dx, recently_symp_inds)

        is_inf_pos = np.concatenate((
            cv.binomial_filter(
                sym7d_sens,
                recently_symp_inds),  # Higher sensitivity for <7 days
            cv.binomial_filter(other_sens,
                               other_inds)  # Lower sensitivity of otheres
        ))

        not_lost = cv.n_binomial(1.0 - loss_prob, len(is_inf_pos))
        true_positive_uids = is_inf_pos[not_lost]

        # Store the date the person will be diagnosed, as well as the date they took the test which will come back positive
        # Not for antigen tests?  date_diagnosed would interfere with later PCR.
        #ppl.date_diagnosed[true_positive_uids] = t + delay
        #ppl.date_pos_test[true_positive_uids] = t

        # False positivies
        if specificity < 1:
            non_infectious_uids = np.setdiff1d(inds, is_infectious_not_dx)
            false_positive_uids = cv.binomial_filter(1 - specificity,
                                                     non_infectious_uids)
        else:
            false_positive_uids = np.empty(0, dtype=np.int64)

        # At low prevalence, true_positive_uids will likely outnumber false_positive_uids
        return np.concatenate((true_positive_uids, false_positive_uids))
 def __init__(self, sim, uids, layer):
     super().__init__(uids, layer)
     self.students = cv.itruei(sim.people.student_flag, self.uids)
     self.staff = cv.itruei(sim.people.staff_flag, self.uids)
     self.teachers = cv.itruei(sim.people.teacher_flag, self.uids)
     self.A_base_layer, self.B_base_layer = self.split_layer()
     self.schedule = {
         'Monday': 'A',
         'Tuesday': 'A',
         'Wednesday': 'distance',
         'Thursday': 'B',
         'Friday': 'B',
         'Saturday': 'weekend',
         'Sunday': 'weekend',
     }
Exemplo n.º 5
0
def test_indexing():

    # Definitions
    farr = np.array([1.5, 0, 0, 1, 1, 0])  # Float array
    barr = np.array(farr, dtype=bool)  # Boolean array
    darr = np.array([0, np.nan, 1, np.nan, 0,
                     np.nan])  # Defined/undefined array
    inds = np.array([0, 10, 20, 30, 40, 50])  # Indices
    inds2 = np.array([1, 2, 3, 4])  # Skip first and last index

    # Test true, false, defined, and undefined
    assert cv.true(farr).tolist() == [0, 3, 4]
    assert cv.false(farr).tolist() == [1, 2, 5]
    assert cv.defined(darr).tolist() == [0, 2, 4]
    assert cv.undefined(darr).tolist() == [1, 3, 5]

    # Test with indexing
    assert cv.itrue(barr, inds).tolist() == [0, 30, 40]
    assert cv.ifalse(barr, inds).tolist() == [10, 20, 50]
    assert cv.idefined(darr, inds).tolist() == [0, 20, 40]
    assert cv.iundefined(darr, inds).tolist() == [10, 30, 50]

    # Test with double indexing
    assert cv.itruei(barr, inds2).tolist() == [3, 4]
    assert cv.ifalsei(barr, inds2).tolist() == [1, 2]
    assert cv.idefinedi(darr, inds2).tolist() == [2, 4]
    assert cv.iundefinedi(darr, inds2).tolist() == [1, 3]

    return
Exemplo n.º 6
0
    def initialize(self, sim):
        ''' Find the schools and seed infections '''
        for st in self.s_types:
            self.school_ids[st] = sim.people.school_types[st]
            for sid in self.school_ids[st]:
                sch_uids = np.array(sim.people.schools[sid])
                if self.choose_students:
                    s_uids = cv.itruei(sim.people.student_flag, sch_uids)
                else:
                    s_uids = sch_uids
                choices = cv.choose(len(s_uids), self.n_infections)
                self.seed_inds[st] += s_uids[choices].tolist()

        return
    def update(self, sim):
        ''' Called on each day to update school statistics '''

        t = sim.t
        ppl = sim.people
        rescale = sim.rescale_vec[t]

        if self.school.ct_mgr.school_day:
            self.num_school_days += 1

        student_uids = cv.itruei(ppl.student_flag, self.school.uids)
        teacher_uids = cv.itruei(ppl.teacher_flag, self.school.uids)
        staff_uids = cv.itruei(ppl.staff_flag, self.school.uids)

        infectious_ids = {}
        for group, ids in zip(['students', 'teachers', 'staff'],
                              [student_uids, teacher_uids, staff_uids]):
            infectious_ids[group] = cv.true(ppl.infectious[ids])
            self.infectious[group][t] = len(infectious_ids[group]) * rescale
            self.newly_exposed[group][t] = len(
                cv.true(ppl.date_exposed[ids] == t - 1)) * rescale
            self.scheduled[group][t] = len(
                np.intersect1d(self.school.scheduled_uids,
                               ids)) * rescale  # Scheduled
            self.in_person[group][t] = len(
                np.intersect1d(self.school.uids_passed_screening,
                               ids)) * rescale  # Post-screening

        # Tracing statistics to compare against previous work:
        # if len(self.school.uids_arriving_at_school) > 0:
        #     school_infectious = cv.itrue(ppl.infectious[self.school.uids_arriving_at_school], self.school.uids_arriving_at_school)
        # else:
        #     school_infectious = np.empty(0, dtype='int64')

        # Options here: (TODO - avoid code replication)
        # 1. Use ids of students who arrived as school (pre-screening): self.school.uids_arriving_at_school (pre-screening)
        # 2. Use ids of students who passed screening: self.school.uids_passed_screening
        # First "infectious_arrive_at_school" assumes there is a transmission risk even pre-screening (e.g. bus)

        n_students_at_school = len(
            cv.itruei(ppl.student_flag * ppl.infectious,
                      self.school.uids_arriving_at_school))
        n_teachers_at_school = len(
            cv.itruei(ppl.teacher_flag * ppl.infectious,
                      self.school.uids_arriving_at_school))
        n_staff_at_school = len(
            cv.itruei(ppl.staff_flag * ppl.infectious,
                      self.school.uids_arriving_at_school))
        for group, count in zip(
            ['students', 'teachers', 'staff'],
            [n_students_at_school, n_teachers_at_school, n_staff_at_school]):
            self.infectious_arrive_at_school[group][t] = count * rescale

        # Second "infectious_stay_at_school" effectively assumes "screen-positive" kids would be kept home from school in the first place
        n_students_passedscreening = len(
            cv.itruei(ppl.student_flag * ppl.infectious,
                      self.school.uids_passed_screening))
        n_teachers_passedscreening = len(
            cv.itruei(ppl.teacher_flag * ppl.infectious,
                      self.school.uids_passed_screening))
        n_staff_passedscreening = len(
            cv.itruei(ppl.staff_flag * ppl.infectious,
                      self.school.uids_passed_screening))
        for group, count in zip(['students', 'teachers', 'staff'], [
                n_students_passedscreening, n_teachers_passedscreening,
                n_staff_passedscreening
        ]):
            self.infectious_stay_at_school[group][t] = count * rescale