Chapter 5: Epidemic

In this set of exercises, you'll make a more biologically-relevant simulation which may provide you with some ideas for your project.

You will also learn now to make graphs - another item that will be extremely useful for your project..

Learning Objectives:

  • Learn how to use random numbers to control agent traits and movement
  • Learn how to use more complex "if..." statements (aka "Conditionals")
  • Give an example of a response to a collision that depends on the traits of the agents involved
  • Learn how to manage and use the clock
  • Learn how to count agents with specific traits
  • Construct a line graph of healthy and infected turtle agents
  • Compare and contrast this model with a real-life epidemic

New blocks and tools:

  • random...
  • if/then/else
  • with ... chance
  • clock
  • count agents within....
  • clock
  • line graph

Block Reference Table

Below are the new blocks you will use in Epidemic. Look them over carefully and think about how you might use them in the project.

You may want to review some of the blocks you learned about in previous exercises.

Block Drawer What the block does NetLogo code equivalent

if/then

Logic Do something or don't depending on the result of a test.

In this case, the test is "is the size less than 5". If this is true, then it will execute the code inside its 'mouth'.

Here, if the size is less than 5, then it will set the color to cyan; if the size is 5 or higher, then it will do nothing to the color.

Any code outside the block will always be executed - in this case, their shape will be set to lion no matter how big they are.
if size < 5 
 [ set color cyan ]
set shape "lion"

Note that the square braces - "[" and "]" - take the place of the 'mouth' in the SLN block.

if/then/else

Logic  Choose between two alternatives depending on the result of a test.

In this case, the test is "is the size less than 5". If this is true, then it will execute the code in the top 'mouth' else, it will execute the code in the bottom ('else') mouth.

Here, if the size is less than 5, then it will set the color to cyan; else (the size must be 5 or higher), it will set the color to green. No matter the size, it will set the color to either cyan or green.

Any code outside the block will always be executed - in this case, their shape will be set to lion no matter how big they are.
ifelse size < 5 
 [ set color cyan ]  ;; "if" code
 [ set color green ] ;; "else" code
set shape "lion"     ;; "always" code

Note that the top square braces correspond to the top 'mouth' while the bottom sqaure braces correspond to the bottom 'mouth'.

And, because the "set shape lion" is not in either of the braces, it will always run.

comparisons

Logic These allow you to make "if" statements that test all sorts of comparisons.

The "and" and "or" can be used to combine the ones above to do things like "if x > 3 and x < 5".
xcor = 5  ;; equal to
xcor != 5 ;; not equal to
xcor < 5  ;; less than
xcor > 5  ;; greater than
xcor <= 5 ;; less than or equal to
xcor >= 5 ;; greater than or equal to
(xcor > 3) and (xcor < 5)
(xcor > 3) or (xcor < 5)

	  

random

Math Generate a random integer in a range including the specified endpoints.

In this case, it will choose a random number from this set: 0, 1, 2, 3, 4 and 5.
random 6

Note that, to get integers from 0 through and including 5, you have to enter "6" as the limit. NetLogo will generate random integers up to but not including the limit you specify.

random decimal

Math Generate a random decimal number between 0.00000... and 0.999999...
random-float 1

Note that, if you want decimal numbers up to but not including, for example 5, you'd write "random-float 5".

with ... chance do...

Logic Run the code inside the block with a certain probability.

In this case, approximately one time in every 10 times this block is run, the color will be set to cyan. The other times, the color will not be changed.
if random 100 <= 9 [
  set color cyan
]

Note that, since NetLogo's random numbers include 0 and not the limit, you need to use the values above. If you wanted a 50% chance, you'd use "<= 49".

add data to line graph

Interface Adds one point of data to a graph that is made up of pairs of x- and y- coordinates.

Typically, this goes in a "while forever toggled...." block so that the graph is updated every time 'tick'. This code should also go in setup so that the graph starts off with the initial conditions at time = 0.
;; to plot a point at each time step
plot <value to plot> 
;; for example:
plot count turtles


		

Note that these commands are not entered in the "Code" window but in the plot's settings. More on this later.

count ... within...

Detection Counts the number of agents of a specific breed with a specific trait in a given radius from the agent running the command.

When this is run in the "World" tab, it 'looks' from the center of Spaceland (0,0), so, to count the whole of Spaceland, you should set the radius to 200 steps. Other values may be useful in other contexts.
;; to count ALL turtles
count turtles
;; to count only red turtles
count turtles with [ color = red ]


		

Note that there is no need to specify a radius; it will survey the whole world by default.

clock

Environment Returns the value of the clock, measured in “ticks”. This value increments by 1 every time the code runs, which is 5x per second at normal speed.
ticks 
	  

set clock

Environment Sets the value of clock to some number. Typically, when you reset the clock, you want to start it at 0.
reset-ticks  ;; sets clock to 0
tick         ;; advance clock one step		

Note that, in NetLogo, you can't set the ticks to an arbitraty value, you can only clear it or advance it by one 'tick'.

Unlike SLN, you must manually 'tick' the clock every time your forever block runs (see later); this will also automatically update the graphs.

clear line graph

Interface Removes the existing data on the graph.
clear-all 
		

This command clears EVERYTHING.

Part 1: Create a new project and have it start with a population of healthy and sick agents

In this section, you will create a population of agents, some of which are sick and some not.

Steps:
  1. Create a new project and give it a descriptive name - something like "epidemic", perhaps.
  2. On the "World" page, build some setup code to:
  3. Clear the world of any leftover turtles
    • Create 300 yellow turtle agents with an interesting shape scattered over Spaceland
      • The yellow color will indicate that the agents are un-infected.
    • Make a randomly-chosen 5% of the agents red to indicate that they're infected

Note that the order of the "set my..." blocks is very important. You should be sure that you understand why this is the way it is. Be sure to try several different arrangements to see how it works.

Hint: think it through step-by-step like this:

This all happens 300 times, one by one:

  1. I am born
  2. my shape is set to cube
  3. my color is set to yellow
  4. Randomly, on average 5 times out of 100, my color is changed to red; the rest of the time, nothing happens and I stay yellow
  5. I always get scattered to a random spot in space land

to setup
  clear-all
  create-turtles 300 [
    set color yellow
    set shape "box"
    if random 100 <= 4 [ set color red] ;; 5% chance
    set xcor (random 32) - 16
    set ycor (random 32) - 16
  ]
  
end
	

You can download a template NetLogo file with "setup" and "forever" buttons here.

Check your code:

Check carefully to be sure that all of these happen when you click "setup":
  • A lot of turtles are made and they're scattered all over SpaceLand. No need to count to 300...
  • Almost all of them are yellow.
  • A very few (about 15) are red.
  • Each time you click "setup" the turtles should be in different places and there should be a (slightly) different number of red ones.

Part 2: Make the agents move 'realistically'.

In the past, agents moved in straight lines. This is not very realistic. In this section, you'll code them to 'meander'.

Steps:
  1. In the turtle page, create code that:
    • moves the turtles forward 1 step each 'tick'
    • have them turn right a random number of degrees between 0 and 10
    • have them turn left a random number of degrees between 0 and 10

At first glance, this seems like a waste - to turn 10 degrees right, then 10 degrees left - does that do anything at all?

The key here is that the two turns are each a random number of degrees, so, for example, it might turn 5 degrees left and then 8 degrees right - for a net of 3 degrees right.

You might well ask:

  • So why don't you just say "turn left random 0 to 10"? Try it and see what they do.
  • Why not "turn left random -10 to 10"? Try it and see. It makes them meander more. Why?
In the end, how much you make them 'meander' is a matter of personal taste and the objective of the simulation. Take some time to play around until the agents move in a way that looks sufficiently 'real' to you.

The histograms below illustrate the difference between the two turning methods. As you can see, using two random blocks causes the agent to turn sometimes but go straight more often.

to forever
  ask turtles [
    forward 1
    right random 11
    left random 11
  ]
  
end

	  

Note that, in order to get a range from 0-10, you need to ask for "random 11" since 11 won't be included.

Check your code:

When you click "setup" then "forever", the agents should 'meander' about SpaceLand. Be sure they're not just going in straight lines - try watching one agent carefully.

Part 3: Model the Spread of Disease

Make the disease spread by contact - collisions.

Steps:

In the "turtle" page, write code that:
  1. When a turtle collides with a sick (red) turtle, it becomes sick (red).

Hint: the turtle that has hit you is the 'collidee' - you can test the color of the collidee to see if you bumped into a healthy (yellow) or sick (red) turtle.

Add code to the "to forever" block to make this:

Be sure that it's inside the "ask turtles" part.

to forever
  ask turtles [
    forward 1
    right random 11
    left random 11
    ;; collision code
    if any? turtles in-radius 1 with [ color = red ] [
      set color red
    ]
  ]
  tick
end		
		

Check your code.

Look for these things to be sure it's working:

  • Watch an individual red (infected) turtle - you should see that, when it hits a yellow (healthy) turtle, the yellow one turns red (gets sick).
  • If two yellow (uninfected) agents collide, they should both stay yellow.
  • Watch the population over time. Eventually, they all should be red (sick).

Part 4: Add a Graph of Sick and Healthy Agents

Create widgets and write code to plot the number of healthy and sick agents over time.

1) Create a line graph widget.
  1. Click "edit interface" at the top of SpaceLand.
  2. Make some space for a graph - it will be about as big as SpaceLand - by dragging the buttons and SpaceLand as you prefer.
  3. Choose "Line Graph" from the "Create Widget" menu.
  4. Drag the box containing the graph to where you want it to sit.

In NetLogo, the steps are:

  1. Drag the lower left corner of the window to make the "Interface" pane large enough for the graph.
  2. Move the buttons and SpaceLand to make space for the graph. For each:
    1. right-click or control-click the thing you want to move
    2. choose "select" from the pop-up menu
    3. you can now drag the thing to where you want it
    4. click anywhere else in the "Interface" pane to un-select
  3. Choose "Plot" from the "Button" menu and place the plot where you want it. A window will also pop up to let you configure the plot; click "OK" to close it for now. You may want to make the plot a little bigger than the default.
2) Set up the graph widget.
  1. Click the graph and a little window will pop up where you can enter settings for the graph.
  2. Set the X-axis title to "time" and the y-axis title to "# of turtles"
  3. Set the name of the first series to "# of healthy turtles" and change the pen color for that line from red to yellow by clicking the little pen button to the right of the label blank
  4. Click "(+) Add Series" and add another series named "# of sick turtles" and use the default red pen color.
  5. Close the window by clicking the X in the upper right corner.
  6. Click "lock interface" when you've got everything set up nicely.

The steps in NetLogo are very similar. The key difference is that you need to enter the plotting code in the "Plot pens" section. Don't forget the [braces] in the code.

3) Set up the graphing code.
  1. In the "World" tab, add blocks to, while "forever" is toggled to continually add counts of healthy and sick turtles to the graph.
  2. In the "World" tab, add blocks to, when "setup" is pushed, clear the line graph and set the clock to 0.

The code for counting was already set when you set up the graph above, so the code here is really simple.

Just add "reset-ticks" in your setup code (outside of the create-turtles block) and "tick" in your forever code (outside of the ask turtles block).

This is all the code so far.

to setup
  clear-all
  create-turtles 300 [
    set color yellow
    set shape "box"
    if random 100 <= 4 [ set color red] ;; 5% chance
    set xcor (random 32) - 16
    set ycor (random 32) - 16
  ]
  reset-ticks
end



to forever
  ask turtles [
    forward 1
    right random 11
    left random 11
    ;; collision code
    if any? turtles in-radius 1 with [ color = red ] [
      set color red
    ]
  ]
  tick
end		
		
4) Check your work so far.

Click "setup", then "forever" and you should see:
  • Note that, in SLN, you have to click the little graph button at the top of the graph or you'll just see the numerical data.
  • The graph update as time passes.
  • the line for "healthy turtles" should drop while the line for "sick turtles" should rise
  • you will notice the graph re-scaling itself as data arrive.
  • Eventually, the healthy turtles line should go to 0 and the sick turtles line should go to 300

Part 5: Add Recovery and Immunity

In real life, individuals typically recover from illness after some time and then are immune to re-infection.

We can make our model more reaistic by adding this.

We'll use the color blue to represent recovered - and therefore immune - agents.

As practice for your projects, take a few minutes before looking at the code to think how you might do this.

Steps:

Add code and change the graph settings as needed to:

  1. Have a 5% random chance every time step for an infected agent to become immune - this simulates the time it takes to 'get better'. (There are ways to do this more realistically but, this will work for now)   
  2. Once an agent becomes immune, it cannot be re-infected.
  3. Add a line to the graph for "immune" agents and update it with the number of immune agents

The entire code for this is:

to setup
  clear-all
  create-turtles 300 [
    set color yellow
    set shape "box"
    if random 100 <= 4 [ set color red] ;; 5% chance
    set xcor (random 32) - 16
    set ycor (random 32) - 16
  ]
  reset-ticks
end

to forever
  ask turtles [
    forward 1
    right random 11
    left random 11
    ;; collision code
    if any? turtles in-radius 1 with [ color = red ] [
      if color = yellow [
        set color red
      ]
    ]
    ;; recovery code
    ;; only recover if infected (red)
    if color = red [
      if random 100 < 6 [ set color blue ]
    ]
  ]
  tick
end

Don't forget to add a new pen to the graph - make the pen blue and call it "# of recovered agents" and add this code to the "Pen update commands":

plot count turtles with [ color = blue ]

You can download the full NetLogo project here.

Check your code.

There's a lot to check here - be sure your code passes all of these tests:
  • Be sure all the previous code still works:
    • On setup, you get mostly yellow and some red turtles
    • When a red turtle hits a yellow turtle, the yellow one turns red
  • No blue turtles are created on setup
  • While it's running, watch a few red turtles and see that they eventually turn blue.
  • Watch a few blue turtles, when they hit red ones, they should still stay blue.
  • No yellows should ever turn blue.
  • No blues should ever change color at all.
  • At first, the epidemic spreads and there are a lot of sick (red) turtles but, eventually, they all end up recovered-immune (blue)

Part 6: Extensions

Try taking this a little further

Try some of these as practice for your project: