void IndividualHumanMalaria::CountPositiveSlideFields( RANDOMBASE * rng, int nfields, float uL_per_field, int& positive_asexual_fields, int& positive_gametocyte_fields) const { float asexual_density = GetMalariaSusceptibilityContext()->get_parasite_density(); float gametocyte_density = (m_female_gametocytes + m_male_gametocytes) * m_inv_microliters_blood; float asexual_prob_per_field = EXPCDF(-asexual_density * uL_per_field); float gametocyte_prob_per_field = EXPCDF(-gametocyte_density * uL_per_field); // binomial random draw (or poisson/normal approximations thereof) positive_asexual_fields = rng->binomial_approx2(nfields, asexual_prob_per_field); positive_gametocyte_fields = rng->binomial_approx2(nfields, gametocyte_prob_per_field); }
void VectorProbabilities::SetNodeProbabilities(INodeVectorInterventionEffects* invie, float dt) { outdoorareakilling = EXPCDF( -dt * invie->GetOutdoorKilling() ); outdoorareakilling_male = EXPCDF( -dt * invie->GetOutdoorKillingMale() ); kill_PFV = invie->GetPFVKill(); attraction_ADIV = invie->GetADIVAttraction(); attraction_ADOV = invie->GetADOVAttraction(); spatial_repellent = invie->GetVillageSpatialRepellent(); sugarTrapKilling = invie->GetSugarFeedKilling(); kill_livestockfeed = invie->GetAnimalFeedKilling(); outdoorRestKilling = invie->GetOutdoorRestKilling(); }
void VectorProbabilities::SetNodeProbabilities(INodeVectorInterventionEffects* invie, float dt) { outdoorareakilling = EXPCDF( -dt * invie->GetOutdoorKilling() ); outdoorareakilling_male = EXPCDF( -dt * invie->GetOutdoorKillingMale() ); kill_PFV = invie->GetPFVKill(); attraction_ADIV = invie->GetADIVAttraction(); attraction_ADOV = invie->GetADOVAttraction(); spatial_repellent = invie->GetVillageSpatialRepellent(); sugarTrapKilling = invie->GetSugarFeedKilling(); kill_livestockfeed = invie->GetAnimalFeedKilling(); outdoorRestKilling = invie->GetOutdoorRestKilling(); ADbiocontrol_additional_mortality = 0.0f; // AD biocontrol not implemented (this would be for non-immediate mortality, i.e. an increased mortality over the days following exposure) }
void IndividualHumanVector::ApplyTotalBitingExposure() { // Make random draw whether to acquire new infection // dt incorporated already in ExposeIndividual function arguments float acquisition_probability = float(EXPCDF(-m_total_exposure)); if ( randgen->e() >= acquisition_probability ) return; // Choose a strain based on a weighted draw over values from all vector-to-human pools float strain_cdf_draw = randgen->e() * m_total_exposure; std::vector<strain_exposure_t>::iterator it = std::lower_bound( m_strain_exposure.begin(), m_strain_exposure.end(), strain_cdf_draw, compare_strain_exposure_float_less()); AcquireNewInfection(&(it->first)); }
bool ClimateByData::IsPlausible() { // check to see whether fewer than 2.5% of the values will exceed the upper- and lower-bounds int low_index = int(num_datapoints * 0.025); int high_index = int(num_datapoints * 0.975); std::vector<float> sorted = airtemperature_data; sort(sorted.begin(), sorted.end()); if( sorted[high_index] + (2 * airtemperature_variance) > max_airtemp || sorted[low_index] - (2 * airtemperature_variance) < min_airtemp ) { return false; } sorted = landtemperature_data; sort(sorted.begin(), sorted.end()); if( sorted[high_index] + (2 * landtemperature_variance) > max_landtemp || sorted[low_index] - (2 * landtemperature_variance) < min_landtemp ) { return false; } sorted = humidity_data; sort(sorted.begin(), sorted.end()); if( sorted[high_index] > 1.0 || sorted[low_index] < 0.0 ) return false; sorted = rainfall_data; sort(sorted.begin(), sorted.end()); if(sorted[low_index] < 0) return false; if((rainfall_variance_enabled && (EXPCDF(-1 / sorted[high_index] * resolution_correction * max_rainfall) < 0.975)) || (!rainfall_variance_enabled && sorted[high_index] * resolution_correction > max_rainfall)) { return false; } return true; }
bool ClimateConstant::IsPlausible() { if( base_airtemperature + (2 * airtemperature_variance) > max_airtemp || base_airtemperature - (2 * airtemperature_variance) < min_airtemp || base_landtemperature + (2 * landtemperature_variance) > max_landtemp || base_landtemperature - (2 * landtemperature_variance) < min_landtemp || base_rainfall < 0.0 || base_humidity > 1.0 || base_humidity < 0.0 ) { LOG_DEBUG( "IsPlausible returning false\n" ); return false; } if((rainfall_variance_enabled && (EXPCDF(-1 /base_rainfall * max_rainfall) < 0.975)) || (!rainfall_variance_enabled && base_rainfall > max_rainfall)) { LOG_DEBUG( "IsPlausible returning false\n" ); return false; } return true; }
void IndividualHumanMalaria::DepositInfectiousnessFromGametocytes() { release_assert( malaria_susceptibility ); m_inv_microliters_blood = malaria_susceptibility->get_inv_microliters_blood(); // Now add a factor to limit inactivation of gametocytes by inflammatory cytokines // Important for slope of infectivity v. gametocyte counts double fever_effect = malaria_susceptibility->get_cytokines(); fever_effect = Sigmoid::basic_sigmoid(SusceptibilityMalariaConfig::cytokine_gametocyte_inactivation, float(fever_effect)); // fever_effect*=0.95; // Infectivity is reviewed by Sinden, R. E., G. A. Butcher, et al. (1996). "Regulation of Infectivity of Plasmodium to the Mosquito Vector." Advances in Parasitology 38: 53-117. // model based on data from Jeffery, G. M. and D. E. Eyles (1955). "Infectivity to Mosquitoes of Plasmodium Falciparum as Related to Gametocyte Density and Duration of Infection." Am J Trop Med Hyg 4(5): 781-789. // and Schneider, P., J. T. Bousema, et al. (2007). "Submicroscopic Plasmodium falciparum gametocyte densities frequently result in mosquito infection." Am J Trop Med Hyg 76(3): 470-474. // 2 due to bloodmeal and other factor due to conservative estimate for macrogametocyte ookinete transition, can be a higher reduction due to immune response // that factor also includes effect of successful fertilization with male gametocytes infectiousness = float(EXPCDF(-double(m_female_gametocytes) * m_inv_microliters_blood * MICROLITERS_PER_BLOODMEAL * SusceptibilityMalariaConfig::base_gametocyte_mosquito_survival * (1.0 - fever_effect))); //temp function, see vector_parameter_scratch.xlsx LOG_DEBUG_F("Gametocytes: %lld (male) %lld (female). Infectiousness=%0.2g\n", m_male_gametocytes, m_female_gametocytes, infectiousness); // Effects of transmission-reducing immunity. N.B. interventions on vector success are not here, since they depend on vector-population-specific behavior float modtransmit = susceptibility->GetModTransmit() * interventions->GetInterventionReducedTransmit(); infectiousness *= modtransmit; // Host weight is the product of MC weighting and relative biting float host_vector_weight = float(GetMonteCarloWeight() * GetRelativeBitingRate()); float weighted_infectiousnesss = host_vector_weight * infectiousness; // Effects from vector intervention container IVectorInterventionsEffects* ivie = nullptr; if ( s_OK != interventions->QueryInterface(GET_IID(IVectorInterventionsEffects), (void**)&ivie) ) { throw QueryInterfaceException( __FILE__, __LINE__, __FUNCTION__, "interventions", "IVectorInterventionsEffects", "IndividualHumanVector" ); } // Here we deposit human-to-vector infectiousness based on proportional outcrossing of strain IDs gametocytes_strain_map_t::const_iterator gc1,gc2,end=m_female_gametocytes_by_strain.end(); for (gc1=m_female_gametocytes_by_strain.begin(); gc1!=end; ++gc1) { for (gc2=gc1; gc2!=end; ++gc2) { // Fractional weight is product of component weights float strain_weight; if (gc1==gc2) { strain_weight = pow( float(gc1->second) / float(m_female_gametocytes), 2 ); DepositFractionalContagionByStrain( weighted_infectiousnesss * strain_weight, ivie, gc1->first.GetAntigenID(), gc1->first.GetGeneticID() ); continue; } // Two off-diagonal contributions given how pairwise iteration is done in this loop strain_weight = 2.0f * gc1->second * gc2->second / pow( float(m_female_gametocytes), 2 ); LOG_DEBUG_F("Crossing two strains with weight %0.2f and %0.2f\n", gc1->second/float(m_female_gametocytes), gc2->second/(float)m_female_gametocytes); // Genetic ID from first component int geneticID = gc1->first.GetGeneticID(); if ( geneticID != gc2->first.GetGeneticID() ) { // One outcrossing realization if genetic IDs are different geneticID = MalariaBarcode::getInstance()->fromOutcrossing( geneticID, gc2->first.GetGeneticID() ); LOG_DEBUG_F("Crossing geneticID %d + %d --> %d\n", gc1->first.GetGeneticID(), gc2->first.GetGeneticID(), geneticID); } // Deposit fractional infectiousness to each of indoor and outdoor pools if ( gc1->first.GetAntigenID() == gc2->first.GetAntigenID() ) { DepositFractionalContagionByStrain( weighted_infectiousnesss * strain_weight, ivie, gc1->first.GetAntigenID(), geneticID ); } else { // Deposit half the weight to each if antigenIDs are different. // Note that geneticID is not outcrossed independently for the different antigen IDs. DepositFractionalContagionByStrain( 0.5f * weighted_infectiousnesss * strain_weight, ivie, gc1->first.GetAntigenID(), geneticID ); DepositFractionalContagionByStrain( 0.5f * weighted_infectiousnesss * strain_weight, ivie, gc2->first.GetAntigenID(), geneticID ); LOG_DEBUG_F("Depositing contagion with antigenIDs %d and %d for geneticID=%d\n", gc1->first.GetAntigenID(), gc2->first.GetAntigenID(), geneticID); } } } }
void IndividualHumanMalaria::UpdateGametocyteCounts(float dt) { // Check for mature gametocyte drug killing float drugGametocyteKill = 0; IMalariaDrugEffects* imde = nullptr; if (s_OK == GetInterventionsContext()->QueryInterface(GET_IID(IMalariaDrugEffects), (void **)&imde)) { drugGametocyteKill = imde->get_drug_gametocyteM(); } else { throw QueryInterfaceException( __FILE__, __LINE__, __FUNCTION__, "GetInterventionsContext()", "IMalariaDrugEffects", "IIndividualHumanInterventionsContext" ); } // Older mature gametocytes die; then add in the newly matured ones double pkill = 0; double numkilled = 0; // Decay half-life--Sinden, R. E., G. A. Butcher, et al. (1996). "Regulation of Infectivity of Plasmodium to the Mosquito Vector." Advances in Parasitology 38: 53-117. // Smalley, M. E. and R. E. Sinden (1977). "Plasmodium falciparum gametocytes: their longevity and infectivity." Parasitology 74(01): 1-8. pkill = EXPCDF(-dt * (0.277 + drugGametocyteKill));// half-life of 2.5 days corresponds to a decay time constant of 3.6 days, 0.277 = 1/3.6 m_male_gametocytes = 0; for( gametocytes_strain_map_t::iterator gc = m_male_gametocytes_by_strain.begin(); gc != m_male_gametocytes_by_strain.end(); ) { // Gaussian approximation of binomial errors for each strain that is present numkilled = (randgen->eGauss() * sqrt(pkill * gc->second * (1.0 - pkill)) + pkill * gc->second); // halflife of 2.5 days numkilled = max(0.0, numkilled); //can't add by killing gc->second = int64_t(gc->second - numkilled); gc->second = max(0L, gc->second); if ( gc->second == 0 ) { gc = m_male_gametocytes_by_strain.erase(gc); // remove empty strains from map } else { m_male_gametocytes += gc->second; ++gc; } } m_female_gametocytes = 0; for( gametocytes_strain_map_t::iterator gc = m_female_gametocytes_by_strain.begin(); gc != m_female_gametocytes_by_strain.end(); ) { numkilled = (randgen->eGauss() * sqrt(pkill * gc->second * (1.0 - pkill)) + pkill * gc->second); // halflife of 2.5 days numkilled = max(0.0, numkilled); //can't add by killing gc->second = int64_t(gc->second - numkilled); gc->second = max(0L, gc->second); if ( gc->second == 0 ) { gc = m_female_gametocytes_by_strain.erase(gc); // remove empty strains from map } else { m_female_gametocytes += gc->second; ++gc; } } infectiousness = 0; int64_t tmp_male_gametocytes = 0; int64_t tmp_female_gametocytes = 0; StrainIdentity tmp_strainIDs; // Loop over infections and add newly matured male and female gametocytes by strain for (auto infection : infections) { // Cast from Infection --> InfectionMalaria IInfectionMalaria *tempinf = nullptr; if( infection->QueryInterface( GET_IID(IInfectionMalaria), (void**)&tempinf ) != s_OK ) { throw QueryInterfaceException( __FILE__, __LINE__, __FUNCTION__, "Infection", "IInfectionMalaria", "tempinf" ); } //InfectionMalaria *tempinf = static_cast<InfectionMalaria *>(infection); // Get gametocytes that have matured in this timestep // N.B. malariaCycleGametocytes is called once per asexual cycle (several days), // so the stage-5 counter is reset to avoid multiple counting. tmp_male_gametocytes = tempinf->get_MaleGametocytes(5); tempinf->reset_MaleGametocytes(/* stage */5); tmp_female_gametocytes = tempinf->get_FemaleGametocytes(5); tempinf->reset_FemaleGametocytes(/* stage */5); // No new gametocytes if ( tmp_male_gametocytes==0 && tmp_female_gametocytes==0 ) continue; // Add new gametocytes to those carried over (and not killed) from the previous time steps infection->GetInfectiousStrainID(&tmp_strainIDs); m_male_gametocytes_by_strain[tmp_strainIDs] += tmp_male_gametocytes; m_male_gametocytes += tmp_male_gametocytes; m_female_gametocytes_by_strain[tmp_strainIDs] += tmp_female_gametocytes; m_female_gametocytes += tmp_female_gametocytes; } }