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_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_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_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_basicSimulationInternalAgeStructure_invariants( age_transitions, demographics, commute_moves, compartment_names, age_infection_matrix, num_infected, generic_infection, seed, ): age_to_trans = np.setUpParametersAges( loaders.readParametersAgeStructured(age_transitions)) population = loaders.readPopulationAgeStructured(demographics) graph = loaders.genGraphFromContactFile(commute_moves) states = np.setupInternalPopulations(graph, compartment_names, list(age_to_trans.keys()), population) old_graph = copy.deepcopy(graph) old_age_to_trans = copy.deepcopy(age_to_trans) initial_population = sum(_count_people_per_region( states[0])) + num_infected np.basicSimulationInternalAgeStructure( rand=random.Random(seed), graph=graph, numInfected=num_infected, timeHorizon=50, genericInfection=generic_infection, ageInfectionMatrix=age_infection_matrix, diseaseProgressionProbs=age_to_trans, dictOfStates=states, ) # population remains constant assert all([ sum(_count_people_per_region(state)) == pytest.approx( initial_population) for state in states.values() ]) # the graph is unchanged assert nx.is_isomorphic(old_graph, graph) # infection matrix is unchanged assert age_to_trans == old_age_to_trans
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_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
def test_basic_simulation(age_transitions, demographics, commute_moves, compartment_names, age_infection_matrix): age_to_trans = np.setUpParametersAges( loaders.readParametersAgeStructured(age_transitions)) population = loaders.readPopulationAgeStructured(demographics) graph = loaders.genGraphFromContactFile(commute_moves) states = np.setupInternalPopulations(graph, compartment_names, list(age_to_trans.keys()), population) result = np.basicSimulationInternalAgeStructure( rand=random.Random(1), graph=graph, numInfected=10, timeHorizon=200, genericInfection=0.1, ageInfectionMatrix=age_infection_matrix, diseaseProgressionProbs=age_to_trans, dictOfStates=states, ) expected = [ 0, 4.27, 5.959639, 7.495598979703686, 9.31292448442533, 11.550960285080539, 14.32076069530553, 17.750346856443436, 21.996595859880493, 27.253215606191763, 33.75958029276324, 41.81147883471944, 51.77434261313086, 64.09953959129047, 79.34443722167374, 98.19708895391234, 121.5065842268399, 150.32032333168627, 185.92974139403356, 229.92631464707316, 284.27004075722795, 351.3729944719362, 434.2010173334121, 536.3970957055917, 662.4304939975676, 817.7762023518806, 1009.1296689642635, 1244.6620222362512, 1534.3209088397605, 1890.1814875375615, 2326.8507704591293, 2861.926080186407, 3516.5045468063877, 4315.734994514654, 5289.3961276280115, 6472.475902589639, 7905.717433786824, 9636.08906655341, 11717.13446074682, 14209.16871256282, 17179.315999723975, 20701.439040274323, 24856.09052908778, 29730.707243910434, 35420.33217223618, 42029.128554931965, 49672.773024855385, 58481.44396269627, 68602.60309097261, 80202.27853153124, 93463.37789059673, 108579.96624726593, 125747.53880875603, 145150.90161910592, 166952.82966413427, 191287.47020551964, 218261.74745540041, 247965.3261465324, 280485.2367071461, 315916.38015373435, 354356.14564567205, 395872.69490304653, 440443.1364258809, 487868.5388265991, 537684.1860953799, 589091.5046792259, 640938.9095905811, 691769.9762481726, 739939.1843065555, 783772.9904113912, 821736.8679191938, 852567.1996643285, 875343.2246963251, 889499.9704796937, 894803.485637448, 891314.7525319818, 879359.4394061461, 859505.977536541, 832543.5198251844, 799448.8236543302, 761336.2708291251, 719393.6436135583, 674812.7866198674, 628726.0228195366, 582156.5631853839, 535986.5646189475, 490942.3244969345, 447593.5332414354, 406362.5717409869, 367540.01510870096, 331303.2145504978, 297735.6728639047, 266845.6949524783, 238583.40447859198, 212855.66475276518, 189538.74944848128, 168488.80761225612, 149550.28647197766, 132562.53827530914, 117364.86191178164, 103800.22980549172, 91717.93520231653, 80975.37134265121, 71439.12677319416, 62985.553271939556, 55500.93643588842, 48881.374979513224, 43032.45371205615, 37868.777124977256, 33313.415413891256, 29297.302334462536, 25758.61423633403, 22642.151601387908, 19898.738109895345, 17484.64737342592, 15361.063743396788, 13493.580801682876, 11851.739073032668, 10408.603009095552, 9140.37625068078, 8026.053473547509, 7047.106679898116, 6187.203546762776, 5431.955332005772, 4768.691828813375, 4186.260919647075, 3674.8503875840925, 3225.8297793633656, 2831.6102674926847, 2485.5206191429197, 2181.697540636489, 1914.9888235502897, 1680.8678687529227, 1475.3583061787265, 1294.9675597411838, 1136.6283280441162, 997.6470624276589, 875.6586246476982, 768.5863975872606, 674.6072044116167, 592.1204651473781, 519.721085459352, 456.1756310875024, 400.40139364220994, 351.44799986096695, 308.4812575877343, 270.76896818966605, 237.66846737351318, 208.61568486118352, 183.11553854396615, 160.73350093111426, 141.08819527652577, 123.8448960080496, 108.70982326635439, 95.42513472402354, 83.76452961376395, 73.52939023666997, 64.54539531517312, 56.65954754922215, 49.73756475976603, 43.66159017682611, 38.328182852791116, 33.64655394541582, 29.537018798984292, 25.929638426375362, 22.763027221103627, 19.98330656117008, 17.54318645356159, 15.401159551545785, 13.520793793496033, 11.870111594347737, 10.42104499749586, 9.148957491085977, 8.032224330272163, 7.051864205475331, 6.191215972979529, 5.435654933281273, 4.7723438175693484, 4.1900142350687, 3.678774853837169, 3.2299430438278187, 2.835897111408885, 2.4899466059017845, 2.186218487054244, 1.9195572129748524, 1.6854370455381997, 1.4798850786813753, 1.29941367791204, 1.1409611798590402, 1.001839841559402, 0.8796901527963475, 0.772440733292397, 0.6782731317724259, 0.5955909274692558, 0.5229926079757407, 0.45924776170425224, 0.40327617969564616, 0.35412951108933594, 0.3109751600700831, 0.2730821502880063, ] assert result == pytest.approx(expected)