https://github.com/PublicHealthDynamicsLab/FRED
Revision a45e04ad99c865724a3c2b1a2d3fd979b3c6be88 authored by John Grefenstette on 07 January 2016, 16:32:02 UTC, committed by John Grefenstette on 07 January 2016, 16:32:02 UTC
1 parent 9bc2dce
Tip revision: a45e04ad99c865724a3c2b1a2d3fd979b3c6be88 authored by John Grefenstette on 07 January 2016, 16:32:02 UTC
working markov epidemic model
working markov epidemic model
Tip revision: a45e04a
Household.h
/*
This file is part of the FRED system.
Copyright (c) 2010-2015, University of Pittsburgh, John Grefenstette,
Shawn Brown, Roni Rosenfield, Alona Fyshe, David Galloway, Nathan
Stone, Jay DePasse, Anuroop Sriram, and Donald Burke.
Licensed under the BSD 3-Clause license. See the file "LICENSE" for
more information.
*/
//
//
// File: Household.h
//
#ifndef _FRED_HOUSEHOLD_H
#define _FRED_HOUSEHOLD_H
#include <map>
#include <bitset>
#include <set>
#include "Global.h"
#include "Hospital.h"
#include "Place.h"
class Person;
class HH_Adult_Sickleave_Data;
// The following enum defines symbolic names for Household Income. These categories are defined by the RTI Synthetic
// Population (see Quickstart Guide https://www.epimodels.org/midas/Rpubsyntdata1.do for description)
// Note that these are just for classification purposes. We leave it to researchers
// to define the income that actually corresponds to the income level.
// The last element should always be UNCLASSIFIED.
namespace Household_income_level_code {
enum e {
CAT_I,
CAT_II,
CAT_III,
CAT_IV,
CAT_V,
CAT_VI,
CAT_VII,
UNCLASSIFIED
};
};
/**
* The following enum defines symbolic names for whether or not a household
* member is currently on an extended absence from the household.
* The last element should always be HOUSEHOLD_EXTENDED_ABSENCE.
*/
namespace Household_extended_absence_index {
enum e {
HAS_HOSPITALIZED,
//HAS_IN_PRISON,
//HAS_IN_NURSING_HOME,
//HAS_IN_COLLEGE_DORM,
HOUSEHOLD_EXTENDED_ABSENCE
};
};
/**
* The following enum defines symbolic names for places that
* members of this household may visit.
* The last element should always be HOUSEHOLD_VISITATION.
*/
namespace Household_visitation_place_index {
enum e {
HOSPITAL,
//PRISON,
//NURSING_HOME,
//COLLEGE_DORM,
HOUSEHOLD_VISITATION
};
};
/**
* This class represents a household location in the FRED application. It inherits from <code>Place</code>.
* The class contains static variables that will be filled with values from the parameter file.
*
* @see Place
*/
class Household : public Place {
public:
static std::map<int, int> count_inhabitants_by_household_income_level_map;
static std::map<int, int> count_children_by_household_income_level_map;
static std::map<long int, int> count_inhabitants_by_census_tract_map;
static std::map<long int, int> count_children_by_census_tract_map;
static std::set<long int> census_tract_set;
static const char* household_income_level_lookup(int idx) {
assert(idx >= 0);
assert(idx <= Household_income_level_code::UNCLASSIFIED);
switch(idx) {
case Household_income_level_code::CAT_I:
return "cat_I";
case Household_income_level_code::CAT_II:
return "cat_II";
case Household_income_level_code::CAT_III:
return "cat_III";
case Household_income_level_code::CAT_IV:
return "cat_IV";
case Household_income_level_code::CAT_V:
return "cat_V";
case Household_income_level_code::CAT_VI:
return "cat_VI";
case Household_income_level_code::CAT_VII:
return "cat_VII";
case Household_income_level_code::UNCLASSIFIED:
return "Unclassified";
default:
Utils::fred_abort("Invalid Household Income Level Code", "");
}
return NULL;
}
static int get_household_income_level_code_from_income(int income) {
if(income < 0) {
return Household_income_level_code::UNCLASSIFIED;
} else if(income < Household::Cat_I_Max_Income) {
return Household_income_level_code::CAT_I;
} else if(income < Household::Cat_II_Max_Income) {
return Household_income_level_code::CAT_II;
} else if(income < Household::Cat_III_Max_Income) {
return Household_income_level_code::CAT_III;
} else if(income < Household::Cat_IV_Max_Income) {
return Household_income_level_code::CAT_IV;
} else if(income < Household::Cat_V_Max_Income) {
return Household_income_level_code::CAT_V;
} else if(income < Household::Cat_VI_Max_Income) {
return Household_income_level_code::CAT_VI;
} else {
return Household_income_level_code::CAT_VII;
}
}
/**
* Default constructor
* Note: really only used by Allocator
*/
Household();
/**
* Constructor with necessary parameters
*/
Household(const char* lab, char _subtype, fred::geo lon, fred::geo lat);
~Household() {}
static void get_parameters();
/**
* @see Place::get_group(int disease, Person* per)
*/
int get_group(int disease, Person* per);
/**
* @see Mixing_Group::get_transmission_prob(int disease_id, Person* i, Person* s)
*
* This method returns the value from the static array <code>Household::Household_contact_prob</code> that
* corresponds to a particular age-related value for each person.<br />
* The static array <code>Household_contact_prob</code> will be filled with values from the parameter
* file for the key <code>household_prob[]</code>.
*/
double get_transmission_prob(int disease_id, Person* i, Person* s);
double get_transmission_probability(int disease, Person* i, Person* s);
/**
* @see Place::get_contacts_per_day(int disease)
*
* This method returns the value from the static array <code>Household::Household_contacts_per_day</code>
* that corresponds to a particular disease.<br />
* The static array <code>Household_contacts_per_day</code> will be filled with values from the parameter
* file for the key <code>household_contacts[]</code>.
*/
double get_contacts_per_day(int disease);
/**
* Use to get list of all people in the household.
* @return vector of pointers to people in household.
*/
vector<Person*> get_inhabitants() {
return this->enrollees;
}
/**
* Set the household income.
*/
void set_household_income(int x) {
this->household_income = x;
this->set_household_income_code(static_cast<int>(Household::get_household_income_level_code_from_income(x)));
if(x != -1) {
if(x >= 0 && x < Household::Min_hh_income) {
Household::Min_hh_income = x;
//Utils::fred_log("HH_INCOME: Min[%i]\n", Household::Min_hh_income);
}
if(x > Household::Max_hh_income) {
Household::Max_hh_income = x;
//Utils::fred_log("HH_INCOME: Max[%i]\n", Household::Max_hh_income);
}
}
}
/**
* Get the household income.
* @return income
*/
int get_household_income() {
return this->household_income;
}
/**
* Determine if the household should be open. It is dependent on the disease and simulation day.
*
* @param day the simulation day
* @param disease an integer representation of the disease
* @return whether or not the household is open on the given day for the given disease
*/
bool should_be_open(int day, int disease) {
return true;
}
/**
* Record the ages and the id's of the original members of the household
*/
void record_profile();
/**
* @return the original count of agents in this Household
*/
int get_orig_size() {
return static_cast<int>(this->ids.size());
}
/*
* @param i the index of the agent
* @return the id of the original household member with index i
*/
int get_orig_id(int i) {
return this->ids[i];
}
void set_deme_id(unsigned char _deme_id) {
this->deme_id = _deme_id;
}
unsigned char get_deme_id() {
return this->deme_id;
}
void set_group_quarters_units(int units) {
this->group_quarters_units = units;
}
int get_group_quarters_units() {
return this->group_quarters_units;
}
void set_shelter(bool _sheltering) {
this->sheltering = _sheltering;
}
bool is_sheltering() {
return this->sheltering;
}
bool is_sheltering_today(int day) {
return (this->shelter_start_day <= day && day < this->shelter_end_day);
}
void set_shelter_start_day(int start_day) {
this->shelter_start_day = start_day;
}
void set_shelter_end_day(int end_day) {
this->shelter_end_day = end_day;
}
int get_shelter_start_day() {
return this->shelter_start_day;
}
int get_shelter_end_day() {
return this->shelter_end_day;
}
void set_seeking_healthcare(bool _seeking_healthcare) {
this->seeking_healthcare = _seeking_healthcare;
}
bool is_seeking_healthcare() {
return this->seeking_healthcare;
}
void set_is_primary_healthcare_available(bool _primary_healthcare_available) {
this->primary_healthcare_available = _primary_healthcare_available;
}
bool is_primary_healthcare_available() {
return this->primary_healthcare_available;
}
void set_other_healthcare_location_that_accepts_insurance_available(bool _other_healthcare_location_that_accepts_insurance_available) {
this->other_healthcare_location_that_accepts_insurance_available = _other_healthcare_location_that_accepts_insurance_available;
}
bool is_other_healthcare_location_that_accepts_insurance_available() {
return this->other_healthcare_location_that_accepts_insurance_available;
}
void set_is_healthcare_available(bool _healthcare_available) {
this->healthcare_available = _healthcare_available;
}
bool is_healthcare_available() {
return this->healthcare_available;
}
int get_household_income_code() const {
return this->household_income_code;
}
/**
* @return a pointer to this household's visitation hospital
*/
Hospital* get_household_visitation_hospital() {
return static_cast<Hospital*>(get_household_visitation_place(Household_visitation_place_index::HOSPITAL));
}
void set_household_visitation_hospital(Hospital* hosp) {
set_household_visitation_place(Household_visitation_place_index::HOSPITAL, hosp);
}
void set_household_has_hospitalized_member(bool does_have);
bool has_hospitalized_member() {
return this->not_home_bitset[Household_extended_absence_index::HAS_HOSPITALIZED];
}
void set_group_quarters_workplace(Place* p) {
this->group_quarters_workplace = p;
}
Place* get_group_quarters_workplace() {
return this->group_quarters_workplace;
}
bool has_school_aged_child();
bool has_school_aged_child_and_unemployed_adult();
void set_sympt_child(bool _hh_sympt_childl) {
this->hh_sympt_child = _hh_sympt_childl;
}
bool has_sympt_child() {
return this->hh_sympt_child;
}
void set_hh_schl_aged_chld_unemplyd_adlt_chng(bool _hh_status_changed) {
this->hh_schl_aged_chld_unemplyd_adlt_chng = _hh_status_changed;
}
void set_working_adult_using_sick_leave(bool _is_using_sl) {
this->hh_working_adult_using_sick_leave = _is_using_sl;
}
bool has_working_adult_using_sick_leave() {
return this->hh_working_adult_using_sick_leave;
}
void prepare_person_childcare_sickleave_map();
bool have_working_adult_use_sickleave_for_child(Person* adult, Person* child);
void set_income_quartile(int _income_quartile) {
assert(_income_quartile >= Global::Q1 && _income_quartile <= Global::Q4);
this->income_quartile = _income_quartile;
}
int get_income_quartile() {
return this->income_quartile;
}
int get_count_seeking_hc() {
return this->count_seeking_hc;
}
void set_count_seeking_hc(int _count_seeking_hc) {
this->count_seeking_hc = _count_seeking_hc;
}
int get_count_primary_hc_unav() {
return this->count_primary_hc_unav;
}
void set_count_primary_hc_unav(int _count_primary_hc_unav) {
this->count_primary_hc_unav = _count_primary_hc_unav;
}
int get_count_hc_accept_ins_unav() {
return this->count_hc_accept_ins_unav;
}
void set_count_hc_accept_ins_unav(int _count_hc_accept_ins_unav) {
this->count_hc_accept_ins_unav = _count_hc_accept_ins_unav;
}
void reset_healthcare_info() {
this->set_is_primary_healthcare_available(true);
this->set_other_healthcare_location_that_accepts_insurance_available(true);
this->set_is_healthcare_available(true);
this->set_count_seeking_hc(0);
this->set_count_primary_hc_unav(0);
this->set_count_hc_accept_ins_unav(0);
}
static int get_min_hh_income() {
return Household::Min_hh_income;
}
static int get_max_hh_income() {
return Household::Max_hh_income;
}
static int get_min_hh_income_90_pct() {
return Household::Min_hh_income_90_pct;
}
static void set_min_hh_income_90_pct(int _hh_income) {
Household::Min_hh_income_90_pct = _hh_income;
}
private:
static double contacts_per_day;
static double same_age_bias;
static double** prob_transmission_per_contact;
//Income Limits for classification
static int Cat_I_Max_Income;
static int Cat_II_Max_Income;
static int Cat_III_Max_Income;
static int Cat_IV_Max_Income;
static int Cat_V_Max_Income;
static int Cat_VI_Max_Income;
static int Min_hh_income;
static int Max_hh_income;
static int Min_hh_income_90_pct;
Place* group_quarters_workplace;
bool sheltering;
bool primary_healthcare_available;
bool other_healthcare_location_that_accepts_insurance_available;
bool healthcare_available;
bool seeking_healthcare;
int count_seeking_hc;
int count_primary_hc_unav;
int count_hc_accept_ins_unav;
bool hh_schl_aged_chld_unemplyd_adlt_chng;
bool hh_schl_aged_chld;
bool hh_schl_aged_chld_unemplyd_adlt;
bool hh_sympt_child;
bool hh_working_adult_using_sick_leave;
unsigned char deme_id; // deme == synthetic population id
int group_quarters_units;
int shelter_start_day;
int shelter_end_day;
int household_income;
int household_income_code;
int income_quartile;
// true iff a household member is at one of the places for an extended absence
//std::bitset<Household_extended_absence_index::HOUSEHOLD_EXTENDED_ABSENCE> not_home_bitset;
std::bitset<4> not_home_bitset;
// Places that household members may visit
std::map<Household_visitation_place_index::e, Place*> household_visitation_places_map;
// profile of original housemates
std::vector<unsigned char> ages;
std::vector<int> ids;
// Sicktime available to watch children for adult housemates
std::map<Person*, HH_Adult_Sickleave_Data> adult_childcare_sickleave_map;
void set_household_income_code(int _household_income_code) {
if(_household_income_code >= 0 ||
_household_income_code <= Household_income_level_code::UNCLASSIFIED) {
this->household_income_code = _household_income_code;
} else {
Utils::fred_abort("Invalid Household Income Level Code", "");
this->household_income_code = Household_income_level_code::UNCLASSIFIED;
}
}
Place* get_household_visitation_place(Household_visitation_place_index::e i) {
if(this->household_visitation_places_map.find(i) != this->household_visitation_places_map.end()) {
return this->household_visitation_places_map[i];
} else {
return NULL;
}
}
void set_household_visitation_place(Household_visitation_place_index::e i, Place* p) {
if(p != NULL) {
this->household_visitation_places_map[i] = p;
} else {
std::map<Household_visitation_place_index::e, Place*>::iterator itr;
itr = this->household_visitation_places_map.find(i);
if(itr != this->household_visitation_places_map.end()) {
this->household_visitation_places_map.erase(itr);
}
}
}
};
/**
* This is a helper class that is used to store information about the children in the household
* The adults in the household who work will each be mapped to one of these objects to keep
* track of whether or not they have already used a sick day for a given child
*/
class HH_Adult_Sickleave_Data {
public:
HH_Adult_Sickleave_Data() { }
void add_child_to_maps(Person* child) {
std::pair<std::map<Person*, bool>::iterator, bool> ret;
ret = this->stayed_home_for_child_map.insert(std::pair<Person*, bool>(child, false));
assert(ret.second); // Shouldn't insert the child twice
}
bool stay_home_with_child(Person* child) {
std::map<Person*, bool>::iterator itr;
bool ret_val = false;
itr = this->stayed_home_for_child_map.find(child);
if(itr != this->stayed_home_for_child_map.end()) {
if(!itr->second) { //didn't already stay home with this child
itr->second = true;
ret_val = true;
}
}
return ret_val;
}
private:
std::map<Person*, bool> stayed_home_for_child_map;
};
#endif // _FRED_HOUSEHOLD_H
Computing file changes ...