First Steps with NetLogo

Lets take a few first steps with our modeling frameworks.  We will be fairly brief , limiting ourselves to simple "kicking the tires" and writing a hello world in each ABM system (here is the RePast First Steps).  Our goal is to gain a feel for what each system is capable of so that we can make intelligent decisions on which one to use for a given task.  Note: most images below can be clicked on for a full size image.

Introducing NetLogo

To download NetLogo, go to their web site, downloading the package for your system.  As of this writing, the version is 1.2.  During the download you can join the mail list, which I recommend. 

The package will include considerable browser-based documentation in the docs/ directory for fast viewing.  I show the results of downloading "Other Java-enabled platform" to the right.  The NetLogo.jar is double clickable, starting the application.  Specific downloads are available for Mac and Windows.

The NetLogoLite.jar file is used for exporting your models to the web, like this example.




When NetLogo starts, you are presented with an empty model, left, which you can modify.  You also can browse the Model Library, right. Start by selecting the Segregation model from the Social Science collection. 

To run the model, click "Setup", then "go".  The model runs until each agent (called turtles) is "satisfied" .. i.e. has neighbors of at least "%-similar-wanted" as himself.   You can experiment with number of turtles and the % setting by changing the sliders.



Note the surprising result with the initial settings: wanting 30% similar neighbors generally results in over 70% similar!  This suggests very minor desire for similarity among residents of a neighborhood results in segregation.  Click on the tabs on the top of the window to see more information about the model, and to see the source code itself.  The code is surprisingly simple for what it does.

Now lets try a few simple commands.  To do this, we'll select New in the File menu to get an empty new model.  This presents just two items: the graphics window and the command center.  The graphics window shows the patches and turtles, while the command center lets you type in commands, helpful for experimenting to see how they work.

Kicking The Tires: The Command Center

The command center accepts commands in three contexts: commands for the global Observer, or for commands sent to all of the individual Turtles or Patches as a group.  You choose which sort of command you want via the small drop down menu.  In the image below left we show the patches being selected. The center image shows the result of one command: "set pcolor (pxcor + pycor)" which simply sets the color (a number between 0 and 140) to the sum of the x and y coordinates.  Note that, because the command is going to all of the patches, the entire Graphics Window is changed.  Silly but illustrative! We then switch to Observer mode and reset the display and create 36 turtles with these two commands: "clear-patches" and "create-turtles 36".  We then switch to Turtle mode, and do "set heading who * 10" and "forward 15" which turns the turtles in all directions ("who" is the number of the turtle from 0 to 35) and then has them move forward 15 units, resulting in the image on the right.


Programs are run using a very simple Logo-like language, along with an easy to use GUI for building sliders, buttons, and graphs.  To understand this a bit further, we'll use the (excellent!) documentation that came with the download.  The index page is to the right.  Use your browser to look at the doc/index.html that came with your system.

Take some time to browse through the documentation.  The three tutorial modules are quite good as are the three reference sections.  Look at the Interface Guide .. it will show you all the visible components in a model, and explain how they are used.  Then look at the Programming Guide .. it will guide you through all of the NetLogo language features.  Finally, the Primitives Dictionary gives detailed information on every language primitive.  It will be your constant companion as you write models!


Buttons: A "Hello World" Model


In Stuart Kauffman's wonderful book "At Home in the Universe", he presents an example of a rapid "phase transition".  This is modeled by a set of buttons which, during each turn, a random pair are chosen to be tied together. 

Initially there are lots of isolated pairs tied together.  Later threes, fours and abruptly there is a steep transition to most of the buttons being tied together .. an emergent giant cluster.  In the example shown here, there are 500 buttons and we plot 1000 turns.  The rapid change occurs at around the 1/4 mark where the number of threads is about half the number of buttons.



We can model this in NetLogo by having the buttons be turtles placed randomly on the graphic window.  Each tick we will chose a pair of buttons, connecting them together and changing their color to be the same.  At the end of each turn we will find the largest cluster, posting its size.

Before we start, you can try the model in your browser, and browse the source code.

As we begin programming, use your "Open File" menu to open the docs/index.html that came with your NetLogo download, and click on the Primitives Dictionary, so that you can look up the NetLogo language keywords as we use them.   On my system, it looks like this.

We will build our model in four phases, in order to make learning a simple, step-by-step process. 

  1. Initialization: Building the "button" agents and randomly placing them on the display
  2. Behavior: Building the procedure that ties a pair of buttons together, merging their two sets of buttons.
  3. Control: Building the GUI elements that control the setup and execution of the simulation
  4. Data: Building the GUI elements that show the data gathered by the simulation
The majority of the programming is done in steps 1 and 2, while the buttons and graphs are added in steps 3 and 4.

Buttons Phase 1: The Button Turtles and the setup Procedure

From the File menu chose "New". This will give us a "blank" new model with an empty graphics window and a command center.  Use the File menu's Save command to save the model on your disk in a convenient place.  We'll use the name Buttons, which is stored with the extension ".nlogo" automatically.  Ours looks like this.

Click on the Procedures tab where the model program is built.  It will look like this.  It has one line:

; add model procedures here

The ";" begins a comment which goes to the end of the line.   We'll delete this and begin by building the buttons agents.  Our first phase simply builds 500 turtles (buttons) and randomly places them on the screen.  The source file is here and looks like this, where we've added line numbers for reference:

1 globals [buttons]           ; Global variables

2 to setup ; Initializes model for new run.
3 set-default-shape turtles "circle" ; Turtles are circles
4 clear-all ; Reset turtles and patches
5 set buttons 500 ; Set number of buttons to 500
6 create-turtles (buttons) ; Create "buttons" number of turtles
7 ask turtles [setup-turtles] ; Initialize each turtle
8 end

9 to setup-turtles ; Called for each turtle during setup
10 setxy random screen-size-x random screen-size-y ; Set our x,y randomly
11 end
Cut and paste the source into the (empty) procedures tab.  It will look like the image on the right when your are done.  Note the color coding used to make it easier to understand the elements of the Logo language.  In this case, language commands, like "set" or "ask" are blue, built-in variables are purple, literal numbers and strings are red, our variables and procedures are black and structural keywords (globals, to, end) are dark green.

To compile the code, click on the Compile icon, or simply click on the Interface tab where we are going next.  Anytime you exit the Procedures tab, it will automatically compile if needed.


To run the current code, click on the Interface tab.  We have not built a GUI yet so will have to use the Command Center like we did in the "Kicking the Tires" introduction above.  Make sure the type-in area of the Command Center is in "Observer" mode (i.e. the left of the type-in area shows "O >").  A small drop-down menu is used to change between Observer, Turtle, and Patches, see the introduction above. 

Click in the type-in area to the right of the "O >" symbol and type "setup".  You can do this several times, getting a new random set of buttons each time.


Line 1 declares the global variable, "buttons", the number of buttons for this run of the model.  Note that it is not declared as an integer variable, which it happens to be.  NetLogo dynamically types variables as needed.  And indeed, you can have the same variable be a string, a list, an integer and so on during the execution of the program.  Look up "globals" in the NetLogo Primitives Dictionary by clicking on the "G" Alphabetical index, or by scrolling primitives frame, or by searching to the word "globals" using your browser's "Find".  Also note the comments at the end of the line: everything past a ";" is a comment, just like C/C++ "//" comments or the shell's "#" comments.

Lines 2 and 8 ("to" and "end") enclose the definition of the procedure "setup".  Line 3 sets the shape of the turtles to be circles rather than the default arrow-like shape.  Line 4 initializes the system by killing all existing turtles, resetting all globals, and clearing the patches and plots.  This lets us re-run the model multiple times.  Line 5 sets the global "buttons" to  be 500.  Line 6 creates that number of turtles.  Line 7 then causes the procedure on line 9 to be called for each turtle.

For each of the commands above, there is an entry in the Primitives Dictionary in the documentation.  To the right we show the "clear-all" entry.  The "ca" in the banner tells us that we can use ca as an abbreviation for clear-all.  The eye-ball tells us that it executes in the observer context (as discussed in the Command Center above).  If you have any doubt how a command works, just look it up!



The "ask" command is special: it executes the command in each individual turtle's context. This exposes variables like "color, xcor" which can be set, and "who", which cannot be changed.

The documentation contains special entries for these variables.  To the right we show the entry for turtles.  You can also check the variables for patches.  There are also predefined variables for constants like "red" , "pi", and so on.


Just as Lines 2 and 8 enclose the procedure "setup", lines 9 and 11 enclose the procedure "setup-turtles".  Line 10 is our first compound command which contains three simple commands, two instances of the "random" command and one instance of the "setxy" command.  Calling "random integer-variable" returns a number between 0 and (integer-variable - 1).  The "setxy" command takes two variables and sets the turtle's xcor and ycor (coordinate) values to these two numbers.  Note that Logo typically uses these compound commands, much like Lisp and other sophisticated recursive languages.

The "setxy" statement introduces us to the coordinate system used by the turtles and patches.  This is discussed in Tutorial #1 in the Changing Graphics Window Settings section.  The origin, x=0, y=0, is in the center of the patches.  This causes NetLogo to have the screen-size-x and screen-size-y to be an odd number of cells.

But in the setxy command, we use screen-size which is twice the edge length plus one for the center! This works because NetLogo wraps the coordinates around the edges.  So when an X coordinate is one greater than the right edge, it really on the far left edge.  This means the NetLogo modeling space is actually a torus.  This is common in modeling frameworks.

A similar style is applied to colors.  Colors go from 0-140 as discussed in Tutorial #2 in the Working With Colors section.  If you set a color beyond the 140 colors, they wrap as well.  Thus color 150 is the same as color 10.  This lets us use colors equal to the "who" number of the turtles without error.

Buttons Phase 2: Adding Behavior, the "Go" procedure

Our first phase simply let us initialize our Buttons model.  This phase adds the model's behavior of selecting pairs of buttons and tying them together, one pair each step of the model.  The "go" and "joinClusters" procedures contain the new code we need.  This phase completes most of the programming, the additional phases are primarily GUI building.  Here is the new source code, again shown below with reference line numbers:
1 globals [buttons]           ; Global variables
2 turtles-own [group] ; Each turtle has "group" as a variable

3 to setup ; Initializes model for new run.
4 set-default-shape turtles "circle" ; Turtles are circles
5 clear-all ; Reset turtles and patches
6 set buttons 500 ; Set number of buttons to 500
7 create-turtles (buttons) ; Create "buttons" number of turtles
8 ask turtles [setup-turtles] ; Initialize each turtle
9 end

10 to setup-turtles ; Called for each turtle during setup
11 set group who ; Initialize "group" ins var to ID built-in
12 setxy random screen-size-x random screen-size-y ; Set our x,y randomly
13 end

14 to go ; Step the model once
15 locals [g1 g2] ; This procedure has some temp local variables
16 set g1 group-of turtle random buttons ; g1 & g2 are two group values
17 set g2 group-of turtle random buttons ; chosen from two random turtles
18 ask turtles [joinClusters g1 g2] ; Merge group g1 with group g2
19 end

20 to joinClusters [g1 g2] ; Convert group g1 turtles into g2 turtles
21 if (group = g1) [set group g2 set color color-of turtle g2]
22 end

As we did before, lets start with your placing the new source code in the Procedures tab, as shown on the right (replacing all the earlier code). Click on the Interface tab (which auto-compiles the code) which lets us use the Command Center.  As before, enter "setup" to initialize the model.  You can also run "go" a couple of times.  But note this makes little in the way of change.

To run the model several times, use the "repeat" command which takes a count and a procedure.  We'll use "repeat buttons [go]" to run it the number of times we have buttons.  On the left we have the results of such a run.  Note that a considerable number of the buttons now belong to a large cluster.


Line 2 adds a new variable, "group", to each turtle, using the "turtles-own" command.  This is initialized in line 11, inside our earlier "setup-turtles" procedure, to be the value of the turtle's "who" variable.  Recall "who" is automatically assigned to turtles and cannot be changed.  Thus each turtle starts out in a group of one, itself.  This means there are no threads yet tied between any of the turtles.  These two lines are the only changes to our earlier procedures.  The other changes are to add the "go" and "joinClusters" procedures.

As before, lines 14, 19, 20 and 22 enclose our two new procedures using "to" and "end" pairs. At line 15, the "go" procedure uses the "locals" primitive to declare two local variables.  Local variables are only "visible" within the defining procedure and are thus temporary to the execution of the procedure. Line 16 is a compound command, using the "set", "-of", "turtle", and "random" primitives.  The execution is from right to left.  First, "random buttons" returns an integer between 0 and buttons-1.  Next, the "turtle" primitive uses this to return the turtle who's ID ("who" value) is equal to that random number.  Next, the "group-of" command returns the "group" variable's value of that particular turtle.  (Look at the -of primitive in the Primitives Dictionary, under "O".)  Finally, the "set" command stores the result in the "g1" local variable.  Line 17 simply repeats this for a second time to get a second group value, "g2", to use.

Whew!  These three lines could have been written:

                locals [g1 who1 t1 g2 who2 t2]
set who1 random buttons
set t1 turtle who1
set g1 group-of t1
set who2 random buttons
set t2 turtle who2
set g2 group-of t2

But as you become more adapt at NetLogo, you'll find the terse form far easier to read and understand.

Line 18 in the "go" procedure asks each turtle to execute the command: "joinClusters g1 g2".  JoinClusters is the first procedure we have created with arguments passed to it (g1 & g2).  The task of "joinClusters" is to make every turtle in group g1 become a g2 member by setting its group value to g2 and its color to be the same as all the turtles of g2.  It does this with a single line with several parts.  It is easier to understand rewritten as follows:

        if (group = g1) [
set group g2
set color color-of turtle g2
]

The "if" primitive takes a boolean (true/false) expression and if it evaluates to true, executes the supplied procedure.  The ()'s are not necessary but improve readability.  Note that "a = b" does not mean "set a to b" but "does a equal b".  The first line of the if statement's procedure simply sets the group variable of the turtle to be g2.  The second statement is a compound statement: turtle g2 returns the turtle who's ID ("who" value) is g2.  We then set the color of the current turtle to be the color of turtle g2.  This is a bit subtle: "turtle g2" is guaranteed to be in the g2 group because of the way we initialized the groups to be turtle IDs.  Thus its color is the color of the g2 group.  Actually, we could just as simply set the merged group colors to be "red" or some other value.  We are simply trying to make all the turtles in groups g1 and g2 to look alike.

Buttons Phase 3: Graphic Controls

By now, we've done all the hard programming parts: built a set of random buttons and built the procedure to pick up a pair of buttons and join their groups.  Phase 3 and 4 are the graphic parts: providing controls and input parameters, and providing outputs showing the results of the model.

You'll be delighted to hear that for this phase, we actually take two lines of code out of the program!  We do this by placing a ";" in front of lines 1 and 6 above, see the Procedures window to the left.  Go ahead and do this.

Initially this will cause an error, see Error window, right.  Don't panic!  Its important to see how NetLogo handles errors, so lets dwell on this a bit.

When you commented out the two lines above, it left NetLogo not knowing about the "buttons" variable which tells us how many buttons to use.  When you click to leave the Procedures tab, or you click the compile icon, NetLogo finds the error, and automatically opens the Error tab, with the error highlighted in blue, and explained in yellow.  You can still go the Interface tab, but to help you remember you're in an error state, both the Procedures tab and Errors tab will be highlighted red.

So how do we fix the error?  NetLogo's sliders both declare a global variable and set its value .. exactly the two lines we commented out. To make our own slider, go to the Interface tab and click the slider control as shown on the right.

When we click on the slider control button, we are presented with a cross-hair cursor, asking where on the window to place the slider. After we click, we get an "empty" slider and an editing window. 

On the right we show our entering "buttons" as the global variable name associated with this slider, thus fixing the error.  We also set 100, 100, 1000 as the Minimum, Increment, and Maximum values for the slider, and 500 for its current value.  Go ahead and do this now.  After you are done, you can compile the program without error by entering the Procedures tab and clicking on the compile icon.


After creating the slider, it can be moved and resized by selecting it: click in the white part of the window and drag over the slider.  By then clicking on the edit icon, you can also edit the parameters you set up when you made the slider initially.

At this point, you can run the program as you did in Phase 2: using the Command Center for entering "setup" and "go" commands, while using the slider to control the number of buttons used.  The rest of this section will add two buttons to replace this use of the Command Center

First, we'll add a NetLogo button to call "setup".  To do this, in the Interface Tab, click the Button icon, and with the cross-hair cursor, click where you want to place the "setup" button.  Put "setup" in the resulting dialog's code box.  This will default to being the display name as well.  Each click will re-initialize the buttons.

Similarly, create a "go" button, with the additional step of checking the "Forever" check box, causing it to repeat indefinitely (until the stop command above).  We can now run the model easily without the command center.

Next, we'll generate graphical data for the simulation.

Buttons Phase 4: Graphical Results

To complete the simulation, we'll add three graphical data outputs: a plot of the number of buttons in the largest group, the current tick count, and the current largest cluster.  Here is the new source code  which contains just 9 new lines.  Save your Phase 3 model and then cut and paste the new source into the Procedures window.
1  globals [ClusterSz ticks]   ; Global variables
2 turtles-own [group] ; Each turtle has "group" as a variable

3 to setup ; Initializes model for new run.
4 set-default-shape turtles "circle" ; Turtles are circles
5 clear-all ; Reset turtles and patches
6 set ticks 0 ; Initialize ticks global to 0
7 set ClusterSz 1 ; Initialize ClusterSz global to 1
8 set-plot-y-range 0 buttons ; Set Y axis to be 0 .. "buttons" tall
9 create-turtles (buttons) ; Create "buttons" number of turtles
10 ask turtles [setup-turtles] ; Initialize each turtle
11 end

12 to setup-turtles ; Called for each turtle during setup
13 set group who ; Initialize "group" ins var to ID built-in
14 setxy random screen-size-x random screen-size-y ; Set our x,y randomly
15 end

16 to go ; Step the model once
17 locals [g1 g2 thisClusterSz] ; This procedure has some temp local variables
18 set g1 group-of turtle random buttons ; g1 & g2 are two group values
19 set g2 group-of turtle random buttons ; chosen from two random turtles
20 ask turtles [joinClusters g1 g2] ; Merge group g1 with group g2

21 set thisClusterSz (count turtles with [group = g2]) ; Calculate merged size
22 set ClusterSz (max list ClusterSz thisClusterSz) ; Update global max size
23 plot ClusterSz ; Plot current max cluster size
24 set ticks (ticks + 1) ; Keep track of number of steps
25 if (ClusterSz = buttons) [stop] ; Stop if we have one huge cluster
26 end

27 to joinClusters [g1 g2] ; Convert group g1 turtles into g2 turtles
28 if (group = g1) [set group g2 set color color-of turtle g2]
29 end
Compiling this code will not create an error.  But when the "setup" button is clicked, we get a run-time error. 

This is caused by our not yet having a plot window, thus the "set-plot-y-range" command fails.  We'll solve this by adding the NetLogo plot GUI item.

But first, lets look at the changes in the final version of the program's source code.


Line 1 adds two global variables we will use to monitor the simulation: "clusterSz" and "ticks".  ClusterSz is the number of buttons in the largest group of buttons.  We initialize this to 1 in line 7.  Ticks is the number of times we've run the "go" procedure.  We initialize this to 0 in line 6.  Line 8 initializes the plot we are about to build to have the Y axis go from 0 to buttons, the size of the largest cluster when all buttons are connected to each other.

Lines 21-25 manage clusterSz and ticks in the go procedure.  Line 21 sets a local variable, "thisClusterSz", to be the size of the newly merged two groups of buttons.  The phrase "turtles with [group = g2] returns the set of turtles who's group variable is g2.  The "count" primitive returns the number of turtles in this set, which is used to set the value of thisClusterSz.  The global variable clusterSz is then set to the maximum value of itself and the local thisClusterSz. Line 23 adds the new value of ClusterSz to the plot.  Line 24 simply increments the "ticks" global variable.  Finally, line 25 halts the program when we've reached the point where all the buttons are in the same group.

Just as with the slider, we click on the Plot icon, get a cross-hair cursor for placing the plot, and a plot editing window appears for setting the plot parameters.

We make four changes: fill in the Name to Cluster Size, X Axis Label to Steps, Y Axis Label to Cluster and set the X Max Value to 1000.

To use the new plot item, click setup, then go, and watch the plot grow over time.



To create the ClusterSz display, click on the Monitor icon, then clicking where you want to place the display.  In the resulting dialog, enter "ClusterSz" in the "reporter" box. (A Reporter in NetLogo is any value or procedure returning a value). 

Similarly create the "ticks" monitor which shows how many times the simulation "go" procedure has been run.


To make the model clearer for the user, we'll clean up the layout a bit my moving and resizing our GUI items, and adding two text items.

First, select and drag the  buttons and slider down enough to leave a white space for a text label.  Repeat for the two monitors and the plot, resizing the plot as shown.  This separates the controls from the data items, leaving space for labels.  Create two Text items describing the new layout, see details on the right.

The final results appear like the image to the left.


Summary and Home Work!

In this fairly elementary (only 29 lines of code, after all!) NetLogo tutorial, we've tried several things:
Here are a few explorations you can try for your next steps into NetLogo
  1. Add a "step" button which calls the "go" procedure, but only once rather than continuously.
  2. Look at the Information tab.  Fill it out for this model.  This will appear in the model if you send it to someone therefore is very useful!  And it will be included in the web page you are going to make in 5 below.
  3. Create the initial plot with an X axis length of 2*buttons.  Thus if buttons is set to 700, the X axis will go from 0 to 1400.
  4. Our current model lets multiple buttons exist on a single patch.  Change the program to allow only one turtle to exist on a given patch (x, y location).  Hint: use the "turtles-at" or "turtles-here" style commands.  Or simply ask a random number of patches to create the initial turtles.  This is the "best practice" method.
  5. Use "Save as Applet" from the file menu.  This will create an html file that will include the current model in the web page as an applet, along with explanatory information as to how to deploy it.  It will include the information from the Information tab.  Make sure you copy the NetLogoLite.jar file to where you put your applet!  It contains the reduced NetLogo jar file appropriate for a web based model.
  6. Our current model can pick up the same button and connect it to itself!  Change the program so that this does not happen.
  7. Our current model randomly merges two groups of buttons.  Change the model to merge the smaller group into the larger one.  Hint: use "count turtles with [..]" twice to figure out which of g1 or g2 is larger.
Extra Credit: Most models have the agents move during the simulation. Using many of the above explorations, I've added motion to the model.  In this version of the model, the two groups being joined together move towards each other if there is an empty space available. For your extra credit asignment, try using this version of the model, and read the code to understand how the motion was achieved.

Feel free to contact me if you run into difficulties or have suggestions for improving the tutorial!

On to RePast

Now that you've completed this tutorial, on to RePast First Steps.  It will let you see the same Buttons simulation done in RePast using the Java programming language.  Note that even if you do not plan to use Java, its interesting to compare the two systems.