COVID-19 mitigation with personal habits and intermittent short lockdowns
Do you have questions or comments about this model? Ask them here! (You'll first need to log in.)
WHAT IS IT?
This is an extension of the "COVID-19 epidemics with Non-Pharmaceutical Interventions and zonal restraints" model (http://modelingcommons.org/browse/one_model/6374), that incorporates some additional interventions including personal hygiene habits (mask-using and hand-washing) as an individual choice, plus an intermittent 3x4 or "accordion lockdown" (the lockdown is periodically enforced 3 days and lifted the following 4 days), along with the possibility of unlocking a particular zone or set of zones. Such new changes implemented in this extended version are documented in the WHAT IS NEW and NEW THINGS TO NOTICE sections at the end of this page. The original model description is given below.
The model is an agent-based system to simulate the evolution of the COVID-19 epidemics and the mitigation impact of Non-Pharmaceutical Interventions (NPI) within a toy city. NPIs are the mechanisms that public health offices around the world are using to attempt to contain the spread of the virus.
We consider a number of NPIs, including social distancing, case isolation, home quarantine, total lockdown, sentinel testing, mask protection and a proposed zonal restriction where these interventions can be applied to separated districts or zones of the city. The effect of these strategies are measured in terms of morbidity, mortality, lethality -infection fatality rate (IFR) and case fatality rate (CFR)-, doubling time, reproduction number and plots of infection, recovery and death during the simulation timeline. The main purpose of the tool is to let modelers assess which NPIs or combination of NPIs can help flattening or crushing the curve of spread of the disease (mitigate or suppress, respectively), and the effects on the corresponding epidemics indicators.
HOW IT WORKS
The model implements the NPIs within the epidemic SIRE+CARDS model (see [1]) as well as the agent behavior rules. We build upon the compartmental SIRE epidemic framework (Susceptible-Infectious-Recovered-Extinct), but we regarded the Infectious compartment as an extended-state consisting of a number of conditions: Confirmed or not (indicating the patient will remain isolated), Risky or not (meaning predisposition to develop severe or critical disease), Asymptomatic or not (meaning patient is unaware of being a virus carrier), Severe or not (meaning it requires to be hospitalized to avoid dead), and Deadly or not (indicating the patient requires Intensive Care Unit -ICU- assistance). The details of event transition rules and condition activation are described in [1].
The simulation tracks an individual disease path for every agent, from susceptible to recovery or death, according to the SIRE+CARDS epidemic model described above. Each agent is assigned a daily routine consisting of going outdoors and returning home with a commuting distance range randomly chosen from {25, 50, 100, 200} unit steps; the actual route the agent follows varies slightly due to random fluctuations in his orientation. In addition the length of each step can be set as a global parameter between 0.1 and 1 units. Similarly, the day length can be defined with a given number of ticks in the range between 600 and 2400.
Individuals interact randomly with other agents around. Virus transmission occurs due to proximity of an infectious agent with other susceptible agent within a spatial radius of 0.5 units; the chance of contagion depends on what mask protection intervention is applied. On recovery from the disease, individuals acquire immunity to the virus so they cannot be re-infected. In this model all deaths are considered to be caused by COVID-19. The flow of events applied to each agent at each timestep are: lifestyle, epidemic, isolation, quarantine, distancing, sentinel, lockdown, illness, clock and indicators (see code and [1] for further details).
In the simulation view area, agents are represented with different shapes according to the zone where they reside. The color of the agent represents its extended state (healthy: same color as zone ground; immune: white; sick: red or yellow if asymptomatic; dead: black X). Special agents intended to implement some of the NPIs such as households for home-quarantine and ambulances for sentinel-testing can also be seen.
HOW TO USE IT
The control panel is organised in sections related to general, city and COVID-19 settings, monitors of epidemic indicators, parameters, action commands to execute the simulation, and a dedicated section for NPI activation with their corresponding parameters.
A typical setup for a simulation run is: POP-SIZE=400 (total number of simulated people or agents), ZONES=9 (number of residential zones), DAYS=60 (period of observation days or simulation length), %-HIGH-RISK=30 (percentage of population with co-morbidities), HOSPITAL-BEDS=12 (total number of hospital beds available), ICU-BEDS=2 (total number of ICU beds available), AMBULANCES-ZONE=1 (number of ambulances or sentinels per zone), HOUSING?=on (show households in the view area), AVG-DURATION=18 (average day period to recover from illness), %-ASYMPTOMATIC=50 (percentage of patients showing mild or no symptoms), TICKS-DAY=1200 (number of ticks after one day elapse), STEP-SIZE=0.1 (distance each agent move every tick), END-DAY=60 (simulation timeline).
Once setup is done, activate or deactivate the NPIs you want to assess (the details of meaning and implementation of each NPI can be found in [1]), then press SETUP, then GO. After a few simulated hours (or ticks) you can seed a patient zero randomly (or many other, if you want) by pressing INFECT. Alternatively, using OUTBREAK you can randomly infect a percentage (%-SPREAD) of the population. Afterwards, you will be able to see the emergence of the epidemic SIRE curves in the plot area, as well as the other epidemic indicators in the monitor area, while the contagion, recover and death of people unfolds as a result of the development of the COVID-19 epidemics with such particular settings.
THINGS TO NOTICE
The NPIs control panel can be used to handle their application even while the epidemic unfolds. For example, you can activate/disactivate a total lockdown at any time, and it will take effect at the 00:00 of the next simulated day. Or you can isolate or release confirmed cases inmmediately, by switching it on or off. Similar thing occurs with the rest of NPIs. In contrast, you should not change any of the other parameters (general, city, or COVID-19 settings), as they are used to setup the model just and only before running the simulation.
There are two distinctive features in this model that allows the application of NPIs with a zonal scope. This means, firstly, you can restrict mobility of agents within their zone of residence; hence, you can try and see if this kind of restriction (ZONE-ENFORCING) is advantageous in flattening the curve when combined with other NPIs compared to the single application of said NPIs. Secondly, when enforcing a TOTAL-LOCKDOWN, you are able to lift this NPI in an arbitrary zone or zones using the PICK-ZONE slider and UNLOCK-ZONE button. Again, you can see how the resulting emergencies compare to maintaining the total lockdown in the entire city. These features may yield interesting insights about alternative implementation of these measures that usually have a hard impact on the economy of the city. Notice that TOTAL-LOCKDOWN has an associated parameter %-PERMITS that determines the amount of agents permitted to go out of their households.
The SENTINEL-TESTING intervention is also useful to assess the impact of mass-test campaigns in the population. Sentinels are shown as ambulances moving around the city while testing any agent they find in their ways; again, you can restrict sentinels mobility with a zonal scope (ZONAL?) and see the difference with respect to allowing city-wide mobility. Notice that since test kits are a finite resource, the model assigns an initial stock of tests equals to the population size. When ambulances run out of tests they stop and stay still. You can of course replenish the stock for each ambulance using the RESUPPLY button to re-activate sentinels' journeys.
THINGS TO TRY
Start-off by defining the general, city, COVID-19 and NPI settings you want to simulate in a single run (a suggested set of settings was given above, see HOW TO USE IT). Execute the simulation to observe how the contagion spreads and how the epidemics evolve by inspecting the monitors, plots and view areas. Then try changing the NPI parameters to assess their mitigation impact by comparing with previous outputs (see also THINGS TO NOTICE). If you like, start running the simulation with only one zone (choose 1 in the ZONES pull down menu); this will be equivalent to have a single district in the entire city, so agents will to move around freely. Then experiment simulations with many districts or multi-zone (choose ZONES in {4, 9, 16}), and try to apply ZONE-ENFORCING to see how agents mobility becomes restricted to their zones of residence.
The HOUSING? switch is used as a decoration and as a behaviour feature. When this switch is on, the model shows households in the simulation view area and assigns agents randomly to each one with a proportion of one house per four agents approximately. When this switch is off, the household of an agent would be the patch were he/she was created randomly at the beginning of the simulation; no houses will be seen. If you try the CASE-ISOLATION or TOTAL-LOCKDOWN interventions with HOUSING? on, agents will be sent home and stay confined in their corresponding households (they will be hidden as they stay inside the house); in contrast, if HOUSING? is off, they will move to their home patch and stay quiet there, being visible and showing their shape, color and state.
Finally, the SEE-SUNSET is a decoration feature. Try it and surprise yourself!
WHAT IS NEW
This extended version includes two personal health interventions implemented as an individual choice, namely using face masks at all times and hand-washing regularly during the day. For this purpose, two sliders, %-MASK-USERS and %-HAND-WASHERS have been enabled. These two parameters will define the tendency of an agent to develop those two hygiene habits. Recent studies have suggested that these two personal interventions can have positive effect in mitigating the contagion of the coronavirus (see [2] and references within). This is reasonable, as they reduce the risk of getting infected when a healthy agent encounters an infectious agent, which may be even more effective when physical distancing to other agents is observed (try and see it!).
Given that these three interventions depend mostly on individual decisions rather than government policy, it would be of great interest in the post-COVID19 scenario, to study strategies where they are combined with other interventions not affecting the mobility of the agents (such as SENTINEL-TESTING) to continue with epidemic mitigation while opening economy and social interaction.
Regarding mobility restrictions, when the TOTAL-LOCKDOWN intervention is on, in this extended model it is possible to lift it independently on the agents residing in a particular zone. For this aim, the user can choose the desired zone number with the PICK-ZONE slider and then should press the UNLOCK button. Then, the agents residing in such zone will start immediately to get out of their households and move freely around, while the rest of the population stays at home, as it can be attested in the simulation view area. When the ZONE-ENFORCING intervention is simultaneously activated, its residents will move around but only within the zone limits.
In addition, this extended version enables the application of the TOTAL-LOCKDOWN intervention with an intermittent 3x4 schedule (the so called "accordion" scheme), where the mobility restriction is applied adhering to a 7-day loop consisting of enforcing stay-at-home order during 3 consecutive days, and lifting the rule the remaining 4 days (hoping in this way to ameliorate the negative impact of shutting down economy due to indefinite lockdowns). To apply the accordion intervention, the user can press the LOCK3x4 button to activate/inactivate this scheme; when activated, a "3x4 ON" sign will be displayed in the bottom-left corner of the simulation view area. We remark that once activated, this intervention, similarly to the TOTAL-LOCKDOWN takes effect starting at zero hours of the next day (you can check it on the CLOCK monitor).
NEW THINGS TO NOTICE
Observe that now the chance of a contagion depends on the individual decisions regarding keeping physical distance, using mask and washing hands, which varies amply depending on the habits of the two agents involved in a contagion encounter. The actual risk on a particular encounter can be seen in the LAST CONTAGION RISK monitor. You can try and see how the risks fluctuate as you change the combination of sliders of %-WILLINGS to keep personal distance, and %-MASK-USERS and %-HAND-WASHERS with values between 0 and 100 (these parameters have effect only at the beginning of the simulation, when the population is created).
Now, when the ZONE-ENFORCING and TOTAL-LOCKDOWN interventions are simultaneously been applied, it would be interesting to verify if releasing a particular single zone or a couple of them having low contagion rates, would be advantageous to facilitate mobility (and encourage economic recovering) of a group of the population without worsening too much the overall epidemic indicators of the city.
Lastly, the impact of the "accordion" LOCK3x4 intervention is evident in the epidemic SIRE+CARDS curves, which adopt a "staircase" or "chainsaw" shape with discrete rising and falling steps, corresponding to the periods of intermittent enforce/lift of the lockdown.
EXTENDING THE MODEL
Given the complex nature of human behavior and virus infection, attempting to model every mechanism of the COVID-19 epidemic may prove difficult; necessary assumptions need to be taken to simplify the representation of the agents and their interactions. We have made a few of them, as described above, so evidently there are interesting aspects that can be addressed to extend the model. We mention just some ideas here (for a more comprehensive discussion we refer the reader to [1]):
- consider virus incubation periods after infection,
- model infectiousness, aggressiveness or symptomatic severity levels,
- include age or gender structures,
- account for births or deaths due to other causes,
- expand further risk stratification for co-morbidities and age windows,
- add hubs or attractor sites (i.e. mass transport, schools, cinemas, etc.),
- incorporate explicit sites for hospitals were severe or critical patients are moved instead of staying still,
- set up daily schedules for agent routines (e.g. going forth and back to/from work, or leisure or shopping, etc.),
- measure the economical impact of NPIs (model food or money supply at a population or individual level),
- simulate cotagions not only by direct contact, but also indirect by surface contact (virus particles adhered to patches),
- implement of other epidemic indicators (different estimates of R0) or measuring them within subpopulations corresponding to residents of the different zones,
- design mechanisms allowing tendencies to develop personal health habits (like wearing masks and routinely washing hands) to emerge as consequence of changes in the psychological biases or beliefs of the agents.
CREDITS AND REFERENCES
Authors:
Sergio Rojas-Galeano and Lindsay Alvarez
Copyright (c) September 2020
email: srojas@udistrital.edu.co, lalvarez@udistrital.edu.co
Version 1.27
Licenses:
The model code is licensed as GNU General Public License (GPLv3) (see https://www.gnu.org/licenses/gpl-3.0.txt)
This Info Tab document is licensed as CC BY-NC-ND (see https://creativecommons.org/licenses/by-nc-nd/4.0/)
References:
[1] Alvarez, L. and Rojas-Galeano, S. "Simulation of Non-Pharmaceutical Interventions on COVID-19 with an Agent-based Model of Zonal Restraint". medRxiv pre-print 2020/06/13; https://www.medrxiv.org/content/10.1101/2020.06.13.20130542v1 doi: 10.1101/2020.06.13.20130542
[2] Alvarez, L. and Rojas-Galeano, S. "Impact of Personal Care Habits on Post-Lockdown COVID-19 Contagion: Insights from Agent-based Simulations". medRxiv pre-print 2020/10/01; https://www.medrxiv.org/content/10.1101/2020.09.23.20200212v2 doi: 10.1101/2020.09.23.20200212
Comments and Questions
;; -------------------------------------------------------------------------- ;; COVID-19 mitigation with personal habits and intermittent short lockdowns ;; ;; A model by Sergio Rojas-Galeano and Lindsay Alvarez ;; v1.27 Copyright (c) September 2020 The authors ;; Correspondance email: srojas@udistrital.edu.co ;; Universidad Distrital Francisco Jose de Caldas, Bogota, Colombia ;; ;; This is an extended version of the of the COVID-19 epidemic simulation ;; with Non-Pharmaceutical Interventions and zonal restraints model ;; ;; This program is free software: you can redistribute it and/or modify ;; it under the terms of the GNU General Public License (GPLv3) ;; (see license at: https://www.gnu.org/licenses/gpl-3.0.txt) ;; ;; The model is made publicly available in the hope that it will be useful ;; to modelers, but WITHOUT ANY WARRANTY whatsoever (see license for details). ;; -------------------------------------------------------------------------- ;; Define globals globals [ daytime? ; is it day or night? ( 1 day + 1 night = ticks-day) sort-codes ; a list of codes to identify each zone of a city shapes-list ; a list of shapes to identify agents of the same zone colors-list ; a list of colors to identify different zones day hour ; the current day and hour since simulation started sicks-day ; list of daily count of sicks n-cases ; number of overall COVID-19 sick people n-confirmed ; number of confirmed COVID-19 sick people n-tested ; number of overall people tested by sentinel n-positives ; number of people that tested COVID-19 positive doubling-time ; estimated days to double today's number of sicks R0 S0 R0_ ; reproduction number and initial Susceptibles p-contagion ; probability of contagion on a single encounter intermittent? ; is it intermittent lockdown on or off (i.e. "accordion strategy")? ] ;; Define breeds for healthy and infected people breed[ healthies healthy ] breed[ sicks sick ] breed[ deaths death ] breed[ houses house ] breed[ ambulances ambulance ] ;; Define attributes for patches patches-own [ zone ; the zone code of this patch ] ;; Define attributes of all the people turtles-own [ homebase ; the home patch of this person scope ; the reach of distance away from home for this person speed ; how fast does he/she move? A speed of 0 is still unlocked? ; is the person free from lockdown? tested? ; was the person tested by sentinel test? contagions ; how many people this person infected if he/she ever got sick mask-habit? ; is the person willing to wear protection mask? wash-habit? ; is the person willing to wash his hands regularly? ] ;; Define attributes for sick people only sicks-own [ days-to-cure ; the actual duration of the illness for this person recovery ; counter of days remaining to recovery confirmed? ; is the person isolated at homebase? asymptomatic? ; is the person asymptomatic? risky? ; is the person high-risk due to existing factor (obese, diabetes, older, etc) severe? ; is the person in severe condition? deadly? ; is the person in deadly (critical) condition? hospitalised? ; has he/she been admitted to hospital? ICU-admitted? ; has he/she been admitted to ICU? ] ;; Define attributes for healthy people only healthies-own [ immune? ; has the person recovered and acquired immunity? ] ;; Define attributes for ambulances ambulances-own [ tests-stock ; how many tests in stock tests-supply ; numbers of tests to top-up (depends on amount of zone residents) ] ;; One iteration of simulation's steps to go if ticks = ticks-day / 2 [ outbreak ] ; Epidemic begins with outbreak at 0d:12h (enable this line only for BehaviourSpace experiments) ifelse day < end-day [ tick ] [ stop ] ;screenshot stop ] lifestyle epidemic isolation quarantine distancing sentinel lockdown illness clock indicators end ;; Simulate everyday routine of people to lifestyle ask (turtle-set healthies sicks with [not confirmed?] ) [ if zone-enforcing? [ if zone != [zone] of homebase [ face homebase fd 0.5 ] ; if away from resident zone, head back ] forward speed ; move ahead if distance homebase > scope [ face homebase ] ; if too far from home, head back set heading heading + (random-float 3 - random-float 3) ; change direction swiftly ] end ;; Spread the infection from sicks not yet isolated, to healthies to epidemic ask sicks with [not confirmed?] [ let counter 0 ; number of contagions made by this sick let sick-masked? mask-habit? ; is the sick wearing mask? ask healthies with [not immune?] in-radius .5 [ let healthy-masked? mask-habit? ; is the healthy wearing mask? ;; Set contagion risk depending on mask-wearing habits set p-contagion contagion-risk sick-masked? healthy-masked? ;; Contagion risk may decrease further depending on hand-washing habits of healthies if wash-habit? [ set p-contagion (p-contagion * 0.3) ] ; P(Contagion | p-contagion, healthy-washer?) if random-float 1 < p-contagion [ get-sick set counter counter + 1 ] ] set contagions contagions + counter ] end ;; Probablity of contagion depending on mask wearing combination to-report contagion-risk [sick-masked? healthy-masked?] let p 0 if not sick-masked? and not healthy-masked? [ set p 0.9 ] ; P(Contagion | False, False) if not sick-masked? and healthy-masked? [ set p 0.5 ] ; P(Contagion | False, True ) if sick-masked? and not healthy-masked? [ set p 0.3 ] ; P(Contagion | True, False) if sick-masked? and healthy-masked? [ set p 0.1 ] ; P(Contagion | True, True) report p end ;; Make a single person ill to get-sick ;; S->I (set the initial properties of a sick person) set breed sicks set shape item ([zone] of homebase) shapes-list set confirmed? false set tested? false set severe? false set deadly? false set hospitalised? false set ICU-admitted? false ;; Set stochastic attributes set days-to-cure abs int random-normal avg-duration 4 ; duration of illness for this sick set recovery 0 ; initial count of days until recovery set asymptomatic? (random 100) < %-asymptomatics ; is this an asymptomatic patient? set risky? (random 100) < %-high-risk and not asymptomatic? ; is it high-risk (co-morbidities) given not asymptomatic? set color ifelse-value asymptomatic? [ yellow ] [ red ] ;; Update how many cases so far set n-cases n-cases + 1 end ;; Ask confirmed sick people to stay home to isolation ;; If quarantine on, enforce isolation of symptomatic ifelse case-isolation? [ ask sicks with [ not asymptomatic? and not confirmed? ] [ move-to homebase set confirmed? true set n-confirmed n-confirmed + 1 ; these sicks are now confirmed cases ] ] ;; Else lift isolation, except if was sent sentinel testing [ ask sicks with [ not tested? and confirmed? ] [ set confirmed? false set n-confirmed n-confirmed - 1 ; these sicks are set back to not confirmed cases ] ] ;; Decorate houses with color of isolated people ask houses [ set color ifelse-value any? sicks-here with [ not asymptomatic? ] [ red ] [ ifelse-value any? sicks-here with [ asymptomatic? ] [ yellow ] [ white ] ] ] end ;; Ask housemates of isolated people to stay home to quarantine if home-quarantine? [ ask sicks with [ confirmed? ] [ let sick-home homebase ask other turtles with [ homebase = sick-home ] [ move-to homebase ] ] ] ;; Decorate houses with color of quarantined people ask houses [ set color ifelse-value any? sicks-here with [ not asymptomatic? ] [ red ] [ ifelse-value any? sicks-here with [ asymptomatic? ] [ yellow ] [ white ] ] ] end ;; Avoid contacting nearby people (closer than than min-dist) to distancing if social-distancing? [ let people (turtle-set healthies sicks) let willings (count people * %-willings / 100) ask n-of willings people [ if any? other people in-radius 0.6 [ ; a radius of 0.6 is slightly higher than the 0.5 threshold to contagion let closest min-one-of other people [distance myself] face closest rt 180 ; head in the opposite direction of closest person ] ] ] end ;; Ask ambulances to catch sicks by mass testing to sentinel ifelse sentinel-testing? [ ask ambulances [ st if tests-stock > 0 [ ;; Move ambulances around forward speed if zonal? [ if zone != [zone] of homebase [ face homebase fd 0.5 ] ] ; keep ambulance in-zone set heading heading + (random-float 10 - random-float 10) ; change ambulance's heading randomly ;; Pick nearbys and perform tests let target-people ((turtle-set healthies sicks) in-radius 5) with [not tested?] ask target-people [ if is-sick? self and not confirmed? [ ; if sick and not isolated, target is positive move-to homebase set confirmed? true set n-positives n-positives + 1 ; update count positives tests so far set n-confirmed n-confirmed + 1 ; update count of confirmed cases so far ] set tested? true ; mark this person as tested ] set n-tested n-tested + (count target-people) ; update count of tests made so far set tests-stock tests-stock - (count target-people) ; update stock of tests available ] ] ] ;; Else, stop and hide ambulances [ ask ambulances [ ht ] ] end ;; Enforce everyone staying home, except for a few permits to lockdown if (hour mod 24) = 0 [ ; lockdown starts or ends at 00:00 of next day ifelse total-lockdown? [ let people (turtle-set healthies sicks) with [not unlocked?] ; for people not in an unlocked zone ask people [ move-to homebase set speed 0 ] ; sent everyone home, not confirmed foreach sort-codes [ z -> let residents people with [ zone = z ] let permits (count residents * %-permits / 100) ask n-of permits residents [ set speed step-size ] ] if intermittent? and (day mod 7) >= 3 [ ; apply flexible lockdown: 3 days out of 7 days period ask people [ set speed step-size ] ] ] ;; Else unlock everyone [ ask (turtle-set healthies sicks) [ set speed step-size set unlocked? false ] if intermittent? [ lock3X4 ] ] ] end ;; Allow to lift total lockdown by unlocking zones gradually to unlock ;let pick-zone random zones ask (turtle-set healthies sicks) with [ zone = (pick-zone - 1) ] [ set speed step-size set unlocked? true ] ;not unlocked? ] end ;; Enable/disable 3x4 flexible lockdown i.e. "accordion rule": 3 days lockdown by 4 days free movement to lock3X4 set intermittent? (not intermittent?) ; flip to the opposite value ask patch (min-pxcor + 20) (min-pycor + 2) [ ; show/hide indicator label at bottom-left corner set plabel-color black set plabel ifelse-value intermittent? [ "3x4 ON" ] [""] ] end ;; Simulate illness evolution in each person to illness if (ticks mod ticks-day) = 0 [ ; illness unfolds in a daily basis ;; I->R (sicks recovering after days-to cure) ask sicks [ set recovery recovery + 1 ; countdown of days left to recover if recovery >= days-to-cure [ get-well ] ; if recovery time over, the person is cured ] ;; I->E (sicks getting extinct, that is, dead) ask sicks with [not asymptomatic?] [ ;; Define probability of death let p 0.005 ; P(Extinct | Symptomatic) if deadly? and not ICU-admitted? [ set p 1.0 ] ; P(Extinct | Deadly, no ICU) if deadly? and ICU-admitted? [ set p 0.5 ] ; P(Extinct | Deadly, ICU) if severe? and not hospitalised? [ set p 0.2 ] ; P(Extinct | Severe, Hospitalised) if severe? and hospitalised? [ set p 0.05 ] ; P(Extinct | Severe, no Hospitalised) ;; Death may occur any day within days-to-cure, with triangular probability distribution peaking at half the days-to-cure let day-chance cdf-triangle recovery days-to-cure ; CDF of triangle distribution ;; Simulate death let r random-float 1.0 if r < (p * day-chance) [ pass-away ] ] ;; I+Severe ask sicks with [not asymptomatic? and not (severe? or deadly?)] [ let p 0.0 if not risky? [ set p 0.05 ] ; P(Severe | Symptomatic, no Risky) if risky? [ set p 0.25 ] ; P(Severe | Symptomatic, Risky) ;; Severity may arise any day within days-to-cure, following an uniform distribution let day-chance recovery / days-to-cure ; CDF of uniform distribution ;; Simulate severity let r random-float 1.0 if r < (p * day-chance) [ set severe? true ] ] ;; I+Deadly ask sicks with [severe?] [ let p 0.0 if not risky? [ set p 0.05 ] ; P(Deadly | Severe, no Risky) if risky? [ set p 0.25 ] ; P(Deadly | Severe, Risky) ;; Deadliness may arise any day within days-to-cure, following an uniform distribution let day-chance recovery / days-to-cure ; CDF of uniform distribution ;; Simulate deadliness let r random-float 1.0 if r < (p * day-chance) [ set deadly? true set severe? false ] ] ;; I+Hospitalised let occupied count sicks with [severe? and hospitalised?] let required count sicks with [severe? and not hospitalised?] let incoming min list (hospital-beds - occupied) required ; how many can be hospitalised? ask n-of incoming sicks with [severe? and not hospitalised?] [ ; hospitalised as many as possible set hospitalised? true set tested? true ; so they can't move even when isolation off if not confirmed? [ set confirmed? true set n-confirmed n-confirmed + 1 ] ; if wasn't confirmed yet, confirm and update count ] ;; I+ICU-admitted set occupied count sicks with [deadly? and ICU-admitted?] set required count sicks with [deadly? and not ICU-admitted?] set incoming min list (ICU-beds - occupied) required ; how many can be admitted to ICU? ask n-of incoming sicks with [deadly? and not ICU-admitted?] [ ; ICU-admit as many as possible set ICU-admitted? true set tested? true ; so they can't move even when isolation off if not confirmed? [ set confirmed? true set n-confirmed n-confirmed + 1 ] ; if wasn't confirmed yet, confirm and update count ] ] end ;; Compute Cumulative Distribution Function (CDF) of triangular distribution at a given number of days elapsed (x) within illness period (width) to-report cdf-triangle [x width] ;; Height of the inner triangle to obtain CDF, i.e. the value of the PDF on x let height 2 * (width - abs (width - (2 * x))) / (width ^ 2) ;; If x is before peak, CDF is the area of the inner triangle with base x ifelse x <= (width / 2) [ let base x report height * base / 2 ] ;; Else if x is after peak, CDF is to total area (1) minus area of inner triangle with base (width - x) [ let base (width - x) report 1 - (height * base / 2) ] end ;; Become healthy again to get-well let old-shape shape set breed healthies set immune? true set shape old-shape set color white set speed step-size end ;; Become dead to pass-away if not confirmed? [ set confirmed? true set n-confirmed n-confirmed + 1 ] ; some cases are confirmed only at death set breed deaths set shape "x" set speed 0 set color black end ;; Update counters of days and hours to clock set day int (ticks / ticks-day) ; track of number of days elapsed since beginning set hour int ((ticks / ticks-day) * 24) ; track of number of hours elapsed since beginning sunset end ;; Record epidemic indicators to indicators ;; Daily statistics are sicks per day and doubling-time if ticks mod ticks-day = 0 [ set sicks-day lput (count sicks) sicks-day ;; Compute doubling time ;; see (Bakir, 2016, "Compound Interest Doubling Time Rule: Extensions and Examples from Antiquities.") if any? sicks[ ifelse (last sicks-day) > (item (day - 1) sicks-day) [ set doubling-time ln 2 / ln ((last sicks-day) / (item (day - 1) sicks-day + 1E-10)) ] [ set doubling-time "Inf" ] ] ] if ticks mod (ticks-day / 24) = 0 [ ;; Estimate R0 based on the final size of susceptibles in population ;; see (Dietz, 1993, "The estimation of the basic reproduction number for infectious diseases.") if S0 != 0 [ let Sn count healthies with [ not immune? ] / pop-size set R0 (ln (S0 + 1E-10) - ln (Sn + 1E-10)) / (S0 - Sn + 1E-10) ] ;; Estimate R0_ with an individual-based approach, as the average of contagions per sick if any? turtles with [contagions > 0] [ set R0_ mean [contagions] of turtles with [contagions > 0] ] ] end ;; Inoculate infection on one agent to infect if any? healthies with [not immune?][ ask one-of healthies with [not immune?] [ get-sick ] ] ;; Record the initial count of susceptibles for R0 computation set S0 (count healthies with [not immune?]) / pop-size end ;; Contagion by an outbreak to outbreak ;; Infect a percentage of population repeat pop-size * (%-spread / 100) [ infect ] ;; Record the initial count of susceptibles for R0 computation set S0 (count healthies with [not immune?]) / pop-size end ;; Light up or down the city depending on daytime to sunset if see-sunset? [ if (ticks mod (ticks-day / 2)) = 0 [ ifelse daytime? [ ask patches [ set pcolor pcolor + 4 ] ] [ ask patches [ set pcolor pcolor - 4 ] ] set daytime? not daytime? ] ] end ;; Get ready to go to setup clear-all reset-ticks setup-globals setup-city setup-people setup-ambulances set daytime? false set intermittent? false end ;; Initialize global variables to setup-globals ;; Codes to identify zones set sort-codes n-values zones [ i -> i ] ;; Residents of each zone are identified with different shapes and color set shapes-list [ "dog" "cat" "cow skull" "fish 2" "chess knight" "ant 2" "wolf 7" "bird" "butterfly 2" "rabbit" "bug" "spider" "ghost" "monster" "person" "fish" "sheep" "bee 2"] set colors-list [ cyan pink violet green brown turquoise gray sky lime violet blue brown gray sky pink turquoise ] ;; Initalise daily sicks, positives, total-tested, total and confirmed cases set sicks-day [0] set n-positives 0 set n-tested 0 set n-cases 0 set n-confirmed 0 ;; Initial value for doubling time set doubling-time 0.0 end ;; Split the city into zones and setup facilities to setup-city set-patch-size 1.9 ;; Layout a grid of patch square zones by assingning auxiliary codes let step world-width / sqrt zones ask patches[ let units int ((pxcor + max-pxcor) / step) let tens int ((pycor + max-pycor) / step) set zone 10 * tens + units ] ;; Now map those auxiliary codes to consecutive sort-codes and corresponding colors let aux-codes sort remove-duplicates [zone] of patches (foreach aux-codes sort-codes [ [old new] -> ask patches with [zone = old] [set zone new] ]) ask patches [ set pcolor (item zone colors-list) + 1 ] ;foreach sort-codes [ c -> ask one-of patches with [zone = c] [set plabel zone] ] ; display zone code on view area ;; If housing, create houses if housing? [ create-houses pop-size / 4 [ setxy random-xcor random-ycor set color white set shape "house" set size 9 ] ] end ;; Create initial population to setup-people create-healthies pop-size [ ;; Assign as homebase either a house if any, otherwise his initial position ifelse housing? [ set homebase one-of houses move-to homebase ][ setxy random-xcor random-ycor set homebase patch-here ] ;; Assign color and shape depending on homebase's zone set color item zone colors-list - 2 set shape item zone shapes-list set size 9 set heading random 360 set scope one-of (list 25 50 100 200) ; choose radomly movement range set immune? false set unlocked? false set tested? false set contagions 0 set mask-habit? random 100 < %-mask-users ; set face mask protection social habit set wash-habit? random 100 < %-handwashers ; set hand-washing social habit set speed step-size ;0.1 ;0.5 forward 3 ; peek out of house to be seen at the beginning ] end ;; Create ambulances to setup-ambulances foreach range zones [ z -> create-ambulances ambulances-zone [ move-to one-of patches with [ zone = z ] set homebase patch-here set shape "ambulance 2" set size 12 set color white set speed 4 * step-size ; ambulances move faster than people let residents (turtle-set healthies sicks) with [ zone = z ] ;; The amount of tests supply depends on residents population set tests-supply round (count residents * (%-tests / 100) / ambulances-zone ) set tests-stock tests-supply ; initialise stock of tests ] ] end ;; Replenish the stock of available tests in ambulances to supply-ambulances ask ambulances [ set tests-stock tests-stock + tests-supply ] end ;; Replenish an infinite stock of tests in ambulances to supply-infinity ask ambulances [ set tests-stock 1000000 ] end ;; Save a screenshot of the interface (view+plots, etc) in a file to screenshot display ;export-interface (word "COVID19-NPI-ABM-" random 1000 random 1000 ".png") end
There are 5 versions of this model.
Attached files
File | Type | Description | Last updated | |
---|---|---|---|---|
COVID-19 mitigation with personal habits and intermittent short lockdowns.png | preview | Preview image | about 4 years ago, by Sergio Rojas-Galeano | Download |
COVID_19_NPI_Zones_UserGuide_v1_27.pdf | User guide | about 4 years ago, by Sergio Rojas-Galeano | Download |
Parent: COVID-19 epidemics with Non-Pharmaceutical Interventions and zonal restraints
This model does not have any descendants.