Is it possible to create a set number of turtles, from a file, to have their own patches? Like always be in the same location?
I've got 106 turtles I'm reading in from a file and I was hoping to have them be created on their own patches, like a square latice kind of thing. I want to be able to look at the model world and easily identify a turtle.
file-open "turtledata_A.txt"
show file-read-line
while [not file-at-end?]
[
set param read-from-string (word "[" file-read-line "]")
create-turtles 1 [setxy ??]
]
file-close
]
Probably easiest to use the csv extension and just add xy data to the file you're reading in. For example, if you have a turtle_data.csv file that looks like:
param-to-read,x,y
John,-10,10
Billy,-5,5
Bob,0,0
Simon,5,-5
Michael,10,-10
You can do:
extensions [ csv ]
turtles-own [ param ]
to setup
ca
reset-ticks
file-close-all
file-open "turtle_data.csv"
;; read the headings line in to skip it for data extraction
let headings csv:from-row file-read-line
while [ not file-at-end? ] [
let data csv:from-row file-read-line
create-turtles 1 [
set param item 0 data
setxy item 1 data item 2 data
]
]
file-close-all
end
which would give you something like:
Then you can modify the x and y values in your .csv file to place your turtles where you want them. Would that work?
Of course, you can add other columns in the .csv file (like color, size, shape, etc) that will help you identify turtles at a glance.
Related
I'm building an agent-based model in NetLogo where the agents walk to a target. I'm using the GIS Extension for NetLogo 6.3. At each tick they record the patch where they are currently standing on a list called "path".
I want to include a button to export this list to a shapefile, but I don't know how to do it. I believe I need to use the "gis:store-dataset" function. I'm using it like this:
to export-path
let file (word "path_output.shp")
if file-exists? file [file-delete file]
file-open file
let exported-path path
gis:store-dataset exported-path file
end
At the interface page I've set up a button calling the procedure with an ask turtles []. However I got the error message saying that this is not a dataset. Anyone can help me with this?
Thanks.
For computation and precision (depending on how big of an area your patches represent) I would suggest that instead of storing the patches in their lists, the turtles simply record their coordinates (using something like envelope-of) so that you can use your GIS to translate their coordinates into a shapefile with finer control:
extensions [ gis csv ]
turtles-own [ path ]
to setup
ca
reset-ticks
let shp_path "C:/gis_example/british_columbia_administrative.shp"
let prj_path "C:/gis_example/british_columbia_administrative.prj"
gis:load-coordinate-system prj_path
let shp gis:load-dataset shp_path
let base_envelope gis:envelope-of shp
gis:set-world-envelope-ds base_envelope
gis:set-drawing-color white
gis:draw shp 1
ask n-of 3 patches [
sprout 1 [
set path ( list self-ticks-coords )
show path
]
]
end
to-report self-ticks-coords
; Report the current ticks and then middle two 'envelope' values of the turtle
report sentence ticks (reduce sentence sublist gis:envelope-of self 1 3)
end
to go
ask turtles [
rt random 60 - 30
fd 1
set path lput self-ticks-coords path
]
tick
end
to go-10-then-export
repeat 10 [
go
]
let out-list reduce sentence [self-who-tick-coords] of turtles
set out-list fput [ "who" "tick" "x" "y" ] out-list
csv:to-file "C:/gis_example/example_coords.csv" out-list
end
to-report self-who-tick-coords
; Report a formatted list of who, tick, and coordinate vlaues
let who-tick-coord-list map [ i -> ( sentence who i ) ] path
report who-tick-coord-list
end
This exports a csv that stores the turtle identifier, the timestep, and coordinates (and flexibly can store whatever info you need) which I find more useful. My two cents!
Dataset downloaded from MapCruzin.com
I have a list of cells destination_cells, and am trying to loop through each cell and count the number of turtles and the average weight of the turtles in each. For each cell, I want to write the cell's ID (which I am assuming is just destination_cells as coordinates) and the two variables to a list cell_list. I think my confusion stems from not understanding how to use anonymous reporters in foreach. If I replace 'next cell' with destination_cells in the foreach block, I get, for example, the same total_turtle_in_destination_cells value for every single cell in destination_cells. The same occurs with using next_cells in the block. Where am I making a mistake?
set destination_cells [self] of patches with [ any? turtles-here]
foreach destination_cells [next_cell -> ask next_cell
[
; Counts number of turtles in each cell
set total_turtle_in_destination count turtles-on destination_cells
; Finds average weight of turtles in each cell
set avg_weight_turtle_in_destination mean [mass] of turtles-on destination_cells
]
set cell_list lput (csv:to-row (list
destination_cells
total_turtle_in_destination
avg_weight_turtle_in_destination
)) cell_events_list
]
Here is an alternative that:
Makes a reporter to get the info desired (the patch info as patch x and y, the total turtles on a patch, the mean weight of present turtles) from whatever patch that calls the reporter
Updates the info list directly by querying the destination_cells
turtles-own [ weight ]
globals [ destination_cells cell_info_list]
to setup
ca
resize-world 0 5 0 5
set-patch-size 30
reset-ticks
crt 20 [
set weight random 10 + 1
move-to one-of patches
]
end
to-report report-self-info
let n_turtles_here count turtles-here
let mean_weight mean [weight] of turtles-here
report (list self n_turtles_here mean_weight)
end
to create-info-list
set destination_cells patches with [ any? turtles-here]
set cell_info_list [report-self-info] of destination_cells
print cell_info_list
end
In response to your question "how can the patch call the reporter? I tried ask destination_cell [report-self-info], but a command is expected":
When you make a to-report procedure with the structure like the above that uses self, it's somewhat like a turtles-own or patches-own variable. In this case, you can call it just as you would have a turtle variable like color or xcor or a patch variable like pcolor or pxcor- if you run something like:
ask one-of patches [ print report-self-info ]
You should get something like
[(patch 5 2) 2 7.5]
This is why the set cell_info_list [report-self-info] of destination_cells above works- because you could do something like set cell_info_list [pcolor] of destination_cells in a similar way.
I'm still trying to extract the coordinates of the path taken by every turtle in the world. For example, I would like to know the path taken by turtle 0 was patch 00 patch 0 5 patch 0 2 and patch 1 4 and save this information in a .csv file. In this way, I would like to extract the coordinates of the path taken by all the turtles in the world. I'm thinking about creating a list that gives me this information and then saving it.
The problem is that I cannot create an empty list for each turtle created and then, before every move, add the current patch location to the lists. And finally, generate the file of this information in .csv
That is, when inspecting the turtle I don't see the list and when creating the file in .csv it is not generated. Can anyone help me with the code?
Thanks in advance
turtles-own [ mypathx mypathy mytimer]
to setup
ca
reset-ticks
crt 5
ask turtles [
setxy random-xcor random-ycor
let i [ ]
pen-down
]
end
to go
move
let n count turtles
if n = 0 and output? = true [output] ;; ouput? is an switch on interface
if n = 0 [ stop ]
tick
end
to move
ask turtles [
rt random 360
fd 1
if ticks >= 10
[
die
]
]
end
To output
file-open "test.txt"
ask turtles [
set mypathx lput pxcor mypathx
set mypathy lput pycor mypathy
let maxer length mypathx
let i 0
repeat maxer
[
file-print (word item i mypathx " " item i mypathy " " item i mytimer)
let x ( i + 1 )
]
]
file-close
end
There are a number of things to note here, so I hope I understood what you inteded to do.
First of all, note that your code goes to output only after all the turtles died (that is infact one of the conditions to go to output: if n = 0). Therefore, it is normal that there is no data to be exported: in output you ask turtles, but when output is executed all turtles already left the simulation.
However, there is also something that Filip rightly noticed in the comment to the question: it seems logical to ask turtles to save the coordinates of their journey as they move - as opposed to asking them to do so at the end of the simulation.
Based on the current code, turtles simply move in the simulation, and only at the end (e.g. when output is called) they are are asked to save their current location. It would be ideal to include a piece of code where you ask turtles, after each move, to record their location in the list.
To combine this point and the previous one, I would do something like:
to setup
clear-all
reset-ticks
create-turtles 5 [
; I talk about this piece in point 3.
]
end
to go
move
tick
end
to move
ask turtles [
right random 360
forward 1
register-coordinates
]
end
to register-coordinates
set mypathx lput pxcor mypathx
set mypathy lput pycor mypathy
set mytimer lput ticks mytimer ; This is what I assumed you want mytimer to do.
end
And here comes the other problem. You are not initiating the turtles-own variables as lists.
If you run your piece of code now, nothing happens because all turtles are dead by the time you ask them to output. But if you just remove the die command, or if you ask turtles to output before they die, you would get an error - saying that lput expected a list but got something else instead.
From the NetLogo Dictionary you can see that the list primitive is used to create a list with two values.
If you want to create a list containing any other amount of values, you have to use (list ...). This includes the case in which you want to create an empty list. To do that, I would therefore do:
create-turtles 5 [
setxy random-xcor random-ycor
set mypathx (list)
set mypathy (list)
set mytimer (list)
pen-down
]
Now, mypathx, mypathy and mytimer are legal inputs to the lput procedure.
Finally, you can include the output at the end of your simulation (note how I changed go compared to the previous code example):
to go
if ticks = 11 [
ask turtles [output]
stop
]
move
tick
end
...
to output
file-open "test.csv"
file-print (word who "," mypathx "," mypathy "," mytimer)
file-close
end
So, overall, improtant adjustments are: initiate variables as lists if you want to treat them as such; ask your turtles to save their coordinates at every step in their turtles-own list variables; only at the end, ask them to write their list variables in the output file; do not kill your turtles before you ask them to output information.
Integrating all of the above, the code would look like:
turtles-own [mypathx mypathy mytimer]
to setup
clear-all
reset-ticks
create-turtles 5 [
setxy random-xcor random-ycor
set mypathx (list)
set mypathy (list)
set mytimer (list)
pen-down
]
end
to go
if ticks = 11 [
ask turtles [output]
stop
]
move
tick
end
to move
ask turtles [
right random 360
forward 1
register-coordinates
]
end
to register-coordinates
set mypathx lput pxcor mypathx
set mypathy lput pycor mypathy
set mytimer lput ticks mytimer
end
to output
file-open "test.csv"
file-print (word who "," mypathx "," mypathy "," mytimer)
file-close
end
Final notes on the code above:
I am not sure which exact format you want your output to be, but this example code works fine in saving the lists in the .csv file - so you can take it from there and play around to make it fit your needs.
I removed the pcolor part because it seemed unnecessary for the purpose of the question.
I am not sure what you wanted i to do in setup, but it seemed unnecessary for the purpose of the question so I removed that too from my exemplar code. Be careful at how you use item: I don't know what you wanted to do, but the way you included it in your question was often giving runtime errors.
I created a .csv as per the title of the question, instead of a .txt as per the code you provided.
I'd need to pick an object in a bag containing 20 elements with attributes c (color) and s (size). Both color and size are numbers (e.g. c= {red = 256, black = 0, ... } = {256, 0, ...}).
As in Python I'd use random.choice in numpy library, I found on the web that the corresponding function in Netlogo is the extension rnd.
Struggling along a possible solution, I did
Edited:
breed[people person]
people-own
[
ball
size
color
bag
]
to setup
create-people 5
[ set color gray
setxy random-xcor random-ycor
]
ask people[
set bag [ ] ; 0 items
]
end
To create the balls:
to create-balls
set color random 300 ; color
set size random-float 5 ; size
let this-ball self
ask one-of people [ ; ask one of people to put the ball created into the bag
set bag fput this-ball bag ; add ball to the bag
]
end
The code below should include the part of drawing:
to draw
ask one-of people [
rnd:weighted-one-of bag [ ] ; I do not know what I'd write in the brackets
]
end
As you can easily see, I've many doubts about how to implement the code.
How can I select one item from the bag depending on its size (or color)?
Can you please help me out with it?
Here is a complete model that creates people and balls as turtle agents and has 30 of the balls get chosen weighted by their size. It then opens an inspect window for the person who has chosen the most balls.
extensions [rnd]
breed [people person]
people-own [ my-balls ]
breed [balls ball]
balls-own [ chosen? ]
to setup
clear-all
create-people 20
[ setxy random-xcor random-ycor
set my-balls (turtle-set nobody)
]
create-balls 50
[ hide-turtle
set size one-of [1 2 3 4 5]
set color one-of [red white blue yellow]
set chosen? false
]
repeat 30 [draw-ball]
inspect max-one-of people [count my-balls]
end
to draw-ball
ask one-of people
[ let bag-of-balls balls with [not chosen?]
let choice rnd:weighted-one-of bag-of-balls [size]
ask choice [set chosen? true]
set my-balls (turtle-set my-balls choice)
]
end
Some things to notice:
There are NO lists in this code. There are situations where you should use lists. Common uses include memory where the order is important (eg you only want to keep track of the last 5 other people seen) or where the same agent can appear multiple times. And the list commands are very powerful. However, unless you need a list then you should use agentsets.
Each person has their own bag called 'my-balls' that contains the balls they select. That is initialised as a turtle-list as part of the setup.
I used a variable called 'chosen?' that is owned by each ball to track whether it is still in the bag for the next person to choose. Then the bag-of-balls is created only as all the balls not yet chosen.
The code for weighted random choice (when choosing from agentsets) simply has the name of the variable holding the weight as the reporter, but you could use some function such as rnd:weighted-one-of bag-of-balls [size ^ 2] if you wanted a more complicated weighting scheme.
I have a network of nodes and links. This figure
is a capture of the world. The graph represents streets of a city. I have imported a shapefile with the gis extension. The gray lines are links, black dots are nodes and red dots represent people. The people move heading to the next node. In a street corner, the red dot chooses next street by examining the variable popularity owned by the link.
The links breed has a variable, popularity, whose value I would like to copy in the patches that are below.
If I try, for example, something like this to access patches under links will produce an error
ask links [show [(list pxcor pycor)] of patch-here]
Another approach can be to access links variable popularity from patches, but I do not know how to do it.
The reason why I want this is because I want to write in a file a matrix of popularity values and its position in the matrix should correspond with the position of the link in the world. Thus, the patches below the links would give me the matrix form. I have a procedure that for each patch writes the value of the patch in a file. However, I do not know how to pass the popularityvalue from the link to the patch below it.
Is there any way to copy a link owned variable to its patch?
Regards
If someone has a better way of doing this (or can simplify my code), feel free. Here is a complete working example. Copy it into an empty NetLogo model and run it to see it work.
The setup procedure just creates some nodes and links with appropriate test values and then calls the transfer-link-values procedure, which does what I think you want. The setup procedure then puts the values into the patch labels to display them and see the results.
The way the transfer-link-values procedure works is to create a turtle at one end of the link, and that turtle moves toward the other end of the link transferring the value as it goes. When it gets to the other end, the turtle dies.
patches-own [patch-popularity]
links-own [link-popularity]
to setup
clear-all
create-turtles 10 [ setxy random-xcor random-ycor]
while [ any? turtles with [not any? my-links] ]
[ let to-pair turtles with [not any? my-links]
let thisNode one-of to-pair
ask thisNode
[ create-link-with one-of other to-pair
[ set link-popularity 5 + random 5 ]
]
]
transfer-link-values
ask patches [ if patch-popularity != 0 [set plabel patch-popularity ] ]
end
to transfer-link-values
ask links
[ let start-node one-of both-ends
let this-link self
let end-node nobody
ask start-node [ set end-node [other-end] of this-link ]
let transfer-value link-popularity
ask start-node
[ hatch 1
[ face end-node
if transfer-value > patch-popularity
[ ask patch-here [ set patch-popularity transfer-value ] ]
while [ not member? end-node turtles-here ]
[ forward 1
if transfer-value > patch-popularity
[ ask patch-here [ set patch-popularity transfer-value ] ]
]
if transfer-value > patch-popularity
[ ask patch-here [ set patch-popularity transfer-value ] ]
die
]
]
]
end