Configuration file

Config file keys

The JSON configuration file has the following required sections:

patterns

Specifies the regex patterns used to find files. The patterns must be in python style regex. Group names should be specified corresponding to the page_keys and files/filter parameters. If an array is given for a pattern instead of a string, then pybids is used instead of regex. See bids below.

For example, suppose we have an input and an output folder:

.in
├── sub-1
│   ├── anat
│   │   ├── sub-1_T1w.nii
│   │   └── sub-1_acq-fast_T1w.nii
├── sub-2
│   └── anat
│       └── sub-2_T1w.nii
└── MNI152.nii

.out
├── sub-1
│   ├── BET
│   │   ├── sub-1_bet.nii
│   │   └── sub-1_acq-fast_bet.nii
│   ├── classify
│   │   ├── sub-1_dseg.nii
│   │   └── sub-1_acq-fast_dseg.nii
│   ├── logs
│   │   └── sub-1_acq-fast
│   │       └── crash.pklz
└── sub-2
    ├── BET
    │   └── sub-2_bet.nii
    └── classify
        └── sub-2_dseg.nii

where we have multiple subjects, and some subjects also have a “fast” acquisition. Then we might have

   "patterns": {
       "derivatives": "sub-(?P<subject>[a-zA-Z0-9]+)/(?P<dir>[^/]*)/sub-(?P=subject)(_acq-(?P<acquisition>[a-zA-Z0-9]+))?_(?P<suffix>[a-zA-Z0-9]+)\\.nii",
       "models": "(?P<base>[a-zA-Z0-9]+)\\.nii",
       "crash": "sub-(?P<subject>[a-zA-Z0-9]+)/logs/sub-(?P=subject)(_acq-(?P<acquisition>[a-zA-Z0-9]+))?/crash.*\\.pklz"
   },

The “derivatives” pattern will match files in the subject folders, “models” pattern will match files in the root directory, and “crash” will match crash files (in this case only 1). (We can pass both “in” and “out” to the program on the command line, so both directories will be searched.)

bids

The “derivatives” pattern above closely follows the BIDS specification. As such we can instead use pybids to search for files. To signal that we wish to use pybids, we pass an array instead of a string:

   "patterns": {
       "derivatives": ["bids"],
       "models": "(?P<base>[a-zA-Z0-9]+)\\.nii",
       "crash": "sub-(?P<subject>[a-zA-Z0-9]+)/logs/sub-(?P=subject)(_acq-(?P<acquisition>[a-zA-Z0-9]+))?/crash.*\\.pklz"
   },

The contents of the array are passed to BIDSLayout as the “config” parameter. It may either be the name of a default configuration (at the time of this writing, either “bids” or “derivatives”), a filename, or a JSON object. In the above example, the basic “bids” configuration is all that is required.

page_keys

These are the unique keys which identify a single QC page. The keys correspond to regex group names in patterns. Continuing with the example above, if we have multiple subjects and acquisition types, and we want a different QC page for each subject/acquisition combination, we would have

   "page_keys": [
       "subject",
       "acquisition"
   ],

page_filename_template

Template output string for each qc page. page_keys may be used as arguments (e.g., if “subject” is a page key, then one could have “{subject}_QC.html”). If a bracket pair (“[…]”) is used, and inside that bracket is only one keyword argument, the section inside the brackets will be used only if that argument is not None. This syntax was inspired by pybids.

Using the above example if we have

   "page_filename_template": "sub-{subject}[_acq-{acquisition}]_QC.html",

We will have the following output files

  • sub-1_QC.html
  • sub-1_acq-fast_QC.html
  • sub-2_QC.html

index_filename

A string giving the name of the output index file, i.e., the file containing a list of all the QC pages.

   "index_filename": "QC_index.html",

files

A json object where each key identifies a file (for a given QC page), and the values are objects describing how to identify the file. For example

   "files": {
       "T1": {
	   "pattern": "derivatives",
	   "filter": {"suffix": "T1w"}
       },
       "BET": {
	   "pattern": "derivatives",
	   "filter": {"suffix": "bet"}
       },
       "classified": {
	   "pattern": "derivatives",
	   "filter": {"suffix": "dseg"}
       },
       "MNI": {
	   "pattern": "models",
	   "filter": {"base": "MNI152"},
	   "global": true
       },
       "crashfiles": {
	   "pattern": "crash",
	   "filter": {},
	   "allow_multiple": true
       }
   },

The above example defines 5 files, “T1”, “BET”, “classified”, “MNI”, and “crashfiles”. “T1”, “BET”, and “classified” follow the regex in patterns/derivatives. In this case each is uniquely identified as having a specific suffix, where suffix is a group name in the “derivatives” pattern. The filter parameters must uniquely identify a file for each QC page (in this case each sub/acq combination). If multiple files match a pattern, or if a file is detected multiple times (e.g., if the same file is found for both “BET” and “classified”), the program will throw an error.

“MNI” is identified as having the base “MNI152”. However, this is not necessary, as there are no other files that could match the “model” pattern. Note that this file is the same for all sub/acq combinations, i.e., it is the same for each QC page. Therefore, we set the “global” attribute to true. (Without setting global, the program will not be able to determine which subj/acq combination “MNI” belongs to, and will fail.)

“crashfiles” matches the pattern “crash”. Setting “allow_multiple” to true allows multiple files to match the pattern, which are stored in a list.

reportlets

This section specifies the elements of the QC page. It is a list of objects, where each object has a “type” key and then a key/value pair for each parameter to the reportlet indicated by “type”.

   "reportlets": [
       {
	   "type": "compare",
	   "name1": "T1w input file",
	   "image1": "T1",
	   "name2": "Brain extracted files",
	   "image2": "BET"
       },
       {
	   "type": "contour",
	   "name": "Tissue classification",
	   "image": "BET",
	   "labelimage": "classified"
       },
       {
	   "type": "crash",
	   "name": "Errors",
	   "crashfiles": "crashfiles"
       }
   ]

All key/value pairs besides “type” and “relative_dir” are sent to the corresponding reportlet interface. The parameter “use_relative_dir” may be specified (boolean), and if true then “relative_dir” will be set to the proper directory.

global_reportlet_settings

Settings that should apply to all (relevant) reportlets.

Final

The final config file is then:

{
   "patterns": {
       "derivatives": "sub-(?P<subject>[a-zA-Z0-9]+)/(?P<dir>[^/]*)/sub-(?P=subject)(_acq-(?P<acquisition>[a-zA-Z0-9]+))?_(?P<suffix>[a-zA-Z0-9]+)\\.nii",
       "models": "(?P<base>[a-zA-Z0-9]+)\\.nii",
       "crash": "sub-(?P<subject>[a-zA-Z0-9]+)/logs/sub-(?P=subject)(_acq-(?P<acquisition>[a-zA-Z0-9]+))?/crash.*\\.pklz"
   },
   "page_keys": [
       "subject",
       "acquisition"
   ],
   "page_filename_template": "sub-{subject}[_acq-{acquisition}]_QC.html",
   "index_filename": "QC_index.html",
   "files": {
       "T1": {
	   "pattern": "derivatives",
	   "filter": {"suffix": "T1w"}
       },
       "BET": {
	   "pattern": "derivatives",
	   "filter": {"suffix": "bet"}
       },
       "classified": {
	   "pattern": "derivatives",
	   "filter": {"suffix": "dseg"}
       },
       "MNI": {
	   "pattern": "models",
	   "filter": {"base": "MNI152"},
	   "global": true
       },
       "crashfiles": {
	   "pattern": "crash",
	   "filter": {},
	   "allow_multiple": true
       }
   },
   "reportlets": [
       {
	   "type": "compare",
	   "name1": "T1w input file",
	   "image1": "T1",
	   "name2": "Brain extracted files",
	   "image2": "BET"
       },
       {
	   "type": "contour",
	   "name": "Tissue classification",
	   "image": "BET",
	   "labelimage": "classified"
       },
       {
	   "type": "crash",
	   "name": "Errors",
	   "crashfiles": "crashfiles"
       }
   ]
}

Global

The optional config section “global_reportlet_settings” may contain settings that are applied to all reportlets (but do not override individually set values). Currently, these may be “image_width”, “image_height”, and “contour_width”.

Schema

The configuration file has the following schema

{
    "$schema": "http://json-schema.org/draft-07/schema$",
    "definitions": {
	"singlereportlet": {
            "type": "object",
            "additionalProperties": false,
            "required": ["type", "name", "image"],
            "properties": {
		"type": {
		    "type": "string",
		    "const": "single"
		},
		"qcform": {
		    "type": "boolean"
		},
		"nslices": {
		    "type": "integer"
		},
		"name": {
		    "type": "string"
		},
		"image": {
		    "type": "string"
		},
		"image_width": {
		    "type": "number"
		},
		"image_height": {
		    "type": "number"
		},
		"max_intensity_fraction": {
		    "type": "number"
		},
		"affine_absolute_tolerance": {
		    "type": "number"
		},
		"affine_relative_tolerance": {
		    "type": "number"
		},
		"description": {
		    "type": "string"
		}
            }
	},
	"comparereportlet": {
            "type": "object",
            "additionalProperties": false,
            "required": ["type", "name1", "image1", "name2", "image2"],
            "properties": {
		"type": {
		    "type": "string",
		    "const": "compare"
		},
		"qcform": {
		    "type": "boolean"
		},
		"nslices": {
		    "type": "integer"
		},
		"name1": {
		    "type": "string"
		},
		"image1": {
		    "type": "string"
		},
		"name2": {
		    "type": "string"
		},
		"image2": {
		    "type": "string"
		},
		"image_width": {
		    "type": "number"
		},
		"image_height": {
		    "type": "number"
		},
		"slice_to_image2": {
		    "type": "boolean"
		},
		"max_intensity_fraction_image1": {
		    "type": "number"
		},
		"max_intensity_fraction_image2": {
		    "type": "number"
		},
		"affine_absolute_tolerance": {
		    "type": "number"
		},
		"affine_relative_tolerance": {
		    "type": "number"
		},
		"description": {
		    "type": "string"
		}
            }
	},
	"contourreportlet": {
            "type": "object",
            "additionalProperties": false,
            "required": ["type", "name", "image", "labelimage"],
            "properties": {
		"type": {
		    "type": "string",
		    "const": "contour"
		},
		"qcform": {
		    "type": "boolean"
		},
		"nslices": {
		    "type": "integer"
		},
		"name": {
		    "type": "string"
		},
		"image": {
		    "type": "string"
		},
		"labelimage": {
		    "type": "string"
		},
		"image_width": {
		    "type": "number"
		},
		"image_height": {
		    "type": "number"
		},
		"contour_width": {
		    "type": "number"
		},
		"slice_to_label": {
		    "type": "boolean"
		},
		"max_intensity_fraction": {
		    "type": "number"
		},
		"affine_absolute_tolerance": {
		    "type": "number"
		},
		"affine_relative_tolerance": {
		    "type": "number"
		},
		"description": {
		    "type": "string"
		},
		"contour_levels": {
		    "type": "array",
		    "items": {
			"type": "number"
		    }
		},
		"threshold_above_zero": {
		    "type": "boolean"
		}
            }
	},
	"overlayreportlet": {
            "type": "object",
            "additionalProperties": false,
            "required": ["type", "name", "image", "labelimage"],
            "properties": {
		"type": {
		    "type": "string",
		    "const": "overlay"
		},
		"qcform": {
		    "type": "boolean"
		},
		"nslices": {
		    "type": "integer"
		},
		"name": {
		    "type": "string"
		},
		"image": {
		    "type": "string"
		},
		"labelimage": {
		    "type": "string"
		},
		"image_width": {
		    "type": "number"
		},
		"image_height": {
		    "type": "number"
		},
		"slice_to_label": {
		    "type": "boolean"
		},
		"max_intensity_fraction": {
		    "type": "number"
		},
		"affine_absolute_tolerance": {
		    "type": "number"
		},
		"affine_relative_tolerance": {
		    "type": "number"
		},
		"description": {
		    "type": "string"
		},
		"transparency": {
		    "type": "number",
		    "minimum": 0.0,
		    "maximum": 1.0
		}
            }
	},
	"probmapreportlet": {
            "type": "object",
            "additionalProperties": false,
            "required": ["type", "name", "image", "probmapimage"],
            "properties": {
		"type": {
		    "type": "string",
		    "const": "probmap"
		},
		"qcform": {
		    "type": "boolean"
		},
		"nslices": {
		    "type": "integer"
		},
		"name": {
		    "type": "string"
		},
		"image": {
		    "type": "string"
		},
		"probmapimage": {
		    "type": "string"
		},
		"image_width": {
		    "type": "number"
		},
		"image_height": {
		    "type": "number"
		},
		"slice_to_probmap": {
		    "type": "boolean"
		},
		"max_intensity_fraction": {
		    "type": "number"
		},
		"affine_absolute_tolerance": {
		    "type": "number"
		},
		"affine_relative_tolerance": {
		    "type": "number"
		},
		"description": {
		    "type": "string"
		}
            }
	},
	"distributionsreportlet": {
            "type": "object",
            "additionalProperties": false,
            "required": ["type", "name", "distsfile", "labelfile"],
            "properties": {
		"type": {
		    "type": "string",
		    "const": "distributions"
		},
		"qcform": {
		    "type": "boolean"
		},
		"nslices": {
		    "type": "integer"
		},
		"name": {
		    "type": "string"
		},
		"distsfile": {
		    "type": "string"
		},
		"labelfile": {
		    "type": "string"
		},
		"description": {
		    "type": "string"
		}
            }
	},
	"crashreportlet": {
            "type": "object",
            "additionalProperties": false,
            "required": ["type", "name", "crashfiles"],
            "properties": {
		"type": {
		    "type": "string",
		    "const": "crash"
		},
		"qcform": {
		    "type": "boolean"
		},
		"nslices": {
		    "type": "integer"
		},
		"name": {
		    "type": "string"
		},
		"crashfiles": {
		    "type": "string"
		}
            }
	},
	"ratingreportlet": {
            "type": "object",
            "additionalProperties": false,
            "required": ["name", "type"],
            "properties": {
		"type": {
		    "type": "string",
		    "const": "rating"
		},
		"name": {
		    "type": "string"
		},
		"widgets": {
		    "type": "array",
		    "items": {
			"anyOf": [
			    { "$ref": "#/definitions/radiowidget" },
			    { "$ref": "#/definitions/checkboxwidget" },
			    { "$ref": "#/definitions/textwidget" }
			]
		    }
		}
	    }
	},
	"radiowidget": {
	    "type": "object",
	    "additionalProperties": false,
	    "required": ["name", "type", "options"],
	    "properties": {
		"name": {
		    "type": "string"
		},
		"type": {
		    "type": "string",
		    "const": "radio"
		},
		"options": {
		    "type": "array",
		    "items": {
			"type": "object",
			"additionalProperties": false,
			"required": ["name", "value"],
			"properties": {
			    "name": {
				"type": "string"
			    },
			    "value": {
				"type": ["string", "number"]
			    }
			}
		    }
		}
	    }
	},
	"checkboxwidget": {
	    "type": "object",
	    "additionalProperties": false,
	    "requried": ["name", "type", "fields"],
	    "properties": {
		"name": {
		    "type": "string"
		},
		"type": {
		    "type": "string",
		    "const": "checkbox"
		},
		"fields": {
		    "type": "array",
		    "items": {
			"type": "string"
		    }
		}
	    }
	},
	"textwidget": {
	    "type": "object",
	    "additionalProperties": false,
	    "required": ["name", "type"],
	    "properties": {
		"name": {
		    "type": "string"
		},
		"type": {
		    "type": "string",
		    "const": "text"
		}
	    }
	}
    },
    "type": "object",
    "required": ["page_keys", "page_filename_template", "patterns", "index_filename", "files", "reportlets"],
    "properties": {
        "page_keys": {
            "type": "array",
            "items": {
                "type": "string",
		"pattern": "^[a-zA-Z0-9]*$"
            },
            "minItems": 1
        },
        "page_filename_template": {
            "type": "string",
            "pattern": "^([^][]*(\\[[^][}{]*\\{[a-zA-Z0-9]*\\}[^][}{]*\\]*)*)*$"
        },
        "index_filename": {
            "type": "string"
        },
        "patterns": {
            "type": "object",
            "patternProperties": {
                ".*": {
                    "type": ["string", "array"]
                }
            }
        },
        "files": {
            "type": "object",
            "patternProperties": {
                ".*": {
                    "type": "object",
                    "required": ["pattern", "filter"],
                    "properties": {
                        "pattern": {
                            "type": "string"
                        },
                        "filter": {
                            "type": "object"
                        },
                        "global": {
                            "type": "boolean"
                        },
                        "allow_multiple": {
                            "type": "boolean"
                        }
                    }
                }
            }
        },
	"derived": {
	    "type": "object",
	    "patternProperties": {
		".*": {
		    "type": "object",
		    "required": ["requires", "expr"],
		    "properties": {
			"requires": {
			    "type": "array"
			},
			"expr": {
			    "type": "string"
			}
		    }
		}
	    }
	},
        "reportlets": {
            "type": "array",
            "items": {
		"anyOf": [
		    { "$ref": "#/definitions/singlereportlet" },
		    { "$ref": "#/definitions/comparereportlet" },
		    { "$ref": "#/definitions/contourreportlet" },
		    { "$ref": "#/definitions/probmapreportlet" },
		    { "$ref": "#/definitions/overlayreportlet" },
		    { "$ref": "#/definitions/distributionsreportlet" },
		    { "$ref": "#/definitions/crashreportlet" },
		    { "$ref": "#/definitions/ratingreportlet" }
		]
	    }
        },
	"global_reportlet_settings": {
	    "type": "object",
	    "properties": {
		"image_width": {
		    "type": "number"
		},
		"image_height": {
		    "type": "number"
		},
		"contour_width": {
		    "type": "number"
		}
	    }
	}
    }
}