Skip to content

Configuration

matbii is highly configurable thanks to the modular agent-based design of icua. Various files are used in the configuration of tasks and experiments, these files are described in the sections below.

Main Configuration

Matbii can be configured using a .json file.

The path of this file is supplied as -c <CONFIG_PATH>, for example:

python -m matbii -c ./experiment-config.json

The default entry point (main) configuration has sections corresponding to a specific aspect of the simulation. Not all options need to be specified and all have reasonable default values.

ExperimentConfiguration

Configuration relating to the experiment to be run.

  • id (string | null) = null: The unique ID of this experiment.

  • path (string) = './': The full path to the directory containing task configuration files. If this is a relative path it is relative to the current working directory.

  • duration (integer) = -1: The duration (in seconds) of this experiment (the simulation will close after this time), a negative value will leave the simulation running forever.

  • enable_video_recording (boolean) = False: Whether to begin a screen recording of the experiment when the simulation starts, the video will be saved to the logging path when the experiment ends.

  • enable_tasks (array) = ['system_monitoring', 'resource_management', 'tracking']: Which tasks to enable at the start of the simulation.

  • meta (object) = {}: Any additional meta data you wish to associate with this experiment.

Example
"experiment": {
  "id": null,
  "path": "./",
  "duration": -1,
  "enable_video_recording": false,
  "enable_tasks": [
    "system_monitoring",
    "resource_management",
    "tracking"
  ],
  "meta": {}
}
ParticipantConfiguration

Configuration relating to the participant (or user).

  • id (string | null) = null: The unique ID of the participant that is taking part in the experiment.

  • meta (object) = {}: Any additional meta data you wish to associate with the participant.

Example
"participant": {
  "id": null,
  "meta": {}
}
GuidanceConfiguration

Configuration relating to guidance that may be provided to a user.

  • enable (boolean) = True: Whether to enable guidance, if this is False then no guidance agent will be created. Only set this False if you do not plan to use AT ALL in your experiments, otherwise set counter_factual to True.

  • counter_factual (boolean) = False: Whether to show guidance to the user, if False then guidance agent will be configured NOT to display guidance but will still take actions for logging purposes (if they support this).

  • break_ties (string) = 'random': How to break ties if guidance may be shown on multiple tasks simultaneously.

  • grace_mode (string) = 'attention': Condition for which the grace_period is waiting. Options: 'guidance_task' - time from last guidance a task, 'guidance_any' - time from last guidance on any task, 'failure' - time from last failure a task, 'attention' - time from when the user last attended to a task (according to attention_mode).

  • attention_mode (string) = 'fixation': Method used to track the attention of the user. Options: 'fixation' - use eyetracking fixations, 'gaze' - use eyetracking (fixation & saccade), 'mouse' - use the mouse position.

  • grace_period (number) = 3.0: The grace period to use (seconds) - how long to wait before guidance is shown to the user, see also grace_mode.

  • arrow (GuidanceArrowConfiguration) required: Configuration for displaying arrow guidance.

    • enable (boolean) = True: Whether to enable arrow guidance.

    • mode (string) = 'gaze': The mode to use for the arrow guidance, gaze will use the current gaze position, mouse will use the current mouse position, fixed will use the fixed offset specified in arrow_offset.

    • scale (number) = 1.0: The scale of the arrow.

    • fill_color (string) = 'none': The fill colour of the arrow.

    • stroke_color (string) = '#ff0000': The line colour of the arrow outline.

    • stroke_width (number) = 4.0: The line width of the arrow outline.

    • offset (array) = [80, 80]: The offset of the arrow from its set position, this is the position of the arrow if in "fixed" mode.

  • box (GuidanceBoxConfiguration) required: Configuration for displaying box guidance.

    • enable (boolean) = True: Whether to enable the guidance box.

    • stroke_color (string) = '#ff0000': The line colour of the box outline.

    • stroke_width (number) = 4.0: The line width of the box outline.

Example
"guidance": {
  "enable": true,
  "counter_factual": false,
  "break_ties": "random",
  "grace_mode": "attention",
  "attention_mode": "fixation",
  "grace_period": 3.0,
  "arrow": {
    "enable": true,
    "mode": "gaze",
    "scale": 1.0,
    "fill_color": "none",
    "stroke_color": "#ff0000",
    "stroke_width": 4.0,
    "offset": [
      80.0,
      80.0
    ]
  },
  "box": {
    "enable": true,
    "stroke_color": "#ff0000",
    "stroke_width": 4.0
  }
}
WindowConfiguration

Window Configuration.

  • x (integer) = 0: Horizontal position of the window

  • y (integer) = 0: Vertical position of the window

  • width (integer) = 640: Width of the window

  • height (integer) = 480: Height of the window

  • title (string) = 'window': Title of the window

  • resizable (boolean) = False: Whether the window is resizable

  • fullscreen (boolean) = False: Whether the window is fullscreen

  • background_color (string) = '#ffffff': Background color of the window

Example
"window": {
  "x": 0,
  "y": 0,
  "width": 640,
  "height": 480,
  "title": "window",
  "resizable": false,
  "fullscreen": false,
  "background_color": "#ffffff"
}
EyetrackingConfiguration

Configuration relating to eyetracking.

  • uri (string | null) = null: The eye tracker address (example: 'tet-tcp://172.28.195.1'). If left unspecified matbii will attempt to find an eye tracker. For details on setting up eye tracking, consult the wiki.

  • sdk (string) = 'tobii': The eye tracking SDK to use, current options are: ['tobii'].

  • enable (boolean) = False: Whether eye tracking is enabled.

  • moving_average_n (integer) = 5: The window size to used to smooth eye tracking coordinates.

  • velocity_threshold (number) = 0.5: The threshold on gaze velocity which will determine saccades/fixations. This is defined in screen space, where the screen coordinates are normalised in the range [0,1]. IMPORTANT NOTE: different monitor sizes may require different values, unfortunately this is difficult to standardise without access to data on the gaze angle (which would be monitor size independent).

Example
"eyetracking": {
  "uri": null,
  "sdk": "tobii",
  "enable": false,
  "moving_average_n": 5,
  "velocity_threshold": 0.5
}
LoggingConfiguration

Configuration relating to logging (including event logging).

  • level (string) = 'INFO': The logging level to use: ['DEBUG', 'INFO', 'WARNING', 'ERROR'], this will not affect event logging.

  • path (string) = './logs/': The path to the directory where log files will be written.

Example
"logging": {
  "level": "INFO",
  "path": "./logs/"
}
UIConfiguration

Configuration relating to rendering and the UI.

  • width (integer) = 810: The width of the canvas used to render the tasks.

  • height (integer) = 680: The height of the canvas used to render the tasks.

Example
"ui": {
  "width": 810,
  "height": 680
}

The default configuration file can be found below, you can simply copy it and modify as needed.

default-configuration.json
{
  "experiment": {
    "id": null,
    "path": "./",
    "duration": -1,
    "enable_video_recording": false,
    "enable_tasks": [
      "system_monitoring",
      "resource_management",
      "tracking"
    ],
    "meta": {}
  },
  "participant": {
    "id": null,
    "meta": {}
  },
  "guidance": {
    "enable": true,
    "counter_factual": false,
    "break_ties": "random",
    "grace_mode": "attention",
    "attention_mode": "fixation",
    "grace_period": 3.0,
    "arrow": {
      "enable": true,
      "mode": "gaze",
      "scale": 1.0,
      "fill_color": "none",
      "stroke_color": "#ff0000",
      "stroke_width": 4.0,
      "offset": [
        80.0,
        80.0
      ]
    },
    "box": {
      "enable": true,
      "stroke_color": "#ff0000",
      "stroke_width": 4.0
    }
  },
  "window": {
    "x": 0,
    "y": 0,
    "width": 810,
    "height": 680,
    "title": "icua matbii",
    "resizable": false,
    "fullscreen": false,
    "background_color": "#ffffff"
  },
  "eyetracking": {
    "uri": null,
    "sdk": "tobii",
    "enable": false,
    "moving_average_n": 5,
    "velocity_threshold": 0.5
  },
  "logging": {
    "level": "INFO",
    "path": "./logs/"
  },
  "ui": {
    "width": 810,
    "height": 680
  }
}

Custom entry points

The main configuration outlined here is used in the default entry point (main.py), but may also be useful for custom entry points. Other entry points include --example <EXAMPLE> (see here), and --script <SCRIPT>, (see here).

Command line overrides

It is possible to override the configuration options via the command line using:

--config.*KEYS *VALUES

where *KEYS is a dot seperated path to the configuration option you wish to override, and *VALUES is one of more (space separated) values for the option. For example:

--config.experiment.id 'experiment-1'
Values must be valid python literals (str, int, float, bool, list, tuple, dict). String values must be surrounded by single quotes.


Task Configuration

Along with the main configuration which provides some general options for configuring experiments the tasks themselves can be configured. Task configuration is independent of the entry point.

There are two types of task configuration files:

  • State files (.json)
  • Schedule files (.sch)

For a single experiment these files will all be placed in a single directory, for example:

experiment/
 ├─resource_management.json  
 ├─resource_management.sch  
 ├─system_monitoring.json  
 ├─system_monitoring.sch  
 ├─tracking.json  
 └─tracking.sch

The directory experiment above should be used as the experiment.path option in the main configuration file. You may or may not decide to place the main configuration inside this directory. Either way, it is better to provide an absolute path in experiment.path to avoid issues with path resolution (recall that the configuration path is relative to the working directory - where python -m matbii -c <CONFIG> is run).

Naming convention

Each configuration file must be named after the task (as above): resource_management, system_monitoring, tracking with .json for state files and .sch for schedule files. These names are also used when enabling a task in the main configuration file.

Default configuration

All tasks have a default configuration which will be used in place of state or schedule if the file is not given. Each of the files above is overriding the default state or schedule for the corresponding task.

State files

State files contain values that determine the starting state of the task and influence how the task is displayed in the UI. Options are described below.

Resource Management Task Configuration
  • x (integer) = 260: x position of the task
  • y (integer) = 360: y position of the task
  • width (integer) = 540: width of the task
  • height (integer) = 300: height of the task
  • padding (integer) = 10: padding surrounding the task
  • pump_on_color (color) = "#00ff00": color of pumps when in the "on" state
  • pump_off_color (color) = "#add9e6": color of pumps when in the "off" state
  • pump_failure_color (color) = "#ff0000": color of pumps when in the "failure" state
  • stroke_color (color) = "#000000": line colour
  • stroke_width (integer) = 2: line width
  • show_tank_labels (boolean) = true: whether to show textual labels next to each tank
  • background_color (color) = "#ffffff": background color of the tanks
  • debug (boolean) = false: whether to display debug information
  • tank_capacity (dict): See details below:
  • tank_capacity.a (integer) = 2000: capacity for tank a
  • tank_capacity.b (integer) = 2000: capacity for tank b
  • tank_capacity.c (integer) = 1500: capacity for tank c
  • tank_capacity.d (integer) = 1500: capacity for tank d
  • tank_capacity.e (integer) = 1000: capacity for tank e
  • tank_capacity.f (integer) = 1000: capacity for tank f
  • tank_level (dict): See details below:
  • tank_level.a (integer) = 1000: starting fuel level for tank a (< tank_capacity.a)
  • tank_level.b (integer) = 1000: starting fuel level for tank b (< tank_capacity.b)
  • tank_level.c (integer) = 750: starting fuel level for tank c (< tank_capacity.c)
  • tank_level.d (integer) = 750: starting fuel level for tank d (< tank_capacity.d)
  • tank_level.e (integer) = 750: starting fuel level for tank e (< tank_capacity.e)
  • tank_level.f (integer) = 750: starting fuel level for tank f (< tank_capacity.f)
  • pump_state (dict): See details below:
  • pump_state.ab (str) = "off": starting state of pump ab (options "off", "on", "failure")
  • pump_state.ba (str) = "off": starting state of pump ba (options "off", "on", "failure")
  • pump_state.ca (str) = "off": starting state of pump ca (options "off", "on", "failure")
  • pump_state.ec (str) = "off": starting state of pump ec (options "off", "on", "failure")
  • pump_state.ea (str) = "off": starting state of pump ea (options "off", "on", "failure")
  • pump_state.db (str) = "off": starting state of pump db (options "off", "on", "failure")
  • pump_state.fd (str) = "off": starting state of pump fd (options "off", "on", "failure")
  • pump_state.fb (str) = "off": starting state of pump fb (options "off", "on", "failure")
System Monitoring Task Configuration
  • x (integer) = 0: x position of the task
  • y (integer) = 0: y position of the task
  • width (integer) = 240: width of the task
  • height (integer) = 330: height of the task
  • padding (integer) = 10: padding surrounding the task
  • debug (boolean) = false: whether to display debug information
  • show_keyboard_shortcuts (boolean) = false: whether to display keyboard shortcuts
  • font_size (integer) = 12: font size
  • stroke_width (integer) = 2: line width
  • light_state (list) = [0, 0]: initial states of each light (options: 0 or 1)
  • light_on_color (color) = "#00ff00": color of light 1 when on
  • light_failure_color (color) = "#ff0000": color of light 2 when on
  • light_off_color (color) = "#add9e6": color of light 1 and 2 when off
  • light_width (integer) = 75: width of each light
  • light_height (integer) = 50: height of each light
  • slider_num_increments (integer) = 11: number of increments in each slider
  • slider_state (list) = [5, 5, 5, 5]: intial states of each slider (options: 0 to slider_num_increments-1)
  • slider_width (integer) = 30: width of each slider
  • slider_height (integer) = 20: height of each slider
  • slider_background_color (color) = "#add9e6": slider background color
  • slider_color (color) = "#4682b4": slider color
  • slider_arrow_color (color) = "#ffff00": slider arrow color
Tracking Task Configuration
  • x (integer) = 320: x position of the task
  • y (integer) = 0: y position of the task
  • width (integer) = 320: width of the task
  • height (integer) = 320: height of the task
  • padding (integer) = 10: padding surrounding the task
  • debug (boolean) = false: whether to display debug information
  • line_color (color) = "#1d90ff": line color
  • target_color (color) = "#1d90ff": line color of the target
  • target_line_width (integer) = 4: width of the target lines
  • target_x_offset (integer) = 0: starting x position of the target
  • target_y_offset (integer) = 0: starting y position of the target
  • target_radius (integer) = 25: size of the target
  • dash_array (string) = "4,2,1,2": dash array for dashed lines

Schedule files

Schedule files determine how each task evolves, the files are written in a DSL (Domain Specific Language) details of which can be found here.

Briefly, schedule files contain a list of actions with times to execute them. Each line of a configuration file follows a template:

ACTION(...) @ [T1, T2, ...] : R

Where T1, T2, ... are times to wait before executing the action ACTION, and R is the number of times to repeat the given sequence of wait times, the special character * means repeat forever.

Each task has a number of actions that have been defined which will update the task's state.

Actions

Actions make a change to the state of matbii and have their own internal definition. The full list of actions avaliable for use in a schedule is given below. Some examples are given in the next section.

Action Reference

Tracking

  • move_target(direction: tuple[float, float] | int | float, speed: float)
  • perturb_target(speed: float)

System Monitoring

  • on_light(target: int)
  • off_light(target: int)
  • toggle_light(target: int)
  • perturb_slider(target: int)

Resource Management

  • burn_fuel(target: int | str, burn: float)
  • pump_fuel(target: int | str, flow: float)
  • toggle_pump_failure(target: int | str)
  • toggle_pump(target: int | str)

Timing functions

Timings can be specified explicitly as constant int or float values (seconds).

Example 1

toggle_light(1) @ [10]:*
This will toggle light number 1 on/off every 10 seconds.

but we may want some more complicated schedule. This can be acheived using some built-in timing functions to introduce randomness or otherwise.

  • uniform(a : int, b : int) - a random integer between a and b (inclusive).
  • uniform(a : float, b : float) - a random float between a and b (inclusive).

Example 2

toggle_light(1) @ [uniform(10,20)]:*
This will toggle light number 1 on/off at times randomly chosen between 10 and 20 seconds.

We can build more complex schedules that mix timing functions and constant values.

Example 3

toggle_pump_failure("ab") @ [uniform(3,10), 2]:*
This will trigger a pump failure for 2 seconds after some random time between 3-10 seconds and repeat.

Example Schedules

Tracking Task Schedule
# this moves the target around randomly by 5 units every 0.1 seconds
perturb_target(5) @ [0.1]:*
System Monitoring Task Schedule
# this makes the lights turn to their unacceptable state every 10-20 seconds
off_light(1) @ [uniform(10,20)]:*    # this means failure for light 1
on_light(2) @ [uniform(10,20)]:*     # this means failure for light 2
# toggle_light(1) is also an option
# toggle_light(2) is also an option

# this randomly moves the sliders (up/down by 1) every 5-6 seconds.
perturb_slider(1) @ [uniform(5,6)]:*
perturb_slider(2) @ [uniform(5,6)]:*
perturb_slider(3) @ [uniform(5,6)]:*
perturb_slider(4) @ [uniform(5,6)]:*
Resource Management Task Schedule
# these determine pump failures, fail for 2 seconds after between 3 and 10 seconds (and repeat)
toggle_pump_failure("fd") @ [uniform(3,10), 2]:*
toggle_pump_failure("fb") @ [uniform(3,10), 2]:*
toggle_pump_failure("db") @ [uniform(3,10), 2]:*
toggle_pump_failure("ec") @ [uniform(3,10), 2]:*
toggle_pump_failure("ea") @ [uniform(3,10), 2]:*
toggle_pump_failure("ca") @ [uniform(3,10), 2]:*
toggle_pump_failure("ba") @ [uniform(3,10), 2]:*
toggle_pump_failure("ab") @ [uniform(3,10), 2]:*

# these determine the burning of fuel in the two main tanks
burn_fuel("a", 10) @ [0.1]:*
burn_fuel("b", 10) @ [0.1]:*

# these determine the flow of the pumps (when they are "on")
pump_fuel("fd", 20) @ [0.1]:*
pump_fuel("fb", 20) @ [0.1]:*
pump_fuel("db", 20) @ [0.1]:*
pump_fuel("ec", 20) @ [0.1]:*
pump_fuel("ea", 20) @ [0.1]:*
pump_fuel("ca", 20) @ [0.1]:*
pump_fuel("ba", 20) @ [0.1]:*
pump_fuel("ab", 20) @ [0.1]:*

Quick Start

Configuration examples can be found here.

Examples can be run using the --example option:

python -m matbii --example example-A

Events will be logged to ./example-A-logs/, take a look and make sure everything is working as expected. To start running your own experiments, you can copy the example files, or an example and run in the usual way with:

python -m matbii -c <CONFIG_PATH>
You can set up the logging directory using the logging.path option in your main configuration file or by overriding via the command line with --config.logging.path <PATH>.

The next page contains details on the logging system and tools for post-experiment analysis/visualisation.