Rafaela
Rafaela

Reputation: 449

How to adjust files to export data in NetLogo 6.2?

I am trying to export a file in NetLogo 6.2. But I'm having 2 difficulties:

  1. put only 1 header in the output. It only comes out with multiple headers or without header (see figures below)

multiple headers:

enter image description here

without header:

enter image description here

and I would like it to look like this (below). Is it possible?

enter image description here

  1. close the file so that multiple results are not written to the same file. When I use the command "carefully" and "file-delete" and "[]" only the result of a turtle appears:

enter image description here

if I remove the commands "carefully" and "file-delete" and "[]" the result of all turtles appears. However, if I run the model several times, the results will be saved on top. How is it possible to close the file without changing the result?

The code:

globals [ outifile ]
turtles-own [ my-xcor my-ycor my-timer ]

to output 
;  carefully ;; using this command to close the file only saves the path of the last turtle
;  [ file-delete ( word outfile name ".csv" ) ] ;; using this command to close the file only saves the path of the last turtle
;  [ ] ;; using this command to close the file only saves the path of the last turtle
  file-open ( word outifile ".csv" )
  file-print ( word "id;my_xcor;my_ycor;my_timer" ) ;; when removing this line, there is no header
  file-print ( word self  " ; " my-xcor " ; " my-ycor " ; " my-timer )  
  file-close
end

Upvotes: 0

Views: 119

Answers (1)

Matteo
Matteo

Reputation: 2926

The two issues have the same cause and same solution.

For point 1

This is because apparently to output is executed by every turtle, which means that every turtle will first print the headers and then print the values. Note that this is exactly what you're asking them to do, having both of the following lines of code being executed by each turtle:

file-print ( word "id;my_xcor;my_ycor;my_timer" )
file-print ( word self  " ; " my-xcor " ; " my-ycor " ; " my-timer )

Therefore, you have to print the headers first, before asking turtles to do anything (i.e. the observer is the one who has to print the headers, and then has to ask turtles to print values).

For point 2

This issue too comes from the fact that you have every turtle executing the whole to output procedure. In this case, this means that every turtle will run

carefully
 [file-delete (word outfile name ".csv")]
 []

Hence, every turtle will make sure that the file has been deleted (or that it doesn't exist) before writing their output.

Again, this is something that the observer should do, because it needs to be done only once.

Fix

To solve these things, you have two absolutely equivalent options:

Option 1

Leave to output a turtle-context procedure (i.e. a procedure executed by turtles) and place the observer's tasks somewhere else in your code, where you know that they will be executed only once - for example in setup or some equivalent place:

to setup
 ; Here you have your normal 'setup' code, plus:
 prepare-output
end

to prepare-output
 carefully
  [file-delete (word outfile name ".csv")]
  []

 file-open (word outifile ".csv")
 file-print (word "id;my_xcor;my_ycor;my_timer")
 file-close
end

So the observer will take care of cleaning the file and creating headers, and when turtles will run to output they will only need to print their values.

Option 2

Change to output from a procedure that is executed by turtles, to a procedure that is executed by the observer. In this case, at the beginning of the procedure the observer will do once its observer's things, and only then ask all turtles to print their values. Once the turtles are done, the observer closes the file. For example:

to go
 ; Here you have your normal 'go' code, plus something like:
 if (stop-condition-reached?) [
  output
  stop
 ]
end

to output
 carefully
  [file-delete (word outfile name ".csv")]
  []

 file-open (word outifile ".csv")
 file-print (word "id;my_xcor;my_ycor;my_timer")

 ask turtles [
  file-print (word self  " ; " my-xcor " ; " my-ycor " ; " my-timer)  
 ]

 file-close
end


The logic behind both options is exactly the same: the observer does its things once (deleting the old file and creating a new one with headers), then each turtle prints its values.

The difference between the two options is only in how the code is organised - i.e. is to output a procedure executed by turtles, or by the observer (who then asks turtles to print)?

In general it is important to keep track of who is executing what. For this reason, in my code I always comment the declaration of each procedure with a note stating what context such procedure is being executed from (e.g. observer context, turtle context, patch context, link context).

Upvotes: 1

Related Questions