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-_]).
link_localizers¶
A boolean indicating if the localizer should be linked between different contexts. More information about contexts bellow.
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 |
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 |
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.