Skip to content

Commit

Permalink
Merge pull request #215 from SwissTPH/ic50
Browse files Browse the repository at this point in the history
Ic50
  • Loading branch information
dhardy authored Nov 30, 2018
2 parents 36d35ec + 94847fa commit 7739452
Show file tree
Hide file tree
Showing 17 changed files with 86 additions and 52 deletions.
7 changes: 5 additions & 2 deletions model/PkPd/Drug/LSTMDrug.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
#include "util/checkpoint_containers.h"

namespace OM {
namespace WithinHost {
class CommonInfection;
}
namespace PkPd {

/** A class holding pkpd drug use info.
Expand Down Expand Up @@ -68,10 +71,10 @@ class LSTMDrug {
* This doesn't adjust concentration because this function may be called
* several times (for each infection) per time step, or not at all.
*
* @param genotype An identifier for the genotype of the infection.
* @param inf A pointer to the infection of interest
* @param body_mass Weight of patient in kg
*/
virtual double calculateDrugFactor(uint32_t genotype, double body_mass) const =0;
virtual double calculateDrugFactor(WithinHost::CommonInfection *inf, double body_mass) const =0;

/** Updates concentration variable and clears day's doses.
*
Expand Down
12 changes: 7 additions & 5 deletions model/PkPd/Drug/LSTMDrugConversion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
*/

#include "PkPd/Drug/LSTMDrugConversion.h"
#include "WithinHost/Infection/CommonInfection.h"
#include "util/errors.h"
#include "util/StreamValidator.h"
#include "util/vectors.h"
Expand Down Expand Up @@ -190,28 +191,29 @@ void LSTMDrugConversion::setConversionParameters(Params_convFactor& p,
}

void LSTMDrugConversion::setKillingParameters(Params_convFactor& p,
uint32_t genotype) const
WithinHost::CommonInfection *inf) const
{
uint32_t genotype = inf->genotype();
const LSTMDrugPD& pdP = parentType.getPD(genotype), &pdM =
metaboliteType.getPD(genotype);
p.nP = pdP.slope();
p.VP = pdP.max_killing_rate();
p.KnP = pdP.IC50_pow_slope();
p.KnP = pdP.IC50_pow_slope(parentType.getIndex(), inf);
p.nM = pdM.slope();
p.VM = pdM.max_killing_rate();
p.KnM = pdM.IC50_pow_slope();
p.KnM = pdM.IC50_pow_slope(metaboliteType.getIndex(), inf);
}

// TODO: in high transmission, is this going to get called more often than updateConcentration?
// When does it make sense to try to optimise (avoid doing decay calcuations here)?
double LSTMDrugConversion::calculateDrugFactor(uint32_t genotype, double body_mass) const {
double LSTMDrugConversion::calculateDrugFactor(WithinHost::CommonInfection *inf, double body_mass) const {
if( qtyG == 0.0 && qtyP == 0.0 && qtyM == 0.0 && doses.size() == 0 ){
return 1.0; // nothing to do
}

Params_convFactor p;
setConversionParameters(p, body_mass);
setKillingParameters(p, genotype);
setKillingParameters(p, inf);

double time = 0.0; // time since start of day
double totalFactor = 1.0; // survival factor for whole day
Expand Down
4 changes: 2 additions & 2 deletions model/PkPd/Drug/LSTMDrugConversion.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class LSTMDrugConversion : public LSTMDrug {

virtual void medicate (double time, double qty, double bodyMass);

virtual double calculateDrugFactor(uint32_t genotype, double body_mass) const;
virtual double calculateDrugFactor(WithinHost::CommonInfection *inf, double body_mass) const;
virtual void updateConcentration (double body_mass);
double getMetaboliteConcentration() const;
double getParentConcentration() const;
Expand Down Expand Up @@ -89,7 +89,7 @@ class LSTMDrugConversion : public LSTMDrug {

private:
void setConversionParameters(Params_convFactor& p, double body_mass) const;
void setKillingParameters(Params_convFactor& p, uint32_t genotype) const;
void setKillingParameters(Params_convFactor& p, WithinHost::CommonInfection *inf) const;
};

}
Expand Down
12 changes: 7 additions & 5 deletions model/PkPd/Drug/LSTMDrugOneComp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
*/

#include "PkPd/Drug/LSTMDrugOneComp.h"
#include "WithinHost/Infection/CommonInfection.h"
#include "util/errors.h"
#include "util/StreamValidator.h"
#include "util/vectors.h"
Expand Down Expand Up @@ -51,7 +52,7 @@ void LSTMDrugOneComp::medicate(double time, double qty, double bodyMass)

// TODO: in high transmission, is this going to get called more often than updateConcentration?
// When does it make sense to try to optimise (avoid doing decay calcuations here)?
double LSTMDrugOneComp::calculateDrugFactor(uint32_t genotype, double body_mass) const {
double LSTMDrugOneComp::calculateDrugFactor(WithinHost::CommonInfection *inf, double body_mass) const {
if( concentration == 0.0 && doses.size() == 0 ) return 1.0; // nothing to do

/* Survival factor of the parasite (this multiplies the parasite density).
Expand All @@ -63,15 +64,16 @@ double LSTMDrugOneComp::calculateDrugFactor(uint32_t genotype, double body_mass)
double concentration_today = concentration; // mg / l
double neg_elim_rate = neg_elim_sample * pow(body_mass, typeData.neg_m_exponent());

const LSTMDrugPD& drugPD = typeData.getPD(genotype);
const LSTMDrugPD& drugPD = typeData.getPD(inf->genotype());
const double Kn = drugPD.IC50_pow_slope(typeData.getIndex(), inf);

double time = 0.0;
typedef pair<double,double> TimeConc;
foreach( TimeConc time_conc, doses ){
// we iteratate through doses in time order (since doses are sorted)
if( time_conc.first < 1.0 /*i.e. today*/ ){
if( time < time_conc.first ){
totalFactor *= drugPD.calcFactor( neg_elim_rate, &concentration_today, time_conc.first - time );
totalFactor *= drugPD.calcFactor( Kn, neg_elim_rate, &concentration_today, time_conc.first - time );
time = time_conc.first;
}else{ assert( time == time_conc.first ); }
// add dose (instantaneous absorption):
Expand All @@ -81,7 +83,7 @@ double LSTMDrugOneComp::calculateDrugFactor(uint32_t genotype, double body_mass)
}
}
if( time < 1.0 ){
totalFactor *= drugPD.calcFactor( neg_elim_rate, &concentration_today, 1.0 - time );
totalFactor *= drugPD.calcFactor( Kn, neg_elim_rate, &concentration_today, 1.0 - time );
}

return totalFactor; // Drug effect per day per drug per parasite
Expand Down Expand Up @@ -128,4 +130,4 @@ void LSTMDrugOneComp::checkpoint(istream& stream){
}

}
}
}
2 changes: 1 addition & 1 deletion model/PkPd/Drug/LSTMDrugOneComp.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class LSTMDrugOneComp : public LSTMDrug {

virtual void medicate (double time, double qty, double bodyMass);

virtual double calculateDrugFactor(uint32_t genotype, double body_mass) const;
virtual double calculateDrugFactor(WithinHost::CommonInfection *inf, double body_mass) const;
virtual void updateConcentration (double body_mass);

protected:
Expand Down
10 changes: 6 additions & 4 deletions model/PkPd/Drug/LSTMDrugThreeComp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
*/

#include "PkPd/Drug/LSTMDrugThreeComp.h"
#include "WithinHost/Infection/CommonInfection.h"
#include "util/errors.h"
#include "util/StreamValidator.h"

Expand Down Expand Up @@ -161,15 +162,16 @@ double LSTMDrugThreeComp::calculateFactor(const Params_fC& p, double duration) c

// TODO: in high transmission, is this going to get called more often than updateConcentration?
// When does it make sense to try to optimise (avoid doing decay calcuations here)?
double LSTMDrugThreeComp::calculateDrugFactor(uint32_t genotype, double body_mass) const {
double LSTMDrugThreeComp::calculateDrugFactor(WithinHost::CommonInfection *inf, double body_mass) const {
if( conc() == 0.0 && doses.size() == 0 ) return 1.0; // nothing to do
updateCached(body_mass);

Params_fC p;
p.cA = concA; p.cB = concB; p.cC = concC; p.cABC = concABC;
p.na = na; p.nb = nb; p.ng = ng; p.nka = nka;
const LSTMDrugPD& pd = typeData.getPD(genotype);
p.n = pd.slope(); p.V = pd.max_killing_rate(); p.Kn = pd.IC50_pow_slope();
const LSTMDrugPD& pd = typeData.getPD(inf->genotype());
p.n = pd.slope(); p.V = pd.max_killing_rate();
p.Kn = pd.IC50_pow_slope(typeData.getIndex(), inf);

double time = 0.0; // time since start of day
double totalFactor = 1.0; // survival factor for whole day
Expand Down Expand Up @@ -284,4 +286,4 @@ void LSTMDrugThreeComp::checkpoint(istream& stream){
}

}
}
}
2 changes: 1 addition & 1 deletion model/PkPd/Drug/LSTMDrugThreeComp.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class LSTMDrugThreeComp : public LSTMDrug {

virtual void medicate (double time, double qty, double bodyMass);

virtual double calculateDrugFactor(uint32_t genotype, double body_mass) const;
virtual double calculateDrugFactor(WithinHost::CommonInfection *inf, double body_mass) const;
virtual void updateConcentration (double body_mass);

protected:
Expand Down
19 changes: 14 additions & 5 deletions model/PkPd/Drug/LSTMDrugType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

#include "PkPd/Drug/LSTMDrugType.h"
#include "WithinHost/Genotypes.h"
#include "WithinHost/Infection/CommonInfection.h"
#include "util/errors.h"
#include "util/random.h"
#include "util/CommandLine.h"
Expand Down Expand Up @@ -52,14 +53,11 @@ vector<size_t> drugsInUse;

LSTMDrugPD::LSTMDrugPD( const scnXml::Phenotype& phenotype ){
n = phenotype.getSlope ();
Kn = pow(phenotype.getIC50 (), n);
IC50.setParams(phenotype.getIC50 (), phenotype.getIC50().getSigma());
V = phenotype.getMax_killing_rate ();
if( phenotype.getIC50().getSigma() > 0.0 ){
throw util::unimplemented_exception("sampling IC50");
}
}

double LSTMDrugPD::calcFactor( double neg_elim_rate, double* conc, double duration ) const{
double LSTMDrugPD::calcFactor( double Kn, double neg_elim_rate, double* conc, double duration ) const{
const double C0 = *conc;
const double C1 = C0 * exp(neg_elim_rate * duration);

Expand All @@ -74,6 +72,17 @@ double LSTMDrugPD::calcFactor( double neg_elim_rate, double* conc, double durati
return pow( numerator / denominator, power ); // unitless
}

double LSTMDrugPD::IC50_pow_slope(size_t index, WithinHost::CommonInfection *inf) const{
double Kn; // gets sampled once per infection
if (inf->Kn.count(index) != 0) {
Kn = inf->Kn.at(index);
} else {
Kn = pow(IC50.sample(), n);
inf->Kn[index] = Kn;
}
return Kn;
}


void LSTMDrugType::init (const scnXml::Pharmacology::DrugsType& drugData) {
foreach( const scnXml::PKPDDrug& drug, drugData.getDrug() ){
Expand Down
18 changes: 11 additions & 7 deletions model/PkPd/Drug/LSTMDrugType.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ namespace scnXml{
class Phenotype;
}
namespace OM {
namespace WithinHost {
class CommonInfection;
}
namespace PkPd {
using util::LognormalSampler;

Expand All @@ -62,27 +65,28 @@ class LSTMDrugPD {
* It is expected that no drug doses are taken over the period for which
* this function calculates a drug factor.
*
* @param Kn IC50^slope, sampled per infection
* @param neg_elim_rate -k (sampled)
* @param C0 Concentration of drug in blood at start of period. Will be
* updated to correct concentration at end of period. Units: mg/l
* @param duration Timespan over which the factor is being calculated. Units: days.
* @return survival factor (unitless)
*/
double calcFactor( double neg_elim_rate, double* C0, double duration ) const;
double calcFactor( double Kn, double neg_elim_rate, double* C0, double duration ) const;

inline double slope() const{ return n; }
inline double IC50_pow_slope() const{ return Kn; }
double IC50_pow_slope(size_t index, WithinHost::CommonInfection *inf) const;
inline double max_killing_rate() const{ return V; }

private:
/// Slope of the dose response curve (no unit)
double n; // slope
/// Concentration with 50% of the maximal parasite killing to-the-power-of slope ((mg/l)^slope)
double Kn; // IC50_pow_slope
/// Concentration with 50% of the maximal parasite killing
LognormalSampler IC50; // IC50
/// Maximal drug killing rate per day (units: 1/days)
double V; // max_killing_rate;
};


/** Drug PK & PD parameters (one instance per drug type).
*
Expand Down Expand Up @@ -162,8 +166,8 @@ class LSTMDrugType {
// non-copyable (due to allocation of members of drugPhenotype)
LSTMDrugType( const LSTMDrugType& );

/** The drug index. Stored here since LTSMDrug stores a pointer to this
* struct object, not the index. */
/** The drug index in drugTypes and a unique identifier for the drug type.
* Stored here since LTSMDrug stores a pointer to this struct object, not the index. */
size_t index;

/// Index of metabolite
Expand Down
4 changes: 2 additions & 2 deletions model/PkPd/LSTMModel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,12 +128,12 @@ double LSTMModel::getDrugConc (size_t drug_index) const{
return c;
}

double LSTMModel::getDrugFactor (uint32_t genotype, double body_mass) const{
double LSTMModel::getDrugFactor (WithinHost::CommonInfection *inf, double body_mass) const{
double factor = 1.0; //no effect

for( DrugVec::const_iterator drug = m_drugs.begin(), end = m_drugs.end();
drug != end; ++drug ){
double drugFactor = drug->calculateDrugFactor(genotype, body_mass);
double drugFactor = drug->calculateDrugFactor(inf, body_mass);
factor *= drugFactor;
}
return factor;
Expand Down
5 changes: 4 additions & 1 deletion model/PkPd/LSTMModel.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ namespace OM {
namespace Host{
class Human;
}
namespace WithinHost {
class CommonInfection;
}
namespace PkPd {
using boost::ptr_vector;

Expand Down Expand Up @@ -124,7 +127,7 @@ class LSTMModel {
* Each time step, on each infection, the parasite density is multiplied by
* the return value of this infection. The WithinHostModels are responsible
* for clearing infections once the parasite density is negligible. */
double getDrugFactor (uint32_t genotype, double body_mass) const;
double getDrugFactor (WithinHost::CommonInfection *inf, double body_mass) const;

/** After any resident infections have been reduced by getDrugFactor(),
* this function is called to update drug levels to their effective level
Expand Down
6 changes: 3 additions & 3 deletions model/WithinHost/CommonWithinHost.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,9 +191,9 @@ void CommonWithinHost::update(int nNewInfs, vector<double>& genotype_weights,
bool expires = ((*inf)->bloodStage() ? treatmentBlood : treatmentLiver);

if( !expires ){ /* no expiry due to simple treatment model; do update */
double survivalFactor = survivalFactor_part *
(*inf)->immunitySurvivalFactor(ageInYears, cumulative_h, cumulative_Y) *
pkpdModel.getDrugFactor((*inf)->genotype(), body_mass);
const double drugFactor = pkpdModel.getDrugFactor(*inf, body_mass);
const double immFactor = (*inf)->immunitySurvivalFactor(ageInYears, cumulative_h, cumulative_Y);
const double survivalFactor = survivalFactor_part * immFactor * drugFactor;
// update, may result in termination of infection:
expires = (*inf)->update(survivalFactor, now, body_mass);
}
Expand Down
4 changes: 3 additions & 1 deletion model/WithinHost/Infection/CommonInfection.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ class CommonInfection : public Infection {
return updateDensity( survivalFactor, bsAge, body_mass );
}

map<size_t, double> Kn; // IC50^slope per drug type, if sampled

protected:
/** Update: calculate new density.
*
Expand All @@ -83,4 +85,4 @@ class CommonInfection : public Infection {
};

} }
#endif
#endif
5 changes: 4 additions & 1 deletion model/WithinHost/Infection/DummyInfection.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@

namespace OM { namespace WithinHost {

//! Create a dummy infection (used directly by unit test).
CommonInfection* createDummyInfection (uint32_t protID);

//! Models of infection.
/*!
Models related to the within-host dynamics of infections.
Expand All @@ -44,4 +47,4 @@ class DummyInfection : public CommonInfection {
};

} }
#endif
#endif
Loading

0 comments on commit 7739452

Please sign in to comment.