Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 9 additions & 7 deletions Processing/Main/A_ConfigModel.pde
Original file line number Diff line number Diff line change
Expand Up @@ -104,12 +104,12 @@ private void configModel() {
int CENTER_X = 500;
int CENTER_Y = 500;
int BASE_RANGE = 100;
epidemic.randomPlaces(N*25, "Public Space", LandUse.PUBLIC, CENTER_X, CENTER_Y, 5*BASE_RANGE, 5*BASE_RANGE, 500, 2000);
epidemic.randomPlaces(N*250, "Dwelling Unit", LandUse.DWELLING, CENTER_X, CENTER_Y, 5*BASE_RANGE, 5*BASE_RANGE, 50, 200);
epidemic.randomPlaces(N*20, "Office Space", LandUse.OFFICE, CENTER_X, CENTER_Y, 4*BASE_RANGE, 4*BASE_RANGE, 500, 1000);
epidemic.randomPlaces(N*4, "School", LandUse.SCHOOL, CENTER_X, CENTER_Y, 5*BASE_RANGE, 5*BASE_RANGE, 500, 2000);
epidemic.randomPlaces(N*25, "Retail Shopping", LandUse.RETAIL, CENTER_X, CENTER_Y, 4*BASE_RANGE, 4*BASE_RANGE, 50, 1000);
epidemic.randomPlaces(N*1, "Hospital", LandUse.HOSPITAL, CENTER_X, CENTER_Y, 1*BASE_RANGE, 1*BASE_RANGE, 2000, 2000);
epidemic.randomPlaces(N*25*2, "Public Space", LandUse.PUBLIC, CENTER_X, CENTER_Y, 5*BASE_RANGE, 5*BASE_RANGE, 500, 2000);
epidemic.randomPlaces(N*250*2, "Dwelling Unit", LandUse.DWELLING, CENTER_X, CENTER_Y, 5*BASE_RANGE, 5*BASE_RANGE, 50, 200);
epidemic.randomPlaces(N*20*2, "Office Space", LandUse.OFFICE, CENTER_X, CENTER_Y, 4*BASE_RANGE, 4*BASE_RANGE, 500, 1000);
epidemic.randomPlaces(N*4*2, "School", LandUse.SCHOOL, CENTER_X, CENTER_Y, 5*BASE_RANGE, 5*BASE_RANGE, 500, 2000);
epidemic.randomPlaces(N*25*2, "Retail Shopping", LandUse.RETAIL, CENTER_X, CENTER_Y, 4*BASE_RANGE, 4*BASE_RANGE, 50, 1000);
epidemic.randomPlaces(N*1*2, "Hospital", LandUse.HOSPITAL, CENTER_X, CENTER_Y, 1*BASE_RANGE, 1*BASE_RANGE, 2000, 2000);

// Resilience*: Impact of Demographic on Pathogen Intensities (1.0 == no impact; < 1 == less resilient; > 1 == more resilient)
Rate childResilience = new Rate(1.5);
Expand All @@ -123,9 +123,11 @@ private void configModel() {
int maxAge = 85;
int minDwellingSize = 1;
int maxDwellingSize = 4;

Rate contactTracingAppAdoptionRate = new Rate(0.2);

// Add people to Model assigned to one random primary location (home) and one random secondary location (job or school)
epidemic.populate(minAge, maxAge, adultAge, seniorAge, childResilience, adultResilience, seniorResilience, minDwellingSize, maxDwellingSize);
epidemic.populate(minAge, maxAge, adultAge, seniorAge, contactTracingAppAdoptionRate, childResilience, adultResilience, seniorResilience, minDwellingSize, maxDwellingSize);

// Number of Ventilator ICU Beds Per Capita:
// In actuality, this rate is only about 0.04% in the United States according to NYTimes!!!
Expand Down
6 changes: 4 additions & 2 deletions Processing/Main/A_ConfigView.pde
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public void configView(CityModel model) {
String info =
"Epidemic Simulation" + "\n" +
"EDGEof Planetary Insight Center" + "\n" +
"by Ira Winder, F. Calalang, D. Goldman" + "\n\n" +
"by Ira Winder, F. Calalang, D. Goldman and Antonio Parraga" + "\n\n" +

"This is a simple simulation of a viral outbreak using " +
"an agent-based population activity model. " + "\n\n" +
Expand Down Expand Up @@ -96,6 +96,7 @@ public void configView(CityModel model) {

// Compartment Names
viz.setName(Compartment.SUSCEPTIBLE, "Susceptible");
viz.setName(Compartment.EXPOSURE_NOTIFIED, "Exposure notified");
viz.setName(Compartment.INCUBATING, "Incubating");
viz.setName(Compartment.INFECTIOUS, "Infectious");
viz.setName(Compartment.RECOVERED, "Recovered");
Expand All @@ -104,12 +105,13 @@ public void configView(CityModel model) {

// Compartment Colors
viz.setColor(Compartment.SUSCEPTIBLE, color(250, 250, 250, 255)); // White;
viz.setColor(Compartment.EXPOSURE_NOTIFIED, color( 255, 255, 0, 255)); // Yellow
viz.setColor(Compartment.INCUBATING, color(255, 150, 0, 255)); // Orange
viz.setColor(Compartment.INFECTIOUS, color(255, 0, 0, 255)); // Dark Red
viz.setColor(Compartment.RECOVERED, color(100, 100, 100, 255)); // Black
viz.setColor(Compartment.DEAD_TREATED, color( 0, 50, 255, 255)); // Teal
viz.setColor(Compartment.DEAD_UNTREATED, color( 0, 255, 0, 255)); // Green

// Pathogen Names
viz.setName(PathogenType.CORONAVIRUS, "Coronavirus");
viz.setName(PathogenType.RHINOVIRUS, "Rhinovirus");
Expand Down
34 changes: 33 additions & 1 deletion Processing/Main/BM_CityModel.pde
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,7 @@ public class CityModel extends EpiModel {
* @param minDwellingSize smallest household size of a dwelling unit
* @param maxDwellingSize largest household size of a dwelling unit
*/
public void populate(int minAge, int maxAge, int adultAge, int seniorAge, Rate childResilience, Rate adultResilience, Rate seniorResilience, int minDwellingSize, int maxDwellingSize) {
public void populate(int minAge, int maxAge, int adultAge, int seniorAge, Rate contactTracingAppAdoptionRate, Rate childResilience, Rate adultResilience, Rate seniorResilience, int minDwellingSize, int maxDwellingSize) {

for(Place l : this.place.get(LandUse.DWELLING)) {
int numTenants = (int) random(minDwellingSize, maxDwellingSize+1);
Expand All @@ -366,6 +366,13 @@ public class CityModel extends EpiModel {
int age = (int) random(minAge, maxAge);
person.setAge(age);

if(random(0, 100) < 100 * contactTracingAppAdoptionRate.rate) {
person.setContactTracingApp(true);
}
else {
person.setContactTracingApp(false);
}

// Set Demographic
person.setDemographic(adultAge, seniorAge);

Expand Down Expand Up @@ -517,6 +524,11 @@ public class CityModel extends EpiModel {
// Add Person encounter to results
if(h instanceof Person && h2 instanceof Person) {
stats.tallyEncounter((Person)h, (Person)h2);

if(((Person)h).hasContactTracingApp() == true && ((Person)h2).hasContactTracingApp()) {
stats.registerContactTracingExposure((Person)h, (Person)h2);
}

}

// 1. Transmit pathogen from Host to Host if one is infectious
Expand Down Expand Up @@ -602,6 +614,11 @@ public class CityModel extends EpiModel {
}

h.update(current, treated);
for(Pathogen pt : this.getPathogens()) {
if(pt.getType() == PathogenType.CORONAVIRUS && h.getStatus(pt).infectious()) {
stats.notifyExposureToPersons((Person) h);
}
}
}
}

Expand All @@ -624,6 +641,21 @@ public class CityModel extends EpiModel {
}
}

// Also quarantine people living in the same house as someone notified
for(Demographic d1 : Demographic.values()) {
for(Person p1 : this.person.get(d1)) {
for(Demographic d2 : Demographic.values()) {
for(Person p2 : this.person.get(d2)) {
if(p1.getPrimaryPlace() == p2.getPrimaryPlace() &&
(p1.hasBeenExposedToInfected() || p2.hasBeenExposedToInfected())) {
p1.notifyExposure();
p2.notifyExposure();
}
}
}
}
}

// Add Number of Hospital Beds to Results Table
stats.setHospitalBeds(this.hospitalBeds);

Expand Down
4 changes: 3 additions & 1 deletion Processing/Main/B_ChoiceModel.pde
Original file line number Diff line number Diff line change
Expand Up @@ -386,14 +386,16 @@ public class ChoiceModel {
p.moveToHospital();

// Are you Obeying a Strict Quarantine?
} else if(quarantine == Quarantine.STRICT && !disobeyQuarantine) {
} else if((quarantine == Quarantine.STRICT || (p.hasBeenExposedToInfected() && p.isInfected())) && !disobeyQuarantine) {
p.moveToPrimary();

// Carry one!
} else {
// Current Place
Place currentPlace = p.getPlace();



// Dominant Place
PlaceCategory phaseDomain = this.getPhaseDomain(currentPhase);
Place dominantPlace = currentPlace;
Expand Down
22 changes: 22 additions & 0 deletions Processing/Main/B_Person.pde
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ public class Person extends Host {
// Demographic of Person
private Demographic demographic;

private Boolean contactTracingApp;

private Boolean exposedToInfected;

// Primary Environment (e.g. home, dwelling, etc)
private Place primaryPlace;

Expand All @@ -40,6 +44,8 @@ public class Person extends Host {
super();
this.age = 18;
this.setDemographic(18, 65);
this.contactTracingApp = false; //by default
this.exposedToInfected = false; //by default
this.primaryPlace = new Place();
this.secondaryPlace = new Place();
this.closestHospital = new Place();
Expand All @@ -66,6 +72,14 @@ public class Person extends Host {
return this.age;
}

public void setContactTracingApp(Boolean contactTracingApp) {
this.contactTracingApp = contactTracingApp;
}

public Boolean hasContactTracingApp() {
return this.contactTracingApp;
}

/**
* Set the Person's Demographic
*
Expand Down Expand Up @@ -165,6 +179,14 @@ public class Person extends Host {
this.move(destination);
}

public void notifyExposure() {
this.exposedToInfected = true;
}

public Boolean hasBeenExposedToInfected() {
return this.exposedToInfected;
}

/**
* Move Person to Secondary Place
*/
Expand Down
5 changes: 5 additions & 0 deletions Processing/Main/CV_EpiView.pde
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,12 @@ public class EpiView extends ViewModel {
}
int w = (int) this.getValue(ViewParameter.HOST_DIAMETER);
Compartment c = h.getStatus(pathogen).getCompartment();

color viewFill = this.getColor(c);
if(h instanceof Person && ((Person) h).hasBeenExposedToInfected() && h.isInfected()) {
viewFill = this.getColor(Compartment.EXPOSURE_NOTIFIED);
}

color viewStroke = this.getColor(ViewParameter.HOST_STROKE);
int alpha = (int) this.getValue(ViewParameter.HOST_ALPHA);
int strokeWeight = (int) this.getValue(ViewParameter.HOST_WEIGHT);
Expand Down
14 changes: 14 additions & 0 deletions Processing/Main/C_Host.pde
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,20 @@ public class Host extends Element {
return true;
}

/**
* Check if Host is Infected
*
* @return true if infected
*/
public boolean isInfected() {
for(HashMap.Entry<Pathogen, PathogenEffect> entry : this.status.entrySet()) {
if(entry.getValue().isInfected()) {
return true;
}
}
return false;
}

@Override
public String toString() {
return "Host UID: " + this.getUID() + "; Name: " + this.getName();
Expand Down
8 changes: 8 additions & 0 deletions Processing/Main/C_PathogenEffect.pde
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,14 @@ public class PathogenEffect {
}
}

public boolean isInfected() {
if(this.compartment == Compartment.INCUBATING || this.compartment == Compartment.INFECTIOUS) {
return true;
} else {
return false;
}
}

/**
* Check if currently hospitalized
*
Expand Down
Loading