Exemple #1
0
def test_class_Collector():
    """tests to ensure the behaviour class Collector"""
    from_inits = [20, 30, 40]
    to_init = int(np.sum(from_inits))

    for itest in range(2):

        from_pops = [Population('from_pop_' + str(i), from_inits[i]) for i in range(len(from_inits))]
        to_pop = Population('to_pop', to_init)

        if itest == 0:
            test_collector = Collector('test_add', from_pops, to_pop)
            from_futures = [5.1, -3.4, 17.8]

            for i in range(len(from_inits)):
                from_pops[i].future = [from_futures[i]]

            test_collector.update_expectation()
            assert to_pop.future[0] == np.sum(from_futures)

        if itest == 1:
            test_collector = Collector('test_add', from_pops, to_pop)
            from_futures = [5, -3, 17]

            for i in range(len(from_inits)):
                from_pops[i].future = [from_futures[i]]

            test_collector.update_data()
            assert to_pop.future[0] == np.sum(from_futures)
Exemple #2
0
def test_class_Subtractor():
    """tests to ensure the behaviour class Subtractor"""
    from_init = 20
    to_init = 10
    from_pop = Population('from_pop', from_init)
    to_pop = Population('to_pop', to_init)
    to_next = 40
    to_pop.future = [to_next]
    test_subtractor = Subtractor('test_sub', from_pop, to_pop)
    test_subtractor.update_expectation()
    assert from_pop.future[0] == -1 * to_next
Exemple #3
0
def test_class_Adder():
    """tests to ensure the behaviour class Adder"""
    for itest in range(6):
        from_init = 5
        to_init = 10
        f_over_t = 1.*from_init/to_init
        from_pop = Population('from_pop', from_init)
        from_next = 40
        from_pop.future = [from_next]
        to_pop = Population('to_pop', to_init)
        if itest == 0:
            test_adder = Adder('test_add', from_pop, to_pop)
            test_adder.update_expectation()
            assert to_pop.future[0] == from_next
        elif itest == 1:
            sf = 0.2
            scale_factor = Parameter('scale_factor', sf, 0., 10.)
            test_adder = Adder('test_add', from_pop, to_pop, scale_factor=scale_factor)
            test_adder.update_expectation()
            assert to_pop.future[0] == from_next * sf
        elif itest == 2:
            sf = 0.3
            ratio_pops = [from_pop, to_pop]
            scale_factor = Parameter('scale_factor', sf, 0., 10.)
            test_adder = Adder('test_add', from_pop, to_pop, scale_factor=scale_factor, ratio_populations=ratio_pops)
            test_adder.update_expectation()
            assert to_pop.future[0] == from_next * sf * f_over_t
        elif itest == 3:
            sf = 0.3
            ratio_pops = [from_pop, to_pop]
            scale_factor = Parameter('scale_factor', sf, 0, 10.)
            test_adder = Adder('test_add', from_pop, to_pop, scale_factor=scale_factor, ratio_populations=ratio_pops)
            test_adder.update_data()
            prob = sf * f_over_t
            sigma = np.sqrt(from_next*prob*(1-prob))
            assert np.abs(to_pop.future[0] - from_next * sf * f_over_t)<3.*sigma
        elif itest == 4:
            sf = 0.31
            ratio_pops = [from_pop, to_pop]
            scale_factor = Parameter('scale_factor', sf, 0., 10.)
            test_adder = Adder('test_add', from_pop, to_pop, scale_factor=scale_factor, ratio_populations=ratio_pops)
            test_adder.update_data()
            assert np.abs(to_pop.future[0] - from_next * sf * f_over_t)<3.*sigma
        elif itest == 5:
            sf = 0.31
            r1 = Parameter('r1', sf/3., parameter_min=1., parameter_max=100.)
            r2 = Parameter('r2', 3., parameter_min=1., parameter_max=100.)
            ratio_pops = [from_pop, to_pop]
            # scale_factor = Parameter('scale_factor', sf, 0., 10.)
            scale_factor = Operator([r1,r2],'*')
            test_adder = Adder('test_add', from_pop, to_pop, scale_factor=scale_factor, ratio_populations=ratio_pops)
            test_adder.update_data()
            assert to_pop.future[0] >= from_next * int(sf) * f_over_t
Exemple #4
0
def test_class_Injector():
    """tests to ensure the behaviour class Injector"""
    test_model = Model('test_model')
    number = 50.
    inject = Parameter('inject', number, parameter_min=0., parameter_max=1000.)
    time = 5
    trans_time = Parameter('time', time, parameter_type='int', parameter_min=0, parameter_max=1000)
    to_pop = Population('to_pop', 0)
    test_injector = Injector('injector', 'rel_days', trans_time, to_pop, inject, model=test_model)
    test_model.add_transition(test_injector)
    for time_step in [1., 1. / 4.]:
        test_model.set_time_step(time_step)
        to_pop.reset()
        test_injector.take_action()
        assert to_pop.future[0] == number
        assert np.abs(test_injector.trigger_step - time / time_step) < 0.1
Exemple #5
0
def test_class_Splitter():
    """tests to ensure the behaviour class Splitter"""
    test_model = Model('test_model')
    start = 100000
    from_pop = Population('from_pop', 0)
    from_pop.future = [start]
    to_pops = [Population('to_pop1', 0.), Population('to_pop2', 0.)]
    fracs = [0.4, 0.6]
    fraction = Parameter('frac', fracs[0])
    mean = 10.
    std_dev = 4.
    delay_pars = {
        'mean': Parameter('mean', mean, parameter_min=-100., parameter_max=100.),
        'sigma': Parameter('sigma', std_dev, parameter_min=-100., parameter_max=100.)
    }
    test_delay = Delay('test_delay', 'norm', delay_parameters=delay_pars, model=test_model)

    test_split = Splitter('test_prop', from_pop, to_pops, [fraction], test_delay)
    test_model.add_connector(test_split)
    for time_step in [1., 1. / 4.]:
        test_model.set_time_step(time_step)
        for func in [test_split.update_expectation, test_split.update_data]:
            EPS = 0.01
            if func == test_split.update_data:
                EPS = 0.1
            to_pops[0].reset()
            to_pops[1].reset()
            func()
            total = 0
            for i in range(2):
                distribution = to_pops[i].future
                frac = fracs[i]
                sum_p = 0.
                sum_tp = 0.
                sum_ttp = 0.
                for i in range(len(distribution)):
                    sum_p += distribution[i]
                    sum_tp += i * distribution[i] * time_step
                    sum_ttp += i * i * distribution[i] * time_step ** 2
                total += sum_p
                assert np.abs(sum_p - start * frac) < EPS * start * frac
                est_mean = sum_tp / (start * frac)
                assert np.abs(est_mean - mean) < EPS * mean
                est_sigma = np.sqrt(sum_ttp / (start * frac) - est_mean ** 2)
                assert np.abs(est_sigma - std_dev) < EPS * std_dev
            assert np.abs(total - start) < 0.1
Exemple #6
0
def test_class_Propagator():
    """tests to ensure the behaviour class Propagator"""
    test_model = Model('test_model')
    start = 100000
    from_pop = Population('from_pop', 0)
    from_pop.future = [start]
    to_pop = Population('to_pop', 0.)
    frac = 0.4
    fraction = Parameter('frac', frac)
    mean = 10.
    std_dev = 4.
    delay_pars = {
        'mean': Parameter('mean', mean, parameter_min=-100., parameter_max=100.),
        'sigma': Parameter('sigma', std_dev, parameter_min=-100., parameter_max=100.)
    }
    test_delay = Delay('test_delay', 'norm', delay_parameters=delay_pars, model=test_model)

    test_prop = Propagator('test_prop', from_pop, to_pop, fraction, test_delay)
    test_model.add_connector(test_prop)
    for time_step in [1., 1. / 4.]:
        test_model.set_time_step(time_step)
        for func in [test_prop.update_expectation, test_prop.update_data]:
            EPS = 0.01
            if func == test_prop.update_data:
                EPS = 0.1
            to_pop.reset()
            func()
            distribution = to_pop.future
            sum_p = 0.
            sum_tp = 0.
            sum_ttp = 0.
            for i in range(len(distribution)):
                sum_p += distribution[i]
                sum_tp += i * distribution[i] * time_step
                sum_ttp += i * i * distribution[i] * time_step ** 2
            assert np.abs(sum_p - start * frac) < EPS * start * frac
            est_mean = sum_tp / (start * frac)
            assert np.abs(est_mean - mean) < EPS * mean
            est_sigma = np.sqrt(sum_ttp / (start * frac) - est_mean ** 2)
            assert np.abs(est_sigma - std_dev) < EPS * std_dev
Exemple #7
0
"""

from pypmca import Model, Population, Delay, Parameter, Multiplier, Propagator, \
    Splitter, Adder, Subtractor, Chain, Modifier, Injector

# Test by building a population model for BC

bc_model = Model('ref_model_2_8')
bc_model.set_t0(2020, 3, 1)

# Initialization

initial_pop_par = Parameter('N_0', 5000000, 5000, 50000000,
                            'Population of the region at t0', 'int')

total_pop = Population('total', initial_pop_par,
                       'total population of the region', color='black')
susceptible_pop = Population('susceptible', initial_pop_par,
                             'number of people who could become infected', color='cornflowerblue')
infected_pop = Population('infected', 0,
                          'total number of people ever infected', color='orange')

# Define the infection cycle
# oooooooooooooooooooooooooooo

initial_contagious_par = Parameter('cont_0', 10., 0., 5000.,
                                   'Number of contagious people at t0',
                                   hidden=False)

contagious_pop = Population('contagious', initial_contagious_par,
                            'number of people that can cause someone to become infected',
                            hidden=False, color='red')
Exemple #8
0
"""

from pypmca import Model, Population, Delay, Parameter, Multiplier, Propagator, \
    Splitter, Adder, Subtractor, Chain, Modifier, Injector

# Test by building a population model for BC

bc_model = Model('ref_model_1')
bc_model.set_t0(2020, 3, 1)

# Initialization

initial_pop_par = Parameter('N_0', 5000000, 5000, 50000000,
                            'Population of the region at t0', 'int')

total_pop = Population('total', initial_pop_par,
                       'total population of the region', color='black')
susceptible_pop = Population('susceptible', initial_pop_par,
                             'number of people who could become infected', color='cornflowerblue')
infected_pop = Population('infected', 0,
                          'total number of people ever infected', color='orange')

# Define the infection cycle
# oooooooooooooooooooooooooooo

initial_contagious_par = Parameter('cont_0', 55., 0., 5000.,
                                   'Number of contagious people at t0',
                                   hidden=False)

contagious_pop = Population('contagious', initial_contagious_par,
                            'number of people that can cause someone to become infected',
                            hidden=False, color='red')
Exemple #9
0
from pypmca import Model, Population, Delay, Parameter, Multiplier, Propagator, \
    Splitter, Adder, Subtractor, Chain, Modifier, Injector

# Test by building a population model for BC

bc_model = Model('ref_model_2_4')
bc_model.set_t0(2020, 3, 1)

# Initialization

initial_pop_par = Parameter('N_0', 5000000, 5000, 50000000,
                            'Population of the region at t0', 'int')

total_pop = Population('total',
                       initial_pop_par,
                       'total population of the region',
                       color='black')
susceptible_pop = Population('susceptible',
                             initial_pop_par,
                             'number of people who could become infected',
                             color='cornflowerblue')
infected_pop = Population('infected',
                          0,
                          'total number of people ever infected',
                          color='orange')

# Define the infection cycle
# oooooooooooooooooooooooooooo

initial_contagious_par = Parameter('cont_0',
                                   10.,
Exemple #10
0
    def __init__(self, name: str, model):
        """Constructor
         - Model specifies the reference model: populations etc should match those in
         the ensemble of models. It can be specified as a model, or as a filename
        """
        super().__init__(name)

        self.model = None
        in_model = None
        if isinstance(model, Model):
            in_model = model
        elif isinstance(model, str):
            in_model = Model.open_file(model)
        else:
            raise TypeError(
                'Error creating ensemble. The model argument needs to be a model object '
                + 'or have a .pypm filename')

        # to avoid the possibility that the reference model is subsequently modified, make a copy
        # that will not be as exposed to tampering
        self.model = copy.deepcopy(in_model)

        # point to the population objects in self.model to save the histories
        # this allows for consistent access to history between models and ensembles
        for pop_name in self.model.populations:
            pop = self.model.populations[pop_name]
            self.populations[pop_name] = pop

        # the parameters will be set once the list of models are read in
        self.parameters = {}

        # the boot parameters point to the ones copied from the reference
        self.boot_pars = self.model.boot_pars

        # the important scaling parameter for the ensemble gets defined here
        # this is forced to be a parameter when each model is created and
        # checked when the models are included in the ensemble

        boot_pop = self.populations[self.boot_pars['boot_population']]
        boot_pop_ip = boot_pop.initial_value
        self.parameters[boot_pop_ip.name] = boot_pop_ip
        # When this scaling parameter is changed, all the model scaling parameters
        # must also be scaled accordingly.
        boot_pop_ip.set_must_update(self)

        # The list of models (either provided directly or as a list of .pypm files)
        # They are required to have unique names for user interaction
        # Ordering is preserved to match the transmission matrix
        self.model_list = []
        self.models = {}
        self.infected_name = None
        self.susceptible_name = None
        self.total_name = None
        self.contagious_name = None
        self.alpha_name = None
        self.infection_cycle_name = None
        self.contact = None
        self.contact_matrix = None
        self.contact_type = ''
        self.null_pop = Population('null', 0.)
        self.total_goal = None
        self.boot_achieved = {}
        self.max_scale_factor = None

        self.__distribution = None
        self.__nbinom_par = None
        self.set_distribution('poisson', None)
Exemple #11
0
def test_class_Chain():
    """tests to ensure the behaviour class Chain"""
    test_model = Model('test_model')
    from_pop = Population('from_pop', 0.)
    to_pop = Population('to_pop', 0.)
    pop_a = Population('pop_a', 0.)
    pop_b = Population('pop_b', 0.)
    start = 100000
    from_pop.future = [start]

    mean = 10.
    sigma = 2.
    delay_pars = {'mean': Parameter('mean', mean, parameter_min=0.1, parameter_max=100.),
                  'sigma': Parameter('sigma', sigma, parameter_min=0.1, parameter_max=1000.)}
    delay = Delay('delay', 'norm', delay_pars, test_model)
    frac = 0.8
    fraction = Parameter('frac', frac)
    chain = []
    chain.append(Propagator('prop_0', from_pop, pop_a, fraction, delay))
    chain.append(Propagator('prop_1', pop_a, pop_b, fraction, delay))

    test_chain = Chain('test_chain', from_pop, to_pop, chain, fraction, delay, test_model)
    test_model.add_connector(test_chain)

    for time_step in [1., 1. / 4.]:
        test_model.set_time_step(time_step)
        for func in [test_chain.update_expectation, test_chain.update_data]:
            EPS = 0.02
            if func == test_chain.update_data:
                EPS = 0.2
            to_pop.reset()
            pop_a.reset()
            pop_b.reset()
            func()
            for pop in [to_pop, pop_b]:
                distribution = pop.future
                total = start * (1. - frac ** 2) * frac
                ave = mean
                std_dev = sigma
                if pop == pop_b:
                    total = start * frac ** 2
                    ave = 2. * mean
                    std_dev = np.sqrt(2.) * sigma
                sum_p = 0.
                sum_tp = 0.
                sum_ttp = 0.
                for i in range(len(distribution)):
                    sum_p += distribution[i]
                    sum_tp += i * distribution[i] * time_step
                    sum_ttp += i * i * distribution[i] * time_step ** 2
                assert np.abs(sum_p - total) < EPS * total
                est_mean = sum_tp / total
                assert np.abs(est_mean - ave) < EPS * ave
                est_sigma = np.sqrt(sum_ttp / total - est_mean ** 2)
                assert np.abs(est_sigma - std_dev) < EPS * std_dev
Exemple #12
0
def test_class_Multiplier():
    """tests to ensure the behaviour class Multiplier"""
    test_model = Model('test_model')
    EPS = 1.
    n1 = 50.
    n2 = 20.
    n3 = 2.
    scale = 0.1
    f_pops = [Population('f1_pop', n1), Population('f2_pop', n2), Population('f3_pop', n3)]
    to_pop = Population('to_pop', 0.)
    scale_par = Parameter('alpha', scale)
    delay = Delay('fast', 'fast')
    test_multiplier = Multiplier('test_multiplier', f_pops, to_pop, scale_par, delay, model=test_model)
    test_model.add_connector(test_multiplier)
    for time_step in [1., 1. / 4.]:
        test_model.set_time_step(time_step)
        # expectation:
        expected = n1 * n2 / n3 * scale * time_step
        to_pop.reset()
        test_multiplier.set_distribution('poisson', None)
        test_multiplier.update_expectation()
        assert to_pop.future[0] == expected

        # Poisson
        n_rep = 1000
        n_list = []
        for i in range(n_rep):
            to_pop.reset()
            test_multiplier.update_data()
            n_list.append(to_pop.future[0])
        assert np.abs(np.mean(n_list) - expected) < EPS
        assert np.abs(np.std(n_list) - np.sqrt(expected)) < EPS

        # Negative binomial
        p_nb = 0.2
        nbinom_par = Parameter('nb', p_nb)
        test_multiplier.set_distribution('nbinom', nbinom_par)

        n_rep = 1000
        n_list = []
        for i in range(n_rep):
            to_pop.reset()
            test_multiplier.update_data()
            n_list.append(to_pop.future[0])
        assert np.abs(np.mean(n_list) - expected) < EPS
        assert np.abs(np.std(n_list) - np.sqrt(expected / p_nb)) < EPS
Exemple #13
0
def test_class_Population():
    """tests to ensure the behaviour class Population"""
    init_value = 100
    test_pop = Population('test population', init_value, description='For testing populations',
                          hidden=True, color='black', show_sim=False, report_noise=False,
                          report_noise_par=None)
    assert test_pop.history[0] == init_value

    model = Model.open_file(path_model_2_8)
    test_pop.set_model(model)

    incoming = 10
    test_pop.update_future_fast(incoming)
    assert test_pop.future[0] == incoming

    test_pop.do_time_step()
    assert test_pop.history[1] == init_value + incoming
    assert len(test_pop.future) == 0 or test_pop.future == 0

    scale_factor = 0.5
    test_pop.scale_history(scale_factor)
    assert test_pop.history[0] == init_value * scale_factor
    assert test_pop.history[1] == (init_value + incoming) * scale_factor

    # check that noise in reporting makes sense
    # Expectations are not effected - data should be
    # but the total reported should be the same after all reporting complete
    noise_factor = Parameter('noise_factor', 0.3)
    backlog_factor = Parameter('backlog_factor', 0.8)
    # restart - back to initial value
    for expectations in [True, False]:
        test_pop.reset()
        future = [0, 10, 100, 100, 100, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
        future_sum = np.sum(np.array(future))
        test_pop.set_report_noise(True, noise_factor, backlog_factor, None)
        test_pop.future = future
        for i in range(len(future) + 5):
            test_pop.do_time_step(expectations=expectations)
        assert test_pop.history[-1] == init_value + future_sum

    report_days = Parameter('report_days', 127, parameter_min=-7, parameter_max=127, parameter_type='int')
    for report_day_value in [127, 63, -1, -2, -5, -7]:
        report_days.set_value(report_day_value)
        test_pop.reset()
        future = [0, 10, 100, 100, 100, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
        future_sum = np.sum(np.array(future))
        test_pop.set_report_noise(True, noise_factor, backlog_factor, report_days)
        test_pop.future = future
        for i in range(len(future) + 5):
            test_pop.do_time_step(expectations=expectations)
        assert test_pop.history[-1] == init_value + future_sum