def test_createNetworkOfPopulation_transition_to_exposed(data_api): progression = pd.DataFrame([ { "age": "70+", "src": "A", "dst": "E", "rate": 0.7 }, { "age": "70+", "src": "A", "dst": "A", "rate": 0.3 }, { "age": "70+", "src": "E", "dst": "E", "rate": 1.0 }, ]) population = pd.DataFrame([ { "Health_Board": "S08000016", "Sex": "Female", "Age": "70+", "Total": 31950 }, ]) commutes = pd.DataFrame([{ "source": "S08000015", "target": "S08000015", "weight": 100777.0, "delta_adjustment": 1.0 }]) mixingMatrix = pd.DataFrame([{ "source": "70+", "target": "70+", "mixing": 1.0 }]) with pytest.raises(AssertionError): np.createNetworkOfPopulation( progression, population, commutes, mixingMatrix, data_api.read_table("human/infectious-compartments"), data_api.read_table("human/infection-probability"), data_api.read_table("human/initial-infections"), data_api.read_table("human/trials"), )
def test_basicSimulationInternalAgeStructure_invalid_compartment(data_api): with pytest.raises(AssertionError): np.createNetworkOfPopulation( data_api.read_table("human/compartment-transition"), data_api.read_table("human/population"), data_api.read_table("human/commutes"), data_api.read_table("human/mixing-matrix"), pd.DataFrame([{ "Compartment": "INVALID" }]), data_api.read_table("human/infection-probability"), data_api.read_table("human/initial-infections"), data_api.read_table("human/trials"), )
def test_basic_simulation_stochastic(data_api_stochastic): network, _ = np.createNetworkOfPopulation( data_api_stochastic.read_table("human/compartment-transition", "compartment-transition"), data_api_stochastic.read_table("human/population", "population"), data_api_stochastic.read_table("human/commutes", "commutes"), data_api_stochastic.read_table("human/mixing-matrix", "mixing-matrix"), data_api_stochastic.read_table("human/infectious-compartments", "infectious-compartments"), data_api_stochastic.read_table("human/infection-probability", "infection-probability"), data_api_stochastic.read_table("human/initial-infections", "initial-infections"), data_api_stochastic.read_table("human/trials", "trials"), data_api_stochastic.read_table("human/start-end-date", "start-end-date"), data_api_stochastic.read_table("human/movement-multipliers", "movement-multipliers"), data_api_stochastic.read_table("human/stochastic-mode", "stochastic-mode"), ) seed = loaders.readRandomSeed( data_api_stochastic.read_table("human/random-seed", "random-seed")) result, issues = np.basicSimulationInternalAgeStructure( network, {"S08000016": { "[17,70)": 10 }}, numpy.random.default_rng(seed)) _assert_baseline_dataframe(result) assert not issues
def test_basic_simulation_with_dampening(data_api): network, _ = np.createNetworkOfPopulation( data_api.read_table("human/compartment-transition", "compartment-transition"), data_api.read_table("human/population", "population"), data_api.read_table("human/commutes", "commutes"), data_api.read_table("human/mixing-matrix", "mixing-matrix"), data_api.read_table("human/infectious-compartments", "infectious-compartments"), data_api.read_table("human/infection-probability", "infection-probability"), data_api.read_table("human/initial-infections", "initial-infections"), data_api.read_table("human/trials", "trials"), data_api.read_table("human/start-end-date", "start-end-date"), data_api.read_table("human/movement-multipliers", "movement-multipliers"), ) df, issues = np.basicSimulationInternalAgeStructure( network, {"S08000016": { "[17,70)": 10.0 }}, numpy.random.default_rng(123)) result = calculateInfectiousOverTime(df, network.infectiousStates) _assert_baseline(result) assert not issues
def test_basic_simulation_100_runs(data_api): network, _ = np.createNetworkOfPopulation( data_api.read_table("human/compartment-transition", "compartment-transition"), data_api.read_table("human/population", "population"), data_api.read_table("human/commutes", "commutes"), data_api.read_table("human/mixing-matrix", "mixing-matrix"), data_api.read_table("human/infectious-compartments", "infectious-compartments"), data_api.read_table("human/infection-probability", "infection-probability"), data_api.read_table("human/initial-infections", "initial-infections"), data_api.read_table("human/trials", "trials"), data_api.read_table("human/start-end-date", "start-end-date"), ) runs = [] rand = random.Random(1) issues = [] for _ in range(100): regions = rand.choices(list(network.graph.nodes()), k=1) assert network.initialState[regions[0]][("[17,70)", "E")] == 0 df, new_issues = np.basicSimulationInternalAgeStructure( network, {regions[0]: { "[17,70)": 10.0 }}, numpy.random.default_rng(123)) result = calculateInfectiousOverTime(df, network.infectiousStates) result.pop( ) # TODO: due to historical reasons we have to ignore the last entry runs.append(result) issues.extend(new_issues) result = common.generateMeanPlot(runs) _assert_baseline(result) assert not issues
def test_createNetworkOfPopulation_invalid_infection_probability( data_api, time, prob): with pytest.raises(ValueError): np.createNetworkOfPopulation( data_api.read_table("human/compartment-transition"), data_api.read_table("human/population"), data_api.read_table("human/commutes"), data_api.read_table("human/mixing-matrix"), data_api.read_table("human/infectious-compartments"), pd.DataFrame([{ "Time": time, "Value": prob }]), data_api.read_table("human/initial-infections"), data_api.read_table("human/trials"), )
def test_basicSimulationInternalAgeStructure_no_infection_prob(data_api): network = np.createNetworkOfPopulation( data_api.read_table("human/compartment-transition"), data_api.read_table("human/population"), data_api.read_table("human/commutes"), data_api.read_table("human/mixing-matrix"), data_api.read_table("human/infectious-compartments"), pd.DataFrame([{ "Time": 0, "Value": 0.0 }]), data_api.read_table("human/initial-infections"), data_api.read_table("human/trials"), ) susceptibles = 0.0 for region in network.initialState.values(): for (age, state) in region.keys(): if state == "S": susceptibles += region[(age, state)] people_to_infect = 30 result = np.basicSimulationInternalAgeStructure( network, 50, {"S08000024": { "[0,17)": people_to_infect }}) new_susceptibles = result[(result.time == result.time.max()) & (result.state == "S")].total.sum() assert new_susceptibles + people_to_infect == susceptibles
def test_basicSimulationInternalAgeStructure_no_movement_of_people_invariants( data_api, region, num_infected): network = np.createNetworkOfPopulation( data_api.read_table("human/compartment-transition"), data_api.read_table("human/population"), data_api.read_table("human/commutes"), data_api.read_table("human/mixing-matrix"), data_api.read_table("human/infectious-compartments"), data_api.read_table("human/infection-probability"), data_api.read_table("human/initial-infections"), data_api.read_table("human/trials"), pd.DataFrame([{ "Time": 0, "Movement_Multiplier": 0.0, "Contact_Multiplier": 1.0 }]), ) initial_population = sum(_count_people_per_region(network.initialState)) old_network = copy.deepcopy(network) result = np.basicSimulationInternalAgeStructure( network, 50, {region: { "[0,17)": num_infected }}) # population remains constant populations = result.groupby("time").total.sum() assert all([ total == pytest.approx(initial_population) for node, total in populations.to_dict().items() ]) # the graph is unchanged assert nx.is_isomorphic(old_network.graph, network.graph) # infection matrix is unchanged assert list(network.mixingMatrix) == list(old_network.mixingMatrix) for a in network.mixingMatrix: assert list(network.mixingMatrix[a]) == list( old_network.mixingMatrix[a]) for b in network.mixingMatrix[a]: assert network.mixingMatrix[a][b] == old_network.mixingMatrix[a][b] # no spread across regions assert result[(result.node != region) & ( result.state.isin(network.infectiousStates))].total.sum() == 0.0
def test_basicSimulationInternalAgeStructure_no_infection_prob_before_time_25( data_api): def count_susceptibles(state): susceptibles = 0.0 for region in state.values(): for (age, state) in region.keys(): if state == "S": susceptibles += region[(age, state)] return susceptibles network = np.createNetworkOfPopulation( data_api.read_table("human/compartment-transition"), data_api.read_table("human/population"), data_api.read_table("human/commutes"), data_api.read_table("human/mixing-matrix"), data_api.read_table("human/infectious-compartments"), pd.DataFrame([{ "Time": 0, "Value": 0.0 }, { "Time": 25, "Value": 1.0 }]), data_api.read_table("human/initial-infections"), data_api.read_table("human/trials"), ) people_to_infect = 30 susceptibles = count_susceptibles(network.initialState) - people_to_infect result = np.basicSimulationInternalAgeStructure( network, 50, {"S08000024": { "[0,17)": people_to_infect }}) # no infection before time 25 for total in result[(result.time < 25) & (result.state == "S")].groupby( "time").total.sum().to_list(): assert total == susceptibles # infections happen after time 25 for total in result[(result.time >= 25) & (result.state == "S")].groupby( "time").total.sum().to_list(): assert total != susceptibles
def test_basic_simulation(data_api): network = np.createNetworkOfPopulation( data_api.read_table("human/compartment-transition"), data_api.read_table("human/population"), data_api.read_table("human/commutes"), data_api.read_table("human/mixing-matrix"), data_api.read_table("human/infectious-compartments"), data_api.read_table("human/infection-probability"), data_api.read_table("human/initial-infections"), data_api.read_table("human/trials"), ) result = calculateInfectiousOverTime( np.basicSimulationInternalAgeStructure( network, 200, {"S08000016": { "[17,70)": 10.0 }}), network.infectiousStates) _assert_baseline(result)
def test_basic_simulation_stochastic(data_api_stochastic): network = np.createNetworkOfPopulation( data_api_stochastic.read_table("human/compartment-transition"), data_api_stochastic.read_table("human/population"), data_api_stochastic.read_table("human/commutes"), data_api_stochastic.read_table("human/mixing-matrix"), data_api_stochastic.read_table("human/infectious-compartments"), data_api_stochastic.read_table("human/infection-probability"), data_api_stochastic.read_table("human/initial-infections"), data_api_stochastic.read_table("human/trials"), data_api_stochastic.read_table("human/movement-multipliers"), data_api_stochastic.read_table("human/stochastic-mode"), data_api_stochastic.read_table("human/random-seed")) result = np.basicSimulationInternalAgeStructure( network, 200, {"S08000016": { "[17,70)": 10 }}) _assert_baseline_dataframe(result)
def test_createNetworkOfPopulation(data_api): network = np.createNetworkOfPopulation( data_api.read_table("human/compartment-transition"), data_api.read_table("human/population"), data_api.read_table("human/commutes"), data_api.read_table("human/mixing-matrix"), data_api.read_table("human/infectious-compartments"), data_api.read_table("human/infection-probability"), data_api.read_table("human/initial-infections"), data_api.read_table("human/trials"), ) assert network.graph assert network.mixingMatrix assert network.initialState assert network.progression assert network.movementMultipliers == {} assert set(network.infectiousStates) == {"I", "A"} assert network.infectionProb == {0: 1.0} assert network.initialInfections == {"S08000016": {"[17,70)": 100}} assert network.trials == 1
def test_randomlyInfectRegions(data_api, regions, age_groups, infected): network = np.createNetworkOfPopulation( data_api.read_table("human/compartment-transition"), data_api.read_table("human/population"), data_api.read_table("human/commutes"), data_api.read_table("human/mixing-matrix"), data_api.read_table("human/infectious-compartments"), data_api.read_table("human/infection-probability"), data_api.read_table("human/initial-infections"), data_api.read_table("human/trials"), ) random.seed(3) infections = np.randomlyInfectRegions(network, regions, age_groups, infected) assert len(infections) == regions assert list(age_groups[0] in infection for infection in infections.values()) assert all(infection[age_groups[0]] == infected for infection in infections.values())
def test_stochastic_seed_sequence(data_api_stochastic): network, _ = network_of_populations.createNetworkOfPopulation( data_api_stochastic.read_table("human/compartment-transition", "compartment-transition"), data_api_stochastic.read_table("human/population", "population"), data_api_stochastic.read_table("human/commutes", "commutes"), data_api_stochastic.read_table("human/mixing-matrix", "mixing-matrix"), data_api_stochastic.read_table("human/infectious-compartments", "infectious-compartments"), data_api_stochastic.read_table("human/infection-probability", "infection-probability"), data_api_stochastic.read_table("human/initial-infections", "initial-infections"), pd.DataFrame({"Value": [2]}), data_api_stochastic.read_table("human/start-end-date", "start-end-date"), data_api_stochastic.read_table("human/movement-multipliers", "movement-multipliers"), pd.DataFrame({"Value": [True]}), ) issues = [] r1, r2 = sampleUseOfModel.runSimulation(network, random_seed=123, issues=issues, max_workers=2) df1 = r1.output df2 = r2.output # It's very unlikely these numbers would match unless both runs produce the same numbers assert df1[df1.state == "D"].total.sum() != df2[df2.state == "D"].total.sum() assert not issues
def test_basicSimulationInternalAgeStructure_no_node_infection_invariant( data_api, num_infected): nodes = pd.DataFrame([{ "source": "S08000016", "target": "S08000016", "weight": 0.0, "delta_adjustment": 1.0 }]) population = pd.DataFrame([ { "Health_Board": "S08000016", "Sex": "Female", "Age": "[0,17)", "Total": 31950 }, { "Health_Board": "S08000016", "Sex": "Female", "Age": "[17,70)", "Total": 31950 }, { "Health_Board": "S08000016", "Sex": "Female", "Age": "70+", "Total": 31950 }, ]) dampening = pd.DataFrame([{ "Time": 0, "Movement_Multiplier": 1.0, "Contact_Multiplier": 0.0 }]) network = np.createNetworkOfPopulation( data_api.read_table("human/compartment-transition"), population, nodes, data_api.read_table("human/mixing-matrix"), data_api.read_table("human/infectious-compartments"), data_api.read_table("human/infection-probability"), data_api.read_table("human/initial-infections"), data_api.read_table("human/trials"), dampening, ) initial_population = sum(_count_people_per_region(network.initialState)) result = np.basicSimulationInternalAgeStructure( network, 50, {"S08000016": { "[17,70)": num_infected }}) # population remains constant populations = result.groupby("time").total.sum() assert all([ total == pytest.approx(initial_population) for node, total in populations.to_dict().items() ]) # susceptibles are never infected for total in result[result.state == "S"].groupby( "time").total.sum().to_list(): assert total == 3 * 31950 - num_infected