The pyAFQ Image API#

In the process of tractometry, it is sometimes necessary to apply images to the data. By default, pyAFQ can automatically generate these images from the DWI data. However, pyAFQ also has a system for users to specify which image to use, called the Image API. Specifying an image, in general, is not as simple as just providing a path to a file, because each subject and each session will have a different image. That is why we developed pyAFQ’s Image API.

Currently, there are three different images that pyAFQ uses for tractometry:

  1. The brain image. This is used to mask the dwi data and throw out any signal that is outside of the brain. It is typically applied before fitting ODF models. By default, it is calculated using AFQ.definitions.image.B0Image.

  2. The tractography seed image. This image determines where tractography is seeded. If it is floating point, the image is thresholded interally after interpolation using the seed_threshold parameter. This is recommended. However, the seed image can aslo be a binary image. By default, the seed image is AFQ.definitions.image.ScalarImage (best_scalar) where best_scalar is chosen by the API based on valid scalars (typically “dti_fa”).

  3. The tractography stop image. This image determines where tractography stops. If it is floating point, the image is thresholded interally after interpolation using the stop_threshold parameter. This is recommended. However, the stop image can aslo be a binary image. By default, the stop image is AFQ.definitions.image.ScalarImage (best_scalar) where best_scalar is chosen by the API based on valid scalars (typically “dti_fa”).

In AFQ/definitions/image.py, there are several image classes one can use to specify images. As a user, one should initialize image classes and pass them to the AFQ.api objects, or write out the initialization as a string inside of one’s configuration file for use with the CLI.

  • AFQ.definitions.image.ImageFile: The simplest image class is AFQ.definitions.image.ImageFile. If the image you want to use is already generated, use this class. It is initialized using BIDS filters, which pyAFQ will use to find images for each subject in each session.

  • AFQ.definitions.image.FullImage: The AFQ.definitions.image.FullImage class is used if one does not want to mask at all. This image is True everywhere.

  • AFQ.definitions.image.RoiImage: All ROIs are “logically or’d” together in subject space to create this image. This is useful to provide as the seed image. In segmentation, pyAFQ retains only streamlines that pass through the ROIs. So, for efficiency, one can choose to only seed in the ROIs in the first place.

  • AFQ.definitions.image.B0Image: This image uses dipy’s median_otsu on the subject’s b0 to generate an image. This is the default brain image.

  • AFQ.definitions.image.LabelledImageFile: This image is similar to AFQ.definitions.image.ImageFile. It is also initialized using BIDS filters but instead expects to find a labelled segmentation file. In the initialization, the user also provides inclusive and exclusive labels. These specify which labels to include and which labels to exclude in the image. If both inclusive and exclusive labels are set, the combine parameter is used to specify how to combine the images generated by the inclusive and exclusive labels. A common use of this class would be to pass BIDS filters to some segmentation file, and also set exclusive_labels = [0]. This will mark all labels that are not 0 as a part of the image, and can be used as a brain image.

  • AFQ.definitions.image.ThresholdedImageFile: This image is similar to AFQ.definitions.image.ImageFile. It allows the user to also provide a lower and upper bound. The bounds threshold the data from the file. Note that for the tractography seed and stop images, thresholding should typically be done using the seed_threshold and stop_threshold parameters, not using an already thresholded image.

  • AFQ.definitions.image.ScalarImage: This image is initialized only by specifying a scalar. Use this image if you want an image to be based on a scalar that pyAFQ already calculates, like “dti_fa” or “dti_md”.

  • AFQ.definitions.image.ThresholdedScalarImage: This image is similar to AFQ.definitions.image.ScalarImage. It allows the user to also provide a lower and upper bound. The bounds threshold the scalar data. Note that for the tractography seed and stop images, thresholding should typically be done using the seed_threshold and stop_threshold parameters, not using an already thresholded image.

  • AFQ.definitions.image.PFTImage: A image for specifying the segmentations used in PFT. Should only be used as a stop image. It’s three arguments are three other images, which specify the three segmentations: white matter, gray matter, and corticospinal fluid.

  • AFQ.definitions.image.CombinedImage: This class can be used to combine the other images. It takes a list of images and allows the user to specify whether they should be combined using a logical “and” or “or”.

Here is an example of using the AFQ.definitions.image.RoiImage and AFQ.definitions.image.LabelledImageFile on the HCP data with the AFQ.api objects:

from AFQ.data.fetch import fetch_hcp
from AFQ.api.group import GroupAFQ
import AFQ.definitions.image as afm

# Download a subject to the AWS Batch machine from s3
_, hcp_bids = fetch_hcp(
    [1],
    profile_name=False,
    study=f"HCP_1200")

# make 500,000 seeds randomly distributed in the ROIs
tracking_params = {
    "seed_image": afm.RoiImage(),
    "n_seeds": 500000,
    "random_seeds": True}

# use segmentation file from HCP to get a brain image,
# where everything not labelled 0 is considered a part of the brain
brain_image_definition = afm.LabelledImageFile(
    suffix='seg', {'scope': 'dmriprep'}, exclusive_labels=[0])

# define the api GroupAFQ object
myafq = GroupAFQ(
    hcp_bids,
    brain_image_definition=brain_image_definition,
    tracking_params=tracking_params)

# export_all runs the entire pipeline and creates many useful derivates
myafq.export_all()