BIDS Stats Models Object Reference#
This section defines the valid keys and values in a BIDS Stats Model. A BIDS Stats Model is defined in a JSON document.
Object definitions#
A BIDS Stats Model is a JSON file that defines one or more hierarchical models on brain imaging data. |
|
A node represents an estimator that applies to a given level of analysis. |
|
Transformations describe modifications of variables to prepare a design matrix. |
|
The model to fit to the collection of input images. |
|
Specification of a hemodynamic response function (HRF) model. |
|
Estimation options that are common to multiple estimation packages. |
|
Contrasts are weighted sums of parameter estimates (betas) generated by a model fit. |
|
Dummy contrasts are contrasts with one condition, a weight of one, and the same name as the condition. |
|
An Edge connects two |
BIDSStatsModel
is the top-level structure,
while the remaining classes define sub-structures.
To demonstrate this hierarchy, here we show an example model
in this structure, with missing fields rendered as None
:
BIDSStatsModel(
Description="My first BIDS model: a simple 2-condition contrast.",
Name="my_first_model",
BIDSModelVersion="1.0.0",
Input={"task": ["stroop"]},
Nodes=[
Node(
Description=None,
Level="Run",
Name="run",
GroupBy=["run", "subject"],
Transformations=None,
Model=Model(
Description=None,
Type="glm",
X=["congruent", "incongruent", "nuissance1", "nuissance2", 1],
Formula=None,
HRF=None,
Options=None,
Software=None,
),
Contrasts=[
Contrast(
Description=None,
Name="incongruent_vs_congruent",
ConditionList=["incongruent", "congruent"],
Weights=[1, -1],
Test="t",
)
],
DummyContrasts=None,
),
Node(
Description=None,
Level="Subject",
Name="subject",
GroupBy=["contrast", "subject"],
Transformations=None,
Model=Model(
Description=None,
Type="meta",
X=[1],
Formula=None,
HRF=None,
Options=None,
Software=None,
),
Contrasts=None,
DummyContrasts=DummyContrasts(Description=None, Contrasts=None, Test="t"),
),
Node(
Description=None,
Level="Dataset",
Name="dataset",
GroupBy=["contrast"],
Transformations=None,
Model=Model(
Description=None,
Type="glm",
X=[1],
Formula=None,
HRF=None,
Options=None,
Software=None,
),
Contrasts=None,
DummyContrasts=DummyContrasts(Description=None, Contrasts=None, Test="t"),
),
],
Edges=[
Edge(Description=None, Source="run", Destination="subject", Filter=None),
Edge(Description=None, Source="subject", Destination="dataset", Filter=None),
],
)
{
"Name": "my_first_model",
"BIDSModelVersion": "1.0.0",
"Description": "My first BIDS model: a simple 2-condition contrast.",
"Input": {
"task": ["stroop"]
},
"Nodes": [
{
"Level": "Run",
"Name": "run",
"GroupBy": ["run", "subject"],
"Model": {
"X": ["congruent", "incongruent", "nuissance1", "nuissance2", 1],
"Type": "glm"
},
"Contrasts": [
{
"Name": "incongruent_vs_congruent",
"ConditionList": ["incongruent", "congruent"],
"Weights": [1, -1],
"Test": "t"
}
]
},
{
"Level": "Subject",
"Name": "subject",
"GroupBy": ["contrast", "subject"],
"Model": {
"X": [1],
"Type": "meta"
},
"DummyContrasts": {"Test": "t"}
},
{
"Level": "Dataset",
"Name": "dataset",
"GroupBy": ["contrast"],
"Model": {
"X": [1],
"Type": "glm"
},
"DummyContrasts": {"Test": "t"}
}
],
"Edges": [
{"Source": "run", "Destination": "subject"},
{"Source": "subject", "Destination": "dataset"}
]
}
Note that each structured field has a Description
subfield.
Any JSON object may have a Description
key where the author or generator of a model
can provide an explanation of the section.
How to read object definitions#
The object definitions linked above have a common structure that may not be obvious.
Some confusion may arise from a conflation of JSON and Python terms,
as the definitions are written as
Pydantic models and use
Python typing
to constrain values.
Here we present an “explainer model” that demonstrates different types, how they appear in the definition, and their corresponding JSON.
- object ExplainerModel#
This is an example model.
In schema terms, the structure that defines a JSON object is a “model”. To avoid confusion with BIDS Stats Models and more general notions of mathematical or statistical models, we will use “schema model” to unambiguously refer to this concept.
A schema model defines a JSON object with fields that have both a name and a type, where “type” indicates the range of acceptable values.
Below are a number of fields that demonstrate the types we use in this specification. These types can be mixed and matched somewhat. Probably the most complex-looking field is
Contrast.Weights
.- field StringField: str [Required]#
This field is called
StringField
and has typestr
.This type indicates that any string is acceptable, while other types (even string-like) are unacceptable.
Valid example:
{"StringField": "any string value"}
Invalid examples:
{"StringField": 0} {"StringField": ["list", "of", "strings"]}
- field IntField: str [Required]#
This strict integer field must have integer values.
Valid example:
{"IntField": 0}
Invalid examples:
{"IntField": 1.0} {"IntField": "2"}
- field SomeOptions: Literal[1, 'stringval'] [Required]#
The
Literal
type allows a specific value or set of values.Valid examples:
{"SomeOptions": 1} {"SomeOptions": "stringval"}
Invalid examples:
{"SomeOptions": "1"} {"SomeOptions": "differentstringval"} {"SomeOptions": 2.0}
- field ArrayOfInts: List[str] [Required]#
JSON arrays appear as
List
types, andList[str]
means the values must be integers.Valid example:
{"ArrayOfInts": [1, 2]}
- field Object: Dict[str, Any] [Required]#
JSON objects appear as
Dict
types.The general form is
Dict[str, <value-type>]
, because the field name in a JSON object is always a string. To allow for any values, including integers, strings or nested types, we useAny
.Valid example:
{"Object": {"key1": "stringval", "key2": 1}}
We use these when objects with arbitrary names can be used. If the full list of valid names is known, we define a new schema model.
- field ObjectOfObjects: Dict[str, Dict[str, Any]] [Required]#
Nested objects can start to have hairy type signatures.
Because
Dict[str, <value-type>]
is the general form for objects, the general form for objects of objects isDict[str, Dict[str, <value-type>]]
.The actual result is fairly straightforward, though:
{ "ObjectOfObjects": { "field1": {"subfield": "value of ObjectOfObjects.field1.subfield"}, "field2": {"intsubfield": 1} } }
- field ModelField: DummyContrasts [Required]#
Schema models are nested objects with pre-determined names and types.
This is a specialized version of
Object
, and you can follow the link in the type to learn more.Here, the
DummyContrasts
model defines the structure of the object.Valid example:
{"ModelField": {"Contrasts": ["contrast1", "contrast2"], "Test": "t"}}
- field UnionField: str [Required]#
Unions mean that a value could take multiple types.
Valid examples:
{"UnionField": 1} {"UnionField": "stringval"}
Invalid examples:
{"UnionField": 2.0}
- field OptionalField: str | None#
OptionalField
could be present or absent.Up to now, all fields have been required. If a field is optional, its type will be wrapped in
Optional[]
and will not have[Required]
in its signature.
- field ListOrListOfLists: List[int] | List[List[int]] [Required]#
A 1- or 2D array of integers.
To allow this form, we need to use the
Union
type withList[]
andList[List[]]
. At the “bottom” of the type is an integer.Contrast.Weights
has this form, but instead ofint
, it permits integers, floats or strings because it is intended to allow values like0.5
or"-1/3"
.