Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream> // used for text output for debugging, and for general runtime text
- #include <fstream> // used for saving and loading files
- #include <sstream> // used to load files
- #include <string> // used for text output for debugging and for saving files
- #include <vector> // used for vector class to store data
- #include <random> // used for RNG
- #include <math.h> // used for rounding and other math functions
- #include <functional> // used to bind random distribution and generator
- #include <limits> // used for representing NaNs
- #include <chrono> // used to seed RNG and time code
- // non standard libraries
- #include "boost/date_time/gregorian/gregorian.hpp" // used for dates
- #include "Eigen/Eigen" // used for matrix class
- using std::vector;
- using namespace std::chrono;
- using namespace Eigen;
- using namespace boost::gregorian;
- // used for loading csv data
- const int num_simulations = 1000; // total number of simulations
- typedef Matrix<double, num_simulations, 1> MatrixS1d;
- void load_params(std::ifstream &ifs, Ref<MatrixS1d> my_params)
- {
- double d;
- int i(0);
- for (int i = 0; i != num_simulations; ++i)
- {
- ifs >> d; // load data
- my_params(i) = d;
- ifs.ignore(1, ',');
- }
- };
- template<class T = std::mt19937, std::size_t N = T::state_size>
- auto ProperlySeededRandomEngine() -> typename std::enable_if<!!N, T>::type {
- typename T::result_type random_data[N];
- std::random_device source;
- std::generate(std::begin(random_data), std::end(random_data), std::ref(source));
- std::seed_seq seeds(std::begin(random_data), std::end(random_data));
- T seededEngine(seeds);
- seededEngine.discard(700000);
- return seededEngine;
- }
- int main()
- {
- std::cout << "Model initializing: main" << std::endl;
- // intialize IOFormat for saving file
- IOFormat CSV_Fmt(FullPrecision, DontAlignCols, ",", "\n", "", "", "", ""); // comma seperated values format
- auto start_time = steady_clock::now(); // start time of program in milliseconds
- // unsigned seed = static_cast<int>(std::chrono::high_resolution_clock::now().time_since_epoch().count()); // seed RNG based on current time
- // initialize random number generator
- //std::mt19937 generator(seed);
- auto generator = ProperlySeededRandomEngine();
- double average_year_days = 365.242; // average number of days in a year
- double average_month_days = average_year_days / 12.0; // average number of days in a month
- // initialize uniform distribution
- std::uniform_real_distribution<double> uniform(0.0, 1.0);
- auto sample_uniform_distribution = std::bind(uniform, generator);
- MatrixS1d prevalence_high_risk; // HIV prevalence among high risk partners
- MatrixS1d prevalence_low_risk_mult; // multiplier for low risk partners
- MatrixS1d incidence_high_risk; // HIV incidence among high risk partners
- MatrixS1d condom_frequency_long; // condom use frequency among long term partners
- MatrixS1d condom_frequency_short; // condom use frequency among short term partners
- MatrixS1d condom_efficacy; // condom efficacy
- MatrixS1d hiv_prevalence_clients; // HIV prevalence among clients of sex workers
- MatrixS1d hiv_risk_asymptomatic; // HIV risk per act with asymptomatic partner not on ART
- MatrixS1d relative_phase_risk_acute; // relative HIV acquisition risk with acute partner
- MatrixS1d relative_phase_risk_late; // relative HIV acquisition risk with late partner
- MatrixS1d relative_anal_risk; // relative infectiousness on anal intercourse
- MatrixS1d anal_acts_fraction_clients; // proportion of sex acts that are anal intercourse for clients
- MatrixS1d anal_condom_frequency_clients; // probability for using condom during anal intercourse for clients
- MatrixS1d vaginal_condom_frequency_clients; // probability of using condom during vaginal intercourse for clients
- { // calibrate model
- std::cout << "Loading parameters...";
- std::string title = "calibrated_parameters_8_31.csv";
- std::ifstream file(title);
- if (file.is_open()){
- load_params(file, prevalence_high_risk);
- load_params(file, prevalence_low_risk_mult);
- load_params(file, incidence_high_risk);
- load_params(file, condom_frequency_long);
- load_params(file, condom_frequency_short);
- load_params(file, condom_efficacy);
- load_params(file, hiv_prevalence_clients);
- load_params(file, hiv_risk_asymptomatic);
- load_params(file, relative_phase_risk_acute);
- load_params(file, relative_phase_risk_late);
- load_params(file, relative_anal_risk);
- load_params(file, anal_acts_fraction_clients);
- load_params(file, anal_condom_frequency_clients);
- load_params(file, vaginal_condom_frequency_clients);
- file.close();
- std::cout << "done" << std::endl;
- }
- }
- // epidemic parameters
- Vector3i phase_duration(5, 108, 24); // duration of HIV phases (0-acute, 1-asymptomatic, 2-late) in months
- int hiv_duration_months = phase_duration.sum();
- std::uniform_int_distribution<int> days_infected_distribution(0, std::lrint(average_month_days *
- hiv_duration_months)); // number of days before current date when partner is infected
- auto sample_days_infected_distribution = std::bind(days_infected_distribution, generator);
- double mixing_degree = 0.56; // degree of assortative mixing
- double fraction_high_risk_partners = 0.35; // probability to mix with high risk partners
- double art_efficacy = 0.9; // efficacy of ART in reducing HIV infectivity
- int art_progression = 3; // effect of ART on phase duration
- Vector4d art_drop_rate(0, 0, 0, 0); // rate of ART drop by phase (0-acute, 1-asymptomatic, 2-late, 3-extended)
- Vector4d art_initiation_rate(0, .1, .5, .5); // rate of ART initiation by phase (0-acute, 1-asymptomatic, 2-late, 3-extended)
- art_initiation_rate /= average_year_days; // convert to daily rate
- double fraction_high_risk_particpants = 0.25; // proportion of non FSW which are high risk participants
- double fraction_low_risk_participants = 1 - fraction_high_risk_particpants; // proportion of non FSW which are low risk participants
- Vector4d fraction_fsw_participants(0.0, 0.2, 0.5, 1); // different fractions of FSW by scenario
- Vector4d fraction_non_fsw(1 - fraction_fsw_participants(0),
- 1 - fraction_fsw_participants(1),
- 1 - fraction_fsw_participants(2),
- 1 - fraction_fsw_participants(3));
- // participants by scenario
- vector< std::discrete_distribution<int> > participant_risk_distribution{
- { fraction_non_fsw(0)*fraction_low_risk_participants, fraction_non_fsw(0)*fraction_high_risk_particpants, fraction_fsw_participants(0) }, // low, high, fsw
- { fraction_non_fsw(1)*fraction_low_risk_participants, fraction_non_fsw(1)*fraction_high_risk_particpants, fraction_fsw_participants(1) },
- { fraction_non_fsw(2)*fraction_low_risk_participants, fraction_non_fsw(2)*fraction_high_risk_particpants, fraction_fsw_participants(2) },
- { fraction_non_fsw(3)*fraction_low_risk_participants, fraction_non_fsw(3)*fraction_high_risk_particpants, fraction_fsw_participants(3) } };
- vector <decltype(std::bind(participant_risk_distribution[0], generator))> sample_participant_risk_distribution;
- for (int index = 0; index != 4; ++index)
- sample_participant_risk_distribution.push_back(std::bind(participant_risk_distribution[index], generator));
- Matrix<double, 5, 3> drop_out_rates_annual; // drop out rates for participants, 0 - low risk, 1 - high risk, 2 - female sex workers
- drop_out_rates_annual << 0.05, 0.05, 0.00,
- 0.05, 0.05, 0.05,
- 0.05, 0.05, 0.10,
- 0.05, 0.05, 0.15,
- 0.05, 0.05, 0.20;
- Matrix<double, 5, 3> drop_out_rates = drop_out_rates_annual / 12;
- // double art_fraction = 0.25; // fraction of infected partners on ART
- Vector3d art_fraction_stage(0, 0.172685, 0.65); // fraction of total ART in each stage // fraction of total ART in each stage
- double anal_frequency = 0.4; // fraction of sex acts which are anal for partners who practice anal
- double fraction_partners_practice_anal = 0.2; // fraction of partners who practice anal sex
- Vector3d mixing_high_risk(mixing_degree*fraction_high_risk_partners, (1 - mixing_degree) + mixing_degree*fraction_high_risk_partners,
- fraction_high_risk_partners); // probability to mix with high-risk partner by (0-low risk, 1-high risk, 2-sex worker)
- // participants
- months short_to_long_partnership(9); // time to turn from a short to a long term partnership
- // months min_duration_partnership(1); // minimum duration of partnership
- months min_duration_partnership(0); // minimum duration of partnership
- Vector3d partner_acquisition_rate_nopartners(1.0 / (9 * average_month_days), 1.0 / (3 * average_month_days),
- 1.0 / (9 * average_month_days)); // daily partner acquisition rate for participants with 0 partners (0-low risk, 1-high risk,
- // 2-sex worker)
- Matrix <double, 3, 5> relative_partner_acquisition_rate; // relative partner acquisition rate, rows: low risk, high risk, sex worker,
- // columns: 0L0S, 0L1S, 0L2S, 1L0S, 1L1S (0L1S means 0 long 1 short term partnership)
- relative_partner_acquisition_rate << 1.00, 0.00, 0.00, 0.00, 0.00,
- 1.00, 0.54, 0.00, 0.17, 0.00,
- 1.00, 0.00, 0.00, 0.00, 0.00;
- //vector< std::discrete_distribution<int> > initial_partner_distribution{ { 0.107, 0.294, 0.00, 0.599, 0.00 },
- //{ 0.080, 0.600, 0.12, 0.140, 0.06 },
- //{ 0.107, 0.294, 0.00, 0.599, 0.00 } };
- vector< std::discrete_distribution<int> > initial_partner_distribution{ { 0.00, 0.35, 0.00, 0.65, 0.00 },
- { 0.00, 0.620, 0.14, 0.160, 0.08 },
- { 0.00, 0.35, 0.00, 0.65, 0.00 } }; // initial partner
- // distribution of participants, rows: low risk, high risk, fsw, columns: 0l0s, 0l1s, 0l2s, 1l0s, 1l1s
- // (0l1s means 0 long 1 short term partnership)
- // construct vector of functions which sample initial_partner_distribution
- vector < decltype(std::bind(initial_partner_distribution[0], generator)) > sample_initial_partner_distribution;
- for (int index = 0; index != 3; ++index)
- sample_initial_partner_distribution.push_back(std::bind(initial_partner_distribution[index], generator));
- Vector2d partner_dissolution_rate_onepartner(1.0 / (10 * average_year_days), 1.0 / (1 * average_year_days)); // rate of partner dissolution
- // for participants with 1 partner (0- 1L0S, 1- 0L1S) (0L1S means 0 long 1 short term partnership)
- Matrix <int, 2, 5> relative_partner_dissolution_rate; // relative rate of partner dissolution for participants rows: long term,
- // short term, columns: 0L0S, 0L1S, 0L2S, 1L0S, 1L1S (0L1S means 0 long 1 short term partnership)
- relative_partner_dissolution_rate << 1, 1, 1, 1, 4,
- 2, 1, 2, 2, 2;
- Vector3d sex_frequency(0.2, 0.2, 0.2); // daily probability of sex act for long-term, short-term, and sex worker partners
- Vector3d extended_infection_mult(1 / 6.0, 1 / 6.0, 1 / 6.0); // probability to have sex with partner who is past late phase is ~ 1/30;
- // trial parameters
- const int num_participants = 2000; // number of participants in each arm
- date start_date(2012, Jan, 1); // start date of the trial
- int num_enrollment_interval = 1; // length of enrollment interval
- date end_enrollment_date = start_date ; // end of enrollment date
- int num_months_trial = 12; // length of trial in months
- int num_total_months = num_enrollment_interval + num_months_trial;
- date max_end_date = end_enrollment_date + months(num_months_trial); // end date of the trial
- int max_length_of_trial_days = (max_end_date - start_date).days(); // length of trial in days
- int target_infection_number = 120; // target infection number for trial to end
- // PrEP scenarios
- Matrix < double, 5, Dynamic > prep_efficacy(5, max_length_of_trial_days);
- prep_efficacy.row(0) = VectorXd::Constant(max_length_of_trial_days, 0.6).transpose(); // 60% fixed efficacy
- prep_efficacy.row(1) = VectorXd::Constant(max_length_of_trial_days, 0.8).transpose(); // 80% fixed efficacy
- prep_efficacy.row(2).block(0, 0, 1, 60) = VectorXd::LinSpaced(60, 1, 0.6).transpose(); // 100%-60% waning efficacy over 2 months (152 days ~ 5 average months)
- double diff = prep_efficacy(2, 0) - prep_efficacy(3, 1);
- for (int j = 60; j != 70; ++j)
- {
- double next_val = prep_efficacy(2, j - 1) - diff;
- if (next_val > 0)
- prep_efficacy(2, j) = next_val;
- else
- prep_efficacy(2, j) = 0;
- }
- prep_efficacy.row(3).block(0, 0, 1, 30) = VectorXd::Constant(30, 1).transpose(); // 100% over 30 days
- prep_efficacy.row(3).block(0, 30, 1, 30) = VectorXd::LinSpaced(30, 1, 0.2).transpose(); // 100%-20% over 30 days
- diff = prep_efficacy(3, 30) - prep_efficacy(3, 31);
- for (int j = 60; j != 70; ++j)
- {
- double next_val = prep_efficacy(3,j-1)-diff;
- if (next_val > 0)
- prep_efficacy(3, j) = next_val;
- else
- prep_efficacy(3, j) = 0;
- }
- prep_efficacy.row(4) = VectorXd::Constant(max_length_of_trial_days, 1.0).transpose(); // 100% fixed efficacy
- // behavioral parameters
- const int max_partners = 2; // maximum number of partners a participant can have
- double incidence_low_risk_mult = 0.75; // incidence multiplier for low risk partners
- std::uniform_int_distribution<int> short_days_distribution(30, 213); // number of days to subtract when creating a new short
- // partnership
- auto sample_short_days_distribution = std::bind(short_days_distribution, generator);
- // sample parameters
- std::cout << "Initialization complete!" << std::endl;
- std::cout << "Model start!" << std::endl;
- // typedef for ease of use
- typedef Matrix<int, num_participants, max_partners> MatrixPPi;
- typedef Matrix<double, num_participants, max_partners> MatrixPPd;
- typedef Matrix<date, num_participants, max_partners> MatrixPPdate;
- typedef Matrix<date, num_participants, 1> MatrixP1date;
- typedef Matrix <int, num_participants, 1> MatrixP1i;
- typedef Matrix <int, num_participants, 2> MatrixP2i;
- typedef Matrix <double, num_participants, 1> MatrixP1d;
- for (int prep_scenario = 4; prep_scenario != 5; ++prep_scenario){
- for (int drop_out_scenario = 1; drop_out_scenario != 2; ++drop_out_scenario){ // drop out rate changes
- for (int enrollment_scenario = 0; enrollment_scenario != 4; ++enrollment_scenario){ // proportion of FSW enrolled changes
- // saved statistics
- Matrix <double, num_simulations, 10> sim_observed_incidence; // save incidence statistic
- Matrix <double, num_simulations, 1> sim_observed_efficacy; // save observed efficacy statistic
- Matrix <int, num_simulations, 1> sim_trial_duration_days; // save duration of each trial in days statistic
- MatrixXi sim_trial_duration_months(num_simulations, 1); // save duration of each trial in days statistic
- Matrix <double, num_simulations, 5> sim_exposed_fraction; // save exposed fraction statistic
- MatrixXi sim_num_infections(num_simulations, 8); // save number of infections statistic
- MatrixXi sim_num_infections_sex_work(num_simulations, 2); // save infections from sex work statistic
- MatrixXi sim_follow_up_days(num_simulations, 8); // save follow up time statistic
- MatrixXi sim_num_exposed(num_simulations, 8); // save number of exposed statistic
- MatrixXi sim_num_exposures(num_simulations, 8); // save number of exposures statistic
- MatrixXi sim_num_exposures_sex_work(num_simulations, 2); // save number of exposures statistic
- MatrixXi sim_cum_drop_out_gen(num_simulations, max_length_of_trial_days); // save cumulative drop out by low and high risk participants over the course of the trial
- MatrixXi sim_cum_drop_out_fsw(num_simulations, max_length_of_trial_days); // save cumulative drop out sex workers over the course of the trial
- Matrix <date, num_simulations, 2> sim_date_of_infection; // save date of infection for each arm
- MatrixXi sim_monthly_exposed(num_simulations, num_total_months * 8);
- MatrixXi sim_monthly_active(num_simulations, 2*num_total_months);
- MatrixXi sim_monthly_num_exposures(num_simulations, num_total_months * 8);
- std::poisson_distribution<> num_clients_distribution(10.0 / 7.0);
- auto sample_num_clients_distribution = std::bind(num_clients_distribution, generator);
- for (int sim_id = 0; sim_id != num_simulations; ++sim_id) // iterate over simulations
- {
- Vector2d num_infection_less(0,0);
- // sampled parameters
- Vector2d prevalence_partners(hiv_prevalence_clients(sim_id)*prevalence_low_risk_mult(sim_id), hiv_prevalence_clients(sim_id)); // HIV
- // prevalence of partners (0-low risk, 1-high risk)
- Vector2d incidence_partners(incidence_high_risk(sim_id)*incidence_low_risk_mult, incidence_high_risk(sim_id)); // HIV incidence of
- // partners (0-low risk, 1-high risk, 2-sex worker)
- Vector2d condom_frequency(condom_frequency_long(sim_id), condom_frequency_short(sim_id)); // probability use condom (1-long,
- // 2-short, 3-casual)
- Vector4d relative_phase_risk(relative_phase_risk_acute(sim_id), 1.0, relative_phase_risk_late(sim_id), relative_phase_risk_late(sim_id)); // relative HIV
- // risk by HIV phase of partner (0-acute, 1-asymptomatic, 2-late, 3-extended late)
- date end_date = max_end_date; // end_date is max end_date by default
- // Trial vector initialization
- Matrix <int, 4, 2> num_infections = Matrix <int, 4, 2>::Zero(); // contains the number of infections, rows: 0-low risk,
- // 1-high risk, 2-sex worker, 3-total, columns: 0-CONTROL arm, 1-ACTIVE arm
- Vector2i num_infections_sex_work = Vector2i::Zero(); // number of infections from sex work 0-CONTROL arm, 1-ACTIVE arm
- Matrix <int, 4, 2> follow_up_days = Matrix <int, 4, 2>::Zero(); // contains the total follow up time, rows: 0-low risk,
- // 1-high risk, 2-sex worker, 3-total, columns: 0-CONTROL arm, 1-ACTIVE arm
- Matrix <int, 4, 2> num_exposed = Matrix <int, 4, 2>::Zero(); // contains the number of participants exposed, rows: 0-low risk,
- // 1-high risk, 2-sex worker, 3-total, columns: 0-CONTROL arm, 1-ACTIVE arm
- Matrix <int, 4, 2> num_exposures = Matrix <int, 4, 2>::Zero(); // contains the number of exposures, rows: 0-low risk,
- // 1-high risk, 2-sex worker, 3-total, columns: 0-CONTROL arm, 1-ACTIVE arm
- Vector2i num_exposures_sex_work = Vector2i::Zero(); // 0-control 1-active
- MatrixXi participant_monthly_hiv_exposure = MatrixXi::Zero(num_participants, 2);// 0 if not exposed to HIV, 1 if exposed to HIV for ACTIVE and CONTROL arms
- MatrixXi participant_monthly_num_exposures = MatrixXi::Zero(num_participants, 2);
- MatrixXi monthly_exposures = MatrixXi::Zero(8, num_total_months);
- Matrix <int, 8, Dynamic> monthly_exposed = Matrix <int, 8, Dynamic>::Zero(8, num_total_months);
- int trial_duration_months = 0;
- VectorXi cum_drop_out_gen = VectorXi::Zero(max_length_of_trial_days); // cumulative drop out by low and high risk participants over the course of the trial
- VectorXi cum_drop_out_fsw = VectorXi::Zero(max_length_of_trial_days); // cumulative drop out sex workers over the course of the trial
- VectorXi total_do = VectorXi::Zero(2); // total drop out 0-low and high risk, 1-sex workers
- Vector4i num_participants_risk_group = Vector4i::Zero(); // number of participants in each risk group,
- // 0-low risk, 1-high risk, 2-sex worker, 3-total
- Vector4i num_enrolled_risk_group = Vector4i::Zero(); // number of participants enrolled in each risk group, 0-low risk,
- // 1-high risk, 2-sex worker, 3-total
- num_participants_risk_group(3) = num_participants; // total number of participants in all risk groups
- // participant vector intialization
- MatrixP1date participant_enrollment_date; // enrollment date of participant
- MatrixP1date participant_max_follow_up_date; // last day of follow up for participant
- Matrix <date, num_participants, 2> participant_date_of_infection;
- MatrixP2i participant_hiv_status = MatrixP2i::Zero(); // sets participants HIV status to false for ACTIVE and CONTROL arms
- MatrixP2i partcipant_hiv_exposure = MatrixP2i::Zero(); // 0 if not exposed to HIV, 1 if exposed to HIV for ACTIVE and CONTROL arms
- MatrixP2i participant_active = MatrixP2i::Zero(); // sets participants to deactive; they become active as enrollment proceeds
- MatrixXi participant_monthly_active = MatrixXi::Zero(num_total_months, 2); // number of participants active each month
- MatrixP1i participant_prep_days_count = MatrixP1i::Zero(); // number of days since last PrEP dose.
- MatrixP1i participant_prep_month_count = MatrixP1i::Zero(); // number of months since last PrEP dose.
- int prep_interval = 2; // number of months between PrEP doses
- // they only become active in CONTROL xor in ACTIVE
- MatrixP1i participant_arm; // the arm particpant is in, 0-CONTROl, 1-ACTIVE
- // partner vector initialization
- MatrixPPi partner_active = MatrixPPi::Zero(); // active partners initialize to false
- MatrixP1i participant_days_enrolled = MatrixP1i::Zero(); // number of days participants have been enrolled
- // initiate participants
- // partner vector initialization
- MatrixPPd partner_anal_probability = MatrixPPd::Zero(); // probability for partner to have anal sex
- MatrixPPi partner_risk_group; // risk group of partners for each participant
- MatrixPPi partner_type; // type of partnership 0-long, 1-short
- MatrixPPdate partner_start_date; // date of partnership start
- MatrixPPd partner_sex_probability; // probability for sex with partner
- MatrixPPd partner_condom_probability; // probability to use condom
- MatrixPPd partner_dissolution_probability; // probability to break up
- MatrixPPi partner_hiv_status; // HIV status of partner 0-negative 1-positive
- MatrixPPdate partner_date_of_infection; // date of infection of partner
- MatrixPPi partner_art_status; // ART status of partner 0-no ART 1- on ART
- MatrixP1i participant_risk_group; // risk group of participant
- MatrixP1i number_long_partners; // number of long term partners
- MatrixP1i number_short_partners; // number of short term partners
- MatrixP1i number_partners; // total number of partners
- try // create enrollment blocks with equal number of risk groups and enroll participants accordingly
- {
- if ((num_participants % (2 * num_enrollment_interval)) != 0)
- {
- throw std::invalid_argument("Enrollment intervals can not be evenly split by control/active arm");
- }
- int enrollment_size = num_participants / (2 * num_enrollment_interval);
- int participant_id = 0;
- for (int enrollment_month = 0; enrollment_month != num_enrollment_interval; ++enrollment_month)
- {
- date enrollment_date = start_date + months(enrollment_month); // current enrollment date
- date max_follow_date = enrollment_date + months(num_months_trial); // maximum follow up date of participant
- for (int i = 0; i != enrollment_size; ++i) // add participants to CONTROL arm
- {
- participant_arm(participant_id) = 0; // set to CONTROL arm
- participant_risk_group(participant_id) = sample_participant_risk_distribution[enrollment_scenario]();
- participant_enrollment_date(participant_id) = enrollment_date; // set enrollment date
- participant_max_follow_up_date(participant_id) = max_follow_date; // set maximum follow up date
- ++num_participants_risk_group(participant_risk_group(participant_id)); // add one to risk group total
- ++participant_id;
- }
- for (int i = 0; i != enrollment_size; ++i) // add participants to ACTIVE arm
- {
- participant_arm(participant_id) = 1; // set to ACTIVE arm
- participant_risk_group(participant_id) = sample_participant_risk_distribution[enrollment_scenario](); // set risk group
- participant_enrollment_date(participant_id) = enrollment_date; // set enrollment date
- participant_max_follow_up_date(participant_id) = max_follow_date; // set maximum follow up date
- ++num_participants_risk_group(participant_risk_group(participant_id)); // add one to risk group total
- ++participant_id;
- }
- }
- }
- catch (const std::invalid_argument& e)
- {
- std::cerr << e.what() << std::endl; // output error message
- }
- for (int participant_id = 0; participant_id != num_participants; ++participant_id)
- {
- // initialize partners
- int initial_partners = sample_initial_partner_distribution[participant_risk_group(participant_id)](); // sample initial
- // partner distribution based on risk group
- switch (initial_partners) // determine number of partners
- {
- case 0: number_long_partners(participant_id) = 0; // 0L0S
- number_short_partners(participant_id) = 0;
- break;
- case 1: number_long_partners(participant_id) = 0; // 0L1S
- number_short_partners(participant_id) = 1;
- break;
- case 2: number_long_partners(participant_id) = 0; // 0L2S
- number_short_partners(participant_id) = 2;
- break;
- case 3: number_long_partners(participant_id) = 1; // 1L0S
- number_short_partners(participant_id) = 0;
- break;
- case 4: number_long_partners(participant_id) = 1; // 1L1S
- number_short_partners(participant_id) = 1;
- }
- // total number of partners
- number_partners(participant_id) = number_long_partners(participant_id) + number_short_partners(participant_id);
- int current_partner = 0; // current partner
- for (int partner_id = 0; partner_id != number_long_partners(participant_id); ++partner_id) // add long partners
- {
- partner_risk_group(participant_id, partner_id) = (sample_uniform_distribution() <
- mixing_high_risk(participant_risk_group(participant_id))); // determine risk group of partner, 0-low, 1-high
- partner_type(participant_id, partner_id) = 0; // partner type is long
- partner_start_date(participant_id, partner_id) = start_date - years(1); // start one year before start date of
- // trial define partner sex probability as the sex frequency for long partners (0-long)
- partner_sex_probability(participant_id, partner_id) = sex_frequency(0) * (0.5 + sample_uniform_distribution());
- partner_condom_probability(participant_id, partner_id) = condom_frequency(0) *
- (0.5 + sample_uniform_distribution()); // define partner condom probability as the condom frequency for long
- // partners (0-long)
- partner_dissolution_probability(participant_id, partner_id) = partner_dissolution_rate_onepartner(0); // define
- // partner dissolution probability to be baseline probability for long partners (0-long)
- if (sample_uniform_distribution() < fraction_partners_practice_anal) // if partner practices anal sex
- partner_anal_probability(participant_id, partner_id) = anal_frequency *(0.5 + sample_uniform_distribution());
- partner_hiv_status(participant_id, partner_id) = (sample_uniform_distribution() <
- prevalence_partners(partner_risk_group(participant_id, partner_id))); // determine if partner is HIV positive
- if (partner_hiv_status(participant_id, partner_id)) // if partner is HIV positive
- {
- // partner date of infection is a random number of days before start date
- partner_date_of_infection(participant_id, partner_id) = start_date - days(sample_days_infected_distribution());
- int partner_phase;
- if (start_date < (partner_date_of_infection(participant_id, partner_id) +
- months(phase_duration(0)))) // if partner is in acute phase
- partner_phase = 0;
- else if (start_date < (partner_date_of_infection(participant_id, partner_id) + months(phase_duration(0)) +
- months(phase_duration(1)))) // if partner is in asymptomatic phase
- partner_phase = 1;
- else // if partner is in late phase
- partner_phase = 2;
- partner_art_status(participant_id, partner_id) = (sample_uniform_distribution() < art_fraction_stage(partner_phase));
- }
- else
- partner_date_of_infection(participant_id, partner_id) = (max_end_date + months(1)); // if partner is not HIV
- // positive, infection date is AFTER trial is over by default
- partner_active(participant_id, partner_id) = 1; // partner becomes active
- ++current_partner; // move to next partner
- }
- for (int partner_id = current_partner; partner_id != number_partners(participant_id); ++partner_id) // add short
- { // partners
- partner_risk_group(participant_id, partner_id) = (sample_uniform_distribution() <
- mixing_high_risk(participant_risk_group(participant_id))); // determine risk group of partner, 0-low, 1-high
- partner_type(participant_id, partner_id) = 1; // partner type is short
- partner_start_date(participant_id, partner_id) = start_date - days(sample_short_days_distribution()); // start
- // random days before start of trial
- // define partner sex probability as the sex frequency for long partners (1-short)
- partner_sex_probability(participant_id, partner_id) = sex_frequency(1)* (0.5 + sample_uniform_distribution());
- partner_condom_probability(participant_id, partner_id) = condom_frequency(1) *
- (0.5 + sample_uniform_distribution()); // define partner condom probability as the condom frequency for long
- // partners (1-short)
- partner_dissolution_probability(participant_id, partner_id) = partner_dissolution_rate_onepartner(1); // define
- // partner dissolution probability to be baseline probability for long partners (1-short)
- if (sample_uniform_distribution() < fraction_partners_practice_anal) // if partner practices anal sex
- partner_anal_probability(participant_id, partner_id) = anal_frequency *(0.5 + sample_uniform_distribution());
- partner_hiv_status(participant_id, partner_id) = (sample_uniform_distribution() <
- prevalence_partners(partner_risk_group(participant_id, partner_id))); // determine if partner is HIV positive
- if (partner_hiv_status(participant_id, partner_id)) // if partner is HIV positive
- {
- // partner date of infection is a random number of days before start date
- partner_date_of_infection(participant_id, partner_id) = start_date - days(sample_days_infected_distribution());
- int partner_phase;
- if (start_date < (partner_date_of_infection(participant_id, partner_id) +
- months(phase_duration(0)))) // if partner is in acute phase
- partner_phase = 0;
- else if (start_date < (partner_date_of_infection(participant_id, partner_id) + months(phase_duration(0)) +
- months(phase_duration(1)))) // if partner is in asymptomatic phase
- partner_phase = 1;
- else // if partner is in late phase
- partner_phase = 2;
- partner_art_status(participant_id, partner_id) = (sample_uniform_distribution() < art_fraction_stage(partner_phase));
- }
- else
- partner_date_of_infection(participant_id, partner_id) = max_end_date + months(1); // if partner is not HIV
- // positive, infection date is AFTER trial is over by default
- partner_active(participant_id, partner_id) = 1; // partner becomes active
- }
- }// end participant initialization
- int number_days = 0; // number of days trial has gone on
- int number_month = 0;
- // start trial
- for (month_iterator month_itr(start_date); month_itr != max_end_date; ++month_itr) // iterate over months in the trial
- {
- month_iterator temp_month_itr = month_itr;
- ++temp_month_itr;
- date next_month = *temp_month_itr; // start of next month
- // check enrollment
- for (int participant_id = 0; participant_id != num_participants; ++participant_id)
- {
- if (participant_enrollment_date(participant_id) == *month_itr) // if enrollment date is current date
- {
- ++num_enrolled_risk_group(participant_risk_group(participant_id));
- ++num_enrolled_risk_group(3);
- // participant becomes active
- if (participant_arm(participant_id) == 0)
- participant_active(participant_id, 0) = 1; // participant is in CONTROL arm
- else
- participant_active(participant_id, 1) = 1; // participant is in ACTIVE arm
- }
- if (participant_active(participant_id, 0))
- ++participant_monthly_active(number_month, 0);
- if (participant_active(participant_id, 1))
- ++participant_monthly_active(number_month, 1);
- }
- for (day_iterator day_itr(*month_itr, 1); day_itr != next_month; ++day_itr) // iterate over days in each month
- {
- date current_date = *day_itr; // current date
- // iterate through participants
- std::cout << current_date << " : " << num_infection_less(1) << " / " << num_infection_less(0) << std::endl;
- for (int participant_id = 0; participant_id != num_participants; ++participant_id)
- {
- if (participant_active(participant_id, 0) || participant_active(participant_id, 1)) // if either CONTROL arm
- { // or ACTIVE arm is active
- // search for partners
- int partners = 3 * number_long_partners(participant_id) + number_short_partners(participant_id); // 0-0L0S,
- // 1-0L1S, 2-0L2S, 3-1L0S, 4-1L1S
- double search_probability = partner_acquisition_rate_nopartners(participant_risk_group(participant_id)) *
- relative_partner_acquisition_rate(participant_risk_group(participant_id), partners); // probability to
- // find new partner
- int new_partner = -1; // -1 means NO new partner, if there is a new partner, this will store the id. New
- // partners always have sex with participant
- if ((sample_uniform_distribution() < search_probability))// randomly find new partner
- {
- if (partner_active(participant_id, 0)) // if first partner is active
- new_partner = 1; // new partner is second partner
- else
- new_partner = 0; // otherwise new partner is first partner
- number_partners(participant_id) += 1; // add one to the total number of partners
- number_short_partners(participant_id) += 1; // update number of short partners (all partners start a
- // short term)
- partner_risk_group(participant_id, new_partner) = (sample_uniform_distribution() <
- mixing_high_risk(participant_risk_group(participant_id))); // determine risk group of partner,
- // 0-low, 1-high
- partner_type(participant_id, new_partner) = 1; // partner type is short
- partner_start_date(participant_id, new_partner) = current_date; // start random days before current date
- partner_sex_probability(participant_id, new_partner) = sex_frequency(1) * (0.5 + sample_uniform_distribution()); // define partner sex probability as the sex frequency for
- // short partners (1-short)
- partner_condom_probability(participant_id, new_partner) = condom_frequency(1) *
- (0.5 + sample_uniform_distribution()); // define partner condom probability as the condom frequency
- // for short partners (1-short)
- // define partner dissolution probability to be baseline probability for short partners (1-short)
- partner_dissolution_probability(participant_id, new_partner) = partner_dissolution_rate_onepartner(1);
- if (sample_uniform_distribution() < fraction_partners_practice_anal) // if partner practices anal sex
- partner_anal_probability(participant_id, new_partner) = anal_frequency *
- (0.5 + sample_uniform_distribution());
- partner_hiv_status(participant_id, new_partner) = (sample_uniform_distribution() <
- prevalence_partners(partner_risk_group(participant_id, new_partner))); // determine if partner is
- // HIV positive
- if (partner_hiv_status(participant_id, new_partner)) // if partner is HIV positive
- {
- // partner date of infection is a random number of days before start date
- partner_date_of_infection(participant_id, new_partner) = current_date - days(sample_days_infected_distribution());
- int partner_phase;
- if (current_date < (partner_date_of_infection(participant_id, new_partner) +
- months(phase_duration(0)))) // if partner is in acute phase
- partner_phase = 0;
- else if (current_date < (partner_date_of_infection(participant_id, new_partner) + months(phase_duration(0)) +
- months(phase_duration(1)))) // if partner is in asymptomatic phase
- partner_phase = 1;
- else // if partner is in late phase
- partner_phase = 2;
- partner_art_status(participant_id, new_partner) = (sample_uniform_distribution() < art_fraction_stage(partner_phase));
- }
- else
- partner_date_of_infection(participant_id, new_partner) = max_end_date + months(1); // if partner is not
- // HIV positive, infection date is AFTER trial is over by default
- partner_active(participant_id, new_partner) = 1; // partner becomes active
- } // end search partner
- // have partnership sex, break up with partners and update from short to long partners
- for (int partner_id = 0; partner_id != 2; ++partner_id)
- {
- if (partner_active(participant_id, partner_id)) // only work with active partners
- {
- ++num_infection_less(0);
- // have sex with partner
- double temp_sex_probability = partner_sex_probability(participant_id, partner_id); // temporary
- // probability storage
- //if (number_partners(participant_id) > 1)
- //{
- // temp_sex_probability = temp_sex_probability / number_partners(participant_id); // reduce
- // // probability for sex by number of partners
- //}
- // determine HIV phase partner is in
- Vector3i partner_phase_duration = phase_duration; // base phase duration
- int partner_phase;
- if (current_date < (partner_date_of_infection(participant_id, partner_id) +
- months(partner_phase_duration(0)))) // if partner is in acute phase
- partner_phase = 0;
- else if (current_date < (partner_date_of_infection(participant_id, partner_id) + months(partner_phase_duration(0)) +
- months(partner_phase_duration(1)))) // if partner is in asymptomatic phase
- partner_phase = 1;
- else if (current_date < (partner_date_of_infection(participant_id, partner_id) + months(hiv_duration_months))) // if partner is in late phase
- partner_phase = 2;
- else
- partner_phase = 3; // partner past late phase
- if (partner_phase == 3)
- {
- temp_sex_probability *= extended_infection_mult(partner_type(participant_id, partner_id)); //reduce sex probability if after late phase
- }
- if ((sample_uniform_distribution() < temp_sex_probability) || (partner_id == new_partner)) // if
- { // sample true for sex OR if there is a new partner
- if (partner_hiv_status(participant_id, partner_id)) // if partner is HIV positive
- {
- int use_condom = (sample_uniform_distribution() <
- partner_condom_probability(participant_id, partner_id)); // determine if condom is used
- double hiv_risk = hiv_risk_asymptomatic(sim_id) *
- (1 - use_condom * condom_efficacy(sim_id)); // risk for hiv transmission taking condom use into
- // account
- if ((sample_uniform_distribution() < partner_anal_probability(participant_id, partner_id)))
- { // if sex act is anal
- hiv_risk = hiv_risk * relative_anal_risk(sim_id);
- }
- // determine HIV phase partner is in
- if (partner_art_status(participant_id, partner_id)) // if partner is on ART
- {
- partner_phase_duration(1) = art_progression * partner_phase_duration(1); // ART
- // lengthens the phases
- partner_phase_duration(2) = art_progression * partner_phase_duration(2);
- hiv_risk = (1 - art_efficacy) * hiv_risk; // ART reduces HIV transmission risk
- }
- // HIV transmission
- if (participant_active(participant_id, 0) && !participant_hiv_status(participant_id, 0)) // if control arm is active and not infected
- {
- ++participant_monthly_num_exposures(participant_id, 0);
- if (!partcipant_hiv_exposure(participant_id, 0)) // if participant is has not been exposed
- {
- partcipant_hiv_exposure(participant_id, 0) = 1; //participant is exposed to hiv
- ++num_exposed(participant_risk_group(participant_id), 0);
- ++num_exposed(3, 0);
- }
- if (!participant_monthly_hiv_exposure(participant_id, 0)) // if participant is has not been exposed
- {
- participant_monthly_hiv_exposure(participant_id, 0) = 1; //participant is exposed to hiv
- ++monthly_exposed(participant_risk_group(participant_id), number_month);
- ++monthly_exposed(3, number_month);
- }
- ++num_exposures(participant_risk_group(participant_id), 0);
- ++num_exposures(3, 0);
- ++num_infection_less(1);
- if (sample_uniform_distribution() < (hiv_risk * relative_phase_risk(partner_phase))) // if
- { // HIV is transmitted
- participant_hiv_status(participant_id, 0) = 1; // participant becomes infected
- participant_date_of_infection(participant_id, 0) = current_date;
- }
- }
- // HIV transmission with PrEP use
- // if with PrEP participant is NOT infected (ACTIVE ARM)
- if (participant_active(participant_id, 1) && !participant_hiv_status(participant_id, 1)) // if active arm is active and not infected
- {
- ++participant_monthly_num_exposures(participant_id, 1);
- if (!partcipant_hiv_exposure(participant_id, 1)) // if participant is has not been exposed
- {
- partcipant_hiv_exposure(participant_id, 1) = 1; //participant is exposed to hiv
- ++num_exposed(participant_risk_group(participant_id), 1);
- ++num_exposed(3, 1);
- }
- if (!participant_monthly_hiv_exposure(participant_id, 1)) // if participant is has not been exposed
- {
- participant_monthly_hiv_exposure(participant_id, 1) = 1; //participant is exposed to hiv
- ++monthly_exposed(participant_risk_group(participant_id) + 4, number_month);
- ++monthly_exposed(7, number_month);
- }
- ++num_exposures(participant_risk_group(participant_id), 1);
- ++num_exposures(3, 1);
- // efficacy based on days enrolled
- double protection_efficacy =
- prep_efficacy(prep_scenario, participant_prep_days_count(participant_id));
- if (sample_uniform_distribution() < (hiv_risk * relative_phase_risk(partner_phase) *
- (1 - protection_efficacy))) // if HIV is transmitted
- {
- participant_hiv_status(participant_id, 1) = 1; // participant becomes infected
- participant_date_of_infection(participant_id, 1) = current_date;
- }
- }
- }
- }
- // break up with partners
- if (current_date > (partner_start_date(participant_id, partner_id) + min_duration_partnership)) // if partnership is longer than minimum partnership duration
- {
- double probability_to_break = partner_dissolution_probability(participant_id, partner_id) *
- relative_partner_dissolution_rate(partner_type(participant_id, partner_id), partners);
- // (partners is 0-0L0S, 1-0L1S, 2-0L2S, 3-1L0S, 4-1L1S)
- if (sample_uniform_distribution() < probability_to_break)
- {
- if (partner_type(participant_id, partner_id) == 0) // if partner is long remove long partner
- number_long_partners(participant_id) -= 1;
- else
- number_short_partners(participant_id) -= 1; // if partner is short remove short partner
- partner_active(participant_id, partner_id) = 0; // partner is no longer active
- }
- }
- // update partnership from short to long
- else if ((number_long_partners(participant_id) == 0) &&
- (partner_type(participant_id, partner_id) == 1)) // if number of long partners is 0 and partner
- { // is short (can only have 1 long partner)
- if (current_date > (partner_start_date(participant_id, partner_id) +
- short_to_long_partnership)) // if partnership has lasted long enough
- {
- partner_type(participant_id, partner_id) = 0; // partner type is long
- partner_dissolution_probability(participant_id, partner_id) =
- partner_dissolution_rate_onepartner(0); // update dissolution probability to long
- partner_sex_probability(participant_id, partner_id) = sex_frequency(0) * (0.5 + sample_uniform_distribution()); // update sex probability to long
- // (with randomness)
- partner_condom_probability(participant_id, partner_id) = condom_frequency(0) *
- (0.5 + sample_uniform_distribution()); // update condom use probability to long
- // (with randomness)
- number_long_partners(participant_id) += 1; // add one more long partner
- number_short_partners(participant_id) -= 1; // remove short partner
- }
- }
- if (partner_art_status(participant_id, partner_id))
- {
- partner_art_status(participant_id, partner_id) = (sample_uniform_distribution() > art_drop_rate(partner_phase)); // drop art
- }
- else
- {
- partner_art_status(participant_id, partner_id) = (sample_uniform_distribution() < art_initiation_rate(partner_phase)); // initiate art
- }
- // partner acquire HIV outside of relationship
- if ((!partner_hiv_status(participant_id, partner_id)) && (sample_uniform_distribution() <
- (incidence_partners(partner_risk_group(participant_id, partner_id)) / average_year_days)))
- {
- partner_hiv_status(participant_id, partner_id) = 1; // partner gets infected
- partner_date_of_infection(participant_id, partner_id) = current_date; // date of infection is today
- }
- }
- } // end partnership update
- number_partners(participant_id) = number_long_partners(participant_id) +
- number_short_partners(participant_id); // update number of partners after possible break ups
- // practice sex work
- if (participant_risk_group(participant_id) == 2) // if participant is sex worker
- {
- int num_clients = sample_num_clients_distribution();
- if (num_clients > 6)
- num_clients = 6;
- for (int client_id = 0; client_id != num_clients; ++client_id)
- {
- // HIV status of partner
- if (sample_uniform_distribution() < hiv_prevalence_clients(sim_id)) // if partner is HIV positive
- {
- // partner date of infection is a random number of days before current date
- date client_partner_date_of_infection = current_date - days(sample_days_infected_distribution());
- int client_partner_art_status = 0;
- int partner_phase;
- Vector3i partner_phase_duration = phase_duration; // base phase duration
- if (current_date < (client_partner_date_of_infection +
- months(partner_phase_duration(0)))) // if partner is in acute phase
- partner_phase = 0;
- else if (current_date < (client_partner_date_of_infection + months(partner_phase_duration(0)) +
- months(partner_phase_duration(1)))) // if partner is in asymptomatic phase
- partner_phase = 1;
- else // if partner is in late phase
- partner_phase = 2;
- client_partner_art_status = (sample_uniform_distribution() < art_fraction_stage(partner_phase));
- double hiv_risk = hiv_risk_asymptomatic(sim_id);
- if (client_partner_art_status) // if partner is on ART
- {
- partner_phase_duration(1) = art_progression * partner_phase_duration(1); // ART lengthens the
- // phases
- partner_phase_duration(2) = art_progression * partner_phase_duration(2);
- hiv_risk = (1 - art_efficacy) * hiv_risk; // ART reduces HIV transmission risk
- }
- int use_condom;
- if (sample_uniform_distribution() < anal_acts_fraction_clients(sim_id)) // if anal sex act
- {
- use_condom = (sample_uniform_distribution() < anal_condom_frequency_clients(sim_id));
- hiv_risk = hiv_risk * (1 - use_condom * condom_efficacy(sim_id));
- hiv_risk = hiv_risk * relative_anal_risk(sim_id);
- }
- else
- {
- use_condom = (sample_uniform_distribution() < vaginal_condom_frequency_clients(sim_id));
- hiv_risk = hiv_risk * (1 - use_condom * condom_efficacy(sim_id));
- }
- if (current_date < (client_partner_date_of_infection +
- months(partner_phase_duration(0)))) // if partner is in acute phase
- partner_phase = 0;
- else if (current_date < (client_partner_date_of_infection + months(partner_phase_duration(0)) +
- months(partner_phase_duration(1)))) // if partner is in asymptomatic phase
- partner_phase = 1;
- else // if partner is in late phase
- partner_phase = 2;
- // HIV transmission without PrEP use
- // if without PrEP participant is NOT infected (CONTROL ARM)
- if (participant_active(participant_id, 0) && !participant_hiv_status(participant_id, 0)) // if control arm is active and not infected
- {
- ++participant_monthly_num_exposures(participant_id, 0);
- if (!partcipant_hiv_exposure(participant_id, 0)) // if participant is has not been exposed
- {
- partcipant_hiv_exposure(participant_id, 0) = 1; //participant is exposed to hiv
- ++num_exposed(participant_risk_group(participant_id), 0);
- ++num_exposed(3, 0);
- }
- if (!participant_monthly_hiv_exposure(participant_id, 0)) // if participant is has not been exposed
- {
- participant_monthly_hiv_exposure(participant_id, 0) = 1; //participant is exposed to hiv
- ++monthly_exposed(participant_risk_group(participant_id), number_month);
- ++monthly_exposed(3, number_month);
- }
- ++num_exposures(participant_risk_group(participant_id), 0);
- ++num_exposures(3, 0);
- ++num_exposures_sex_work(0);
- if (sample_uniform_distribution() < (hiv_risk * relative_phase_risk(partner_phase))) // if
- { // HIV is transmitted
- participant_hiv_status(participant_id, 0) = 1; // participant becomes infected
- participant_date_of_infection(participant_id, 0) = current_date;
- ++num_infections_sex_work(0);
- }
- }
- // HIV transmission with PrEP use
- // if with PrEP participant is NOT infected (ACTIVE ARM)
- if (participant_active(participant_id, 1) && !participant_hiv_status(participant_id, 1)) // if active arm is active and not infected
- {
- ++participant_monthly_num_exposures(participant_id, 1);
- if (!partcipant_hiv_exposure(participant_id, 1)) // if participant is has not been exposed
- {
- partcipant_hiv_exposure(participant_id, 1) = 1; //participant is exposed to hiv
- ++num_exposed(participant_risk_group(participant_id), 1);
- ++num_exposed(3, 1);
- }
- if (!participant_monthly_hiv_exposure(participant_id, 1)) // if participant is has not been exposed
- {
- participant_monthly_hiv_exposure(participant_id, 1) = 1; //participant is exposed to hiv
- ++monthly_exposed(participant_risk_group(participant_id) + 4, number_month);
- ++monthly_exposed(7, number_month);
- }
- ++num_exposures(participant_risk_group(participant_id), 1);
- ++num_exposures(3, 1);
- ++num_exposures_sex_work(1);
- // efficacy based on days enrolled
- double protection_efficacy =
- prep_efficacy(prep_scenario, participant_prep_days_count(participant_id));
- if (sample_uniform_distribution() < (hiv_risk * relative_phase_risk(partner_phase) *
- (1 - protection_efficacy))) // if HIV is transmitted
- {
- participant_hiv_status(participant_id, 1) = 1; // participant becomes infected
- participant_date_of_infection(participant_id, 1) = current_date;
- ++num_infections_sex_work(1);
- }
- }
- }
- }
- } // end casual sex
- ++participant_days_enrolled(participant_id); // participant has been enrolled for another day
- } // end active participant check
- if (participant_active(participant_id, 1))
- {
- ++participant_prep_days_count(participant_id);
- }
- }// participant loop
- cum_drop_out_gen(number_days) += total_do(0); // increment cumulative drop out
- cum_drop_out_fsw(number_days) += total_do(1); // increment cumulative drop out
- ++number_days;
- }// end days
- ++trial_duration_months;
- // monthly check up with participants, if HIV positive, remove from trial
- int num_days = (next_month - *month_itr).days(); //total follow up time for participant
- for (int participant_id = 0; participant_id != num_participants; ++participant_id)
- {
- if (participant_active(participant_id, 0)) // check if participant is active in CONTROL arm
- {
- // check if participant drops out of trial
- if (sample_uniform_distribution() <
- drop_out_rates(drop_out_scenario, participant_risk_group(participant_id))){
- // participant becomes inactive regardless of which arm they are in
- participant_active(participant_id, 0) = 0; // participant becomes inactive in CONTROL arm
- if (participant_risk_group(participant_id) == 2)
- ++total_do(1);
- else
- ++total_do(0);
- }
- ++monthly_exposures(participant_risk_group(participant_id), number_month);
- ++monthly_exposures(3, number_month);
- participant_monthly_hiv_exposure(participant_id, 0) = 0;
- participant_monthly_num_exposures(participant_id, 0) = 0;
- follow_up_days(participant_risk_group(participant_id), 0) += num_days; // total number of days since start date
- // for participant's risk group
- follow_up_days(3, 0) += num_days; // total number of days since start date for all risk groups
- if (participant_hiv_status(participant_id, 0)) // check if participant is HIV positive
- {
- ++num_infections(participant_risk_group(participant_id), 0); // increase infection counter for
- // participant's risk group
- ++num_infections(3, 0); // increase infection counter for total
- participant_active(participant_id, 0) = 0; // remove participant from trial
- }
- if (next_month >= participant_max_follow_up_date(participant_id))
- {
- participant_active(participant_id, 0) = 0; // remove participant from trial
- }
- }
- if (participant_active(participant_id, 1)) // check if participant is active in ACTIVE arm
- {
- // check if participant drops out of trial
- if (sample_uniform_distribution() <
- drop_out_rates(drop_out_scenario, participant_risk_group(participant_id))){
- // participant becomes inactive regardless of which arm they are in
- participant_active(participant_id, 1) = 0; // participant becomes inactive in ACTIVE arm
- if (participant_risk_group(participant_id) == 2)
- ++total_do(1);
- else
- ++total_do(0);
- }
- ++monthly_exposures(participant_risk_group(participant_id) + 4, number_month);
- ++monthly_exposures(7, number_month);
- participant_monthly_hiv_exposure(participant_id, 1) = 0;
- participant_monthly_num_exposures(participant_id, 1) = 0;
- ++participant_prep_month_count(participant_id);
- if (participant_prep_month_count(participant_id) >= prep_interval)
- {
- participant_prep_days_count(participant_id) = 0;
- participant_prep_month_count(participant_id) = 0;
- }
- follow_up_days(participant_risk_group(participant_id), 1) += num_days; // total number of days since start date
- // for participant's risk group
- follow_up_days(3, 1) += num_days; // total number of days since start date for all risk groups
- if (participant_hiv_status(participant_id, 1)) // check if participant is HIV positive
- {
- ++num_infections(participant_risk_group(participant_id), 1); // increase infection counter for
- // participant's risk group
- ++num_infections(3, 1); // increase infection counter for total
- participant_active(participant_id, 1) = 0; // remove participant from trial
- }
- if (next_month >= participant_max_follow_up_date(participant_id))
- {
- participant_active(participant_id, 1) = 0; // remove participant from trial
- }
- }
- }
- if ((num_infections(3, 0) + num_infections(3, 1)) >= target_infection_number) // if infection number reaches target
- {
- end_date = next_month; // end date is next month
- break; // exit loop
- }
- ++number_month;
- } // end months / end of trial
- for (int y = 0; y != num_total_months; ++y) // number exposed monthly
- {
- sim_monthly_active(sim_id, y) = participant_monthly_active(y, 0);
- sim_monthly_active(sim_id, num_total_months+y) = participant_monthly_active(y, 1);
- for (int x = 0; x != 8; ++x)
- {
- sim_monthly_exposed(sim_id, x + y * 8) = monthly_exposed(x, y);
- }
- }
- for (int y = 0; y != num_total_months; ++y) // number exposures monthly
- {
- for (int x = 0; x != 8; ++x)
- {
- sim_monthly_num_exposures(sim_id, x + y * 8) = monthly_exposures(x, y);
- }
- }
- for (int y = 0; y != 2; ++y) // calculate incidence
- {
- for (int x = 0; x != 4; ++x)
- {
- if (follow_up_days(x, y) != 0)
- {
- sim_observed_incidence(sim_id, x + 4 * y) = num_infections(x, y) /
- (follow_up_days(x, y) / average_year_days); // calculate observed yearly incidence
- }
- else
- {
- //sim_observed_incidence(sim_id, x + 4 * y) = std::numeric_limits<double>::quiet_NaN(); // incidence not observed!!
- sim_observed_incidence(sim_id, x + 4 * y) = 0; // incidence not observed!!
- }
- }
- }
- for (int y = 0; y != 2; ++y) // calculate incidence
- {
- for (int x = 0; x != 4; ++x)
- {
- if (follow_up_days(x, y) != 0)
- {
- sim_observed_incidence(sim_id, x + 4 * y) = num_infections(x, y) /
- (follow_up_days(x, y) / average_year_days); // calculate observed yearly incidence
- }
- else
- {
- //sim_observed_incidence(sim_id, x + 4 * y) = std::numeric_limits<double>::quiet_NaN(); // incidence not observed!!
- sim_observed_incidence(sim_id, x + 4 * y) = 0; // incidence not observed!!
- }
- }
- }
- if ((follow_up_days(0, 0) + follow_up_days(1, 0)) != 0){
- sim_observed_incidence(sim_id, 8) = (num_infections(0, 0) + num_infections(1, 0)) / ((follow_up_days(0, 0) +
- follow_up_days(1, 0)) / average_year_days); // calculate low and high risk only for CONTROL group
- }
- else{
- // sim_observed_incidence(sim_id, 8) = std::numeric_limits<double>::quiet_NaN();
- sim_observed_incidence(sim_id, 8) = 0;
- }
- if ((follow_up_days(0, 1) + follow_up_days(1, 1)) != 0){
- sim_observed_incidence(sim_id, 9) = (num_infections(0, 1) + num_infections(1, 1)) / ((follow_up_days(0, 1) +
- follow_up_days(1, 1)) / average_year_days); // calculate low and high risk only for ACTIVE group
- }
- else{
- // sim_observed_incidence(sim_id, 9) = std::numeric_limits<double>::quiet_NaN();
- sim_observed_incidence(sim_id, 9) = 0;
- }
- if (sim_observed_incidence(sim_id, 3) != 0)
- {
- sim_observed_efficacy(sim_id) = 1 - (sim_observed_incidence(sim_id, 7) /
- sim_observed_incidence(sim_id, 3)); // calculate observed efficacy
- }
- else{
- //sim_observed_efficacy(sim_id) = std::numeric_limits<double>::quiet_NaN(); // efficacy not observed!!
- sim_observed_efficacy(sim_id) = 0; // efficacy not observed!!
- }
- sim_trial_duration_days(sim_id) = (end_date - start_date).days(); // trial duration
- sim_trial_duration_months(sim_id) = trial_duration_months;
- for (int x = 0; x != 4; ++x) // calculate exposed fraction
- {
- if (num_participants_risk_group(x) != 0)
- {
- sim_exposed_fraction(sim_id, x) = (double)(num_exposed(x, 0) + num_exposed(x, 1)) / (num_enrolled_risk_group(x));
- } // calculate exposed fraction
- else{
- // sim_exposed_fraction(sim_id, x) = std::numeric_limits<double>::quiet_NaN(); // exposed fraction not observed!!
- sim_exposed_fraction(sim_id, x) = 0; // exposed fraction not observed!!
- }
- }
- if (num_enrolled_risk_group(0) + num_enrolled_risk_group(1) != 0){
- sim_exposed_fraction(sim_id, 4) = (double)(num_exposed(0, 0) + num_exposed(0, 1) + num_exposed(1, 0) + num_exposed(1, 1))
- / ((num_enrolled_risk_group(0) + num_enrolled_risk_group(1))); // calculate low and high risk only
- }
- else{
- // sim_exposed_fraction(sim_id, 4) = std::numeric_limits<double>::quiet_NaN();
- sim_exposed_fraction(sim_id, 4) = 0;
- }
- for (int y = 0; y != 2; ++y) // save number of infections
- {
- for (int x = 0; x != 4; ++x)
- {
- sim_num_infections(sim_id, x + 4 * y) = num_infections(x, y);
- }
- }
- sim_num_infections_sex_work(sim_id, 0) = num_infections_sex_work(0);
- sim_num_infections_sex_work(sim_id, 1) = num_infections_sex_work(1);
- for (int y = 0; y != 2; ++y) // save follow up time
- {
- for (int x = 0; x != 4; ++x)
- {
- sim_follow_up_days(sim_id, x + 4 * y) = follow_up_days(x, y);
- }
- }
- for (int y = 0; y != 2; ++y) // save number of exposed
- {
- for (int x = 0; x != 4; ++x)
- {
- sim_num_exposed(sim_id, x + 4 * y) = num_exposed(x, y);
- }
- }
- for (int y = 0; y != 2; ++y) // save number of exposures
- {
- for (int x = 0; x != 4; ++x)
- {
- sim_num_exposures(sim_id, x + 4 * y) = num_exposures(x, y);
- }
- }
- sim_num_exposures_sex_work(sim_id, 0) = num_exposures_sex_work(0);
- sim_num_exposures_sex_work(sim_id, 1) = num_exposures_sex_work(1);
- // save cumulative drop out
- sim_cum_drop_out_gen.block(sim_id, 0, 1, max_length_of_trial_days) = cum_drop_out_gen.transpose();
- sim_cum_drop_out_fsw.block(sim_id, 0, 1, max_length_of_trial_days) = cum_drop_out_fsw.transpose();
- } // end of simulations
- // write to file
- {
- std::string prep_type; // type of prep, fixed vs waning
- std::string scenarioName = "";
- std::string plotsLoc = "plots" + scenarioName + "/";
- switch (prep_scenario)
- {
- case 0:
- {
- prep_type = "60f" + scenarioName;
- break;
- }
- case 1:
- {
- prep_type = "80f" + scenarioName;
- break;
- }
- case 2:
- {
- prep_type = "100_60w" + scenarioName;
- break;
- }
- case 3:
- {
- prep_type = "100_100_20w" + scenarioName;
- break;
- }
- case 4:
- {
- prep_type = "100f" + scenarioName;
- }
- }
- {
- // save monthly exposed
- std::string title = "monthly_exposed_fsw" + std::to_string(static_cast<int>(100 * fraction_fsw_participants(enrollment_scenario)))
- + "_do" + std::to_string(static_cast<int>(100 * drop_out_rates_annual(drop_out_scenario, 0))) + "_"
- + std::to_string(static_cast<int>(100 * drop_out_rates_annual(drop_out_scenario, 2)))
- + "_e"
- + prep_type
- + ".csv";
- std::cout << "Saving file: " << title << "...";
- std::ofstream file(plotsLoc + title);
- if (file.is_open())
- {
- file << sim_monthly_exposed.format(CSV_Fmt);
- file.close();
- std::cout << "done" << std::endl;
- }
- else
- std::cout << "file could not be saved" << std::endl;
- }
- {
- // save monthly exposures
- std::string title = "monthly_exposures_fsw" + std::to_string(static_cast<int>(100 * fraction_fsw_participants(enrollment_scenario)))
- + "_do" + std::to_string(static_cast<int>(100 * drop_out_rates_annual(drop_out_scenario, 0))) + "_"
- + std::to_string(static_cast<int>(100 * drop_out_rates_annual(drop_out_scenario, 2)))
- + "_e"
- + prep_type
- + ".csv";
- std::cout << "Saving file: " << title << "...";
- std::ofstream file(plotsLoc + title);
- if (file.is_open())
- {
- file << sim_monthly_num_exposures.format(CSV_Fmt);
- file.close();
- std::cout << "done" << std::endl;
- }
- else
- std::cout << "file could not be saved" << std::endl;
- }
- {
- // save monthly active
- std::string title = "monthly_active_fsw" + std::to_string(static_cast<int>(100 * fraction_fsw_participants(enrollment_scenario)))
- + "_do" + std::to_string(static_cast<int>(100 * drop_out_rates_annual(drop_out_scenario, 0))) + "_"
- + std::to_string(static_cast<int>(100 * drop_out_rates_annual(drop_out_scenario, 2)))
- + "_e"
- + prep_type
- + ".csv";
- std::cout << "Saving file: " << title << "...";
- std::ofstream file(plotsLoc + title);
- if (file.is_open())
- {
- file << sim_monthly_active.format(CSV_Fmt);
- file.close();
- std::cout << "done" << std::endl;
- }
- else
- std::cout << "file could not be saved" << std::endl;
- }
- {
- // save incidence
- std::string title = "incidence_fsw" + std::to_string(static_cast<int>(100 * fraction_fsw_participants(enrollment_scenario)))
- + "_do" + std::to_string(static_cast<int>(100 * drop_out_rates_annual(drop_out_scenario, 0))) + "_"
- + std::to_string(static_cast<int>(100 * drop_out_rates_annual(drop_out_scenario, 2)))
- + "_e"
- + prep_type
- + ".csv";
- std::cout << "Saving file: " << title << "...";
- std::ofstream file(plotsLoc + title);
- if (file.is_open())
- {
- file << sim_observed_incidence.format(CSV_Fmt);
- file.close();
- std::cout << "done" << std::endl;
- }
- else
- std::cout << "file could not be saved" << std::endl;
- }
- {
- // save efficacy
- std::string title = "efficacy_fsw" + std::to_string(static_cast<int>(100 * fraction_fsw_participants(enrollment_scenario)))
- + "_do" + std::to_string(static_cast<int>(100 * drop_out_rates_annual(drop_out_scenario, 0))) + "_"
- + std::to_string(static_cast<int>(100 * drop_out_rates_annual(drop_out_scenario, 2)))
- + "_e"
- + prep_type
- + ".csv";
- std::cout << "Saving file: " << title << "...";
- std::ofstream file(plotsLoc + title);
- if (file.is_open())
- {
- file << sim_observed_efficacy.format(CSV_Fmt);
- file.close();
- std::cout << "done" << std::endl;
- }
- else
- std::cout << "file could not be saved" << std::endl;
- }
- {
- // save trial duration
- std::string title = "trial_duration_fsw" + std::to_string(static_cast<int>(100 * fraction_fsw_participants(enrollment_scenario)))
- + "_do" + std::to_string(static_cast<int>(100 * drop_out_rates_annual(drop_out_scenario, 0))) + "_"
- + std::to_string(static_cast<int>(100 * drop_out_rates_annual(drop_out_scenario, 2)))
- + "_e"
- + prep_type
- + ".csv";
- std::cout << "Saving file: " << title << "...";
- std::ofstream file(plotsLoc + title);
- if (file.is_open())
- {
- file << sim_trial_duration_days.format(CSV_Fmt);
- file.close();
- std::cout << "done" << std::endl;
- }
- else
- std::cout << "file could not be saved" << std::endl;
- }
- {
- // save trial duration
- std::string title = "trial_duration_months_fsw" + std::to_string(static_cast<int>(100 * fraction_fsw_participants(enrollment_scenario)))
- + "_do" + std::to_string(static_cast<int>(100 * drop_out_rates_annual(drop_out_scenario, 0))) + "_"
- + std::to_string(static_cast<int>(100 * drop_out_rates_annual(drop_out_scenario, 2)))
- + "_e"
- + prep_type
- + ".csv";
- std::cout << "Saving file: " << title << "...";
- std::ofstream file(plotsLoc + title);
- if (file.is_open())
- {
- file << sim_trial_duration_months.format(CSV_Fmt);
- file.close();
- std::cout << "done" << std::endl;
- }
- else
- std::cout << "file could not be saved" << std::endl;
- }
- {
- // save exposed fraction
- std::string title = "exposed_fraction_fsw" + std::to_string(static_cast<int>(100 * fraction_fsw_participants(enrollment_scenario)))
- + "_do" + std::to_string(static_cast<int>(100 * drop_out_rates_annual(drop_out_scenario, 0))) + "_"
- + std::to_string(static_cast<int>(100 * drop_out_rates_annual(drop_out_scenario, 2)))
- + "_e"
- + prep_type
- + ".csv";
- std::cout << "Saving file: " << title << "...";
- std::ofstream file(plotsLoc + title);
- if (file.is_open())
- {
- file << sim_exposed_fraction.format(CSV_Fmt);
- file.close();
- std::cout << "done" << std::endl;
- }
- else
- std::cout << "file could not be saved" << std::endl;
- }
- {
- // save number of infections
- std::string title = "num_infections_fsw" + std::to_string(static_cast<int>(100 * fraction_fsw_participants(enrollment_scenario)))
- + "_do" + std::to_string(static_cast<int>(100 * drop_out_rates_annual(drop_out_scenario, 0))) + "_"
- + std::to_string(static_cast<int>(100 * drop_out_rates_annual(drop_out_scenario, 2)))
- + "_e"
- + prep_type
- + ".csv";
- std::cout << "Saving file: " << title << "...";
- std::ofstream file(plotsLoc + title);
- if (file.is_open())
- {
- file << sim_num_infections.format(CSV_Fmt);
- file.close();
- std::cout << "done" << std::endl;
- }
- else
- std::cout << "file could not be saved" << std::endl;
- }
- {
- // save number of infections
- std::string title = "num_infections_sex_work_fsw" + std::to_string(static_cast<int>(100 * fraction_fsw_participants(enrollment_scenario)))
- + "_do" + std::to_string(static_cast<int>(100 * drop_out_rates_annual(drop_out_scenario, 0))) + "_"
- + std::to_string(static_cast<int>(100 * drop_out_rates_annual(drop_out_scenario, 2)))
- + "_e"
- + prep_type
- + ".csv";
- std::cout << "Saving file: " << title << "...";
- std::ofstream file(plotsLoc + title);
- if (file.is_open())
- {
- file << sim_num_infections_sex_work.format(CSV_Fmt);
- file.close();
- std::cout << "done" << std::endl;
- }
- else
- std::cout << "file could not be saved" << std::endl;
- }
- {
- // save total follow up
- std::string title = "follow_up_days_fsw" + std::to_string(static_cast<int>(100 * fraction_fsw_participants(enrollment_scenario)))
- + "_do" + std::to_string(static_cast<int>(100 * drop_out_rates_annual(drop_out_scenario, 0))) + "_"
- + std::to_string(static_cast<int>(100 * drop_out_rates_annual(drop_out_scenario, 2)))
- + "_e"
- + prep_type
- + ".csv";
- std::cout << "Saving file: " << title << "...";
- std::ofstream file(plotsLoc + title);
- if (file.is_open())
- {
- file << sim_follow_up_days.format(CSV_Fmt);
- file.close();
- std::cout << "done" << std::endl;
- }
- else
- std::cout << "file could not be saved" << std::endl;
- }
- {
- // save number of exposed
- std::string title = "num_exposed_fsw" + std::to_string(static_cast<int>(100 * fraction_fsw_participants(enrollment_scenario)))
- + "_do" + std::to_string(static_cast<int>(100 * drop_out_rates_annual(drop_out_scenario, 0))) + "_"
- + std::to_string(static_cast<int>(100 * drop_out_rates_annual(drop_out_scenario, 2)))
- + "_e"
- + prep_type
- + ".csv";
- std::cout << "Saving file: " << title << "...";
- std::ofstream file(plotsLoc + title);
- if (file.is_open())
- {
- file << sim_num_exposed.format(CSV_Fmt);
- file.close();
- std::cout << "done" << std::endl;
- }
- else
- std::cout << "file could not be saved" << std::endl;
- }
- {
- // save number of exposures
- std::string title = "num_exposures_fsw" + std::to_string(static_cast<int>(100 * fraction_fsw_participants(enrollment_scenario)))
- + "_do" + std::to_string(static_cast<int>(100 * drop_out_rates_annual(drop_out_scenario, 0))) + "_"
- + std::to_string(static_cast<int>(100 * drop_out_rates_annual(drop_out_scenario, 2)))
- + "_e"
- + prep_type
- + ".csv";
- std::cout << "Saving file: " << title << "...";
- std::ofstream file(plotsLoc + title);
- if (file.is_open())
- {
- file << sim_num_exposures.format(CSV_Fmt);
- file.close();
- std::cout << "done" << std::endl;
- }
- else
- std::cout << "file could not be saved" << std::endl;
- }
- {
- // save number of exposures
- std::string title = "num_exposures_sex_work_fsw" + std::to_string(static_cast<int>(100 * fraction_fsw_participants(enrollment_scenario)))
- + "_do" + std::to_string(static_cast<int>(100 * drop_out_rates_annual(drop_out_scenario, 0))) + "_"
- + std::to_string(static_cast<int>(100 * drop_out_rates_annual(drop_out_scenario, 2)))
- + "_e"
- + prep_type
- + ".csv";
- std::cout << "Saving file: " << title << "...";
- std::ofstream file(plotsLoc + title);
- if (file.is_open())
- {
- file << sim_num_exposures_sex_work.format(CSV_Fmt);
- file.close();
- std::cout << "done" << std::endl;
- }
- else
- std::cout << "file could not be saved" << std::endl;
- }
- {
- // save cumulative general drop out
- std::string title = "cum_gen_dropout_fsw" + std::to_string(static_cast<int>(100 * fraction_fsw_participants(enrollment_scenario)))
- + "_do" + std::to_string(static_cast<int>(100 * drop_out_rates_annual(drop_out_scenario, 0))) + "_"
- + std::to_string(static_cast<int>(100 * drop_out_rates_annual(drop_out_scenario, 2)))
- + "_e"
- + prep_type
- + ".csv";
- std::cout << "Saving file: " << title << "...";
- std::ofstream file(plotsLoc + title);
- if (file.is_open())
- {
- file << sim_cum_drop_out_gen.format(CSV_Fmt);
- file.close();
- std::cout << "done" << std::endl;
- }
- else
- std::cout << "file could not be saved" << std::endl;
- }
- {
- // save cumulative general drop out
- std::string title = "cum_fsw_dropout_fsw" + std::to_string(static_cast<int>(100 * fraction_fsw_participants(enrollment_scenario)))
- + "_do" + std::to_string(static_cast<int>(100 * drop_out_rates_annual(drop_out_scenario, 0))) + "_"
- + std::to_string(static_cast<int>(100 * drop_out_rates_annual(drop_out_scenario, 2)))
- + "_e"
- + prep_type
- + ".csv";
- std::cout << "Saving file: " << title << "...";
- std::ofstream file(plotsLoc + title);
- if (file.is_open())
- {
- file << sim_cum_drop_out_fsw.format(CSV_Fmt);
- file.close();
- std::cout << "done" << std::endl;
- }
- else
- std::cout << "file could not be saved" << std::endl;
- }
- }
- }// end enrollment scenarios
- }// end drop out scenario
- }// end prep scenarios
- auto end_time = steady_clock::now(); // end time of program in milliseconds
- auto program_duration = duration_cast<milliseconds>(end_time - start_time); // total duration of program in milliseconds
- std::cout << "The model has finished running!" << std::endl;
- std::cout << "Total runtime: " << program_duration.count() << " ms" << std::endl;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement