Particle Filtering Tractography

Particle Filtering Tractography (PFT) [Girard2014] uses tissue partial volume estimation (PVE) to reconstruct trajectories connecting the gray matter, and not incorrectly stopping in the white matter or in the corticospinal fluid. It relies on a stopping criterion that identifies the tissue where the streamline stopped. If the streamline correctly stopped in the gray matter, the trajectory is kept. If the streamline incorrectly stopped in the white matter or in the corticospinal fluid, PFT uses anatomical information to find an alternative streamline segment to extend the trajectory. When this segment is found, the tractography continues until the streamline correctly stops in the gray matter.

PFT finds an alternative streamline segment whenever the stopping criterion returns a position classified as ‘INVALIDPOINT’.

This example is an extension of example_tracking_probabilistic and example_tracking_stopping_criterion examples. We begin by loading the data, fitting a Constrained Spherical Deconvolution (CSD) reconstruction model, creating the probabilistic direction getter and defining the seeds.

import numpy as np

from dipy.core.gradients import gradient_table
from dipy.data import get_fnames, default_sphere
from dipy.direction import ProbabilisticDirectionGetter
from dipy.io.gradients import read_bvals_bvecs
from dipy.io.image import load_nifti, load_nifti_data
from dipy.io.stateful_tractogram import Space, StatefulTractogram
from dipy.io.streamline import save_trk
from dipy.reconst.csdeconv import (ConstrainedSphericalDeconvModel,
                                   auto_response_ssst)
from dipy.tracking.local_tracking import (LocalTracking,
                                          ParticleFilteringTracking)
from dipy.tracking.streamline import Streamlines
from dipy.tracking import utils
from dipy.viz import window, actor, colormap, has_fury

# Enables/disables interactive visualization
interactive = False

hardi_fname, hardi_bval_fname, hardi_bvec_fname = get_fnames('stanford_hardi')
label_fname = get_fnames('stanford_labels')
f_pve_csf, f_pve_gm, f_pve_wm = get_fnames('stanford_pve_maps')

data, affine, hardi_img = load_nifti(hardi_fname, return_img=True)
labels = load_nifti_data(label_fname)
bvals, bvecs = read_bvals_bvecs(hardi_bval_fname, hardi_bvec_fname)
gtab = gradient_table(bvals, bvecs)

pve_csf_data = load_nifti_data(f_pve_csf)
pve_gm_data = load_nifti_data(f_pve_gm)
pve_wm_data, _, voxel_size = load_nifti(f_pve_wm, return_voxsize=True)

shape = labels.shape

response, ratio = auto_response_ssst(gtab, data, roi_radii=10, fa_thr=0.7)
csd_model = ConstrainedSphericalDeconvModel(gtab, response)
csd_fit = csd_model.fit(data, mask=pve_wm_data)

dg = ProbabilisticDirectionGetter.from_shcoeff(csd_fit.shm_coeff,
                                               max_angle=20.,
                                               sphere=default_sphere)

seed_mask = (labels == 2)
seed_mask[pve_wm_data < 0.5] = 0
seeds = utils.seeds_from_mask(seed_mask, affine, density=2)
  0%|          | 0/77848.12 [00:00<?, ?it/s]
  0%|          | 328/77848.12 [00:00<00:23, 3275.48it/s]
  1%|          | 736/77848.12 [00:00<00:20, 3747.66it/s]
  1%|1         | 1149/77848.12 [00:00<00:19, 3918.51it/s]
  2%|1         | 1556/77848.12 [00:00<00:19, 3974.95it/s]
  3%|2         | 1987/77848.12 [00:00<00:18, 4094.68it/s]
  3%|3         | 2425/77848.12 [00:00<00:18, 4188.89it/s]
  4%|3         | 2844/77848.12 [00:00<00:17, 4184.84it/s]
  4%|4         | 3289/77848.12 [00:00<00:17, 4268.92it/s]
  5%|4         | 3716/77848.12 [00:00<00:17, 4243.35it/s]
  5%|5         | 4161/77848.12 [00:01<00:17, 4306.74it/s]
  6%|5         | 4592/77848.12 [00:01<00:17, 4272.31it/s]
  7%|6         | 5069/77848.12 [00:01<00:16, 4422.22it/s]
  7%|7         | 5512/77848.12 [00:01<00:16, 4331.54it/s]
  8%|7         | 5979/77848.12 [00:01<00:16, 4431.27it/s]
  8%|8         | 6423/77848.12 [00:01<00:16, 4396.01it/s]
  9%|8         | 6895/77848.12 [00:01<00:15, 4489.39it/s]
  9%|9         | 7359/77848.12 [00:01<00:15, 4532.86it/s]
 10%|#         | 7813/77848.12 [00:01<00:15, 4437.13it/s]
 11%|#         | 8290/77848.12 [00:01<00:15, 4534.88it/s]
 11%|#1        | 8745/77848.12 [00:02<00:15, 4530.19it/s]
 12%|#1        | 9199/77848.12 [00:02<00:15, 4452.22it/s]
 12%|#2        | 9657/77848.12 [00:02<00:15, 4489.64it/s]
 13%|#2        | 10108/77848.12 [00:02<00:15, 4494.55it/s]
 14%|#3        | 10558/77848.12 [00:02<00:15, 4450.98it/s]
 14%|#4        | 11019/77848.12 [00:02<00:14, 4496.84it/s]
 15%|#4        | 11485/77848.12 [00:02<00:14, 4543.90it/s]
 15%|#5        | 11940/77848.12 [00:02<00:14, 4516.88it/s]
 16%|#5        | 12413/77848.12 [00:02<00:14, 4577.74it/s]
 17%|#6        | 12886/77848.12 [00:02<00:14, 4622.98it/s]
 17%|#7        | 13349/77848.12 [00:03<00:14, 4553.26it/s]
 18%|#7        | 13834/77848.12 [00:03<00:13, 4638.52it/s]
 18%|#8        | 14308/77848.12 [00:03<00:13, 4667.23it/s]
 19%|#8        | 14775/77848.12 [00:03<00:13, 4648.42it/s]
 20%|#9        | 15241/77848.12 [00:03<00:13, 4647.29it/s]
 20%|##        | 15716/77848.12 [00:03<00:13, 4677.68it/s]
 21%|##        | 16184/77848.12 [00:03<00:13, 4650.73it/s]
 21%|##1       | 16650/77848.12 [00:03<00:13, 4550.42it/s]
 22%|##1       | 17108/77848.12 [00:03<00:13, 4557.25it/s]
 23%|##2       | 17566/77848.12 [00:03<00:13, 4563.63it/s]
 23%|##3       | 18030/77848.12 [00:04<00:13, 4584.69it/s]
 24%|##3       | 18489/77848.12 [00:04<00:13, 4524.44it/s]
 24%|##4       | 18980/77848.12 [00:04<00:12, 4638.04it/s]
 25%|##4       | 19455/77848.12 [00:04<00:12, 4670.78it/s]
 26%|##5       | 19943/77848.12 [00:04<00:12, 4731.50it/s]
 26%|##6       | 20417/77848.12 [00:04<00:12, 4704.50it/s]
 27%|##6       | 20903/77848.12 [00:04<00:11, 4750.56it/s]
 27%|##7       | 21380/77848.12 [00:04<00:11, 4755.95it/s]
 28%|##8       | 21856/77848.12 [00:04<00:11, 4745.99it/s]
 29%|##8       | 22331/77848.12 [00:04<00:11, 4729.57it/s]
 29%|##9       | 22805/77848.12 [00:05<00:11, 4730.20it/s]
 30%|##9       | 23289/77848.12 [00:05<00:11, 4761.46it/s]
 31%|###       | 23766/77848.12 [00:05<00:11, 4737.84it/s]
 31%|###1      | 24240/77848.12 [00:05<00:11, 4686.25it/s]
 32%|###1      | 24738/77848.12 [00:05<00:11, 4772.43it/s]
 32%|###2      | 25225/77848.12 [00:05<00:10, 4800.78it/s]
 33%|###3      | 25706/77848.12 [00:05<00:11, 4735.36it/s]
 34%|###3      | 26180/77848.12 [00:05<00:11, 4691.12it/s]
 34%|###4      | 26687/77848.12 [00:05<00:10, 4801.79it/s]
 35%|###4      | 27168/77848.12 [00:05<00:10, 4798.77it/s]
 36%|###5      | 27649/77848.12 [00:06<00:10, 4765.82it/s]
 36%|###6      | 28126/77848.12 [00:06<00:10, 4737.31it/s]
 37%|###6      | 28602/77848.12 [00:06<00:10, 4738.88it/s]
 37%|###7      | 29082/77848.12 [00:06<00:10, 4753.67it/s]
 38%|###7      | 29558/77848.12 [00:06<00:10, 4707.20it/s]
 39%|###8      | 30040/77848.12 [00:06<00:10, 4738.22it/s]
 39%|###9      | 30514/77848.12 [00:06<00:10, 4659.14it/s]
 40%|###9      | 30999/77848.12 [00:06<00:09, 4712.71it/s]
 40%|####      | 31471/77848.12 [00:06<00:09, 4684.65it/s]
 41%|####1     | 31941/77848.12 [00:06<00:09, 4687.75it/s]
 42%|####1     | 32424/77848.12 [00:07<00:09, 4728.27it/s]
 42%|####2     | 32900/77848.12 [00:07<00:09, 4735.87it/s]
 43%|####2     | 33382/77848.12 [00:07<00:09, 4760.65it/s]
 44%|####3     | 33866/77848.12 [00:07<00:09, 4779.81it/s]
 44%|####4     | 34345/77848.12 [00:07<00:09, 4752.62it/s]
 45%|####4     | 34821/77848.12 [00:07<00:09, 4690.27it/s]
 45%|####5     | 35307/77848.12 [00:07<00:08, 4739.60it/s]
 46%|####5     | 35782/77848.12 [00:07<00:08, 4733.10it/s]
 47%|####6     | 36256/77848.12 [00:07<00:08, 4714.30it/s]
 47%|####7     | 36734/77848.12 [00:08<00:08, 4730.56it/s]
 48%|####7     | 37208/77848.12 [00:08<00:08, 4664.92it/s]
 48%|####8     | 37683/77848.12 [00:08<00:08, 4688.25it/s]
 49%|####9     | 38153/77848.12 [00:08<00:08, 4633.54it/s]
 50%|####9     | 38617/77848.12 [00:08<00:08, 4599.04it/s]
 50%|#####     | 39094/77848.12 [00:08<00:08, 4647.51it/s]
 51%|#####     | 39559/77848.12 [00:08<00:08, 4619.02it/s]
 51%|#####1    | 40024/77848.12 [00:08<00:08, 4627.99it/s]
 52%|#####2    | 40487/77848.12 [00:08<00:08, 4627.13it/s]
 53%|#####2    | 40950/77848.12 [00:08<00:08, 4557.44it/s]
 53%|#####3    | 41406/77848.12 [00:09<00:08, 4477.63it/s]
 54%|#####3    | 41868/77848.12 [00:09<00:07, 4519.34it/s]
 54%|#####4    | 42321/77848.12 [00:09<00:07, 4508.05it/s]
 55%|#####4    | 42773/77848.12 [00:09<00:07, 4470.91it/s]
 56%|#####5    | 43237/77848.12 [00:09<00:07, 4519.43it/s]
 56%|#####6    | 43690/77848.12 [00:09<00:07, 4451.13it/s]
 57%|#####6    | 44160/77848.12 [00:09<00:07, 4523.02it/s]
 57%|#####7    | 44618/77848.12 [00:09<00:07, 4537.75it/s]
 58%|#####7    | 45073/77848.12 [00:09<00:07, 4467.34it/s]
 58%|#####8    | 45536/77848.12 [00:09<00:07, 4513.54it/s]
 59%|#####9    | 45988/77848.12 [00:10<00:07, 4494.50it/s]
 60%|#####9    | 46438/77848.12 [00:10<00:07, 4481.39it/s]
 60%|######    | 46887/77848.12 [00:10<00:06, 4456.35it/s]
 61%|######    | 47371/77848.12 [00:10<00:06, 4568.43it/s]
 61%|######1   | 47832/77848.12 [00:10<00:06, 4577.97it/s]
 62%|######2   | 48290/77848.12 [00:10<00:06, 4543.56it/s]
 63%|######2   | 48754/77848.12 [00:10<00:06, 4568.64it/s]
 63%|######3   | 49211/77848.12 [00:10<00:06, 4547.56it/s]
 64%|######3   | 49666/77848.12 [00:10<00:06, 4524.37it/s]
 64%|######4   | 50119/77848.12 [00:10<00:06, 4519.65it/s]
 65%|######4   | 50574/77848.12 [00:11<00:06, 4527.58it/s]
 66%|######5   | 51027/77848.12 [00:11<00:05, 4477.93it/s]
 66%|######6   | 51501/77848.12 [00:11<00:05, 4554.98it/s]
 67%|######6   | 51959/77848.12 [00:11<00:05, 4562.00it/s]
 67%|######7   | 52416/77848.12 [00:11<00:05, 4512.09it/s]
 68%|######7   | 52868/77848.12 [00:11<00:05, 4474.64it/s]
 69%|######8   | 53357/77848.12 [00:11<00:05, 4596.65it/s]
 69%|######9   | 53831/77848.12 [00:11<00:05, 4639.00it/s]
 70%|######9   | 54296/77848.12 [00:11<00:05, 4614.24it/s]
 70%|#######   | 54762/77848.12 [00:11<00:04, 4626.76it/s]
 71%|#######   | 55226/77848.12 [00:12<00:04, 4629.02it/s]
 72%|#######1  | 55714/77848.12 [00:12<00:04, 4703.09it/s]
 72%|#######2  | 56185/77848.12 [00:12<00:04, 4673.14it/s]
 73%|#######2  | 56657/77848.12 [00:12<00:04, 4682.88it/s]
 73%|#######3  | 57126/77848.12 [00:12<00:04, 4667.55it/s]
 74%|#######3  | 57606/77848.12 [00:12<00:04, 4706.03it/s]
 75%|#######4  | 58082/77848.12 [00:12<00:04, 4717.48it/s]
 75%|#######5  | 58554/77848.12 [00:12<00:04, 4658.31it/s]
 76%|#######5  | 59021/77848.12 [00:12<00:04, 4626.47it/s]
 76%|#######6  | 59484/77848.12 [00:12<00:03, 4599.70it/s]
 77%|#######7  | 59970/77848.12 [00:13<00:03, 4675.44it/s]
 78%|#######7  | 60460/77848.12 [00:13<00:03, 4742.11it/s]
 78%|#######8  | 60935/77848.12 [00:13<00:03, 4705.77it/s]
 79%|#######8  | 61416/77848.12 [00:13<00:03, 4735.04it/s]
 80%|#######9  | 61890/77848.12 [00:13<00:03, 4656.00it/s]
 80%|########  | 62395/77848.12 [00:13<00:03, 4770.84it/s]
 81%|########  | 62884/77848.12 [00:13<00:03, 4803.85it/s]
 81%|########1 | 63365/77848.12 [00:13<00:03, 4749.19it/s]
 82%|########2 | 63841/77848.12 [00:13<00:02, 4747.35it/s]
 83%|########2 | 64316/77848.12 [00:14<00:02, 4682.89it/s]
 83%|########3 | 64816/77848.12 [00:14<00:02, 4775.25it/s]
 84%|########3 | 65301/77848.12 [00:14<00:02, 4797.00it/s]
 84%|########4 | 65781/77848.12 [00:14<00:02, 4777.22it/s]
 85%|########5 | 66264/77848.12 [00:14<00:02, 4791.02it/s]
 86%|########5 | 66744/77848.12 [00:14<00:02, 4738.19it/s]
 86%|########6 | 67251/77848.12 [00:14<00:02, 4835.39it/s]
 87%|########7 | 67735/77848.12 [00:14<00:02, 4812.44it/s]
 88%|########7 | 68217/77848.12 [00:14<00:02, 4729.76it/s]
 88%|########8 | 68691/77848.12 [00:14<00:01, 4694.17it/s]
 89%|########8 | 69161/77848.12 [00:15<00:01, 4666.97it/s]
 89%|########9 | 69671/77848.12 [00:15<00:01, 4793.15it/s]
 90%|######### | 70151/77848.12 [00:15<00:01, 4770.00it/s]
 91%|######### | 70629/77848.12 [00:15<00:01, 4744.51it/s]
 91%|#########1| 71104/77848.12 [00:15<00:01, 4663.03it/s]
 92%|#########1| 71603/77848.12 [00:15<00:01, 4757.96it/s]
 93%|#########2| 72080/77848.12 [00:15<00:01, 4740.47it/s]
 93%|#########3| 72555/77848.12 [00:15<00:01, 4661.64it/s]
 94%|#########3| 73022/77848.12 [00:15<00:01, 4652.75it/s]
 94%|#########4| 73493/77848.12 [00:15<00:00, 4668.08it/s]
 95%|#########5| 73976/77848.12 [00:16<00:00, 4714.13it/s]
 96%|#########5| 74448/77848.12 [00:16<00:00, 4694.95it/s]
 96%|#########6| 74918/77848.12 [00:16<00:00, 4661.05it/s]
 97%|#########6| 75385/77848.12 [00:16<00:00, 4613.83it/s]
 97%|#########7| 75870/77848.12 [00:16<00:00, 4680.32it/s]
 98%|#########8| 76339/77848.12 [00:16<00:00, 4671.93it/s]
 99%|#########8| 76807/77848.12 [00:16<00:00, 4649.92it/s]
 99%|#########9| 77273/77848.12 [00:16<00:00, 4596.37it/s]
100%|#########9| 77773/77848.12 [00:16<00:00, 4713.75it/s]
78245it [00:16, 4701.16it/s]
78716it [00:17, 4685.78it/s]
79185it [00:17, 4623.35it/s]
79711it [00:17, 4807.82it/s]
80193it [00:17, 4722.56it/s]
80667it [00:17, 4725.88it/s]
81140it [00:17, 4616.00it/s]
81658it [00:17, 4779.55it/s]
82137it [00:17, 4755.44it/s]
82614it [00:17, 4752.95it/s]
83090it [00:17, 4665.21it/s]
83582it [00:18, 4739.35it/s]
84057it [00:18, 4710.25it/s]
84529it [00:18, 4634.61it/s]
84993it [00:18, 4619.70it/s]
85478it [00:18, 4686.55it/s]
85947it [00:18, 4685.53it/s]
86416it [00:18, 4625.71it/s]
86905it [00:18, 4702.44it/s]
87376it [00:18, 4651.64it/s]
87842it [00:19, 4557.37it/s]
88323it [00:19, 4629.07it/s]
88787it [00:19, 4491.90it/s]
89238it [00:19, 4494.58it/s]
89702it [00:19, 4534.82it/s]
90157it [00:19, 4441.59it/s]
90634it [00:19, 4536.45it/s]
91089it [00:19, 4454.18it/s]
91552it [00:19, 4504.55it/s]
92004it [00:19, 4433.40it/s]
92451it [00:20, 4442.09it/s]
92899it [00:20, 4450.96it/s]
93345it [00:20, 4337.77it/s]
93780it [00:20, 4339.22it/s]
94215it [00:20, 4226.23it/s]
94645it [00:20, 4247.00it/s]
95071it [00:20, 4177.53it/s]
95490it [00:20, 4165.31it/s]
95907it [00:20, 4126.55it/s]
96320it [00:20, 4060.14it/s]
96727it [00:21, 4025.54it/s]
96989it [00:21, 4582.95it/s]

CMC/ACT Stopping Criterion

Continuous map criterion (CMC) [Girard2014] and Anatomically-constrained tractography (ACT) [Smith2012] both uses PVEs information from anatomical images to determine when the tractography stops. Both stopping criterion use a trilinear interpolation at the tracking position. CMC stopping criterion uses a probability derived from the PVE maps to determine if the streamline reaches a ‘valid’ or ‘invalid’ region. ACT uses a fixed threshold on the PVE maps. Both stopping criterion can be used in conjunction with PFT. In this example, we used CMC.

from dipy.tracking.stopping_criterion import CmcStoppingCriterion

voxel_size = np.average(voxel_size[1:4])
step_size = 0.2

cmc_criterion = CmcStoppingCriterion.from_pve(pve_wm_data,
                                              pve_gm_data,
                                              pve_csf_data,
                                              step_size=step_size,
                                              average_voxel_size=voxel_size)

# Particle Filtering Tractography
pft_streamline_generator = ParticleFilteringTracking(dg,
                                                     cmc_criterion,
                                                     seeds,
                                                     affine,
                                                     max_cross=1,
                                                     step_size=step_size,
                                                     maxlen=1000,
                                                     pft_back_tracking_dist=2,
                                                     pft_front_tracking_dist=1,
                                                     particle_count=15,
                                                     return_all=False)
streamlines = Streamlines(pft_streamline_generator)
sft = StatefulTractogram(streamlines, hardi_img, Space.RASMM)
save_trk(sft, "tractogram_pft.trk")

if has_fury:
    scene = window.Scene()
    scene.add(actor.line(streamlines, colormap.line_colors(streamlines)))
    window.record(scene, out_path='tractogram_pft.png',
                  size=(800, 800))
    if interactive:
        window.show(scene)
tracking pft
examples_built/13_fiber_tracking/tractogram_pft.png

Corpus Callosum using particle filtering tractography

# Local Probabilistic Tractography
prob_streamline_generator = LocalTracking(dg,
                                          cmc_criterion,
                                          seeds,
                                          affine,
                                          max_cross=1,
                                          step_size=step_size,
                                          maxlen=1000,
                                          return_all=False)
streamlines = Streamlines(prob_streamline_generator)
sft = StatefulTractogram(streamlines, hardi_img, Space.RASMM)
save_trk(sft, "tractogram_probabilistic_cmc.trk")

if has_fury:
    scene = window.Scene()
    scene.add(actor.line(streamlines, colormap.line_colors(streamlines)))
    window.record(scene, out_path='tractogram_probabilistic_cmc.png',
                  size=(800, 800))
    if interactive:
        window.show(scene)
tracking pft
examples_built/13_fiber_tracking/tractogram_probabilistic_cmc.png

Corpus Callosum using probabilistic tractography

References

[Girard2014] (1,2)

Girard, G., Whittingstall, K., Deriche, R., & Descoteaux, M. Towards quantitative connectivity analysis: reducing tractography biases. NeuroImage, 98, 266-278, 2014.

[Smith2012]

Smith, R. E., Tournier, J.-D., Calamante, F., & Connelly, A. Anatomically-constrained tractography: Improved diffusion MRI streamlines tractography through effective use of anatomical information. NeuroImage, 63(3), 1924-1938, 2012.

Total running time of the script: ( 1 minutes 8.115 seconds)

Gallery generated by Sphinx-Gallery