function M = HIVmodel(Drugs,DrugCombos,Selective_Disadvantage,Resistance) % % This function builds the original HIV model (see von Kleist M, Menz S, % Stocker H, Arasteh K, Huisinga W, Schuette S (2011) "HIV Quasispecies % Dynamics during Pro-active Treatment Switching: Impact on Multi-Drug % Resistance and Resistance Archiving in Latent Reservoirs", PlosOne, and % von Kleist M, Menz S, Huisinga W (2010) "Drug-Class Specific Impact of % Antivirals on the Reproductive Capacity of HIV", PLoS Comput Biol 6(3):e1000720 % % Input arguments are: % % 1st) Matrix of available drugs, specifying drug target (1st column) % and drug efficacies (2nd column) % % 2nd) Matrix of drug combinations, each row specifies a combination % with entries referring to the index of the drug in the 1st % argument % % 3rd) Selective disadvantage (relative to wildtype) % % 4th) Resistance (relative to wildtype) of each mutant against the % corresponding drug % % % Copyright (C) 2011, Free University Berlin % Contact: vkleist@zedat.fu-berlin.de % % FOR ACADEMIC USE this program is free software; you can redistribute % it and/or modify it under the terms of the GNU General Public License % as published by the Free Software Foundation; either version 2 % of the License, or (at your option) any later version. % % This program is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License for more details. % % You should have received a copy of the GNU General Public License % along with this program; if not, write to the Free Software % Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, % USA. %%%%%%%%%% START %%%%%%%%%% % get drug specific parameters AvailableTargets = 4; NrDrugs = size(Drugs,1); % total number of drugs NrCombinations = size(DrugCombos,1); % total number of drug combinations % check consistancy if ~isempty(find(Drugs(:,1) < 1 | Drugs(:,1) > AvailableTargets, 1)) error('Model:argChk',... ['\nAvailable indices of drug classes are:\n\n'... '\t1 - entry inhibitors (FI/CCR5)\n'... '\t2 - reverse transcriptase inhibitors (NRTI/NNRTI)\n'... '\t3 - integrase (InI) \n'... '\t4 - protease (PI)/ maturation inhibitors (MI)']); end if ~isempty(find(DrugCombos < 1 | DrugCombos > NrDrugs, 1)) error('Model:argChk',... '\nSpecify drug combinations by reffering to valid indices of drugs.'); end % set system specific parameters NrMutants = 2^NrDrugs; % total number of different mutants NrSpeciesPerMutant = 6; % number of species per mutant NrSpecies = 3 + NrSpeciesPerMutant*NrMutants; % total number of different species NrReactionsPerMutant = 3*NrMutants + 9; % number of reactions per mutant NrDeathReactionsPerMutant = 8; % number of death reactions per mutant NrReactions = 5 + (NrReactionsPerMutant+NrDeathReactionsPerMutant)*NrMutants; % total number of different reactions % model parameters used for simulation (see Tabel 1 in main article) lambda_T = 2.0e9; % birth rate of unifected T-cells in unit [1/day] lambda_M = 6.9e7; % birth rate of unifected macrophages in unit [1/day] death_T = 0.02; % death rate of unifected T-cells in unit [1/day] death_T1 = 0.02; % death rate of T1-cells in unit [1/day] death_T2 = 1.0; % death rate of T2-cells in unit [1/day] death_TL = 0.0001; % death rate of latently infected T-cells (TL-cells) in unit [1/day] death_M = 0.0069; % death rate of unifected macrophages in unit [1/day] death_M1 = 0.0069; % death rate of M1-cells in unit [1/day] death_M2 = 0.09; % death rate of M2-cells in unit [1/day] deathPIC_T = 0.35; % intracellular degradation rate of pre-integration complex within T-cells in unit [1/day] deathPIC_M = 0.0035; % intracellular degradation rate of pre-integration complex within macrophages in unit [1/day] beta_T = 8.0e-12; % rate of successfull infection of T-cells in unit [1/day] beta_M = 1.0e-14; % rate of successfull infection of mcarophages in unit [1/day] k_T = 0.35; % integration rate constant in T-cells in unit [1/day] k_M = 0.07; % integration rate constant in M-cells in unit [1/day] n_T = 1000; % total number of released virus from T2-cells in unit [1/day] n_M = 100; % total number of released virus from M2-cells in unit [1/day] CL = 23.0; % clearance rate of virus in unit [1/day] mu = 2.16e-5; % point mutation probability per base and reverse transcritpion process rho = 0.33; % probability that reverse transcription is successfully completed p_latent = 8e-6; % probability that a T-cell becomes latently infected alpha = 0.001; % activation rate of TL-cells frac_uninfect = 0.33; % fraction of uninfectious virus PlasmaFac = 236750.0; % blood plasma conversion factor in unit [mL plasma/HIV RNA] % derived auxilliary variables one_minus_select_dis = 1.0 - Selective_Disadvantage; frac_infect = 1.0 - frac_uninfect; nT_dT2 = frac_infect*n_T/death_T2; nM_dM2 = frac_infect*n_M/death_M2; rho_inv = 1.0/rho; p_unlatent = 1.0 - p_latent; one_minus_p_death_r_TL = 1.0 - p_latent*death_TL/(alpha + death_TL); alpha_r_TL = alpha/(alpha + death_TL); % compute matrices of selective disadvantage and resistances of the mutants SelectionMatrix = ones(AvailableTargets,NrMutants); % selective disadvantages of mutants for every target (1st dimension target, 2nd mutant) MutationMatrix = zeros(NrDrugs,NrMutants); % mutation scheme of mutants against the drugs (1st dimension drug, 2nd mutant) for i = 1:NrMutants % get possible mutation scheme MutationMatrix(:,i) = (int16(bitget(i-1, NrDrugs:-1:1)))'; % find resistant mutations, and DrugIDs = find(MutationMatrix(:,i)); % set slective disadvantage and resistance accordingly if ~isempty(DrugIDs) for j = 1:length(DrugIDs) actualDrug = DrugIDs(j); SelectionMatrix(Drugs(actualDrug,1),i) = SelectionMatrix(Drugs(actualDrug,1),i).*one_minus_select_dis; end end end % resistances of mutants for every target (1st dimension drug, 2nd mutant) ResistanceMatrix = double(MutationMatrix)*Resistance; % compute resistances of the mutants ResistanceMatrix(ResistanceMatrix == 0) = 1; % compute distances of the mutations p = zeros(NrMutants,NrMutants); % mutation probabilities between the different strains for i = 1:NrMutants for j = 1:NrMutants p(i,j) = sum(abs(MutationMatrix(:,i) - MutationMatrix(:,j))); end end p = (mu.^p).*((1-mu).^(NrDrugs-p))'; clear MutationMatrix mu % compute the efficacies of the considered drug combinations Efficacies = ones(NrCombinations,AvailableTargets,NrMutants); % drug efficacies against mutants for every drug combination and target (1st dimension drug combination, 2nd drug target, 3rd mutant) for i = 1:NrCombinations for k = 1:NrMutants for j = DrugCombos(i,:) Efficacies(i,Drugs(j,1),k) = Efficacies(i,Drugs(j,1),k)*(1 - Drugs(j,2)*ResistanceMatrix(j,k)); end end end clear ResistanceMatrix % set system stoichiometry R = sparse(NrSpecies,NrReactions); % net changes in species levels caused by firing of the reactions (1st dimension species, 2nd reaction) V = repmat(struct('reactants',[]),1,NrReactions-2); % index structure of the reactants of every reactions R(1,1) = 1; % birth of TU: -> TU R(2,2) = 1; % birth of MU: -> MU j = 3; % index of reaction (row index) for i = 1:NrMutants % iterate through mutants % infection: TU + V(i) -> T1(i) R(1,j) = -1; % TU R(8+NrSpeciesPerMutant*(i-1),j) = -1; % V(i) R(3+NrSpeciesPerMutant*(i-1),j) = +1; % T1(i) V(j-2).reactants = [1 8+NrSpeciesPerMutant*(i-1)]; % reactants are TU and V(j) j = j+1; % clearance of PIC: T1(i) -> TU R(3+NrSpeciesPerMutant*(i-1),j) = -1; % T1(i) R(1,j) = +1; % TU V(j-2).reactants = 3+NrSpeciesPerMutant*(i-1); % reactant is T1(i) j = j+1; % I. transition/mutation: T1(q) -> T2(i) k = 0; for q = j:j+NrMutants-1 R(3+NrSpeciesPerMutant*k,q) = -1; % T1(q) V(q-2).reactants = 3+NrSpeciesPerMutant*k; % reactant is T1(q) k = k+1; end R(4+NrSpeciesPerMutant*(i-1),j:j+NrMutants-1) = +1; % T2(i) j = j+NrMutants; % II. transition/mutation: T1(q) -> TL(i) k = 0; for q = j:j+NrMutants-1 R(3+NrSpeciesPerMutant*k,q) = -1; % T1(q) V(q-2).reactants = 3+NrSpeciesPerMutant*k; % reactant is T1(q) k = k+1; end R(5+NrSpeciesPerMutant*(i-1),j:j+NrMutants-1) = +1; % TL(i) j = j+NrMutants; % activation of latent cells: TL(i) -> T2(i) R(5+NrSpeciesPerMutant*(i-1),j) = -1; % TL(i) R(4+NrSpeciesPerMutant*(i-1),j) = +1; % T2(i) V(j-2).reactants = 5+NrSpeciesPerMutant*(i-1); % reactant is TL(i) j = j+1; % infection: MU + V(i) -> M1(i) R(2,j) = -1; % MU R(8+NrSpeciesPerMutant*(i-1),j) = -1; % V(i) R(6+NrSpeciesPerMutant*(i-1),j) = +1; % M1(i) V(j-2).reactants = [2 8+NrSpeciesPerMutant*(i-1)]; % reactants are MU and V(i) j = j+1; % clearance of PIC: M1(i) -> MU R(6+NrSpeciesPerMutant*(i-1),j) = -1; % M1(i) R(2,j) = +1; % MU V(j-2).reactants = 6+NrSpeciesPerMutant*(i-1); % reactant is M1(i) j = j+1; % III. transition/mutation: M1(q) -> M2(i) k = 0; for q = j:j+NrMutants-1 R(6+NrSpeciesPerMutant*k,q) = -1; % M1(q) V(q-2).reactants = 6+NrSpeciesPerMutant*k; % reactant is M1(q) k = k+1; end R(7+NrSpeciesPerMutant*(i-1),j:j+NrMutants-1) = +1; % M2(i) j = j+NrMutants; % Ia. production: T2(i) -> V(i) + T2(i) R(8+NrSpeciesPerMutant*(i-1),j) = +1; % V(i) V(j-2).reactants = 4+NrSpeciesPerMutant*(i-1); % reactant is T2(i) j = j+1; % Ib. production: T2(i) -> V_NI + T2(i) R(end,j) = +1; % V_NI V(j-2).reactants = 4+NrSpeciesPerMutant*(i-1); % reactant is T2(i) j = j+1; % IIa. production: M2(i) -> V(i) + M2(i) R(8+NrSpeciesPerMutant*(i-1),j) = +1; % V(i) V(j-2).reactants = 7+NrSpeciesPerMutant*(i-1); % M2(i) j = j+1; % IIb. production: M2(i) -> V_NI + M2(i) R(end,j) = +1; % V_NI V(j-2).reactants = 7+NrSpeciesPerMutant*(i-1); % M2(i) j = j+1; end % death reactions r = 2 + NrReactionsPerMutant*NrMutants; % death of TU: TU -> R(1,r+1) = -1; % TU V(r-1).reactants = 1; % reactant is TU % death of MU: MU -> R(2,r+2) = -1; % MU V(r).reactants = 2; % reactant is MU j = 3; l = 3; for i = 1:NrMutants n = l; % all natural death events for s = j:j+NrSpeciesPerMutant-1 R(s,r+n) = -1; V(r+n-2).reactants = s; n = n+1; end j = j+NrSpeciesPerMutant; l = l+NrSpeciesPerMutant; % Ia. clearance of virus by infection: TU + V(i) -> TU R(j-1,r+l) = -1; % V(i) V(r+l-2).reactants = [1 j-1]; % reactants are TU and V(i) % clearance of virus by infection: MU + V(i) -> MU R(j-1,r+l+1) = -1; % V(i) V(r+l-1).reactants = [2 j-1]; % reactants are MU and V(i) l = l+2; end % death of V_NI: V_NI -> R(NrSpecies,NrReactions) = -1; % V_NI V(NrReactions-2).reactants = NrSpecies; % reactant is V_NI % reactions constants (only birth/death reactions) c = zeros(NrReactions,1); % set fixed values of c c(1) = lambda_T; % -> TU c(2) = lambda_M; % -> MU for i = 0:NrMutants-1 c(4 + i*NrReactionsPerMutant) = deathPIC_T; % T1(i) -> TU(i) c(5 + 2*NrMutants + i*NrReactionsPerMutant) = alpha; % TL(i) -> T2(i) c(7 + 2*NrMutants + i*NrReactionsPerMutant) = deathPIC_M; % M1(i) -> MU(i) c(5 + NrReactionsPerMutant*NrMutants + i*NrDeathReactionsPerMutant) = death_T1; % T1(i) -> c(6 + NrReactionsPerMutant*NrMutants + i*NrDeathReactionsPerMutant) = death_T2; % T2(i) -> c(7 + NrReactionsPerMutant*NrMutants + i*NrDeathReactionsPerMutant) = death_TL; % TL(i) -> c(8 + NrReactionsPerMutant*NrMutants + i*NrDeathReactionsPerMutant) = death_M1; % M1(i) -> c(9 + NrReactionsPerMutant*NrMutants + i*NrDeathReactionsPerMutant) = death_M2; % M2(i) -> c(10 + NrReactionsPerMutant*NrMutants + i*NrDeathReactionsPerMutant) = CL; % V(i) -> end c(3 + NrReactionsPerMutant*NrMutants) = death_T; % TU -> c(4 + NrReactionsPerMutant*NrMutants) = death_M; % MU -> c(NrReactions) = CL; % V_NI -> % reaction propensities a = zeros(NrReactions,1); function [] = propensities(y) % initialize propensities with reaction constants a = c; % first two reactions are independent from statse y for i = 3:NrReactions % first two reactions are independent from y a(i) = a(i)*prod(y(V(i-2).reactants)); end end % partition of the reactions (zero = deterministic, one = stochastic) partition = zeros(NrReactions,1); asd = 0; % all reactions with propensities less than 'asd_dflt' will be treated stochastically, otherwise deterministically ysd = 0; % all reactions with any reactant level less than 'ysd_dflt' will be treated stochastically, otherwise deterministically function [] = set_partition(y) propensities(y); for r = 3:NrReactions if a(r) < asd partition(r) = 1; else Reactants = V(r-2).reactants; for s = 1:length(Reactants) if R(Reactants(s),r) && y(Reactants(s)) < ysd partition(r) = 1; break end end end end end % return value of the right hand side (ydot) at time t for given state y function ydot = RHS(t,y) % get propensities propensities(y); % compute right hand side ydot = [R*((1-partition).*a); partition'*a]; end % set all reaction rate constants for specified drug combination dc function [] = set_drugcombination(dc) % get efficacies that correspond to the drug combination dc if dc efficacies = reshape(Efficacies(dc,:,:),AvailableTargets,NrMutants); else efficacies = ones(AvailableTargets,NrMutants); end r = 3; % rate constants of first two reactions never change % iterate for mutants for i = 1:NrMutants c(r) = beta_T*SelectionMatrix(1,i)*efficacies(1,i)*SelectionMatrix(2,i)*efficacies(2,i); % TU + VI(i) -> T1(i) [successful infection of T-cells] r = r+2; for j = 1:NrMutants c(r) = p_unlatent*p(j,i)*k_T*SelectionMatrix(3,j)*efficacies(3,j); % T1(i) -> T2(j) [proviral integration + phenotypic mutation] c(r+NrMutants) = p_latent*p(j,i)*k_T*SelectionMatrix(3,j)*efficacies(3,j); % T1(i) -> TL(j) [proviral integration + phenotypic mutation] c(r+2*NrMutants+3) = p(j,i)*k_M*SelectionMatrix(3,j)*efficacies(3,j); % M1(i) -> M2(j) [proviral integration + phenotypic mutation] r = r+1; end r = r+ NrMutants + 1; c(r) = beta_M*SelectionMatrix(1,i)*efficacies(1,i)*SelectionMatrix(2,i)*efficacies(2,i); % MU + VI(i) -> M1(i) [successful infection of M-cells] r = r+NrMutants+2; c(r) = n_T*frac_infect*SelectionMatrix(4,i)*efficacies(4,i); % T2(i) -> VI(i) + T2(i) [release of infectious Virus from productively infect. T-cells] r = r+1; c(r) = n_T*(1.0 - frac_infect*SelectionMatrix(4,i)*efficacies(4,i)); % T2(i) -> VNI + T2(i) [release of non-infectious Virus from productively infect. T-cells] r = r+1; c(r) = n_M*frac_infect*SelectionMatrix(4,i)*efficacies(4,i); % M2(i) -> VI(i) + M2(i) [release of infectious Virus from productively infect. M-cells] r = r+1; c(r) = n_M*(1.0 - frac_infect*SelectionMatrix(4,i)*efficacies(4,i)); % M2(i) -> VNI + M2(i) [release of non-infectious Virus from productively infect. M-cells] r = r+1; c(11 + NrReactionsPerMutant*NrMutants + (i-1)*NrDeathReactionsPerMutant) = beta_T*SelectionMatrix(1,i)*efficacies(1,i)*(rho_inv - SelectionMatrix(2,i)*efficacies(2,i)); % TU + VI(i) -> TU [clearance of virus by unsuccessful infection of T-cells] c(12 + NrReactionsPerMutant*NrMutants + (i-1)*NrDeathReactionsPerMutant) = beta_M*SelectionMatrix(1,i)*efficacies(1,i)*(rho_inv - SelectionMatrix(2,i)*efficacies(2,i)); % MU + VI(i) -> MU [clearance of virus by unsuccessful infection of M-cells] end end % compute and return initial conditions of the system: % initial state is approximated by a pre-run of length T, % if the flag 'wt_only' is set to true the inital state will contain no mutants function y0 = set_initial_conditions(T,wt_only) % pseudo-initial loads (obtained by pure deterministic simulations, used as initial conditions for pre-run) Initial_T = 2.0e11 + 0.02*2.0e11 - 1.0e6 - 1.0e5; Initial_T1 = 1.0e5; Initial_T2 = 1.0e6; Initial_TL = 1.0e5; Initial_M = 2.0e9 + 0.02*2.0e9 - 1.0e6 - 1.0e5; Initial_M1 = 1.0e3; Initial_M2 = 1.0e4; Initial_V = 17.5e6; % set pseudo-initial species numbers y0 = [zeros(NrSpecies,1); 0]; y0(1:8) = [Initial_T;Initial_M;Initial_T1;Initial_T2;Initial_TL;Initial_M1;Initial_M2;Initial_V]; % compute reaction constants for the case when no drug is given if wt_only SelectionMatrixBackUp = SelectionMatrix; SelectionMatrix(1:AvailableTargets,2:end) = 0; end set_drugcombination(0); % initially set all reaction to deterministic partition = zeros(NrReactions,1); set_asd(0); set_ysd(0); % integrator options: all species numbers have non-negative values! options = odeset('NonNegative',1:NrSpecies); % compute initial species numbers [t,y] = ode15s(@RHS,[0 T],y0,options); % set initial species vector y0 = round(y(end,:)); if wt_only y0(8:end-2) = 0; SelectionMatrix = SelectionMatrixBackUp; clear SelectionMatrixBackUp; end % draw first random number for stochastic reaction event y0(end) = log(rand); % choose first drug combination set_drugcombination(1); % set default partitioning thresholds and update partitioning set_asd(asd_dflt); set_ysd(ysd_dflt); set_partition(y0); end % functions to set partitioning thresholds function [] = set_asd(threshold) asd = threshold; end function [] = set_ysd(threshold) ysd = threshold; end % set default partitioning thresholds asd_dflt = 20; ysd_dflt = 20; set_asd(asd_dflt); set_ysd(ysd_dflt); % event function of stochastic reaction function [value,isterminal,direction] = reaction_event(y) value = y(end); isterminal = 1; direction = 1; end % perform stochastic reaction event function y = perform_reaction_event(y) propensities(y); % compute propensities of all reactions a = partition.*a; % take only stochastic reaction r = find(cumsum(a) >= sum(a)*rand,1); % and choose a reaction (first reaction algorithm by Gillespie) y = [max(y(1:end-1)+R(:,r)',0) log(rand)]; % update species levels accordingly and draw new random number % update partitioning of reactions set_partition(y); end % compute and return viral load at state y function vl = get_viral_load(y) vl = y(end-1); % V_NI for m = 1:NrMutants vl = vl+y((m-1)*NrSpeciesPerMutant + 8); end vl = vl/PlasmaFac; end % compute and return reproductive capacities at state y function rc = get_reproductive_capacities(y) rc = zeros(1,NrCombinations); for i = 1:NrCombinations n = 3; r = 6; for m = 1:NrMutants CL_by_infT = SelectionMatrix(1,m)*Efficacies(i,1,m); TUbeta = CL_by_infT*SelectionMatrix(2,m)*Efficacies(i,2,m); CL_by_infT = CL_by_infT/rho - TUbeta; CL_by_infM = y(2)*beta_M*CL_by_infT; CL_by_infT = CL_by_infT*y(1)*beta_T; MUbeta = y(2)*beta_M*TUbeta; TUbeta = TUbeta*y(1)*beta_T; trans_rateT = SelectionMatrix(3,m)*Efficacies(i,3,m); trans_rateM = k_M*trans_rateT; trans_rateT = trans_rateT*k_T; trans_deathT = trans_rateT/(death_T1 + deathPIC_T + trans_rateT); trans_deathM = trans_rateM/(death_M1 + deathPIC_M + trans_rateM); rc(i) = rc(i) + (TUbeta + MUbeta) * (y(n)*nT_dT2*trans_deathT*one_minus_p_death_r_TL + y(r)*nM_dM2*trans_deathM); n = n+1; r = r+1; rc(i) = rc(i) + (TUbeta*trans_deathT + MUbeta*trans_deathM) * (y(n)*nT_dT2 + y(n+1)*nT_dT2*alpha_r_TL + y(r)*nM_dM2); r = r+1; rc(i) = rc(i) + y(r)*(TUbeta*nT_dT2*trans_deathT*one_minus_p_death_r_TL + MUbeta*nM_dM2*trans_deathM); rc(i) = rc(i) / (CL + CL_by_infT + TUbeta + CL_by_infM + MUbeta)*SelectionMatrix(4,m)*Efficacies(i,4,m); n = n+5; r = r+4; end end end % return functions for interaction with the model M.NrSpecies = NrSpecies; M.RHS = @RHS; M.set_drugcombination = @set_drugcombination; M.set_initial_conditions = @set_initial_conditions; M.set_asd = @set_asd; M.set_ysd = @set_ysd; M.set_partition = @set_partition; M.reaction_event = @reaction_event; M.perform_reaction_event = @perform_reaction_event; M.get_viral_load = @get_viral_load; M.get_reproductive_capacities = @get_reproductive_capacities; end