def test_safe_dist(): rand_gen = np.random.RandomState(123) dist_info = ObjMap( {"dist_type": "poisson", "vars": {1: {"value": 20, "value_type": "int"}}} ) # numpy dist assert utils.safe_dist(dist_info, rand_gen) > 0 # custom dist dist_info["dist_type"] = "set_value" assert utils.safe_dist(dist_info, rand_gen) == 20 # not a real distribution dist_info["dist_type"] = "fake_dist" with pytest.raises(AttributeError) as excinfo: utils.safe_dist(dist_info, rand_gen) assert "Distribution type fake_dist not found!" in str(excinfo) # pert low = 2 peak = 5 high = 100 temp = 4 pert_info = ObjMap( { "dist_type": "pert", "vars": { 1: {"value": low, "value_type": "int"}, 2: {"value": peak, "value_type": "int"}, 3: {"value": high, "value_type": "int"}, 4: {"value": temp, "value_type": "int"}, }, } ) val = utils.safe_dist(pert_info, rand_gen) assert val > low assert val < high # weibull_modified (2-param weibull) rand_gen = FakeRandom(0.5) shape = 0.5 scale = 11 weibull_info = ObjMap( { "dist_type": "weibull_modified", "vars": { 1: {"value": shape, "value_type": "float"}, 2: {"value": scale, "value_type": "float"}, }, } ) assert utils.safe_dist(weibull_info, rand_gen) == 5.284983153100216
def test_get_partner_attr(): test_rule = ObjMap({ "attribute": "drug_type", "partner_attribute": "__agent__", "agent_value": "Inj", "partner_values": { "Inj": 0.8, "NonInj": 0.1, "__other__": 10 }, }) assert get_partner_attr(test_rule) == "drug_type" test_rule.partner_attribute = "race" assert get_partner_attr(test_rule) == "race"
def test_sex_num_acts(make_model, make_agent, make_relationship, params): params.hiv.dx.risk_reduction.sex = 1.0 model = make_model() model.time = model.params.hiv.start_time model.np_random = FakeRandom(1.0) a = make_agent() p = make_agent() a.partners["Sex"] = set() p.partners["Sex"] = set() rel_Sex = Relationship(a, p, 10, bond_type="Sex") assert Sex.get_num_acts(model, rel_Sex) > 0 a.hiv.active = True a.hiv.dx = True # test nothing happens assert Sex.get_num_acts(model, rel_Sex) == 0 a.location.params.partnership.sex.frequency = ( p.location.params.partnership.sex.frequency) = ObjMap({ "Sex": { "type": "distribution", "distribution": { "dist_type": "set_value", "vars": { 1: { "value": 0, "value_type": "int" } }, }, } }) assert Sex.get_num_acts(model, rel_Sex) == 0
def test_create_agent(make_population, params): pop = make_population(n=100) a1 = pop.create_agent(pop.geography.locations["world"], "white", 0) assert a1.race == "white" assert a1.knowledge.opinion in range( 5 ), f"Agents opinion of injectible PrEP is out of bounds {a1.knowledge.opinion}" a2 = pop.create_agent(pop.geography.locations["world"], "black", 0) assert a2.race == "black" a3 = pop.create_agent(pop.geography.locations["world"], "white", 0, "HM") assert a3.sex_type == "HM" assert a3.race == "white" # check PWID and HIV and high risk pop.pop_random = FakeRandom(-0.1) pop.geography.locations["world"].drug_weights["white"]["HM"] = ObjMap({ "values": ["Inj"], "weights": [1.0] }) a4 = pop.create_agent(pop.geography.locations["world"], "white", 0, "HM") assert a4.drug_type == "Inj" assert a4.hiv.active assert a4.hiv.aids assert a4.hiv.dx assert a4.haart.active assert a4.haart.adherent assert a4.high_risk.active assert a4.high_risk.ever # check not PWID and HIV pop.pop_random = FakeRandom(0.999) pop.geography.locations["world"].drug_weights["white"]["HM"] = ObjMap({ "values": ["None"], "weights": [1.0] }) a4 = pop.create_agent(pop.geography.locations["world"], "white", 0, "HM") assert a4.drug_type == "None" assert a4.hiv.active is False assert a4.prep.active is False assert a4.random_trial.treated is False
def test_pca_num_acts_dist(make_model, make_agent): model = make_model() model.params.partnership.pca.frequency = ObjMap({ "Social": { "type": "distribution", "distribution": { "dist_type": "set_value", "vars": { 1: { "value": 0, "value_type": "int" } }, }, } }) a = make_agent() p = make_agent() rel = Relationship(a, p, 10, bond_type="Social") model.run_random = FakeRandom(-0.1) assert PCA.get_num_acts(model, rel) == 0
def test_get_assort_bond_type(make_population, make_agent, params): pop = make_population() a = make_agent(SO="MSM", race="white") p = make_agent(SO="MSM", race="white") a.hiv.active = True p.hiv.active = True for bond in params.classes.bond_types: a.target_partners[bond] = 1 p.target_partners[bond] = 1 a.partners[bond] = set() p.partners[bond] = set() pop.add_agent(a) pop.add_agent(p) params.features.assort_mix = True # assort with white test_rule = ObjMap({ "attribute": "hiv.active", "partner_attribute": "__agent__", "bond_types": ["Social"], "agent_value": True, "partner_values": { "True": 0.1, "False": 0.9 }, }) params.assort_mix["test_rule"] = test_rule partner = select_partner( a, pop.all_agents.members, pop.sex_partners, pop.pwid_agents, params, FakeRandom(0.5), "Social", ) assert partner is None # get __other__ test_rule = ObjMap({ "attribute": "hiv.active", "partner_attribute": "__agent__", "bond_types": ["Sex"], "agent_value": True, "partner_values": { "True": 0.9, "False": 0.1 }, }) params.assort_mix["test_rule"] = test_rule partner = select_partner( a, pop.all_agents.members, pop.sex_partners, pop.pwid_agents, params, FakeRandom(0.5), "Sex", ) assert partner == p
def test_get_assort_same_race(make_population, make_agent, params): pop = make_population() a = make_agent(SO="MSM", race="white") p1 = make_agent(SO="MSM", race="white") p2 = make_agent(SO="MSM", race="black") for bond in params.classes.bond_types: a.target_partners[bond] = 1 p1.target_partners[bond] = 1 p2.target_partners[bond] = 1 a.partners[bond] = set() p1.partners[bond] = set() p2.partners[bond] = set() pop.add_agent(a) pop.add_agent(p1) pop.add_agent(p2) params.features.assort_mix = True # assort with white test_rule = ObjMap({ "attribute": "race", "partner_attribute": "__agent__", "bond_types": [], "agent_value": "__any__", "partner_values": { "__same__": 0.9, "__other__": 0.1 }, }) params.assort_mix["test_rule"] = test_rule partner = select_partner( a, pop.all_agents.members, pop.sex_partners, pop.pwid_agents, params, FakeRandom(0.5), "Sex", ) assert partner == p1 # get __other__ params.assort_mix["test_rule"]["partner_values"]["__other__"] = 10 partner = select_partner( a, pop.all_agents.members, pop.sex_partners, pop.pwid_agents, params, FakeRandom(0.5), "Sex", ) assert partner == p2 # throw error on key that's not __same__ or __other__ params.assort_mix["test_rule"]["partner_values"]["a_key"] = 100 with pytest.raises(ValueError): select_partner( a, pop.all_agents.members, pop.sex_partners, pop.pwid_agents, params, FakeRandom(0.5), "Sex", )
def test_get_assort_partner_drug_type(make_population, make_agent, params): pop = make_population() a = make_agent(SO="MSM", race="white", DU="Inj") p1 = make_agent(SO="MSM", race="white", DU="Inj") p2 = make_agent(SO="MSM", race="black", DU="None") p3 = make_agent(SO="MSM", race="black", DU="NonInj") for bond in params.classes.bond_types: a.target_partners[bond] = 0 p1.target_partners[bond] = 0 p2.target_partners[bond] = 0 a.partners[bond] = set() p1.partners[bond] = set() p2.partners[bond] = set() pop.add_agent(a) pop.add_agent(p1) pop.add_agent(p2) params.features.assort_mix = True # make sure partnering on sex_type # params.partnership.bonds["PWID"]["Sex"]["prob"] = 10 for race in params.classes.races: for bond in params.classes.bond_types: if bond != "Sex": params.demographics[ race].sex_type.MSM.drug_type.Inj.num_partners[bond].vars[ 1].value = 0.0 # assort with Inj test_rule = ObjMap({ "attribute": "drug_type", "partner_attribute": "__agent__", "bond_types": [], "agent_value": "Inj", "partner_values": { "Inj": 0.8, "NonInj": 0.1, "__other__": 0.1 }, }) params.assort_mix["test_rule"] = test_rule partner = select_partner( a, pop.all_agents.members, pop.sex_partners, pop.pwid_agents, params, FakeRandom(0.5), "Inj", ) assert partner == p1 # get __other__ test_rule = ObjMap({ "attribute": "drug_type", "partner_attribute": "__agent__", "bond_types": [], "agent_value": "Inj", "partner_values": { "Inj": 0.8, "NonInj": 0.1, "__other__": 10 }, }) params.assort_mix["test_rule"] = test_rule partner = select_partner( a, pop.all_agents.members, pop.sex_partners, pop.pwid_agents, params, FakeRandom(0.5), "Sex", ) assert partner == p2
def test_get_assort_partner_high_risk(make_population, make_agent, params): pop = make_population() a = make_agent(SO="MSM", race="white") p1 = make_agent(SO="MSM", race="white") p2 = make_agent(SO="MSM", race="black") a.high_risk = True p1.high_risk = True p2.high_risk = False for bond in params.classes.bond_types: a.target_partners[bond] = 0 p1.target_partners[bond] = 0 p2.target_partners[bond] = 0 a.partners[bond] = set() p1.partners[bond] = set() p2.partners[bond] = set() a.target_partners["Sex"] = 1 p1.target_partners["Sex"] = 1 p2.target_partners["Sex"] = 1 pop.add_agent(a) pop.add_agent(p1) pop.add_agent(p2) params.features.assort_mix = True # assrot with high_risk test_rule = ObjMap({ "attribute": "high_risk", "partner_attribute": "__agent__", "bond_types": [], "agent_value": True, "partner_values": { "True": 0.9, "__other__": 0.1 }, }) params.assort_mix["test_rule"] = test_rule partner = select_partner( a, pop.all_agents.members, pop.sex_partners, pop.pwid_agents, params, FakeRandom(0.5), "Sex", ) assert partner == p1 # get __other__ test_rule = ObjMap({ "attribute": "high_risk", "partner_attribute": "__agent__", "bond_types": [], "agent_value": True, "partner_values": { "True": 0.9, "__other__": 10 }, }) params.assort_mix["test_rule"] = test_rule partner = select_partner( a, pop.all_agents.members, pop.sex_partners, pop.pwid_agents, params, FakeRandom(0.5), "Sex", ) assert partner == p2
def test_sex_transmission(make_model, make_agent): model = make_model() model.time = model.params.hiv.start_time a = make_agent() a.sex_role = "insertive" p = make_agent() p.sex_role = "receptive" a.partners["Sex"] = set() p.partners["Sex"] = set() rel = Relationship(a, p, 10, bond_type="Sex") a.hiv.active = True a.hiv.time = model.time # acute rel.total_sex_acts = 0 model.params.calibration.acquisition = 10 model.params.calibration.acquisition = 5 model.params.calibration.sex.act = 10 model.run_random = FakeRandom(0.6) a.location.params.partnership.sex.frequency = ObjMap({ "Sex": { "type": "bins", "bins": { 1: { "prob": 1.0, "min": 10, "max": 37 } } } }) p.location.params.partnership.sex.frequency = ObjMap({ "Sex": { "type": "bins", "bins": { 1: { "prob": 1.0, "min": 10, "max": 37 } } } }) # test partner becomes Sex.interact(model, rel) assert p.hiv.active p.hiv.active = False a.location.params.partnership.sex.frequency = ( p.location.params.partnership.sex.frequency) = ObjMap({ "Sex": { "type": "distribution", "distribution": { "dist_type": "set_value", "vars": { 1: { "value": 1, "value_type": "int" } }, }, } }) Sex.interact(model, rel) assert p.hiv.active # before hiv start time p.hiv.active = False model.time = model.params.hiv.start_time - 1 Sex.interact(model, rel) assert not p.hiv.active
def test_syringe_services(params_integration, tmpdir): """ If we use syringe services, does the incidence of hiv decrease? """ params_integration.demographics.black.sex_type.MSM.drug_type.Inj.ppl = 1.0 params_integration.demographics.black.sex_type.MSM.drug_type["None"].ppl = 0.0 params_integration.model.num_pop = 500 model_a = TITAN(params_integration) model_a.params.partnership.sex.frequency.Sex = ( ObjMap( # turn off sex to show only injection effects {"type": "bins", "bins": {1: {"prob": 1.0, "min": 0, "max": 1}}} ) ) path_a = tmpdir.mkdir("a") path_a.mkdir("network") path_b = tmpdir.mkdir("b") path_b.mkdir("network") # run with default bins (0-9) model_a.run(path_a) num_bonds = 0 num_ag = 0 for ag in model_a.pop.all_agents: if ag.hiv.active: num_ag += 1 for ptnr in ag.get_partners(["Inj", "SexInj"]): if not ptnr.hiv.active: num_bonds += 1 assert num_bonds # make sure there are serodiscordant partnerships # change the coverage upward for creating model b, use same seeds model_a.params.features.syringe_services = True model_a.params.model.seed.run = model_a.run_seed model_a.params.model.seed.ppl = model_a.pop.pop_seed model_b = TITAN(model_a.params) model_b.run(path_b) result_file_a = os.path.join(path_a, "basicReport.txt") result_file_b = os.path.join(path_b, "basicReport.txt") assert os.path.isfile(result_file_a) with open(result_file_a, newline="") as fa, open(result_file_b, newline="") as fb: reader_a = csv.DictReader(fa, delimiter="\t") res_a = {} for row in reader_a: if row["drug_type"] == "Inj": res_a[row["t"]] = res_a.get(row["t"], 0) + float(row["hiv"]) reader_b = csv.DictReader(fb, delimiter="\t") res_b = {} for row in reader_b: if row["drug_type"] == "Inj": res_b[row["t"]] = res_b.get(row["t"], 0) + float(row["hiv"]) # at start, should be similar t0_hiv_a = res_a["0"] t0_hiv_b = res_b["0"] t0_diff = t0_hiv_a - t0_hiv_b assert math.isclose(t0_hiv_a, t0_hiv_b, abs_tol=15) # within 15 agents # at end, should be different t10_hiv_a = res_a["10"] t10_hiv_b = res_b["10"] t10_diff = t10_hiv_a - t10_hiv_b # a should be higher assert t10_hiv_a > t0_hiv_a assert t10_hiv_b > t0_hiv_b assert t10_diff > t0_diff