-
Notifications
You must be signed in to change notification settings - Fork 203
[ENH]: BEP046, diffusion tractography #2333
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 13 commits
df9b17a
83f9827
2bc5102
b097a2f
9914954
df24d6b
94af812
dcee2ba
974f10c
007d88b
cd98f7d
b128628
b72ce06
cee4f74
e635051
1a6af2a
8b49ca8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,166 @@ | ||
| # Diffusion derivatives | ||
|
|
||
| ## Diffusion-based tractography | ||
|
|
||
| Tractography based on diffusion-weighted MRI data is stored as streamlines in | ||
| the [TRX file format](https://tee-ar-ex.github.io): | ||
|
|
||
| ```Text | ||
| <pipeline_name>/ | ||
| sub-<label>/ | ||
| [ses-<label>/] | ||
| <modality>/ | ||
| <source-entities>[space-<space>]_[tract-<tract name>]_[track-<tracking method>]_tractogram.trx | ||
| <source-entities>[space-<space>]_[tract-<tract name>]_[track-<tracking method>]_tractogram.json | ||
| ``` | ||
|
|
||
| Where `tract` is the anatomical/structural entity that is being imaged, and | ||
| `track` is fully specified in the sidecar as described below. | ||
|
|
||
| For the most common case, a tractogram will be generated from some DWI data, so | ||
| <modality> will typically be “dwi”. In any case, the <modality> allows to | ||
| unequivocally identify the data type from which the tractogram originated. | ||
|
|
||
| For example: | ||
|
|
||
| ```Text | ||
| pyAFQ/ | ||
| sub–01/ | ||
| dwi/ | ||
| sub-01_space-MNI152NLin2009cAsym_tract-wholebrain_track-eudx_tractogram.trx | ||
| sub-01_space-MNI152NLin2009cAsym_tract-wholebrain_track-eudx_tractogram.json | ||
| sub-01_space-MNI152NLin2009cAsym_tract-ArcuateFasciculus_hemi-L_track-eudx_tractogram.trx | ||
| sub-01_space-MNI152NLin2009cAsym_tract-ArcuateFasciculus_hemi-L_track-eudx_tractogram.json | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should values associated with "tract" be a controlled vocabulary? Having to define all possible structures that someone might want to describe would be a real bear. On the other hand, not defining this opens up the possibility that different people would name the Arcuate "ArcuateFasciculus", "ARC", "Arcuate", "FrontoTemporal", and so forth., making it hard to share informatively, integrate across datasets, etc.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we should agree on a minimal set. We can ask the IST subunit to help us with the terms. I know defining them anatomically is not an easy task, but here our job is not to define them anatomically, just to provide a controlled vocabulary, and maybe provide a very broad explanation about them. I believe this is doable for a reasonable amount of tracts.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. One related idea (from @kimberlylray) as expressed just now in the IST Standarization Unit meeting is to allow for flexibility to use one of several “atlases” and then the names are defined by that atlas (for example, the HCP-1065 Young Adult Fiber Templates. Metadata would report which atlas was used.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I wouldn't even shoot for a controlled vocabulary. Even for something as well-known as the arcuate, there is disagreement about exactly what breadth of connections that name refers to---not just in the tractography community, in the neuroanatomy community---so controlling the name doesn't standardise the data. One could make the argument that anything relating to exactly how that tract is defined, ie. the set of criteria used to either reconstruct a tract or extract it from a whole-brain tractogram, is actually a BIDS Provenance issue, and a BEP like this shouldn't attempt to plug that gap. Because even the esoterics of how a particular software package applies that particular set of rules to the data may be consequential, so by the time you embed enough information about not only the set of rules defining the tract but also the software and the processing by which they were applied, hey presto, you've duplicated provenance. If a particular pipeline can provide some information about how the tract was extracted, e.g. a WMQL string or a filename from a piece of software containing a set of rules or a process, maybe there's no harm in it being there as long as it's not to be treated as facilitating reproduction.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I just made a related comment below. I will delete that. I agree that we should implement this, given that not all Arcuate Fasciculi are created equal, we need to know how your arcuate was created, meaning which segmentation or atlas you used. I was thinking to NOT allow produce different tracts by different segmentation methods, but asumen that there will be oalwaysone altas for an entire dataset, if that is a good assumption we can add the atlas / segmentation in the JSON side-car, no? @arokem @kimberlylray |
||
| ``` | ||
|
|
||
| The JSON sidecar accompanying the tractogram contains the following metadata | ||
| fields: | ||
|
|
||
| {{ MACROS___make_metadata_table( | ||
| { | ||
| "Name": ("OPTIONAL", "String", "A human-readable name corresponding to the primary tractography algorithm and/or software used to generate the streamlines data."), | ||
| "Description": ("OPTIONAL", "String", "A longer description of the nature of the tractography experiment"), | ||
| "URL": ("OPTIONAL", "String", "A web link to a more exhaustive description of the process by which the tractography data were generated. This could be a reference to a journal article, software, software command, documentation, or pipeline description."), | ||
| "StreamlineSeeding": ("REQUIRED", "Dict", "The contents of this dictionary are described in Table 2a."), | ||
| "StreamlinePropagation": ("REQUIRED", "Dict", "The contents of this dictionary are described in Table 3a."), | ||
| "StreamlineTermination": ("REQUIRED", "Dict", "The contents of this dictionary are described in Table 4a."), | ||
| "StreamlineAcceptanceCriteria": ("REQUIRED", "Dict", "The contents of this dictionary are described in Table 5a."), | ||
| "StreamlineReconstructionDensity": ("OPTIONAL", "Dict", "The contents of this dictionary are described in Table 6a."), | ||
| } | ||
| ) }} | ||
|
|
||
| Table 2a (contents of the value for key `StreamlineSeeding`) | ||
|
|
||
| {{ MACROS___make_metadata_table( | ||
| { | ||
| "Sources": ("REQUIRED", "List", "A list where each item describes a mechanism by which streamline seed points were derived. The contents of the elements of this list are described in Table 2b"), | ||
| "AcceptanceCriteria": ("OPTIONAL", "List", "he contents of this list are described in Table 2c"), | ||
| } | ||
| ) }} | ||
|
|
||
| Table 2b (contents of elements within list `StreamlineSeeding["Sources"]`): | ||
|
|
||
| {{ MACROS___make_metadata_table( | ||
| { | ||
| "Type": ("REQUIRED", "String", "Selection from the following: ['Random', 'Sphere', 'RandomPerElement', 'GridPerElement', 'CountPerElement', 'RejectionSampling', 'Dynamic']. 'Element' can refer to voxels, fixels, or surface vertex elements based on the filepath referenced by key 'Source'. 'CountPerElement' is interpreted as being, for example, seeding some number of streamlines from precisely the center of each image element, as opposed to other mechanisms that, for each image element, spread the seeds out within the volume ascribed to that image element."), | ||
| "Source": ("REQUIRED unless Type is 'Sphere' in which case MUST NOT be specified.", "String", " Filesystem path or BIDS URI corresponding to the data source used to draw streamline seeds."), | ||
| "SeedsPerElement": ("Either REQUIRED or MUST NOT be specified based on the value of 'Type'", "Int", "For seeding mechanisms that involve a fixed number of streamline seeds for every image element in the seeding source ('RandomPerElement', 'GridPerElement', 'CountPerElement'), this value dictates the number of seeds to be drawn for each such element. For 'GridPerElement', this number must be a perfect cube."), | ||
| "AttemptsPerSeed": ("OPTIONAL", "Int", " If specified, it must be a positive integer. For a stochastic tracking algorithm, this is the number of attempts of initiation that are allowed in each seed."), | ||
| "Unidirectional": ("OPTIONAL", "Binary", "Specifies whether streamline propagation occurred in one direction from the seed point only, or in two antipodally symmetric directions."), | ||
| "InitialDirection": ("OPTIONAL", "Dict", "If absent, assume that the initial streamline tangent from the seed point was determined using the same mechanism as that used for orientation sampling during streamline propagation, but unconstrained by a prior incoming tangent. See Table 2d for possible values."), | ||
| } | ||
| ) }} | ||
|
|
||
| Table 2c (contents of elements of dict `StreamlineSeeding["AcceptanceCriteria"]`): | ||
|
|
||
| {{ MACROS___make_metadata_table( | ||
| { | ||
| "Metric": ("REQUIRED", "String", "Text description of the anisotropy metric mediating whether a streamline was permitted to propagate from the seed point."), | ||
| "Source": ("REQUIRED", "String", "Filesystem path or BIDS URI of image data from which the corresponding anisotropy metric can be extracted/computed."), | ||
| "Threshold": ("REQUIRED", "Float", "Numerical threshold applied to anisotropy metric."), | ||
| } | ||
| ) }} | ||
|
|
||
| Table 2d (contents of elements of dict `StreamlineSeeding["InitialDirection"]`): | ||
|
|
||
| TODO | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This was absent in the google doc, so is still absent here as well. Not 100% sure what this was supposed to describe originally, a random guess is that @Lestropie might have some memory of this (even though it's been a while).
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Did not finish translating the set of streamline reconstruction mechanisms to the document. But as per prior discussion, I would be stripping all of that content out of the BEP. It's not the right environment for that deconstruction, it's not the right resolution of information required for BIDS Derivatives data, some of it is too fine-grained for even tractography experts to be able to fill in, and it draws too much attention and effort away from what should actually be in the BEP. |
||
|
|
||
| Table 3a (contents of the value for key `StreamlinePropagation`): | ||
|
|
||
| {{ MACROS___make_metadata_table( | ||
| { | ||
| "Algorithm": ("REQUIRED", "Dict", "The contents of this dictionary are described in Table 3b."), | ||
| "AnglePerStep": ("OPTIONAL", "Float", "The maximal change in degrees in the streamline tangent between successive steps. Note that exactly how this parameter is interpreted may depend on the value of IntegrationOrder."), | ||
| "Interpolation": ("REQUIRED", "String", "Selection from the following: ['Nearest', 'Linear', 'Cubic', 'Spline']. The mechanism by which sub-voxel information is drawn from the Source based on the precise streamline location."), | ||
| "InterpolationOrder": ("REQUIRED", "Int", "The order of interpolation used (or 0 if linear)"), | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Added here to address comments made in the google doc by @francopestilli and @jhlegarreta
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Following to the google doc comment, I am not sure whether at the time I commented on this there was a proposal for the vocabulary (i.e. |
||
| "MinimumRadius": ("OPTIONAL", "Float", "The radius in mm of the circle formed by a streamline consistently turning at the maximum curvature angle at each step."), | ||
| "IntegrationOrder": ("OPTIONAL", "Int", "Polynomial complexity of numerical integration of fibre orientations over space to form the streamlines."), | ||
| "Source": ("REQUIRED", "String", "Filesystem path or BIDS URI to data used in the determination of streamline tangents during propagation."), | ||
| "StepSize": ("OPTIONAL", "Float", "The distance in mm covered by successive steps of the streamline algorithm. Note that this is not necessarily equivalent to the distance in mm between vertices in the tractogram as stored on file."), | ||
| "AttemptsPerVertex": ("OPTIONAL", "Int", "The maximal number of probabilistic attempts to make in propagating from a streamline vertex before ceasing propagation."), | ||
| } | ||
| ) }} | ||
|
|
||
| Table 3b (contents of dict `StreamlinePropagation["Algorithm"]`): | ||
|
|
||
| {{ MACROS___make_metadata_table( | ||
| { | ||
| "Name": ("REQUIRED", "String", "A human-readable name corresponding to the tractography algorithm used to generate the streamlines."), | ||
| "Description": ("OPTIONAL", "String", "A longer description of the nature of the tractography algorithm."), | ||
| "URL": ("OPTIONAL", "String", "A web link to a more exhaustive description of the algorithm used to generate the tractography data."), | ||
| } | ||
| ) }} | ||
|
|
||
| Table 4a (contents of the value for key `StreamlineTermination`): | ||
|
|
||
| {{ MACROS___make_metadata_table( | ||
| { | ||
| "AnatomicalSegmentation": ("OPTIONAL", "String", "Path to data containing anatomical segmentation that was used to constrain streamline termination."), | ||
| "Anisotropy": ("OPTIONAL", "List", "The contents of each element of this list are described in Table 4b."), | ||
| "AnglePerStep": ("OPTIONAL", "Float", "If a streamline changes tangent between successive steps of greater than this value in degrees, it is terminated."), | ||
| "MinimumRadius": ("OPTIONAL", "Float", "If a streamline changes tangent between successive steps corresponding to a circle of radius smaller than this value in mm, it is terminated."), | ||
| "Masks": ("OPTIONAL", "List", "List of strings corresponding to mask images; a streamline is terminated as soon as it exits the region defined by these masks."), | ||
| "SatisfiedAllAcceptance": ("OPTIONAL", "Binary", "Set to True if streamlines were immediately terminated at the first vertex upon which that streamline had satisfied all acceptance criteria."), | ||
| "MaximumLength": ("OPTIONAL", "Float", "Units of mm. Any streamline exceeding this length was no longer propagated."), | ||
| } | ||
| ) }} | ||
|
|
||
| Table 4b (contents of elements of list `StreamlineTermination["Anisotropy"]`): | ||
|
|
||
| {{ MACROS___make_metadata_table( | ||
| { | ||
| "Metric": ("REQUIRED", "String", "Text description of the anisotropy metric mediating whether a streamline was terminated."), | ||
| "Source": ("REQUIRED", "String", "Filesystem path or BIDS URI of image data from which the corresponding anisotropy metric can be extracted."), | ||
| "Threshold": ("REQUIRED", "Float", "Numerical threshold applied to anisotropy metric."), | ||
| } | ||
| ) }} | ||
|
|
||
| Table 5a (contents of the value for key `StreamlineAcceptanceCriteria`): | ||
|
|
||
| {{ MACROS___make_metadata_table( | ||
| { | ||
| "InclusionRegions": ("OPTIONAL", "List", "List of filesystem paths. A streamline must visit every item in this list at any location along its length in order to be deemed acceptable."), | ||
| "OrderedInclusionRegions": ("OPTIONAL", "List", "List of filesystem paths. A streamline must visit every item in this list in the same sequence as the order in which they appear during streamline propagation."), | ||
| "ExclusionRegions": ("OPTIONAL", "List", "List of filesystem paths. A streamline must not visit any item in this list at any location along its length."), | ||
| "MinimumLength": ("OPTIONAL", "Float", "In units of mm. Any streamline shorter than this length was discarded."), | ||
| "MaximumLength": ("OPTIONAL", "Float", "In units of mm. Any streamline exceeding this length was discarded."), | ||
| "AnatomicalSegmentation": ("OPTIONAL", "String", "Path to data containing anatomical segmentation that influenced whether streamlines were discarded."), | ||
| } | ||
| ) }} | ||
|
|
||
| Table 6a (contents of the value for key `StreamlineReconstructionDensity`): | ||
|
|
||
| {{ MACROS___make_metadata_table( | ||
| { | ||
| "Seeds": ("OPTIONAL", "Int", "Tractogram generation was terminated if this number of unique seed vertices was drawn."), | ||
| "GeneratedStreamlines": ("OPTIONAL", "Int", "Tractogram generation was terminated if this number of streamlines were generated."), | ||
| "AcceptedStreamlines": ("OPTIONAL", "Int", "Tractogram generation was terminated once this number of streamlines was written to the output tractogram."), | ||
| } | ||
| ) }} | ||
|
|
||
| ## Tracking methods | ||
|
|
||
| The `track` entity uses a controlled vocabulary of tracking method abbreviations, | ||
| as defined in the schema `enum` for this entity: | ||
|
|
||
| {{ MACROS___make_subobject_table("metadata.Track") }} | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -502,16 +502,16 @@ tracer: | |
| Please note that the `<label>` does not need to match the actual value of the field. | ||
| type: string | ||
| format: label | ||
| volume: | ||
| name: voi | ||
| display_name: Volume of Interest | ||
| track: | ||
| name: track | ||
| display_name: Tractography Method | ||
| description: | | ||
| The `voi-<label>` entity can be used to distinguish acquisitions localized to different regions. | ||
| The label SHOULD be the name of the body region or part scanned. | ||
| If used, the fields `"BodyPart"` and `"BodyPartDetails"` MUST be defined in the JSON file. | ||
| `BodyPartDetailsOntology` is OPTIONAL to also include. | ||
| The `track-<label>` entity identifies the tractography method | ||
| employed to reconstruct white matter fiber streamlines. | ||
| type: string | ||
| format: label | ||
| enum: | ||
|
jhlegarreta marked this conversation as resolved.
Outdated
|
||
| - $ref: objects.enums._TrackMethod | ||
| tracksys: | ||
| name: tracksys | ||
| display_name: Tracking System | ||
|
|
@@ -526,3 +526,24 @@ tracksys: | |
| may be longer and more human readable. | ||
| type: string | ||
| format: label | ||
|
Comment on lines
505
to
528
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since there is already an entity that uses
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Wouldn't that be confused with the trace of a tensor? Would "tracking" make this less ambiguous? Or "tracto"? We could also go more abstract with "method" or "algo", but that might also ultimately conflict with other corners of the spec.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How about "pathway", "fascicle" or "fasciculus"? I think that would resolve all concerns. Related to https://github.com/bids-standard/bids-specification/pull/2333/changes#r3464492486
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this demonstrates the confusion! Here, we are referring to the method used to propagate streamlines ("track") and not to the anatomical structure ("tract"). Confusing.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🙃 Another reason to avoid "tract" when referring to the anatomical structure.
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Recommend forbidding " |
||
| tract: | ||
| name: tract | ||
| display_name: Anatomical Tract | ||
| description: | | ||
| The `tract-<label>` entity identifies the white matter fiber | ||
| anatomical/structural entity that is imaged through a | ||
| tractogram (for example, `tract-wholebrain` would correspond to a | ||
| whole-brain tractogram, whereas `tract-ArcuateFasciculus` would | ||
| correspond to a tractogram of the arcuate fasciculus). | ||
| type: string | ||
| format: label | ||
| volume: | ||
| name: voi | ||
| display_name: Volume of Interest | ||
| description: | | ||
| The `voi-<label>` entity can be used to distinguish acquisitions localized to different regions. | ||
| The label SHOULD be the name of the body region or part scanned. | ||
| If used, the fields `"BodyPart"` and `"BodyPartDetails"` MUST be defined in the JSON file. | ||
| `BodyPartDetailsOntology` is OPTIONAL to also include. | ||
| type: string | ||
| format: label | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -79,6 +79,18 @@ _iEEGCoordSys: | |
| - $ref: objects.enums.ACPC.value | ||
| - $ref: objects.enums.ScanRAS.value | ||
| - $ref: objects.enums.Other.value | ||
| _TrackMethod: | ||
| type: string | ||
| enum: | ||
| - $ref: objects.enums.act.value | ||
| - $ref: objects.enums.eudx.value | ||
| - $ref: objects.enums.fact.value | ||
| - $ref: objects.enums.ifod.value | ||
| - $ref: objects.enums.sdstream.value | ||
| - $ref: objects.enums.tensor.value | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This seems a little under-constrained. What did you do with this tensor? |
||
| - $ref: objects.enums.pft.value | ||
| - $ref: objects.enums.ptt.value | ||
| - $ref: objects.enums.set.value | ||
| left_hemisphere: | ||
| value: 'L' | ||
| display_name: Left Hemisphere | ||
|
|
@@ -1481,3 +1493,48 @@ PhysioTypeEyetrack: | |
| display_name: Eye-tracking recording | ||
| description: | | ||
| A specific physiological recording type: eye-tracking. | ||
| act: | ||
| value: act | ||
| display_name: Anatomically-constrained tractography | ||
| description: | | ||
| Anatomically-constrained tractography (ACT). | ||
| eudx: | ||
| value: eudx | ||
| display_name: Euler Delta Crossings | ||
| description: | | ||
| Euler Delta Crossings tractography. | ||
| fact: | ||
| value: fact | ||
| display_name: Fiber assignment by continuous tracking | ||
| description: | | ||
| Fiber assignment by continuous tracking algorithm (FACT). | ||
| ifod: | ||
| value: ifod | ||
| display_name: Integration over Fiber Orientation Distributions | ||
| description: | | ||
| Integration over Fiber Orientation Distribution (iFOD) tractography. | ||
| sdstream: | ||
| value: sdstream | ||
| display_name: Streamlines tractography based on Spherical Deconvolution | ||
| description: | | ||
| Streamlines tractography based on Spherical Deconvolution. | ||
| tensor: | ||
| value: tensor | ||
| display_name: Tensor-based tractography | ||
| description: | | ||
| Tensor-based tractography (deterministic or probabilistic). | ||
| pft: | ||
| value: pft | ||
| display_name: Particle Filtering Tractography | ||
| description: | | ||
| Particle Filtering Tractography (PFT). | ||
| ptt: | ||
| value: ptt | ||
| display_name: Parallel Transport Tractography | ||
| description: | | ||
| Parallel Transport Tractography (PTT). | ||
| set: | ||
| value: set | ||
| display_name: Surface-enhanced Tractography | ||
| description: | | ||
| Surface-enhanced Tractography (SET). | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alternatives proposed for "tract" are "fasc" (as in "fascicle"), "subset", "bndl" (as in "bundle"), "part", "str" (for "structure", maybe "strc" or somesuch instead?).