Task Templates

Task templates define the layout for a specific ViewR task. This includes the viewports and the annotation area. It is almost completely customizable. In this section we will describe how to create a template in JSON format.

Basic structure

A task template has to following basic structure:

{
  "template_name": <string>,
  "link_localizers": <bool>,
  "mdl_layout": <string>,
  "contexts": <object>,
  "presets": <list>,
  "sop": <string>
}

As the contexts are very complex they will be discussed in the next section in detail. The other fields are described in the following sub-sections.

template_name

The template name is simple a string by which the template is referenced (e.g. from tasks). It is strongly encouraged to only use simple characters in the name (e.g. [a-zA-Z0-9-_]).

mdl_layout

A piece of MeVisLab MDL that indicates how different contexts are combined in the GUI. By default there is only one context named default. The MDL string in that case would be:

Horizontal {{ expandX=True expandY=True {default} }}

Not that all { and } need to be doubled, as the context content is injected using the format function of Python. The MDL of each context is passed as a keyword argument. So if there are two contexts foo and bar, the mdl_layout should contain {foo} and {bar}, e.g.:

Vertical {{
  expandX=True
  expandY=True
  Box {{
    expandY=True
    title="Foo"
    layout="Horizontal"
    {foo}
  }}
  Box {{
    expandY=True
    title="Bar"
    layout="Horizontal"
    {bar}
  }}
}}

This layout puts the two contexts vertically, with foo located above bar.

Which would look like the following as part of a JSON task template file (note the escape character need for JSON):

{
    ...
    "mdl_layout": "Vertical {{ expandX=True expandY=True Box {{ expandY=True title=\"Foo\" layout=\"Horizontal\" {foo} }} Box {{ expandY=True title=\"Bar\" layout=\"Horizontal\" {bar} }} }}",
    ...
}

presets

Define a number of presets for the viewports. The structure of the elements is layered because presets can include settings in multiple contexts:

{
    "__name__": "preset name",
    "context_1": {
       "viewport_1a":
          "scan": "T1",
          "projection": null
       },
       <other viewports>
    },
    <other contexts>
}

Note that there is always a “__name__” entry which defines the preset name and is not referencing a context. Also this is a single entry for a single preset. The entire presets is a list of these entries.

For each viewport there are the following options that can be set:

Field

Description

scan

The scan to select for the viewport

orientation

The orientation to set for the viewport

annotation

The annotation overlay to set for the viewport

projection

The projection to activate for the viewport. Valid options: null, “min”, “max”

projection_slab

The number of slices over which to perform the projection Should be a positive integer value

This allows the users to switch different layout very quickly.

sop

This is a field where a standard operating procedure can be documented for the task. This should be either a string containing valid HTML or and empty string.

contexts

A context is a group of widgets and data required for a task. Sometimes you might want more than one context (e.g. when rating a follow-up scan, you might want to view the baseline rating for reference). The basic structure of context is:

{
    "viewports": <list>,
    "scans": <object>,
    "annotations": <object>,
    "qa_fields": <object>,
    "mdl_layout": <string>,
}

viewports

Defines the viewports in the template. Viewports have initial values that can be changed by users (or by applying presets). Viewports have a grid layout.

Field

Description

type

currently unused, set to “viewport”

name

name of the viewport

scan

initial scan to show in the viewport

annotation

initial annotation to show in the viewport

x

x location on the grid

y

y location on the grid

linked

initial linking of the localizer

orientation

initial orientation, should be one of “Transversal”, “Coronal”, “Sagittal”. Default is Transversal.

label

initial annotation label to select (show only that label)

projection

initial projection to use, should be in “none”, “min”, “max”. Default is “none”

projection_slab

integer, number of slices to use for a projection, defaults to 5

slice_highlight_interval

integer, highlight every Nth slice

interpolation

interpolation to use, should be ‘nearest’ or ‘linear’, default is ‘nearest’

A minimal example of a single viewport would be:

{
  "type": "viewport",
  "name": "ViewPortLeft",
  "scan": "T1",
  "annotation": null,
  "x": 0,
  "y": 0,
  "linked": true
}

Note that even if there is no annotation, the parameter has to be filled. Use a null value to indicate no annotation should be selected.

scans

This section defines the scans that are to be supplied for the given task. They are referenced by their key. Also the modality and protocol should be supplied:

"scans": {
  "T1": {
    "modality": "MR",
    "protocol": "T1W-3D"
  },
  "SWI": {
    "modality": "MR",
    "protocol": "PD"
  },
  "FLAIR": {
    "modality": "MR",
    "protocol": "FLAIR"
  }
}

annotations

Annotations to display as overlay in the current task. Per annotation image there are some parameters that can be defined:

Field

Description

type

Type of annotation, currently only pixel is supported

editable

Boolean flag to indicate if users should be able to edit the annotation.

editors

The editor to use in case the annotation is editable, currently only ["pixel"] is supported

labels

Define the labels and colours of the annotation. It is a mapping of a pixel value to the corresponding information for that label

An example of an annotation:

"annotations": {
  "tissuewml": {
    "type": "pixel",
    "editable": false,
    "editors": null,
    "labels": <object>
  }
}

The label is a mapping to an object controling how the label is displayed. It contains the fields name, description, colour, and opacity.

An example of a labels object:

{
  "0": {
    "colour": [0, 0, 0],
    "name": "background",
    "description": "background",
    "opacity": "0"
  },
  "1": {
    "colour": [255, 180, 0],
    "name": "CSF",
    "description": "cerebrospinal fluid",
    "opacity": "1"
  }
}

mdl_layout

A context also has an MDL layout. It works very similar to the MDL layout on the template level, however it is not used to composite contexts, but rather the different parts of a context. It combines the following parts of the context into a single layout:

Element

Description

editor

The location where the editor (pixel editor) controls are placed

viewports

The location where viewport grid is placed

qa_fields

The location where the QA fields GUI elements are placed

A good default MDL is:

Horizontal {{
  expandX=True
  expandY=True
  Vertical {{
    expandX=True
    expandY=True
    {editor}
    Grid {{
      expandX=True
      expandY=True
      {viewports}
    }}
  }}
  Vertical {{
    alignY = Top
    w=300
    maxw=300
    Grid {{
      margin = 5
      spacing = 2
      {qa_fields}
    }}
  }}
}}

In context part of the the template JSON this would become:

{
  ...
  "mdl_layout": "Horizontal {{ expandX=True expandY=True Vertical {{ expandX=True expandY=True {editor} Grid {{ expandX=True expandY=True {viewports} }} }} Vertical {{alignY = Top w=300 maxw=300 Grid {{ margin = 5 spacing = 2 {qa_fields} }} }} }}",
  ...
}

qa_fields

The qa_fields part of the context is the most complex and free part of the task template. It defines the GUI widgets used for annotation/rating of the images. It is a mapping of the form {"widget_name": <object>} where the object defines all details of the widget. The required fields are different for each specific widget. Some widgets are even containers that contain a group of other widgets. Widgets are describeds in the section Widgets.