Skip to content

Chapter 2: FRED Output

The FRED Core simulation produces a number of output files that include data generated from each simulation run, including:

  • daily and weekly time-series statistics for every state defined in the model
  • daily and weekly time-series statistics for every global variable defined in the model
  • agent records showing individual agent changes over time
  • detailed records for selected individuals
  • network files for each network defined in the model
  • a log file reporting internal messages from the FRED software
  • error and warnings

A FRED program can control how much detail is included in most of these files using options that will be explained in the sections below.

If the user is running the command line version of FRED using the fred_job command, these files are stored in the FRED_RESULTS JOB directory. For example, ~/FRED/results/JOB/<id> where <id> is the unique id number associated with the job. This directory also contains the meta-data for the job such as the time of the job and the FRED Version used. The specific output files for run N of the job appear in a RUN directory, for example ~/FRED/RESULTS/JOB/<id>/OUT/RUN<n>. When a modeler is developing a model with the command line version of FRED, it is typical to run tests locally using the fred_run or run_fred commands (both identical). In this case, the files are contained in the subdirectory OUT/RUN<N>.

Each RUN directory has a directory DAILY that contains the daily time series for each output variable from that run. These are consolidated in a file called OUT/RUN<n>/out.csv that covers the output for that run. The FRED Core produces and formats the data from a single run.

When the requested runs have completed, the fred_job command summarizes the daily time series files for each output variable from all runs into a directory OUT/PLOT/DAILY. Files in the latter directory report the mean daily value for each variable, along with the standard deviation. The same files also include the min, the max, the median, the 25th percentile, and the 75 percentile for each variable on a daily basis.

The FRED SIMS command fred_plot fetches data from the OUT/PLOT directory to plot each requested variable in a chart, and can display a number of different types of error bars.

This data can also be made available in WEEKLY directories, which summarize the data over weekly time frames. fred_plot knows how to plot weekly data as well as daily data.

Getting the Final Values for Single Output Variables

FRED includes two commands that retrieve the value of single output variables, including:

fred_get_mean --help | -k key -v variable
    -k or --key   the key for a FRED job (required)
    -v or --var   the variable to be reported (required)

fred_get_mean returns the mean value of the given variable at the end of all the runs in the given job. In addition, the command calculates the standard deviation, the 95% confidence interval, and the number of runs in the job:

$ fred_get_mean -k MyJob -v COVID19.totModerate
mean = 183.00000 std = 27.95632 CI = (165.67249,200.32751) N = 10

The command fred_get_median returns the median value of the given variable at the end of all the runs in the given job.

fred_get_median --help | -k key -v variable
    -k or --key   the key for a FRED job (required)
    -v or --var   the variable to be reported (required)

In addition to the median, the command calculates the 25th and 75th percentile value of the variable and the number of runs in the job:

$ fred_get_median -k MyJob -v COVID19.totModerate
median = 184.50000 (q1,q4) = (160.75000,194.00000) N = 10

Time Series Output

FRED output includes the daily time-series for every state defined in the model. The user can access these files either through the FRED Web interface or by using the command line interface discussed here.

We can illustrate the FRED output files using the following FRED program call test.fred. In this example, the setting weekly_data causes FRED to produce weekly output files in a WEEKLY directory for each run.

simulation {
    start_date = 2020-Jan-01
    end_date = 2020-Jan-05
    locations = Jefferson_County_PA
    weekly_data = 1
}

use FRED::Influenza

Suppose we run a job consisting of 4 runs using this program:

fred_job -k test -p test.fred -n 4

This FRED SIMS command creates a new job with the key test and executed the program test.fred four times. FRED SIMS stores all the files associated with this job in a directory dedicated to this job.

One output file is a comma-separated-value (CSV) file that can be opened by standard spreadsheet applications. The fred_csv command retrieves a CSV file giving the values of FRED output variables for each day of the simulation. If the job included multiple runs, you will get the mean and standard deviation for each variable, for each day. You can save this report to a file that can be opened using a spreadsheet program such as Microsoft Excel.

Command description:

fred_csv -k key [options] where options include:
    -k key  #the key for a FRED job (required)
    -v var  #if set, the variable to be reported. #default: report all variables.
    -r run  #if set, report a specific run number. #default: report mean and std over all runs.

To access the csv file use the fred_csv command:

$ fred_csv -k test > test.csv

The file test.csv contains the daily values of all the variables in the model (in this case, the model in the FRED Library FRED::Influenza). This file can be opened with your favorite spreadsheet program, and it looks like this:

Screenshot

The file contains one line of data for each day of each run. The columns show the name of the states defined in the model, as well as simulation day, date, epi-week, and population size.

The FRED::Influenza model includes the condition INF and the following states: S, E, Ia, Is, R, and Import. For each state, FRED records three values for each day:

  • the prevalence (that is, number of individuals in the population who are currently in the given state) labeled with the state name (e.g. INF.S above);
  • the cumulative count (that is, the total number of individuals who have ever been in the given state) labeled COND.totSTATE (e.g., INF.totS above), and
  • the daily incidence (that is, the number of individuals entering this state on the given day) labeled COND.newState (e.g., INF.newS above).

There are two variations of the fred_csv command. If you only want the data for a given run, you can pick the run number with the -n option:

$ fred_csv -k test -n 3

produces output of the following form:

Run,3
Day,Date,EpiWeek,Popsize,INF.newS,INF.S,INF.totS,INF.newE,INF.E,INF.totE,INF.newIs,INF.Is,INF.totIs,INF.newIa,INF.Ia,INF.totIa,INF.newR,INF.R,INF.totR,INF.newImport,INF.Import,INF.totImport,INF.RR
0,2020-01,01,2019.52,45318,45318,45308,45318,10,10,10,0,0,0,0,0,0,0,0,0,1,1,1,1.000000
1,2020-01-02,2019.52,45318,0,45308,45318,0,7,10,3,3,3,0,0,0,0,0,0,0,1,1,0.000000
2,2020-01-03,2019.52,45318,0,45305,45318,3,3,13,5,8,8,2,2,2,0,0,0,0,1,1,0.000000
3,2020-01-04,2019.52,45318,0,45300,45318,5,8,18,0,8,8,0,2,2,0,0,0,0,1,1,0.000000
4,2020-01-05,2020.01,45318,0,45298,45318,2,6,20,2,10,10,2,4,4,0,0,0,0,1,1,0.000000

If you want the combined data for a single column, you can specify the data variable name using the -v option:

$ fred_csv -k test -v INF.totE > totE.csv
$ open totE.csv

Screenshot

This table includes statistics about the specified state for each simulation day over the runs in the job. For each day, the row includes the minimum value, the first quartile, the median, the third quartile, the maximum value, the mean, the standard deviation, and the individual values for each run.

Global Variables as a Time Series

FRED can also produce time-series data on request for global variables defined in the FRED program. For example, suppose the model is keeping track of the number of drug prescriptions over time and includes a global variable:

variables {
    global Prescriptions
    Prescriptions = 0
}

This variable might be updated by each agent who receives a prescription:

state ReceivedPrescription {
    Prescriptions = Prescriptions + 1
    ...
}

To request that this variable appear in the output file, set the output property for this variable to 1.

variables {
    Prescriptions.output = 1
}

By default, the output property for global variables is 0, which produces no output.

The time series for a global variable named X is stored under the file name FRED.X, so the time series for the Prescription variable can by produced by the command:

$ fred_csv -k <job_name> -v FRED.Prescriptions

In addition to program-defined variables, FRED also computes and outputs two special global variables associated with each transmissible condition: the reproductive rate Rt and the generation time Gt.

Reproductive Rate Rt

The reproductive rate Rt is defined as:

Rt(day) = Mean number of individuals infected by agents who were
themselves infected on the given day

In other words, FRED tracks the cohort of individuals infected on each day. For each cohort, FRED tracks how many other individuals are directly infected by the members of each cohort, and outputs the value of Rt as a time series in the main output csv file. The name of the variable is <condition_name>.Rt.

Generation Time Gt

The generate time Gt is defined as:

Gt(day) = Mean time between the time of infection of one agent
and the infection time of all infectees of that agent, averaged
over all the agent infected on the given day

As with the reproductive rate, FRED tracks the cohort of individuals infected on each day. For each cohort, FRED tracks how many other individuals are directly infected by the members of each cohort and the time lag between the infector’s own exposure and the infectee’s exposure. The mean daily value for each cohort is output as time series in the main output csv file under the variable name <condition_name>.Gt.

Global List Variables

There are two properties that control the output of global list-variables:

global_list <list_var_name>
<list_var_name>.output = 0 | 1 (default = 0)
<list_var_name>.output_interval = N

if <list_var_name>.output is set to 1 then the list is exported at the end of the run to a file <list_var_name>.csv within a LIST directory created within the RUN<n> directory. The file has a single column containing the name of the global list-variable as the header line followed by the list of values, one per line.

If <list_var_name>.output_interval = N and N > 0 then a file is exported for each sim_day such that sim_day % N == 0. The file name is <list_var_name>-<sim_day>.csv within the results directory OUT/RUN<n>/LIST.

If N > 0 then <list_var_name>.output_interval = N also implicitly sets <list_var_name>.output = 1. That is, the list is exported at the end of the run, in addition to the periodic output files.

The command fred_get_list can be used to retrieve an exported list of values:

usage: fred_get_list --help | -v var -n run -k key

Here, var is the name of the global list-variable, key is the job key, and run is the run number. The command returns the output file for the indicated list-variable.

Plotting with fred_plot

The previous section shows how to extract output data in spreadsheet format for further analysis or plotting with a preferred plotting tool. FRED also provides a powerful built-in plotting facility. Here we describe how to generate plots using the FRED SIMS command fred_plot. This command creates plots of one or more FRED output variables for one or more fred_jobs.

Note

The fred_plot command requires that you have gnuplot installed on your computer.

$ fred_plot -h

usage: fred_plot -k key -v var [ options ], where options include:
    -a: show all individual runs.
    -b: plot bar charts instead of curves.
    -d 0/1 : display the image file (default = 1).
    -e: include error bars on plot.
    -f font : use the named font.
    -F fontsize: specify font size.
    -h: print this help message.
    -k key [ -k key ... ]: keys of jobs to plot.
    -n: scale y-axis to show counts per <s> people.
    -o outfile: send output image to indicated file.
    -r <n>: show individual run <n>.
    -s <s> : scale factor for normalization.
    -t title: Title to appear on plot.
    -v var [ -v var ... ]: variable to be plotted.
    -V: print list of available variables and exit.
    -w: plot variables averaged over epi weeks.
    -x xmin: min value for x-axis.
    -X xmax: max value for x-axis.
    -y ymin: min value for y-axis.
    -Y ymax: max value for y-axis.
    --yearly: plot annual values
    --monthly: plot monthly values
    --xtics <n>: put a tic mark every <n> units.
    --xlabel <s>: label the x axis with the string <s>.
    --ylabel <s>: label the y axis with the string <s>.
    --year 1: show year in xtics.

The following examples assumes that we have run a FRED job called simpleflu created using the following command:

$ fred_job -k simpleflu -p simpleflu.fred -n 5

The FRED program simpleflu.fred contains the following model. Note that we set weekly_data to 1 so that weekly data is also collected.

#####################################################
#
# A simple influenza model
#

simulation {
    # Simulation location
    locations = Jefferson_County_PA

    # Simulated Time Frame
    start_date = 2020-Jan-01
    end_date = 2020-Jun-01
    weekly_data = 1
}

condition INF {
    start_state = S
    meta_start_state = Import
    transmission_mode = proximity
    exposed_state = E
    R0 = 1.2
    R0_a = 0.0398238
    R0_b = 0.611043

    state S {
        INF.sus = 1
        wait()
        next()
    }

    state E {
        INF.sus = 0
        wait(24 * lognormal(1.9,1.23))
        next(Is) with prob(0.67)
        default(Ia)
    }

    state Is {
        INF.trans = 1
        wait(24 * lognormal(5.0,1.5))
        next(R)
    }

    state Ia {
        INF.trans = 0.5
        wait( 24 * lognormal(5.0, 1.5) )
        next(R)
    }

    state R {
        INF.trans = 0
        wait()
        next()
    }

    state Import {
        import_count(10)
        wait()
        next()
    }
}
#####################################################

Here are some examples of the fred_plot command for this job. A fred_plot command must include at least one job key (introduced with the option -k) and at least one variable (introduced with the option -v). Other command line options are used to format the plot’s title, axes, line types, colors, position of legend, and other aspects.

The first fred_plot command plots the time series associated with the variable INF.newE which contains the count of agents that enter the state INF.E each day. Note that the option -t gives the plot a title. The option -l gives a label for the plot in the legend. The option -o gives the output file name (with the suffix .pdf automatically added).

$ fred_plot -t "Simple Flu Model" -k simpleflu -v INF.newE -l "Incidence" -o fig1

Screenshot

The default is to plot using line graphs. The option -b produces bar charts:

$ fred_plot -t "Simple Flu Model" -k simpleflu -v INF.newE -l "Incidence" -o fig2 -b

Screenshot

The default is to plot the daily value of the request variable. The option -w plots the weekly sum of the variable:

$ fred_plot -t "Simple Flu Model" -k simpleflu -v INF.newE -l "Weekly Incidence" -o fig3 -b -w

Screenshot

The plot variable INF.E contains the current number of agents in the state INF.E each day. This includes agents that enter the state that day as well as agents that remain in the state from the prior day.

$ fred_plot -t "Simple Flu Model" -k simpleflu -v INF.E -l "Latent" -o fig4

Screenshot

If the option -v is be followed by several variables separated by commas (and no spaces), then the plot will contain one graph for each variable. In this case, the label option -l should also contain multiple labels separated by commas (if a label contains a space, make sure that label is in quotation marks). For example:

fred_plot -t "Simple Flu Model" -k simpleflu -v INF.newE,INF.E -l "Incidence","Latent" -o fig5

Screenshot

The plot variable INF.totE contains a running total of agents that have entered the state INF.E:

$ fred_plot -t "Simple Flu Model" -k simpleflu -v INF.totE -l "Total Infected" -o fig6

Screenshot

To convert a count to a prevalence per 100,000, use the normalize option -n.

fred_plot -t "Simple Flu Model" -k simpleflu -v INF.totE -l "Attack Rate" -n -o fig7

Screenshot

By default, the -n option normalizes to a count per 100,000 people. To scale the normalization to another number, use the -s <n> option.

$ fred_plot -t "Simple Flu Model" -k simpleflu -v INF.totE -l "Attack Rate" -n -s 100 -o fig8

Screenshot

Two variables can be summed using a + sign. So if the plot variable is specified as COND.A+COND.B, then the daily sum of COND.A and COND.B is plotted. In the following example, we want to plot the number of infectious agents for each day, which is the sum of the number of agents in the two states INF.Is and NF.Ia:

$ fred_plot -t "Simple Flu Model" -k simpleflu -v INF.S,INF.E,INF.Is+INF.Ia,INF.R \
-l "Susceptible","Exposed","Infectious","Recovered" -o fig9

Screenshot

When the job involves multiple simulation runs, fred_plot normally plots the median daily value for each plot variable. The error bars option -e adds error bars to the plot:

$ fred_plot -t "Simple Flu Model" -k simpleflu -v INF.totE -l "Total Infected" -e

Screenshot

The all option -a adds each individual run to the plot:

$ fred_plot -t "Simple Flu Model" -k simpleflu -v INF.totE -l "Total Infected" -a -o fig10

Screenshot

The previous graph covers part of the legend with data, so we might decide to move the legend outside the plot area using the --legend option:

$ fred_plot -t "Simple Flu Model" -k simpleflu -v INF.totE \
-l "Total Infected" -a -o fig11 --legend out

Screenshot

The x-axis is labelled with the dates of the start of each week by default. If the labels are too crowded, we can label only the first day of each month with the monthly option -M:

$ fred_plot -t "Simple Flu Model" -k simpleflu -v INF.totE \
-l "Total Infected" -a -o fig12 --legend out -M

Screenshot

We can also label the first and 15th day of each month with the biweekly option -B:

$ fred_plot -t "Simple Flu Model" -k simpleflu -v INF.totE \
-l "Total Infected" -a -o fig13 --legend out -B

Screenshot

Alternately, we can label the first, second, and third week of each month with the weekly option -W:

$ fred_plot -t "Simple Flu Model" -k simpleflu -v INF.totE \
-l "Total Infected" -a -o fig14 --legend out -W

Screenshot

The fred_plot command is often used to compare the output from multiple FRED jobs. For example, suppose we create two new jobs called simpleflu1.5 and simpleflu2.0 which set INF.R0 to 1.5 and 2.0, respectively. We can then compare the output on a single plot by naming several jobs in the key option -k. Note here how the variables, labels, and colors are specified for each job.

$ fred_plot -t "Simple Flu Model Weekly Incidence\nEffects of R0" \
-k simpleflu2.0,simpleflu1.5,simpleflu -v INF.newE,INF.newE,INF.newE \
-l R0=2.0,R0=1.5,R0=1.2 -o fig16 -w -X 16  --colors red,blue,green

Screenshot

Other options not discussed here allow you to set the font, line widths, log scale, or to select the range of x or y values to include in the plot. See fred_plot -h for a complete list of options.

Finally, if you wish to hand-tune the plot (e.g. for publication), fred_plot prints the name of the gnuplot file and the pdf file. You can edit the gnuplot source file to make additional changes to the plot. Furthermore, the data required for the plot is included in the gnuplot file.

$ fred_plot -t "Simple Flu Model" -k simpleflu -v INF.newE -l "Incidence" -o fig1
fred_plot: source_file = plot-fig1.plt  image_file = fig1.pdf

$ cat plot-fig1.plt

produces the following output:

# !/usr/local/bin/gnuplot
#
# file: plot-fig1.plt
# created: Fri Jun  5 13:30:14 2020
#
# command line used to generate this file:
# fred_plot -t Simple Flu Model -k simpleflu -v INF.newE -l Incidence -o fig1
#
set terminal pdf font 'Helvetica,12' linewidth 3 size 7,5
set title "Simple Flu Model" font "Helvetica,16"
set output "fig1.pdf"
set output "fig1.pdf"
set key at graph 0.96, graph 0.96 right
set xtics nomirror out 7 font "Helvetica,11"
set ytics mirror in font "Helvetica,11"
set label sprintf("%s","FRED 6.12.1 20-Jun-05 13:30") at screen 0.99,0.01 right font 'Helvetica,6'
date_format(n,x) = (n % 7==0) ? x : ""
set xtics rotate by 270
set grid ytics
set xrange [0:*]
set yrange [0:*]
set datafile separator ','
set xlabel "Date" offset 0,0.5
set ylabel "Individuals" offset 1.2,0
set bars 2.0 front
set xtics rotate by 270

plot '-' using ($0):($7):xtic($0>0 ? sprintf(date_format(int($0), strcol(1))) : '') title 'Incidence' with lines lt rgb 'blue' lw 4, \

DATE,INDEX,N,POPSIZE,MIN,QUART1,MED,QUART3,MAX,MEAN,STD,RUN1,RUN2,RUN3,RUN4,RUN5
2020-Jan-01,0,5,45318,10,10.00,10.00,10.00,10,10.00000,0.00000,10,10,10,10,10
2020-Jan-02,1,5,45318,0,0.00,0.00,0.00,0,0.00000,0.00000,0,0,0,0,0
2020-Jan-03,2,5,45318,0,0.50,2.00,4.00,6,2.20000,2.28035,2,1,2,6,0
2020-Jan-04,3,5,45318,0,0.50,3.00,4.50,5,2.60000,2.07364,3,1,0,4,5
...

Visualization: Map and Movies

The fred_make_movie command produces movies showing the location of individuals in selected states on a map of the simulation location.

The data for maps and movies can be quite substantial, so the default mode is not to create map data unless specifically requested. To create map data, the model needs to include the parameter setting in the simulation block:

enable_data_for_maps = 1

In addition, the model needs to specifically request mapping data for each state that should be visualized as dots on a map. Suppose the user wants to record the locations of agents when they enter either state A or B with a condition COND. Then the model needs to include the following settings in the condition block:

condition COND { A.enable_data_for_maps = 1 B.enable_data_for_maps = 1 } The effect of these statements is that FRED will record the household locations of any agent that enters state A or state B on each day of the simulation. As an example, consider the simple influenza model used in the previous section with the additional code shown below:

simulation {
    enable_data_for_maps = 1
    ...
}

condition INF {
    ...
    E.enable_data_for_maps = 1
    Is.enable_data_for_maps = 1
    Ia.enable_data_for_maps = 1
    R.enable_data_for_maps = 1
    R.is_dormant = 1
    ...
}

Suppose we create a FRED job using the command:

$ fred_job -k fluvis -p simpleflu.fred

Then we can create a movie with the command:

$ fred_make_movie -k fluvis -v INF.E

This produces a file called fluvis.mp4. An image from this movie is shown below:

Screenshot

The fred_make_movie command include several options to refine the format and annotation of the move.

$ fred_make_movie -h

usage: /Users/gref/FRED/bin/fred_make_movie [ options ], where options include [default values]
--api_key <key>: if set, use this api_key to obtain Google maps ["none"]
--border 0/1: if set, display border around map with lat-lon labels [0]
--captioncolors color1,color2,color3 : Colors of text in captions
--leftcaption <text> : text of left caption
--centercaption <text> : text of center caption
--rightcaption <text> : text of right caption
--census_tracts 0/1: plot census tracts [0]
--country <name> : plot the named country [usa]
--grid <0/1>: if set, show grid. [0]
--help: print this help message
--interval <n> : movie include every nth day [1]
--key <id> : plot the job with given id [none - must be specified]
--lightness <n> : set lightness of background map [0]
--lw <n> : use linewidth n to outline counties [2]
--max <val> : use the given value as the maximum for color plots [10]
--parallelism <n> : plot n maps in parallel [10]
--display <0/1> : if set, play the movie after it is made [0]
--period 'n1 n2 n3' : plot agents in the given states during period in days
--ps 'n1 n2 n3' : plot dots using point sizes [ "0.002 0.002 0.002" ]
--run <n> : plot results of run n [1]
--shapefile <0/1> : if set, draw the shapefile for each fips cod
--show_names <0/1>: if set, show local place names
--start day: start movie on specified day [0]
--subtitle <str> : subtitle for each map [" "]
--subsubtitle <str> : second subtitle for each map [" "]
--title <str> : title for each map ["FRED Simulation"]
--vars v1,v2,…vn : variables to be visualized
-x <xmin> : min value for x axis
-X <xmax> : max value for x axis
-y <ymin> : min value for y axis
-Y <xmax> : max value for x axis

Here is an example of a movie command that uses several of these options:

$ fred_make_movie -k fluvis --title "Simple Flu Model" –subtitle "Jefferson County, PA" \
    -v INF.R,INF.newE,INF.newIs,INF.newIa --color gray,blue,red,red --per 0,30,30,30 \
    --int 10 --display 1 --left "Exposed" --center "Infectious" --right "Recovered" \
    --caption "blue,red,gray"

Here is an image captured from the resulting movie:

Screenshot

Dormant States

Dormant states are terminal states for which FRED no longer needs to continue to collect daily map data when map data is enabled. Define a dormant state with the is_dormant property as follows:

condition <condition_name> {
    <state_name>.is_dormant = 1
}

This statement tells FRED not to record the location of an agent once it enters the given state. It does not affect the simulation results, though may save significant computation time and data storage when mapping is enabled.

Individual Agent Records

Upon request, FRED produces information about individual agents, their state transitions, their memberships in mixing groups, and their variables.

Warning: Due to the amount of data collected, it is recommended that individual agent records output should be restricted to a limited set of agents and a limited number of conditions.

To enable the output of individual records, include one of the simulation properties:

simulation {
   agent_records = 1
   all_agent_records = 1
}

If agent_records = 1, records are enabled but are turned off for individual agents by default. Individuals records are controlled at the agent level by the following actions:

  • start_records() turns on individual records for the agent performing this action.
  • stop_records() turns off individual records for the agent performing this action.
  • To turn on records for all agents, set all_agent_records = 1
    • Note: all_agent_records = 1 implies agent_records = 1.

Certain individual records are controlled on a condition by condition basis. Records for each condition are off by default. To enable records for all conditions, set the property:

simulation {
    all_condition_records = 1
}

To turn on individual records for a specific condition, set the property in the condition block:

condition <condition_name> {
   agent_records = 1
}

The following simulation properties further control the type of information that appears in the individual agent records:

simulation {
    agent_list_records = 0/1
    agent_membership_records = 0/1
    agent_state_records = 0/1
    agent_life_records = 0/1
    agent_var_records = 0/1
    agent_records_run_number = N
}

All of the above have value 0 by default, except the final property, which has a default value of N = 1.

List Output

This covers how to control output on agent lists.

agent_list_records

Setting agent_list_records = 1 will output a set of records each time an agent sets a list variable to a list value, one record per item in the new list.

This output is as follows:

SETS <date> <time> day <sim_day> person <id> <variable_name>[index] = <value>

For example, if agent 1234 executes

my_list = list(2,4,6)

then the output includes:

SETS 2020-01-02 10pm day 1 person 1234 my_list[0] = 2
SETS 2020-01-02 10pm day 1 person 1234 my_list[1] = 4
SETS 2020-01-02 10pm day 1 person 1234 my_list[2] = 6

As another example, if agent 1234 executes

my_list = list()

then the output includes:

SETS 2020-01-02 10pm day 1 person 1234 my_list = ()

agent_membership_records

With agent_membership_records = 1, a record is output each time an agent joins or quits a place or network:

JOIN <date> <time> day <sim_day> person <id> <group_name> <site_label> size = <size>

Here are some examples:

JOIN 2020-01-01 12am day 0 person 1234 Block_Group BG-420659503005 size = 42
QUIT 2020-01-01 10am day 99 person 1234 Party Party-700000000005 size = 1

The size is the size of the group after the JOIN or QUIT action.

agent_state_records

For agent_state_records = 1, the simulation will output a record each time an agent changes state in an enabled condition:

NEXT <date> <time> day <sim_day> person <id> <condition>.<state> => <condition>.<state>

or, if the agent is exposed to an enabled condition:

EXPO <date> <time> day <sim_day> person <id> <condition> at <place> from person <id>

where from person -1 means the person was exposed by the meta agent.

Examples:

NEXT 2020-01-02 11pm day 1 person 123456789 FOO.B => FOO.C
EXPO 2020-01-01 6am day 300 person 657483 SARCOV2 at Household from person 657488
EXPO 2020-01-01 6am day 300 person 6579786 SARCOV2 at UNKNOWN from person -1

agent_life_records

With agent_life_records = 1, a record is output each time an agent is exposed to an enabled condition, spawns an agent via the spawn_agent() action, or dies via the die() action.

Examples:

BORN 2020-01-01 2am day 85 person 12345 => person 9945318
DIES 2020-01-01 6am day 311 person 657483 from COVID19

agent_var_records

Setting agent_var_records = 1 cause a record to be written each time an agent sets a variable in an enabled condition:

SETS <date> <time> day <sim_day> person <id> <variable_name> = <value>

Examples:

SETS 2020-01-02 10pm day 1 person 123456789 x = 4
SETS 2020-01-02 10pm day 1 person 123456789 my_y = 6
SETS 2020-01-02 10pm day 1 person 123456789 z[123] = 8.2
SETS 2020-01-02 10pm day 1 person 123456789 my_list[99] = 21.5

agent_records_run_number

The final setting is agent_records_run_number = N. Since the agent records file may be quite large, by default the file is created only for the first run of a job that includes multiple simulation runs. The user can control which run has a agent records file by setting the value of N. If N = -1, agent record files are produced for all runs.

Example of a Model with Individual Agent Records

Consider the following program main.fred that creates individual records

simulation {
    locations = Jefferson_County_PA
    start_date = 2020-Jan-01
    end_date = 2020-Jan-02
    agent_records = 1
    agent_state_records = 1
    agent_var_records = 1
    agent_list_records = 1
    agent_membership_records = 1
}

variables {
    personal my_age
    personal_list my_hh
    global first
    first = 3
}

place Store {
    site = 0,0,0,0
}

condition FOO {
    start_state = A
    agent_records = 1

    state A {
        if (first > 0) then start_records()
        first = first-1
        my_age = age
        my_hh = members(Household)
        wait(2)
        next(B)
    }

    state B {
        join(Store)
        wait(3)
        next(C)
    }

    state C {
        stop_records()
        my_hh = list(1,2,3)
        wait()
        next()
    }
}

The program uses the global variable first to limit output to the first 3 agents that reach state A. Each agent sets a personal variable my_age and a personal list variable my_hh (a list of household members). In state B, each agent joins the single Store site. Agents stop recording when they reach state C.

We can run this program using FRED SIMS commands.

$ fred_delete -f -k test_records ; fred_job -k test_records -p main.fred

The entire file of records can be retrieved using the fred_get_records command.

$ fred_get_records -k test_records
SETS 2020-01-01 12am day 0 person 164281596 first = 2
SETS 2020-01-01 12am day 0 person 164281596 my_age = 42
SETS 2020-01-01 12am day 0 person 164281596 my_hh[0] = 164281596
SETS 2020-01-01 12am day 0 person 164281596 my_hh[1] = 164281597
SETS 2020-01-01 12am day 0 person 164281599 first = 1
SETS 2020-01-01 12am day 0 person 164281599 my_age = 41
SETS 2020-01-01 12am day 0 person 164281599 my_hh[0] = 164281599
SETS 2020-01-01 12am day 0 person 164281599 my_hh[1] = 164281598
SETS 2020-01-01 12am day 0 person 164281603 first = 0
SETS 2020-01-01 12am day 0 person 164281603 my_age = 41
SETS 2020-01-01 12am day 0 person 164281603 my_hh[0] = 164281603
SETS 2020-01-01 12am day 0 person 164281603 my_hh[1] = 164281602
NEXT 2020-01-01 2am day 0 person 164281596 FOO.A => FOO.B
JOIN 2020-01-01 2am day 0 person 164281596 Store Store-710000001 size = 1
NEXT 2020-01-01 2am day 0 person 164281599 FOO.A => FOO.B
JOIN 2020-01-01 2am day 0 person 164281599 Store Store-710000001 size = 2
NEXT 2020-01-01 2am day 0 person 164281603 FOO.A => FOO.B
JOIN 2020-01-01 2am day 0 person 164281603 Store Store-710000001 size = 3
NEXT 2020-01-01 5am day 0 person 164281596 FOO.B => FOO.C
NEXT 2020-01-01 5am day 0 person 164281599 FOO.B => FOO.C
NEXT 2020-01-01 5am day 0 person 164281603 FOO.B => FOO.C

To get just the records for person 164281599, use the -p <person_id> option.

$ fred_get_records -k test_records -p 164281599
SETS 2020-01-01 12am day 0 person 164281599 first = 1
SETS 2020-01-01 12am day 0 person 164281599 my_age = 41
SETS 2020-01-01 12am day 0 person 164281599 my_hh[0] = 164281599
SETS 2020-01-01 12am day 0 person 164281599 my_hh[1] = 164281598
NEXT 2020-01-01 2am day 0 person 164281599 FOO.A => FOO.B
JOIN 2020-01-01 2am day 0 person 164281599 Store Store-710000001 size = 2
NEXT 2020-01-01 5am day 0 person 164281599 FOO.B => FOO.C

To get all the records for any agent entering state FOO.C, use the -s <state_name> option:

$ fred_get_records -k test_records -s FOO.C
NEXT 2020-01-01 5am day 0 person 164281596 FOO.B => FOO.C
NEXT 2020-01-01 5am day 0 person 164281599 FOO.B => FOO.C
NEXT 2020-01-01 5am day 0 person 164281603 FOO.B => FOO.C

To get all the records containing the pattern my_hh, use the -g <pattern> option.

$ fred_get_records -k test_records -g my_hh
SETS 2020-01-01 12am day 0 person 164281596 my_hh[0] = 164281596
SETS 2020-01-01 12am day 0 person 164281596 my_hh[1] = 164281597
SETS 2020-01-01 12am day 0 person 164281599 my_hh[0] = 164281599
SETS 2020-01-01 12am day 0 person 164281599 my_hh[1] = 164281598
SETS 2020-01-01 12am day 0 person 164281603 my_hh[0] = 164281603
SETS 2020-01-01 12am day 0 person 164281603 my_hh[1] = 164281602

Network Files

If the model includes networks, the FRED program will produce output files for a given network if the program includes a property statement of the form:

<network>.print_interval = N

If N = 0 (the default), no output file is produced for the given Network. If N > 0, output files are produced after every N days of the simulation. In addition, when N > 0, network files are produced for first and the last days of the simulation.

For each day that a network is output, two files are produced.

The first file is named <network>-<sim-day>.vna (for example, MyNet-1.vna) and is in the VNA network format. This text file contains lines of the form:

*node data
ID age sex race
39790 20 F 1
43509 66 M 1
...
*tie data
from to weight
43509 43508 1.000000
43509 35391 1.000000
...

The first section contains one line for each agent in the network, giving the agent’s id, age, sex, and race. The second section has one line for each edge in the network, showing the agent, the agent it is connected to, and the weight of the edge.

The second file is called <network>-<sim-ay>.txt (for example, MyNet-1.txt). This text file contains FRED program statements of the form:

INFtrans.edge = 43509 43508 1.000000
INFtrans.edge = 43509 35391 1.000000

These lines can be included verbatim in a FRED program to define the edges in the network.

As an example, suppose you run the example Simple Flu program in the FRED Language Tutorials with the additional program statements:

INFLUENZA.transmission_network = INFtrans
INFtrans.print_interval = 5

The first line above tells FRED to generate a network called INFtrans which contains one node for each infectious agent and one edge between the infectious agent and all those agents exposed by the first agent. The second line tells FRED to output network files every 5 days. Another option would be to pick a larger number, say 1000. In that case, since the simulation lasts only a few months, FRED will produce network files for only the first day and the last day of the simulation.

After running the job, we get the following files for day 0. These show the 10 exposures from the Meta agent (represented by id -1 here):

INFtrans-0.vna:

*node data
ID age sex race
39790 20 F 1
-1 0 M -1
43509 66 M 1
38779 28 F 1
16183 28 M 1
45113 18 F -1
18354 23 M 1
18142 1 F 1
11651 30 F 1
39085 9 M 1
35833 67 F 1
*tie data
from to weight
-1 39790 1.000000
-1 43509 1.000000
-1 38779 1.000000
-1 16183 1.000000
-1 45113 1.000000
-1 18354 1.000000
-1 18142 1.000000
-1 11651 1.000000
-1 39085 1.000000
-1 35833 1.000000

INFtrans-0.txt:

INFtrans.edge = -1 39790 1.000000
INFtrans.edge = -1 43509 1.000000
INFtrans.edge = -1 38779 1.000000
INFtrans.edge = -1 16183 1.000000
INFtrans.edge = -1 45113 1.000000
INFtrans.edge = -1 18354 1.000000
INFtrans.edge = -1 18142 1.000000
INFtrans.edge = -1 11651 1.000000
INFtrans.edge = -1 39085 1.000000
INFtrans.edge = -1 35833 1.000000

After 5 days we get the following files, showing which agents have exposed other agents within the first 5 days of the simulation:

INFtrans-5.vna:

*node data
ID age sex race
39790 20 F 1
-1 0 M -1
43509 66 M 1
38779 28 F 1
16183 28 M 1
45113 18 F -1
18354 24 M 1
18142 1 F 1
11651 30 F 1
39085 9 M 1
35833 67 F 1
43508 61 F 1
38548 30 F 1
35391 70 M 1
33993 36 M 1
16424 27 M 1
4798 29 M 1
39789 56 F 1
28027 34 F 1
41925 35 M 1
28636 70 F 1
*tie data
from to weight
39790 39789 1.000000
-1 39790 1.000000
-1 43509 1.000000
-1 38779 1.000000
-1 16183 1.000000
-1 45113 1.000000
-1 18354 1.000000
-1 18142 1.000000
-1 11651 1.000000
-1 39085 1.000000
-1 35833 1.000000
43509 43508 1.000000
43509 35391 1.000000
43509 28636 1.000000
38779 16424 1.000000
38779 28027 1.000000
16183 38548 1.000000
11651 33993 1.000000
11651 4798 1.000000
43508 41925 1.000000

INFtrans-5.txt:

INFtrans.edge = 39790 39789 1.000000
INFtrans.edge = -1 39790 1.000000
INFtrans.edge = -1 43509 1.000000
INFtrans.edge = -1 38779 1.000000
INFtrans.edge = -1 16183 1.000000
INFtrans.edge = -1 45113 1.000000
INFtrans.edge = -1 18354 1.000000
INFtrans.edge = -1 18142 1.000000
INFtrans.edge = -1 11651 1.000000
INFtrans.edge = -1 39085 1.000000
INFtrans.edge = -1 35833 1.000000
INFtrans.edge = 43509 43508 1.000000
INFtrans.edge = 43509 35391 1.000000
INFtrans.edge = 43509 28636 1.000000
INFtrans.edge = 38779 16424 1.000000
INFtrans.edge = 38779 28027 1.000000
INFtrans.edge = 16183 38548 1.000000
INFtrans.edge = 11651 33993 1.000000
INFtrans.edge = 11651 4798 1.000000
INFtrans.edge = 43508 41925 1.000000

Gephi for Network Display and Analysis

The VNA files can be used to create network diagrams using a number of tools, including Gephi. An example of a display of the day 5 network using Gephi is shown below:

Screenshot

The Gephi system lets you interrogate each node and edge to see its id and other properties and provides numerous other network analysis tools.

The LOG File

The FRED LOG file contains internal messages and progress reports from the FRED Core software. It is often useful to examine the LOG when debugging the FRED software itself. This file is not intended for the casual user.

The following command prints the log file that was generated during the execution of a job. The job key must be supplied using the -k option, and the run number must be supplied with the -n option:

$ fred_get_log -k <key> -n <run>

Errors and Warnings

The FRED Compiler analyzes the FRED program and reports any errors or warnings. Errors are fatal and prevent a program from running. Examples of errors include:

  • Missing simulation location
  • Missing simulation start and end dates
  • Missing wait rules for states
  • Syntax errors in rules, such as mis-matched parentheses
  • Unrecognized expressions or actions

Warnings are informational and do not represent fatal problems with the program.

Commands such as fred_job invoke the compiler automatically, and will only run the simulation if no errors are found. To see errors and warnings directly, use the fred_compile command:

$ fred_compile -p <fred-program>