Vaccine Impact on Covid

No preview image

1 collaborator

Default-person Alex Brown (Author)

Tags

(This model has yet to be categorized with any tags)
Visible to everyone | Changeable by the author
Model was written in NetLogo 6.2.0 • Viewed 441 times • Downloaded 25 times • Run 0 times
Download the 'Vaccine Impact on Covid' modelDownload this modelEmbed this model

Do you have questions or comments about this model? Ask them here! (You'll first need to log in.)


WHAT IS IT?

A model of an infectious disease within a community.

People move about randomly, and if they run into a person who is sick, they have a chance of getting sick themselves. The illness runs on average two weeks, and has a 1% death rate. These processes are all stochastic, so somebody could die on day 2 of the illness, or could have it for a month

Here is what makes this model unique:

I have seen a couple of models online which illustrate the effects of social distancing on the spread of a disease, but they typically did this by social distancing the entire population, which to me seems like a bit of an unnecessary oversimplification. For this model, I'm interested in breaking down social distancing into two of its components: 1. How many people are distancing? Is it half the population? 75%? 10%? 2. How aggressively are they distancing? Are they literally staying in one place? or are they just being more cautious, going out less?

This model allows us to explore how varying 1 and 2 affect the outcome of the entire community. Is social distancing useless unless most people do it? Is social distancing useless unless it's extreme? Can we effect a meaningful change in outcome by having only a small proportion of citizens social distance?

Additionally, I've created a self-balancing mechanism which can be turned on or off. This self-balancing mechanism is to help try to model how a society would eaase out of social distancing while the virus was still present. A couple of new variables that the self-balancing uses:

[threshold] - this is the "acceptable" infected proportion of the population (ie, "the healthcare system can't handle more than 5% of the population sick with this thing at any one time, so we have to keep it under 5%")

[distance-step-ups] - when the proportion of people currently infected ([prop-infected]) nears the threshold, the proportion of the population social distancing increases. If the [prop-infected] rises above the threshold, or daily net new cases are  too high (indicating rapid growth), the proportion of the population taking social distancing measures increases. So, for example, if 11% of the population is infected, the number of people taking social distancing measures would increase by ([distance-step-ups] * [num-people]) amount every day until prop-infected falls below 10%. 

[distance-step-downs] - the same as the above, but for easing social distancing restrictions. Once prop-infected falls below ([threshold]*.75) and net new cases are negative, the proportion of people social distancing is decreased by ([distance-step-downs] * [num-people]). 

What should the step-ups and step-downs be? That’s a good question. The granularity with which a society can adjust how many of its citizens are social distancing unclear and subject to political pressures. On one end of the spectrum, we could imagine a government announcing every morning which birthdays were allowed to leave the house. On the other end of the spectrum, we could imagine a government announcing at the start of the month that everyone must stay inside, and at the end of the month, letting everybody out. The most realistic course of action is probably somewhere in the middle. I think most citizens would get awfully fed up with a government micromanaging and making frequent adjustments, however, we probably want something more attentive than the second scenario. This is an added challenge — we want a self-balancing system that takes large enough steps so as not to require super frequent adjustments, but also keeps the virus at acceptable levels. To start, I’ve set the distancing-step-ups at 10%. I’ve done the same for distancing-step-downs. We can imagine city governments being able to adjust social distancing behavior with this sort of granularity by taking steps such as expanding and contracting the list of “essential businesses”. (Note: I am well aware of the fact that opening and shuttering businesses adds a whole new level of economic stress and greatly impacts these business’s ability to plan. That being said, I think what we’re interested in here is the effect of slowly opening or closing the economy on the spread of a virus, not the economic difficulties and feasibility of opening and closing the economy.)

HOW IT WORKS

&&

HOW TO USE IT

(what rules the agents use to create the overall behavior of the model)

I'll go through the variables and what is a good range for them to be set at:

num-people = This is the number of total people in the community, for this size grid, I think 1500 is a decent starting point. Less people -> disease has harder time spreading, more people -> disease spreads more easily

init-infected = This is how many initial cases the community has. You can set it as low as you want

num-people-social-distancing = of the total number of people, how many of them are socially distancing? Play around with this one, you start to be able to really see the impact once it's over 60% of the population. Also try it with zero! REMEMBER: this number must be lower than num-people

sociability-of-non-distancers = how much do non social distancers move around? The higher this number, the larger their movements. Try different numbers for this.

sociability-of-distancers = how much do social distancers move around? This number should be pretty low, I think generally, below 1. Play around with it, but just remember that it should be lower than sociability-of-non-distancers.

NOTE: the sociability of an individual does not change if he becomes infected. Distancers will continue to distance even if they become infected, but they will change color to red.

Once there are no more active infections in the community, people stop social distancing.

THINGS TO NOTICE

(suggested things for the user to notice while running the model)

THINGS TO TRY

(suggested things for the user to try to do (move sliders, switches, etc.) with the model)

EXTENDING THE MODEL

(suggested things to add or change in the Code tab to make the model more complicated, detailed, accurate, etc.)

NETLOGO FEATURES

(interesting or unusual features of NetLogo that the model uses, particularly in the Code tab; or where workarounds were needed for missing features)

RELATED MODELS

(models in the NetLogo Models Library and elsewhere which are of related interest)

CREDITS AND REFERENCES

To begin building this, I modified code for an SIR model by Paul Smaldino

Comments and Questions

Please start the discussion about this model! (You'll first need to log in.)

Click to Run Model

globals [
  max-infected
  daily-delta
  total-infected
  avg-daily-delta
  total-delta
  moving-average
  day-1
  day-2
  day-3
  day-4
  day-5
  transmissibility ; what is the chance the healthy person becomes sick if they contact a carrier
  ;interactions ; total dialy interactions
  pop-density
  Ro


]


turtles-own[
  infected?
  immune?
  recovered?
  mask?
  dead? ; add superspeader?
  infectionDay?
  recoveryDay?
  quarantineDay?
  death?
  mouthBreather? ;how likely is this person to ifect others if they come into contact
  secondaryinfections?
  superspreader?
  lambda?
  movement? ;how much a turtle moves - also should account for frequency
  distanced?
  quarantine-if-sick?
  quarantined?
  interactions?
  num-neighbors?
  vaccinated?

]

to setup
  clear-all
  set-patch-size (275 / max-pxcor) ; just resets display size
  reset-ticks
  setup-turtles
  setup-masked
  setup-mouthBreather
  setup-distancers
  setup-quarantine
  setup-infected
  set max-infected (count turtles with [infected?])
  set transmissibility (probability-of-transmission)
  set pop-density (num-people / (((max-pxcor * 2) + 1) * ((max-pycor * 2) + 1) ) )
  set Ro (0)
  update-plots
  startingconditions
end 

to setup-turtles
  create-turtles num-people [
    set color white
    set shape "person"
    set size 2
    set infected? false
    set immune? false
    set mask? false
    set dead? false
    set death? false
    set distanced? false
    set mouthBreather? 0
    set secondaryinfections? 0
    set superspreader? false
    set lambda? random-gamma shape-r ((sociability-prob) / (1 - sociability-prob) )
    set movement? 0
    set quarantine-if-sick? false
    set quarantineDay? 0
    set quarantined? false
    set recovered? false
    set interactions? 0
    set num-neighbors? 0
    set vaccinated? false
    setxy random-pxcor random-pycor
  ]
end 

to setup-masked
  ask n-of ((percent-masked / 100) * num-people) turtles [
    set color white
    set shape "person business"
    set mask? true
  ]
end 

to setup-distancers
  ask n-of((prop-distancers / 100) * num-people) turtles [
    set distanced? true
  ]
end 

; this function makes some turtles become infected

to setup-infected
  ask n-of init-infected turtles [    ;n-of takes two inputs, an integer , and a group (turtles),
    set infected? true
    set color 26
    if mask?
      [set shape "person business"]
    recover-time
  ]
end 

to-report random-beta [ #alpha #beta ]
  let XX random-gamma #alpha 1
  let YY random-gamma #beta 1
  report XX / (XX + YY)
end 

to-report random-nbinom [ #r #p ]
  let lambda random-gamma #r ((#p) / (1 - #p) )
  report random-poisson lambda
end 

to setup-mouthBreather
  let mu (Probability-of-Transmission)
  let v (Transmission-shape-parameter)
  let alpha (mu * v)
  let beta ((1 - mu) * v)

  ask turtles [
    set mouthBreather? ((random-beta alpha beta) * transmissibility-scalar)
  ]
end 

to setup-quarantine
  ask n-of ((percent-who-quarantine / 100) * num-people) turtles [
  set quarantine-if-sick? true
  ]
end 

to change-tendencies
  setup-masked
  setup-distancers
  setup-quarantine
end 

to go
    ask turtles [
    set interactions? (0)
  ]
  no-display
  move-normal1
  ;infect-susceptibles
  quarantine
  recover-infected-die
  recolor
  calculate-daily-intereactions
  if (ticks >= 1) [
      calculate-max-infected
      calculate-daily-delta
      calculate-avg-daily-delta
      calculate-total-infected
      calculate-moving-average
      ]
  if (count turtles with [dead? or recovered?] ) >= 1 [
      set Ro (mean [secondaryinfections?] of turtles with [dead? or recovered?])
  ]
  if vaccinations = true [
    if (ticks < 31) [
    vaccinate
    ]
  ]
 ; if ( ((ticks mod 1) > 0.85) and ((ticks mod 1) < 0.95) ) [
    update-plots ;]

  tick-advance 1
  display
end 

to vaccinate
  if (count turtles with [not vaccinated? and not dead? and not immune?] < (num-people * vaccinated-over-30-days) / 30)[
    ask turtles with [not vaccinated? and not dead? and not immune?] [
      set vaccinated? true
    ]
  ]
  if (count turtles with [not vaccinated? and not dead? and not immune?] >= (num-people * vaccinated-over-30-days) / 30)[
      ask n-of ((num-people * vaccinated-over-30-days) / 30) turtles with [not vaccinated? and not dead? and not immune?] [
        set vaccinated? true
      ]
]
end 


; see social distancing model for implementing social distancing w/r turtles

to move-normal1

  ask turtles with [not dead? and not distanced? and not quarantined?] [
    set movement? (random-poisson lambda?)
    let y (0)
    let x (0)
    let z (0)
    while [y < ((movement?))][
      right random 360 ;;get a new random heading
      forward movement?

      set interactions? (interactions? + (count (turtles-on neighbors)))
      ;set neighbor-interactions? (count turtles-on neighbors + neighbor-interactions?)
       ;default socialbility is 3 integer becasue finite number of patches maybe change to long tail distribution,
      if (infected? and not immune?)
      [

      infect-susceptibles

      ]
      let foo (1)
      if vaccinated? [
        set foo (1 - vaccine-efficacy)
      ]


      if (not infected? and not immune? and z = 0 )
      [
        ask turtles-on neighbors [
          set interactions? (interactions? + 1)
         ; set neighbor-interactions? (neighbor-interactions? + 1)
          if (infected? and not quarantined?)[
            let infectivity ifelse-value (mask? = true)
            [(mouthBreather? * masked-transmissibility)]
            [mouthBreather?]


            if (random-float 1 < (infectivity * foo))[
              set secondaryinfections? (secondaryinfections? + 1)
              set z 1
            ]
          ]
          if z = 1 [stop]
        ]

        if (z = 1)[
          set infected? true
          set secondaryinfections? 0
          recover-time
        ]
      ]

     set y (y + 1)
     if (z = 1)[
          stop
      ]


    ; add quarantine metric, see social distance model - sociability distanced: how much do people who are social distances move- typically set at zero
  ]
  ]
end 

to recover-time

  set infectionDay? (floor ticks) ; maybe remove this floor? but also dont if add incubation period
  let rv (7)
  set recoveryDay? (infectionDay? + rv)
   ifelse random-float 1 < 0.01
    [set death? true]
    [set death? false]
  set quarantineDay? (infectionDay? + 5) ; this should eventually be changed
end 

to infect-susceptibles ;; S -> I version of Susceptible Infected Recover model
  ;ask turtles with [infected? and not dead? and not quarantined?][
    let x 0
    let infectivity ifelse-value (mask? = true)
    [(mouthBreather? * masked-transmissibility)]
    [mouthBreather?]
    ask turtles-on neighbors  [
    set interactions? (interactions? + 1)
    let foo (1)
    if vaccinated? [
        set foo (1 - vaccine-efficacy)
      ]
      if (not infected? and not immune?)[
        if (random-float 1 < (infectivity * foo))[
          set secondaryinfections? 0
          set infected? true
          recover-time
          set x (x + 1)
        ]
      ]
    ]
    set secondaryinfections? (secondaryinfections? + x)
    if (secondaryinfections? >= Super-Spreader-Threshold)[
      set superspreader? true
    ]
end 

to quarantine ;
  ask turtles with [infected? and not dead? and quarantine-if-sick?]
  [
    if (ticks >= quarantineDay?)
    [set quarantined? true
    ]
  ]
end 

to recover-infected-die ;;I -> R

  ;;avg case length is 2 weeks.
  ;;should have 50% chance of becoming immune at 2 weeks
  ;;if we are saying each tick equals 1 day,
  ;;daily odds of recovering should be (1-x)^14=.5, x= 0.0483 ;eventually change this to a Normal? distribution look into this


  ask turtles with [infected? and not dead?]
  [
    if (ticks >= recoveryDay?)
    [
      ifelse (death? = false)
      [
        set infected? false
        set recovered? true ;added
        ifelse (are-survivors-immune? = true)
        [
          set immune? true
          ;set color gray
        ]
        [
          ;set color white
        ]
      ]
      [ set dead? true
        ;set color green
        set infected? false

      ]
      set quarantined? false
    ]
  ]
end 

to recolor

  ask turtles with [infected? and not dead? and (secondaryinfections? < Super-Spreader-Threshold)]
  [ set color 26]
  ask turtles with [infected? and not dead? and (secondaryinfections? >= Super-Spreader-Threshold)]
  [ set color red
  set superspreader? true]
  ask turtles with [not infected?]
  [set color white]
  ask turtles with [immune?]
  [set color gray]
  ask turtles with [dead?]
  [ set color green]
  ask turtles with [quarantined?]
  [ set color pink]
end 

to calculate-max-infected
  let x (count turtles with [infected? and not dead?])
  if x > max-infected
  [set max-infected x]
end 

to calculate-total-infected
  set total-infected ((count turtles with [infected? and not dead?])) ;double parenthesis not necessary
end 

to calculate-daily-delta
  set daily-delta (count turtles with [infected? and not dead?] - total-infected)
end 

to calculate-avg-daily-delta
  let y (daily-delta)
  set total-delta (total-delta + y)
  set avg-daily-delta (total-delta / ticks)
end 

to calculate-moving-average

  set day-1 (day-2)
  set day-2 (day-3)
  set day-3 (day-4)
  set day-4 (day-5)
  set day-5 (daily-delta)
 if (ticks >= 5) [
  set moving-average ((day-1 + day-2 + day-3 + day-4 + day-5) / 5)
  ]
end 

to calculate-daily-intereactions
  ask turtles [
    ;set interactions? (interactions? + (count turtles-on neighbors) )
    set num-neighbors? interactions? ; this is pretty dumb and can be cleaned up - but it works rn
  ]
end 

to topdecilex
if ticks > 30 [

print("total infected") print(count(turtles with [infected? or recovered? or dead?]))

let mid (median[secondaryinfections?] of turtles with [infected? or recovered? or dead?])
print("median") print(mid)
print("count above median") print(count(turtles with [(infected? or recovered? or dead?) and secondaryinfections? > mid]))


set mid (median[secondaryinfections?] of turtles with [secondaryinfections? > mid])
print("second median")print(mid)
print("mean")print(mean[secondaryinfections?] of turtles with [secondaryinfections? > mid])
print("count above median")print(count(turtles with [(infected? or recovered? or dead?) and secondaryinfections? > mid]))


set mid (median[secondaryinfections?] of turtles with [secondaryinfections? > mid])
print("third median")print(mid)
print("mean")print(mean[secondaryinfections?] of turtles with [secondaryinfections? > mid])
print("count above median")print(count(turtles with [(infected? or recovered? or dead?) and secondaryinfections? > mid]))


set mid (median[secondaryinfections?] of turtles with [secondaryinfections? > mid])
print("fourth median")print(mid)
print("mean")print(mean[secondaryinfections?] of turtles with [secondaryinfections? > mid])
print("count above median")print(count(turtles with [(infected? or recovered? or dead?) and secondaryinfections? > mid]))


set mid (median[secondaryinfections?] of turtles with [secondaryinfections? > mid])
print("fifth median")print(mid)
print("mean")print(mean[secondaryinfections?] of turtles with [secondaryinfections? > mid])
print("count above median")print(count(turtles with [(infected? or recovered? or dead?) and secondaryinfections? > mid]))


  ]
end 

to-report topdecile
if count(turtles with [infected? or recovered? or dead?]) > 10 [

;print("bloop")
let infectious (count(turtles with [infected? or recovered? or dead?]) / 10)
let avg ( mean ([secondaryinfections?] of max-n-of infectious turtles [secondaryinfections?]))
;print("average")print(avg)

;print("how many are in top 10%")print(count( max-n-of infectious turtles [secondaryinfections?]))
;print("that times average")print(avg * infectious)
;print("total infected recovered or dead")print(count(turtles with [infected? or recovered? or dead?]) - init-infected)
;print("total secondary infections")print(sum ([secondaryinfections?] of turtles))
;print((avg * infectious) / ((count(turtles with [infected? or recovered? or dead?]) - init-infected)))

let proportion ((avg * infectious) / (sum ([secondaryinfections?] of turtles)))

report proportion
  ]


;print (sum [secondaryinfections?] of turtles)
end 

to startingconditions
  print("START")
  print ("num-people") print(num-people)
  print ("sociability-prob") print(sociability-prob)
  print ("shape-r") print(shape-r)
  print ("probability-of-transmission") print(Probability-of-Transmission)
  print ("Transmission-shape-parameter") print(Transmission-shape-parameter)
  print ("density") print(pop-density)
end 

to-report max-infected-prop
  report max-infected / num-people
end 

to-report prop-dead
  let y (count turtles with [dead?])
  report y / num-people
end 

to-report prop-uninfected

  report (count turtles with [not infected? and not immune?]) / num-people
end 

There is only one version of this model, created over 4 years ago by Alex Brown.

Attached files

No files

This model does not have any ancestors.

This model does not have any descendants.