コード例 #1
0
 def streamlines_whole_brain_get(self, csapeaks, white_matter):
     '''Create seeds for fiber tracking from a binary mask,
         evenly distributed in all voxels of mask which are True 
         seeds : points qui couvrent les coordonnées où il y a white matter
         Streamlines : set de streamlines.
         Chaque streamline est un array de 3xM. 
         Chaque ligne correspond aux coordonnées xyz d'un point de la streamline. 
         Et M (nbr de lignes) est le nbr de points qui composent la streamline.
     '''
     print("extracting streamlines ...")
     affine = np.eye(4)
     seeds = utils.seeds_from_mask(
         white_matter, affine,
         density=1)  # Create seeds for fiber tracking from a binary mask,
     # evenly distributed in all voxels of mask which are True
     # seeds : points qui couvrent les coordonnées où il y a white matter
     stopping_criterion = BinaryStoppingCriterion(white_matter)
     # stopping_criterion = ThresholdStoppingCriterion(csapeaks.gfa, .25)
     streamline_generator = LocalTracking(csapeaks,
                                          stopping_criterion,
                                          seeds,
                                          affine=affine,
                                          step_size=0.5)
     streamlines = Streamlines(streamline_generator)
     # # compress streamlines
     # from dipy.tracking.streamlinespeed import compress_streamlines
     # streamlines = compress_streamlines(streamlines, tol_error=0.2)
     return streamlines, affine
コード例 #2
0
def test_binary_stopping_criterion():
    """This tests that the binary stopping criterion returns expected
    streamline statuses.
    """

    mask = np.random.random((4, 4, 4))
    mask[mask < 0.4] = 0.0

    btc_boolean = BinaryStoppingCriterion(mask > 0)
    btc_float64 = BinaryStoppingCriterion(mask)

    # Test voxel center
    for ind in ndindex(mask.shape):
        pts = np.array(ind, dtype='float64')
        state_boolean = btc_boolean.check_point(pts)
        state_float64 = btc_float64.check_point(pts)
        if mask[ind] > 0:
            npt.assert_equal(state_boolean, int(StreamlineStatus.TRACKPOINT))
            npt.assert_equal(state_float64, int(StreamlineStatus.TRACKPOINT))
        else:
            npt.assert_equal(state_boolean, int(StreamlineStatus.ENDPOINT))
            npt.assert_equal(state_float64, int(StreamlineStatus.ENDPOINT))

    # Test random points in voxel
    for ind in ndindex(mask.shape):
        for _ in range(50):
            pts = np.array(ind, dtype='float64') + np.random.random(3) - 0.5
            state_boolean = btc_boolean.check_point(pts)
            state_float64 = btc_float64.check_point(pts)
            if mask[ind] > 0:
                npt.assert_equal(state_boolean,
                                 int(StreamlineStatus.TRACKPOINT))
                npt.assert_equal(state_float64,
                                 int(StreamlineStatus.TRACKPOINT))
            else:
                npt.assert_equal(state_boolean, int(StreamlineStatus.ENDPOINT))
                npt.assert_equal(state_float64, int(StreamlineStatus.ENDPOINT))

    # Test outside points
    outside_pts = [[100, 100, 100], [0, -1, 1], [0, 10, 2], [0, 0.5, -0.51],
                   [0, -0.51, 0.1], [4, 0, 0]]
    for pts in outside_pts:
        pts = np.array(pts, dtype='float64')
        state_boolean = btc_boolean.check_point(pts)
        state_float64 = btc_float64.check_point(pts)
        npt.assert_equal(state_boolean, int(StreamlineStatus.OUTSIDEIMAGE))
        npt.assert_equal(state_float64, int(StreamlineStatus.OUTSIDEIMAGE))
コード例 #3
0
        def loc_track(path,
                      default_sphere,
                      coords=None,
                      npath=None,
                      UParams=None,
                      ang_thr=None):
            data, affine = load_nifti(path + 'data.nii.gz')
            data[np.isnan(data) == 1] = 0
            mask, affine = load_nifti(path + 'nodif_brain_mask.nii.gz')
            mask[np.isnan(mask) == 1] = 0
            mask[:, :, 1:] = 0
            stopper = copy.deepcopy(mask)
            #stopper[:, :, :] = 1
            gtab = gradient_table(path + 'bvals', path + 'bvecs')

            csa_model = CsaOdfModel(gtab, smooth=1, sh_order=12)
            peaks = peaks_from_model(csa_model,
                                     data,
                                     default_sphere,
                                     relative_peak_threshold=0.99,
                                     min_separation_angle=25,
                                     mask=mask)
            if ang_thr is not None:
                peaks.ang_thr = ang_thr
            if os.path.exists(path + 'grad_dev.nii.gz'):
                gd, affine_g = load_nifti(path + 'grad_dev.nii.gz')
                nmask, naffine = load_nifti(npath + 'nodif_brain_mask.nii.gz')
                nmask[np.isnan(nmask) == 1] = 0
                nmask[:, :, 1:] = 0
                seedss = copy.deepcopy(nmask)
                seedss = utils.seeds_from_mask(seedss, naffine, [2, 2, 2])
                useed = []
                UParams = coords.Uparams
                for seed in seedss:
                    us = coords.rFUa_xyz(seed[0], seed[1], seed[2])
                    vs = coords.rFVa_xyz(seed[0], seed[1], seed[2])
                    ws = coords.rFWa_xyz(seed[0], seed[1], seed[2])
                    condition = us >= UParams.min_a and us <= UParams.max_a and vs >= UParams.min_b and vs <= UParams.max_b \
                                and ws >= UParams.min_c and ws <= UParams.max_c
                    if condition == True:
                        useed.append([float(us), float(vs), float(ws)])
                seeds = np.asarray(useed)

            else:
                gd = None
                seedss = copy.deepcopy(mask)
                seeds = utils.seeds_from_mask(seedss, affine, [2, 2, 2])

            stopping_criterion = BinaryStoppingCriterion(stopper)
            tracked = tracking(peaks,
                               stopping_criterion,
                               seeds,
                               affine,
                               graddev=gd,
                               sphere=default_sphere)
            tracked.localTracking()
            return tracked
コード例 #4
0
ファイル: track.py プロジェクト: CaseyWeiner/m2g
    def prep_tracking(self):
        """Uses nibabel and dipy functions in order to load the grey matter, white matter, and csf masks
        and use a tissue classifier (act, cmc, or binary) on the include/exclude maps to make a tissueclassifier object

        Returns
        -------
        ActStoppingCriterion, CmcStoppingCriterion, or BinaryStoppingCriterion
            The resulting tissue classifier object, depending on which method you use (currently only does act)
        """

        if self.track_type == "local":
            tiss_class = "bin"
        elif self.track_type == "particle":
            tiss_class = "cmc"

        self.dwi_img = nib.load(self.dwi)
        self.data = self.dwi_img.get_data()
        # Loads mask and ensures it's a true binary mask
        self.mask_img = nib.load(self.nodif_B0_mask)
        self.mask = self.mask_img.get_data() > 0
        # Load tissue maps and prepare tissue classifier
        self.gm_mask = nib.load(self.gm_in_dwi)
        self.gm_mask_data = self.gm_mask.get_data()
        self.wm_mask = nib.load(self.wm_in_dwi)
        self.wm_mask_data = self.wm_mask.get_data()
        self.wm_in_dwi_data = nib.load(
            self.wm_in_dwi).get_data().astype("bool")
        if tiss_class == "act":
            self.vent_csf_in_dwi = nib.load(self.vent_csf_in_dwi)
            self.vent_csf_in_dwi_data = self.vent_csf_in_dwi.get_data()
            self.background = np.ones(self.gm_mask.shape)
            self.background[(self.gm_mask_data + self.wm_mask_data +
                             self.vent_csf_in_dwi_data) > 0] = 0
            self.include_map = self.wm_mask_data
            self.include_map[self.background > 0] = 0
            self.exclude_map = self.vent_csf_in_dwi_data
            self.tiss_classifier = ActStoppingCriterion(
                self.include_map, self.exclude_map)
        elif tiss_class == "bin":
            self.tiss_classifier = BinaryStoppingCriterion(self.wm_in_dwi_data)
            # self.tiss_classifier = BinaryStoppingCriterion(self.mask)
        elif tiss_class == "cmc":
            self.vent_csf_in_dwi = nib.load(self.vent_csf_in_dwi)
            self.vent_csf_in_dwi_data = self.vent_csf_in_dwi.get_data()
            voxel_size = np.average(self.wm_mask.get_header()["pixdim"][1:4])
            step_size = 0.2
            self.tiss_classifier = CmcStoppingCriterion.from_pve(
                self.wm_mask_data,
                self.gm_mask_data,
                self.vent_csf_in_dwi_data,
                step_size=step_size,
                average_voxel_size=voxel_size,
            )
        else:
            pass
        return self.tiss_classifier
コード例 #5
0
def test_closest_peak_tracker():
    """This tests that the Closest Peak Direction Getter plays nice
    LocalTracking and produces reasonable streamlines in a simple example.
    """
    sphere = HemiSphere.from_sphere(unit_octahedron)

    # A simple image with three possible configurations, a vertical tract,
    # a horizontal tract and a crossing
    pmf_lookup = np.array([[0., 0., 1.],
                           [1., 0., 0.],
                           [0., 1., 0.],
                           [.5, .5, 0.]])
    simple_image = np.array([[0, 1, 0, 0, 0, 0],
                             [0, 1, 0, 0, 0, 0],
                             [2, 3, 2, 2, 2, 0],
                             [0, 1, 0, 0, 0, 0],
                             [0, 1, 0, 0, 0, 0],
                             ])

    simple_image = simple_image[..., None]
    pmf = pmf_lookup[simple_image]

    seeds = [np.array([1., 1., 0.]), np.array([2., 4., 0.])]

    mask = (simple_image > 0).astype(float)
    sc = BinaryStoppingCriterion(mask)

    dg = ClosestPeakDirectionGetter.from_pmf(pmf, 90, sphere,
                                             pmf_threshold=0.1)
    streamlines = Streamlines(LocalTracking(dg, sc, seeds, np.eye(4), 1.))

    expected = [np.array([[0., 1., 0.],
                          [1., 1., 0.],
                          [2., 1., 0.],
                          [3., 1., 0.],
                          [4., 1., 0.]]),
                np.array([[2., 0., 0.],
                          [2., 1., 0.],
                          [2., 2., 0.],
                          [2., 3., 0.],
                          [2., 4., 0.]])]

    def allclose(x, y):
        return x.shape == y.shape and np.allclose(x, y)

    if not allclose(streamlines[0], expected[0]):
        raise AssertionError()
    if not allclose(streamlines[1], expected[1]):
        raise AssertionError()
コード例 #6
0
    def _core_run(self, stopping_path, use_binary_mask, stopping_thr,
                  seeding_path, seed_density, step_size, direction_getter,
                  out_tract, save_seeds):

        stop, affine = load_nifti(stopping_path)
        if use_binary_mask:
            stopping_criterion = BinaryStoppingCriterion(stop > stopping_thr)
        else:
            stopping_criterion = ThresholdStoppingCriterion(stop, stopping_thr)
        logging.info('stopping criterion done')
        seed_mask, _ = load_nifti(seeding_path)
        seeds = \
            utils.seeds_from_mask(
                seed_mask,
                density=[seed_density, seed_density, seed_density],
                affine=affine)
        logging.info('seeds done')

        tracking_result = LocalTracking(direction_getter,
                                        stopping_criterion,
                                        seeds,
                                        affine,
                                        step_size=step_size,
                                        save_seeds=save_seeds)

        logging.info('LocalTracking initiated')

        if save_seeds:
            streamlines, seeds = zip(*tracking_result)
            seeds = {'seeds': seeds}
        else:
            streamlines = list(tracking_result)
            seeds = {}

        sft = StatefulTractogram(streamlines,
                                 seeding_path,
                                 Space.RASMM,
                                 data_per_streamline=seeds)
        save_tractogram(sft, out_tract, bbox_valid_check=False)
        logging.info('Saved {0}'.format(out_tract))
コード例 #7
0
def fiber_tracking(subject):
    # declare the type of algorithm, \in [deterministic, probabilitic]
    algo = 'deterministic'
    #     algo = 'probabilitic'
    '''
    @param subject: string represents the subject name
    @param algo: the name for the algorithms, \in ['deterministic', 'probabilitic']
    @return streamlines: for saving the final results and visualization
    '''

    print('processing for', subject)
    fname, bval_fname, bvec_fname, label_fname = get_file_names(subject)

    data, sub_affine, img = load_nifti(fname, return_img=True)
    bvals, bvecs = read_bvals_bvecs(bval_fname, bvec_fname)
    gtab = gradient_table(bvals, bvecs)
    labels = load_nifti_data(label_fname)

    print('data loading complete.\n')
    ##################################################################

    # set mask(s) and seed(s)
    # global_mask = binary_dilation((data[:, :, :, 0] != 0))
    global_mask = binary_dilation((labels == 1) | (labels == 2))
    #     global_mask = binary_dilation((labels == 2) | (labels == 32) | (labels == 76))
    affine = np.eye(4)
    seeds = utils.seeds_from_mask(global_mask, affine, density=1)
    print('mask(s) and seed(s) set complete.\n')
    ##################################################################

    print('getting directions from diffusion dataset...')

    # define tracking mask with Constant Solid Angle (CSA)
    csamodel = CsaOdfModel(gtab, 6)
    stopping_criterion = BinaryStoppingCriterion(global_mask)

    # define direction criterion
    direction_criterion = None
    print('Compute directions...')
    if algo == "deterministic":
        # EuDX
        direction_criterion = peaks.peaks_from_model(
            model=csamodel,
            data=data,
            sphere=peaks.default_sphere,
            relative_peak_threshold=.8,
            min_separation_angle=45,
            mask=global_mask)


#         # Deterministic Algorithm (select direction with max probability)
#         direction_criterion = DeterministicMaximumDirectionGetter.from_shcoeff(
#             csd_fit.shm_coeff,
#             max_angle=30.,
#             sphere=default_sphere)
    else:
        response, ratio = auto_response(gtab, data, roi_radius=10, fa_thr=0.7)

        # fit the reconstruction model with Constrained Spherical Deconvolusion (CSD)
        csd_model = ConstrainedSphericalDeconvModel(gtab, response, sh_order=6)
        csd_fit = csd_model.fit(data, mask=global_mask)

        #         gfa = csamodel.fit(data, mask=global_mask).gfa
        #     stopping_criterion = ThresholdStoppingCriterion(gfa, .25)

        # Probabilitic Algorithm
        direction_criterion = ProbabilisticDirectionGetter.from_shcoeff(
            csd_fit.shm_coeff, max_angle=30., sphere=default_sphere)

    print('direction computation complete.\n')
    ##################################################################

    print('start tracking process...')
    # start tracking
    streamline_generator = LocalTracking(direction_criterion,
                                         stopping_criterion,
                                         seeds,
                                         affine=affine,
                                         step_size=0.5)

    # Generate streamlines object
    streamlines = Streamlines(streamline_generator)

    sft = StatefulTractogram(streamlines, img, Space.RASMM)

    print('traking complete.\n')
    ##################################################################

    return {
        "subject": subject,
        "streamlines": streamlines,
        "sft": sft,
        "affine": sub_affine,
        "data": data,
        "img": img,
        "labels": labels
    }
コード例 #8
0
ファイル: track.py プロジェクト: dPys/PyNets
def prep_tissues(t1_mask,
                 gm_in_dwi,
                 vent_csf_in_dwi,
                 wm_in_dwi,
                 tiss_class,
                 B0_mask,
                 cmc_step_size=0.2):
    """
    Estimate a tissue classifier for tractography.

    Parameters
    ----------
    t1_mask : Nifti1Image
        T1w mask img.
    gm_in_dwi : Nifti1Image
        Grey-matter tissue segmentation Nifti1Image.
    vent_csf_in_dwi : Nifti1Image
        Ventricular CSF tissue segmentation Nifti1Image.
    wm_in_dwi : Nifti1Image
        White-matter tissue segmentation Nifti1Image.
    tiss_class : str
        Tissue classification method.
    cmc_step_size : float
        Step size from CMC tissue classification method.

    Returns
    -------
    tiss_classifier : obj
        Tissue classifier object.

    References
    ----------
    .. [1] Zhang, Y., Brady, M. and Smith, S. Segmentation of Brain MR Images
      Through a Hidden Markov Random Field Model and the
      Expectation-Maximization Algorithm IEEE Transactions on Medical Imaging,
      20(1): 45-56, 2001
    .. [2] Avants, B. B., Tustison, N. J., Wu, J., Cook, P. A. and Gee, J. C.
      An open source multivariate framework for n-tissue segmentation with
      evaluation on public data. Neuroinformatics, 9(4): 381-400, 2011.
    """
    import gc
    from dipy.tracking.stopping_criterion import (
        ActStoppingCriterion,
        CmcStoppingCriterion,
        BinaryStoppingCriterion,
    )
    from nilearn.masking import intersect_masks
    from nilearn.image import math_img

    # Load B0 mask
    B0_mask_img = math_img("img > 0.01", img=B0_mask)

    # Load t1 mask
    mask_img = math_img("img > 0.01", img=t1_mask)

    # Load tissue maps and prepare tissue classifier
    wm_mask_img = math_img("img > 0.01", img=wm_in_dwi)
    gm_mask_img = math_img("img > 0.01", img=gm_in_dwi)
    vent_csf_in_dwi_img = math_img("img > 0.01", img=vent_csf_in_dwi)
    gm_data = np.asarray(gm_mask_img.dataobj, dtype=np.float32)
    wm_data = np.asarray(wm_mask_img.dataobj, dtype=np.float32)
    vent_csf_in_dwi_data = np.asarray(vent_csf_in_dwi_img.dataobj,
                                      dtype=np.float32)
    if tiss_class == "act":
        background = np.ones(mask_img.shape)
        background[(gm_data + wm_data + vent_csf_in_dwi_data) > 0] = 0
        gm_data[background > 0] = 1
        tiss_classifier = ActStoppingCriterion(gm_data, vent_csf_in_dwi_data)
        del background
    elif tiss_class == "wm":
        tiss_classifier = BinaryStoppingCriterion(
            np.asarray(
                intersect_masks(
                    [
                        mask_img, wm_mask_img, B0_mask_img,
                        nib.Nifti1Image(np.invert(
                            vent_csf_in_dwi_data.astype('bool')).astype('int'),
                                        affine=mask_img.affine)
                    ],
                    threshold=1,
                    connected=False,
                ).dataobj))
    elif tiss_class == "cmc":
        tiss_classifier = CmcStoppingCriterion.from_pve(
            wm_data,
            gm_data,
            vent_csf_in_dwi_data,
            step_size=cmc_step_size,
            average_voxel_size=np.average(mask_img.header["pixdim"][1:4]),
        )
    elif tiss_class == "wb":
        tiss_classifier = BinaryStoppingCriterion(
            np.asarray(
                intersect_masks(
                    [
                        mask_img,
                        B0_mask_img,
                        nib.Nifti1Image(np.invert(
                            vent_csf_in_dwi_data.astype('bool')).astype('int'),
                                        affine=mask_img.affine),
                    ],
                    threshold=1,
                    connected=False,
                ).dataobj))
    else:
        raise ValueError("Tissue classifier cannot be none.")

    B0_mask_img.uncache()
    mask_img.uncache()
    wm_mask_img.uncache()
    gm_mask_img.uncache()
    del gm_data, wm_data, vent_csf_in_dwi_data
    gc.collect()

    return tiss_classifier
コード例 #9
0
ファイル: streamline_tools.py プロジェクト: bgsuper/dipy
csapeaks = peaks.peaks_from_model(model=csamodel,
                                  data=data,
                                  sphere=peaks.default_sphere,
                                  relative_peak_threshold=.8,
                                  min_separation_angle=45,
                                  mask=white_matter)

"""
Now we can use EuDX to track all of the white matter. To keep things reasonably
fast we use ``density=1`` which will result in 1 seeds per voxel. The stopping
criterion, determining when the tracking stops, is set to stop when the
tracking exit the white matter.
"""

seeds = utils.seeds_from_mask(white_matter, density=1)
stopping_criterion = BinaryStoppingCriterion(white_matter)
affine = np.eye(4)

streamline_generator = LocalTracking(csapeaks, stopping_criterion, seeds,
                                     affine=affine, step_size=0.5)
streamlines = Streamlines(streamline_generator)

"""
The first of the tracking utilities we'll cover here is ``target``. This
function takes a set of streamlines and a region of interest (ROI) and returns
only those streamlines that pass though the ROI. The ROI should be an array
such that the voxels that belong to the ROI are ``True`` and all other voxels
are ``False`` (this type of binary array is sometimes called a mask). This
function can also exclude all the streamlines that pass though an ROI by
setting the ``include`` flag to ``False``. In this example we'll target the
streamlines of the corpus callosum. Our ``labels`` array has a sagittal slice
コード例 #10
0
ファイル: conftest.py プロジェクト: dPys/PyNets
def tractography_estimation_data(dmri_estimation_data):
    path_tmp = tempfile.NamedTemporaryFile(mode='w+',
                                           suffix='.trk',
                                           delete=False)
    trk_path_tmp = str(path_tmp.name)
    dir_path = os.path.dirname(trk_path_tmp)

    gtab = dmri_estimation_data['gtab']
    wm_img = nib.load(dmri_estimation_data['f_pve_wm'])
    dwi_img = nib.load(dmri_estimation_data['dwi_file'])
    dwi_data = dwi_img.get_fdata()
    B0_mask_img = nib.load(dmri_estimation_data['B0_mask'])
    mask_img = intersect_masks(
        [
            nib.Nifti1Image(np.asarray(
                wm_img.dataobj).astype('bool').astype('int'),
                            affine=wm_img.affine),
            nib.Nifti1Image(np.asarray(
                B0_mask_img.dataobj).astype('bool').astype('int'),
                            affine=B0_mask_img.affine)
        ],
        threshold=1,
        connected=False,
    )

    mask_data = mask_img.get_fdata()
    mask_file = fname_presuffix(dmri_estimation_data['B0_mask'],
                                suffix="tracking_mask",
                                use_ext=True)
    mask_img.to_filename(mask_file)
    csa_model = CsaOdfModel(gtab, sh_order=6)
    csa_peaks = peaks_from_model(csa_model,
                                 dwi_data,
                                 default_sphere,
                                 relative_peak_threshold=.8,
                                 min_separation_angle=45,
                                 mask=mask_data)

    stopping_criterion = BinaryStoppingCriterion(mask_data)

    seed_mask = (mask_data == 1)
    seeds = seeds_from_mask(seed_mask, dwi_img.affine, density=[1, 1, 1])

    streamlines_generator = LocalTracking(csa_peaks,
                                          stopping_criterion,
                                          seeds,
                                          affine=dwi_img.affine,
                                          step_size=.5)
    streamlines = Streamlines(streamlines_generator)
    sft = StatefulTractogram(streamlines,
                             B0_mask_img,
                             origin=Origin.NIFTI,
                             space=Space.VOXMM)
    sft.remove_invalid_streamlines()
    trk = f"{dir_path}/tractogram.trk"
    os.rename(trk_path_tmp, trk)
    save_tractogram(sft, trk, bbox_valid_check=False)
    del streamlines, sft, streamlines_generator, seeds, seed_mask, csa_peaks, \
        csa_model, dwi_data, mask_data
    dwi_img.uncache()
    mask_img.uncache()
    gc.collect()

    yield {'trk': trk, 'mask': mask_file}
コード例 #11
0
ファイル: track.py プロジェクト: devhliu/PyNets
def prep_tissues(B0_mask,
                 gm_in_dwi,
                 vent_csf_in_dwi,
                 wm_in_dwi,
                 tiss_class,
                 cmc_step_size=0.2):
    """
    Estimate a tissue classifier for tractography.

    Parameters
    ----------
    B0_mask : str
        File path to B0 brain mask.
    gm_in_dwi : str
        File path to grey-matter tissue segmentation Nifti1Image.
    vent_csf_in_dwi : str
        File path to ventricular CSF tissue segmentation Nifti1Image.
    wm_in_dwi : str
        File path to white-matter tissue segmentation Nifti1Image.
    tiss_class : str
        Tissue classification method.
    cmc_step_size : float
        Step size from CMC tissue classification method.

    Returns
    -------
    tiss_classifier : obj
        Tissue classifier object.
    """
    try:
        import cPickle as pickle
    except ImportError:
        import _pickle as pickle
    from dipy.tracking.stopping_criterion import ActStoppingCriterion, CmcStoppingCriterion, BinaryStoppingCriterion
    # Loads mask and ensures it's a true binary mask
    mask_img = nib.load(B0_mask)
    # Load tissue maps and prepare tissue classifier
    gm_mask_data = nib.load(gm_in_dwi).get_fdata()
    wm_mask_data = nib.load(wm_in_dwi).get_fdata()
    vent_csf_in_dwi_data = nib.load(vent_csf_in_dwi).get_fdata()
    if tiss_class == 'act':
        background = np.ones(mask_img.shape)
        background[(gm_mask_data + wm_mask_data +
                    vent_csf_in_dwi_data) > 0] = 0
        include_map = gm_mask_data
        include_map[background > 0] = 1
        tiss_classifier = ActStoppingCriterion(include_map,
                                               vent_csf_in_dwi_data)
        del background
        del include_map
    elif tiss_class == 'bin':
        tiss_classifier = BinaryStoppingCriterion(wm_mask_data.astype('bool'))
    elif tiss_class == 'cmc':
        voxel_size = np.average(mask_img.header['pixdim'][1:4])
        tiss_classifier = CmcStoppingCriterion.from_pve(
            wm_mask_data,
            gm_mask_data,
            vent_csf_in_dwi_data,
            step_size=cmc_step_size,
            average_voxel_size=voxel_size)
    elif tiss_class == 'wb':
        tiss_classifier = BinaryStoppingCriterion(
            mask_img.get_fdata().astype('bool'))
    else:
        raise ValueError('Tissue Classifier cannot be none.')

    del gm_mask_data, wm_mask_data, vent_csf_in_dwi_data
    mask_img.uncache()

    return tiss_classifier
コード例 #12
0
def run_tractography(fdwi,
                     fbval,
                     fbvec,
                     fwmparc,
                     mod_func,
                     mod_type,
                     seed_density=20):
    """
    mod_func : 'str'
        'csd' or 'csa'
    mod_type : 'str'
        'det' or 'prob'
    seed_density : int, default=20
        Seeding density for tractography
    """
    # Getting default params
    sphere = get_sphere("repulsion724")
    stream_affine = np.eye(4)

    # Loading data
    print("Loading Data...")
    dwi, gtab, wm_mask = load_data(fdwi, fbval, fbvec, fwmparc)

    # Make tissue classifier
    tiss_classifier = BinaryStoppingCriterion(wm_mask)

    if mod_func == "csd":
        mod = csd_mod_est(gtab, dwi, wm_mask)
    elif mod_func == "csa":
        mod = odf_mod_est(gtab)

    # Build seed list
    seeds = utils.random_seeds_from_mask(
        wm_mask,
        affine=stream_affine,
        seeds_count=int(seed_density),
        seed_count_per_voxel=True,
    )

    # Make streamlines
    if mod_type == "det":
        print("Obtaining peaks from model...")
        direction_getter = peaks_from_model(
            mod,
            dwi,
            sphere,
            relative_peak_threshold=0.5,
            min_separation_angle=25,
            mask=wm_mask,
            npeaks=5,
            normalize_peaks=True,
        )
    elif mod_type == "prob":
        print("Preparing probabilistic tracking...")
        print("Fitting model to data...")
        mod_fit = mod.fit(dwi, wm_mask)
        print("Building direction-getter...")
        try:
            print(
                "Proceeding using spherical harmonic coefficient from model estimation..."
            )
            direction_getter = ProbabilisticDirectionGetter.from_shcoeff(
                mod_fit.shm_coeff, max_angle=60.0, sphere=sphere)
        except:
            print("Proceeding using FOD PMF from model estimation...")
            fod = mod_fit.odf(sphere)
            pmf = fod.clip(min=0)
            direction_getter = ProbabilisticDirectionGetter.from_pmf(
                pmf, max_angle=60.0, sphere=sphere)

    print("Running Local Tracking")
    streamline_generator = LocalTracking(
        direction_getter,
        tiss_classifier,
        seeds,
        stream_affine,
        step_size=0.5,
        return_all=True,
    )

    print("Reconstructing tractogram streamlines...")
    streamlines = Streamlines(streamline_generator)
    tracks = Streamlines([track for track in streamlines if len(track) > 60])
    return tracks
コード例 #13
0
def QCSA_tractmake(data, affine, vox_size, gtab, mask, masktype, header, step_size, peak_processes, outpathtrk, subject='NA',
                   ratio=1, overwrite=False, get_params=False, doprune=False, figspath=None, verbose=None):
    # Compute odfs in Brain Mask
    t2 = time()
    if os.path.isfile(outpathtrk) and not overwrite:
        txt = "Subject already saved at "+outpathtrk
        print(txt)
        streamlines_generator = None
        params = None
        return outpathtrk, streamlines_generator, params

    csa_model = CsaOdfModel(gtab, 6)
    if peak_processes == 1:
        parallel = False
    else:
        parallel = True
    if verbose:
        send_mail("Starting calculation of Constant solid angle model for subject " + subject,subject="CSA model start")

    wholemask = np.where(mask == 0, False, True)
    print(f"There are {peak_processes} and {parallel} here")
    csa_peaks = peaks_from_model(model=csa_model,
                                 data=data,
                                 sphere=peaks.default_sphere,  # issue with complete sphere
                                 mask=wholemask,
                                 relative_peak_threshold=.5,
                                 min_separation_angle=25,
                                 parallel=parallel,
                                 nbr_processes=peak_processes)

    duration = time() - t2
    if verbose:
        print(subject + ' CSA duration %.3f' % (duration,))

    t3 = time()


    if verbose:
        send_mail('Computing classifier for local tracking for subject ' + subject +
                  ',it has been ' + str(round(duration)) + 'seconds since the start of tractmaker',subject="Seed computation" )

        print('Computing classifier for local tracking for subject ' + subject)

    if masktype == "FA":
        #tensor_model = dti.TensorModel(gtab)
        #tenfit = tensor_model.fit(data, mask=labels > 0)
        #FA = fractional_anisotropy(tenfit.evals)
        FA_threshold = 0.05
        classifier = ThresholdStoppingCriterion(mask, FA_threshold)

        if figspath is not None:
            fig = plt.figure()
            mask_fa = mask.copy()
            mask_fa[mask_fa < FA_threshold] = 0
            plt.xticks([])
            plt.yticks([])
            plt.imshow(mask_fa[:, :, data.shape[2] // 2].T, cmap='gray', origin='lower',
                       interpolation='nearest')
            fig.tight_layout()
            fig.savefig(figspath + 'threshold_fa.png')
    else:
        classifier = BinaryStoppingCriterion(wholemask)

    # generates about 2 seeds per voxel
    # seeds = utils.random_seeds_from_mask(fa > .2, seeds_count=2,
    #                                      affine=np.eye(4))

    # generates about 2 million streamlines
    # seeds = utils.seeds_from_mask(fa > .2, density=1,
    #                              affine=np.eye(4))

    if verbose:
        print('Computing seeds')
    seeds = utils.seeds_from_mask(wholemask, density=1,
                                  affine=np.eye(4))

    #streamlines_generator = local_tracking.local_tracker(csa_peaks,classifier,seeds,affine=np.eye(4),step_size=step_size)
    if verbose:
        print('Computing the local tracking')
        duration = time() - t2
        send_mail('Start of the local tracking ' + ',it has been ' + str(round(duration)) +
                  'seconds since the start of tractmaker', subject="Seed computation")

    #stepsize = 2 #(by default)
    stringstep = str(step_size)
    stringstep = stringstep.replace(".", "_")
    if verbose:
        print("stringstep is "+stringstep)

    streamlines_generator = LocalTracking(csa_peaks, classifier,
                                          seeds, affine=np.eye(4), step_size=step_size)

    if verbose:
        duration = time() - t2
        txt = 'About to save streamlines at ' + outpathtrk + ',it has been ' + str(round(duration)) + \
              'seconds since the start of tractmaker',
        send_mail(txt,subject="Tract saving" )

    cutoff = 2
    if doprune:
        streamlines_generator = prune_streamlines(list(streamlines_generator), data[:, :, :, 0], cutoff=cutoff,
                                                  verbose=verbose)
        myheader = create_tractogram_header(outpathtrk, *header)
        sg = lambda: (s for i, s in enumerate(streamlines_generator) if i % ratio == 0)
        save_trk_heavy_duty(outpathtrk, streamlines=sg,
                            affine=affine, header=myheader,
                            shape=mask.shape, vox_size=vox_size)
    else:
        sg = lambda: (s for i, s in enumerate(streamlines_generator) if i % ratio == 0)
        myheader = create_tractogram_header(outpathtrk, *header)
        save_trk_heavy_duty(outpathtrk, streamlines=sg,
                            affine=affine, header=myheader,
                            shape=mask.shape, vox_size=vox_size)
    if verbose:
        duration = time() - t2
        txt = "Tract files were saved at "+outpathtrk + ',it has been ' + str(round(duration)) + \
              'seconds since the start of tractmaker'
        print(txt)
        send_mail(txt,subject="Tract saving" )

    # save everything - will generate a 20+ GBytes of data - hard to manipulate

    # possibly add parameter in csv file or other to decide whether to save large tractogram file
    # outpathfile=outpath+subject+"bmCSA_detr"+stringstep+".trk"
    # myheader=create_tractogram_header(outpathfile,*get_reference_info(fdwi))
    duration3 = time() - t2
    if verbose:
        print(duration3)
        print(subject + ' Tracking duration %.3f' % (duration3,))
        send_mail("Finished file save at "+outpathtrk+" with tracking duration of " + str(duration3) + "seconds",
                  subject="file save update" )

    if get_params:
        numtracts, minlength, maxlength, meanlength, stdlength = get_trk_params(streamlines_generator, verbose)
        params = [numtracts, minlength, maxlength, meanlength, stdlength]
        if verbose:
            print("For subject " + str(subject) + " the number of tracts is " + str(numtracts) + ", the minimum length is " +
                  str(minlength) + ", the maximum length is " + str(maxlength) + ", the mean length is " +
                  str(meanlength) + ", the std is " + str(stdlength))
    else:
        params = None

    return outpathtrk, streamlines_generator, params
コード例 #14
0
def test_affine_transformations():
    """This tests that the input affine is properly handled by
    LocalTracking and produces reasonable streamlines in a simple example.
    """
    sphere = HemiSphere.from_sphere(unit_octahedron)

    # A simple image with three possible configurations, a vertical tract,
    # a horizontal tract and a crossing
    pmf_lookup = np.array([[0., 0., 1.], [1., 0., 0.], [0., 1., 0.],
                           [.4, .6, 0.]])
    simple_image = np.array([
        [0, 0, 0, 0, 0, 0],
        [0, 1, 0, 0, 0, 0],
        [0, 3, 2, 2, 2, 0],
        [0, 1, 0, 0, 0, 0],
        [0, 0, 0, 0, 0, 0],
    ])

    simple_image = simple_image[..., None]
    pmf = pmf_lookup[simple_image]

    seeds = [np.array([1., 1., 0.]), np.array([2., 4., 0.])]

    expected = [
        np.array([[1., 1., 0.], [2., 1., 0.], [3., 1., 0.]]),
        np.array([[2., 1., 0.], [2., 2., 0.], [2., 3., 0.], [2., 4., 0.]])
    ]

    mask = (simple_image > 0).astype(float)
    sc = BinaryStoppingCriterion(mask)

    dg = DeterministicMaximumDirectionGetter.from_pmf(pmf,
                                                      60,
                                                      sphere,
                                                      pmf_threshold=0.1)

    # TST- bad affine wrong shape
    bad_affine = np.eye(3)
    npt.assert_raises(ValueError, LocalTracking, dg, sc, seeds, bad_affine, 1.)

    # TST - bad affine with shearing
    bad_affine = np.eye(4)
    bad_affine[0, 1] = 1.
    npt.assert_raises(ValueError, LocalTracking, dg, sc, seeds, bad_affine, 1.)

    # TST - bad seeds
    bad_seeds = 1000
    npt.assert_raises(ValueError, LocalTracking, dg, sc, bad_seeds, np.eye(4),
                      1.)

    # TST - identity
    a0 = np.eye(4)
    # TST - affines with positive/negative offsets
    a1 = np.eye(4)
    a1[:3, 3] = [1, 2, 3]
    a2 = np.eye(4)
    a2[:3, 3] = [-2, 0, -1]
    # TST - affine with scaling
    a3 = np.eye(4)
    a3[0, 0] = a3[1, 1] = a3[2, 2] = 8
    # TST - affine with axes inverting (negative value)
    a4 = np.eye(4)
    a4[1, 1] = a4[2, 2] = -1
    # TST - combined affines
    a5 = a1 + a2 + a3
    a5[3, 3] = 1
    # TST - in vivo affine example
    # Sometimes data have affines with tiny shear components.
    # For example, the small_101D data-set has some of that:
    fdata, _, _ = get_fnames('small_101D')
    a6 = nib.load(fdata).affine

    for affine in [a0, a1, a2, a3, a4, a5, a6]:
        lin = affine[:3, :3]
        offset = affine[:3, 3]
        seeds_trans = [np.dot(lin, s) + offset for s in seeds]

        # We compute the voxel size to adjust the step size to one voxel
        voxel_size = np.mean(np.sqrt(np.dot(lin, lin).diagonal()))

        streamlines = LocalTracking(direction_getter=dg,
                                    stopping_criterion=sc,
                                    seeds=seeds_trans,
                                    affine=affine,
                                    step_size=voxel_size,
                                    return_all=True)

        # We apply the inverse affine transformation to the generated
        # streamlines. It should be equals to the expected streamlines
        # (generated with the identity affine matrix).
        affine_inv = np.linalg.inv(affine)
        lin = affine_inv[:3, :3]
        offset = affine_inv[:3, 3]
        streamlines_inv = []
        for line in streamlines:
            streamlines_inv.append([np.dot(pts, lin) + offset for pts in line])

        npt.assert_equal(len(streamlines_inv[0]), len(expected[0]))
        npt.assert_(np.allclose(streamlines_inv[0], expected[0], atol=0.3))
        npt.assert_equal(len(streamlines_inv[1]), len(expected[1]))
        npt.assert_(np.allclose(streamlines_inv[1], expected[1], atol=0.3))
コード例 #15
0
def test_particle_filtering_tractography():
    """This tests that the ParticleFilteringTracking produces
    more streamlines connecting the gray matter than LocalTracking.
    """
    sphere = get_sphere('repulsion100')
    step_size = 0.2

    # Simple tissue masks
    simple_wm = np.array([[0, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0],
                          [0, 1, 1, 1, 0, 0], [0, 1, 1, 1, 0, 0],
                          [0, 0, 0, 0, 0, 0]])
    simple_wm = np.dstack([
        np.zeros(simple_wm.shape), simple_wm, simple_wm, simple_wm,
        np.zeros(simple_wm.shape)
    ])
    simple_gm = np.array([[1, 1, 0, 0, 0, 0], [1, 1, 0, 0, 0, 0],
                          [0, 1, 0, 0, 1, 0], [0, 0, 0, 0, 1, 0],
                          [0, 0, 0, 0, 0, 0]])
    simple_gm = np.dstack([
        np.zeros(simple_gm.shape), simple_gm, simple_gm, simple_gm,
        np.zeros(simple_gm.shape)
    ])
    simple_csf = np.ones(simple_wm.shape) - simple_wm - simple_gm

    sc = ActStoppingCriterion.from_pve(simple_wm, simple_gm, simple_csf)
    seeds = seeds_from_mask(simple_wm, np.eye(4), density=2)

    # Random pmf in every voxel
    shape_img = list(simple_wm.shape)
    shape_img.extend([sphere.vertices.shape[0]])
    np.random.seed(0)  # Random number generator initialization
    pmf = np.random.random(shape_img)

    # Test that PFT recover equal or more streamlines than localTracking
    dg = ProbabilisticDirectionGetter.from_pmf(pmf, 60, sphere)
    local_streamlines_generator = LocalTracking(dg,
                                                sc,
                                                seeds,
                                                np.eye(4),
                                                step_size,
                                                max_cross=1,
                                                return_all=False)
    local_streamlines = Streamlines(local_streamlines_generator)

    pft_streamlines_generator = ParticleFilteringTracking(
        dg,
        sc,
        seeds,
        np.eye(4),
        step_size,
        max_cross=1,
        return_all=False,
        pft_back_tracking_dist=1,
        pft_front_tracking_dist=0.5)
    pft_streamlines = Streamlines(pft_streamlines_generator)

    npt.assert_(np.array([len(pft_streamlines) > 0]))
    npt.assert_(np.array([len(pft_streamlines) >= len(local_streamlines)]))

    # Test that all points are equally spaced
    for l in [1, 2, 5, 10, 100]:
        pft_streamlines = ParticleFilteringTracking(dg,
                                                    sc,
                                                    seeds,
                                                    np.eye(4),
                                                    step_size,
                                                    max_cross=1,
                                                    return_all=True,
                                                    maxlen=l)
        for s in pft_streamlines:
            for i in range(len(s) - 1):
                npt.assert_almost_equal(np.linalg.norm(s[i] - s[i + 1]),
                                        step_size)
    # Test that all points are within the image volume
    seeds = seeds_from_mask(np.ones(simple_wm.shape), np.eye(4), density=1)
    pft_streamlines_generator = ParticleFilteringTracking(dg,
                                                          sc,
                                                          seeds,
                                                          np.eye(4),
                                                          step_size,
                                                          max_cross=1,
                                                          return_all=True)
    pft_streamlines = Streamlines(pft_streamlines_generator)

    for s in pft_streamlines:
        npt.assert_(np.all((s + 0.5).astype(int) >= 0))
        npt.assert_(np.all((s + 0.5).astype(int) < simple_wm.shape))

    # Test that the number of streamline return with return_all=True equal the
    # number of seeds places
    npt.assert_(np.array([len(pft_streamlines) == len(seeds)]))

    # Test non WM seed position
    seeds = [[0, 5, 4], [0, 0, 1], [50, 50, 50]]
    pft_streamlines_generator = ParticleFilteringTracking(dg,
                                                          sc,
                                                          seeds,
                                                          np.eye(4),
                                                          step_size,
                                                          max_cross=1,
                                                          return_all=True)
    pft_streamlines = Streamlines(pft_streamlines_generator)

    npt.assert_equal(len(pft_streamlines[0]), 3)  # INVALIDPOINT
    npt.assert_equal(len(pft_streamlines[1]), 3)  # ENDPOINT
    npt.assert_equal(len(pft_streamlines[2]), 1)  # OUTSIDEIMAGE

    # Test with wrong StoppingCriterion type
    sc_bin = BinaryStoppingCriterion(simple_wm)
    npt.assert_raises(
        ValueError, lambda: ParticleFilteringTracking(dg, sc_bin, seeds,
                                                      np.eye(4), step_size))
    # Test with invalid back/front tracking distances
    npt.assert_raises(
        ValueError,
        lambda: ParticleFilteringTracking(dg,
                                          sc,
                                          seeds,
                                          np.eye(4),
                                          step_size,
                                          pft_back_tracking_dist=0,
                                          pft_front_tracking_dist=0))
    npt.assert_raises(
        ValueError, lambda: ParticleFilteringTracking(
            dg, sc, seeds, np.eye(4), step_size, pft_back_tracking_dist=-1))
    npt.assert_raises(
        ValueError,
        lambda: ParticleFilteringTracking(dg,
                                          sc,
                                          seeds,
                                          np.eye(4),
                                          step_size,
                                          pft_back_tracking_dist=0,
                                          pft_front_tracking_dist=-2))

    # Test with invalid affine shape
    npt.assert_raises(
        ValueError,
        lambda: ParticleFilteringTracking(dg, sc, seeds, np.eye(3), step_size))

    # Test with invalid maxlen
    npt.assert_raises(
        ValueError, lambda: ParticleFilteringTracking(
            dg, sc, seeds, np.eye(4), step_size, maxlen=0))
    npt.assert_raises(
        ValueError, lambda: ParticleFilteringTracking(
            dg, sc, seeds, np.eye(4), step_size, maxlen=-1))

    # Test with invalid particle count
    npt.assert_raises(
        ValueError, lambda: ParticleFilteringTracking(
            dg, sc, seeds, np.eye(4), step_size, particle_count=0))
    npt.assert_raises(
        ValueError, lambda: ParticleFilteringTracking(
            dg, sc, seeds, np.eye(4), step_size, particle_count=-1))

    # Test reproducibility
    tracking1 = Streamlines(
        ParticleFilteringTracking(dg,
                                  sc,
                                  seeds,
                                  np.eye(4),
                                  step_size,
                                  random_seed=0))._data
    tracking2 = Streamlines(
        ParticleFilteringTracking(dg,
                                  sc,
                                  seeds,
                                  np.eye(4),
                                  step_size,
                                  random_seed=0))._data
    npt.assert_equal(tracking1, tracking2)
コード例 #16
0
def prep_tissues(t1_mask, gm_in_dwi, vent_csf_in_dwi, wm_in_dwi, tiss_class, cmc_step_size=0.2):
    """
    Estimate a tissue classifier for tractography.

    Parameters
    ----------
    t1_mask : str
        File path to a T1w mask.
    gm_in_dwi : str
        File path to grey-matter tissue segmentation Nifti1Image.
    vent_csf_in_dwi : str
        File path to ventricular CSF tissue segmentation Nifti1Image.
    wm_in_dwi : str
        File path to white-matter tissue segmentation Nifti1Image.
    tiss_class : str
        Tissue classification method.
    cmc_step_size : float
        Step size from CMC tissue classification method.

    Returns
    -------
    tiss_classifier : obj
        Tissue classifier object.

    References
    ----------
    .. [1] Zhang, Y., Brady, M. and Smith, S. Segmentation of Brain MR Images
      Through a Hidden Markov Random Field Model and the Expectation-Maximization
      Algorithm IEEE Transactions on Medical Imaging, 20(1): 45-56, 2001
    .. [2] Avants, B. B., Tustison, N. J., Wu, J., Cook, P. A. and Gee, J. C.
      An open source multivariate framework for n-tissue segmentation with
      evaluation on public data. Neuroinformatics, 9(4): 381-400, 2011.

    """
    try:
        import cPickle as pickle
    except ImportError:
        import _pickle as pickle
    from dipy.tracking.stopping_criterion import ActStoppingCriterion, CmcStoppingCriterion, BinaryStoppingCriterion
    from nilearn.masking import intersect_masks
    from nilearn.image import math_img

    # Loads mask
    mask_img = nib.load(t1_mask)
    # Load tissue maps and prepare tissue classifier
    wm_img = nib.load(wm_in_dwi)
    gm_img = nib.load(gm_in_dwi)
    gm_mask_data = np.asarray(gm_img.dataobj)
    wm_mask_data = np.asarray(wm_img.dataobj)
    vent_csf_in_dwi_data = np.asarray(nib.load(vent_csf_in_dwi).dataobj)
    if tiss_class == 'act':
        background = np.ones(mask_img.shape)
        background[(gm_mask_data + wm_mask_data + vent_csf_in_dwi_data) > 0] = 0
        gm_mask_data[background > 0] = 1
        tiss_classifier = ActStoppingCriterion(gm_mask_data, vent_csf_in_dwi_data)
        del background
    elif tiss_class == 'bin':
        tiss_classifier = BinaryStoppingCriterion(np.asarray(intersect_masks([math_img('img > 0.0', img=mask_img),
                                                                              math_img('img > 0.0', img=wm_img)],
                                                                             threshold=1, connected=False).dataobj))
    elif tiss_class == 'cmc':
        voxel_size = np.average(mask_img.header['pixdim'][1:4])
        tiss_classifier = CmcStoppingCriterion.from_pve(wm_mask_data, gm_mask_data, vent_csf_in_dwi_data,
                                                        step_size=cmc_step_size, average_voxel_size=voxel_size)
    elif tiss_class == 'wb':
        tiss_classifier = BinaryStoppingCriterion(np.asarray(mask_img.dataobj).astype('bool'))
    else:
        raise ValueError('Tissue classifier cannot be none.')

    del gm_mask_data, wm_mask_data, vent_csf_in_dwi_data
    mask_img.uncache()
    gm_img.uncache()
    wm_img.uncache()

    return tiss_classifier
コード例 #17
0
def main():
    parser = _build_arg_parser()
    args = parser.parse_args()

    if args.verbose:
        logging.basicConfig(level=logging.DEBUG)

    assert_inputs_exist(parser, [args.sh_file, args.seed_file, args.mask_file])
    assert_outputs_exist(parser, args, args.output_file)

    if not nib.streamlines.is_supported(args.output_file):
        parser.error('Invalid output streamline file format (must be trk or ' +
                     'tck): {0}'.format(args.output_file))

    if not args.min_length > 0:
        parser.error('minL must be > 0, {}mm was provided.'.format(
            args.min_length))
    if args.max_length < args.min_length:
        parser.error(
            'maxL must be > than minL, (minL={}mm, maxL={}mm).'.format(
                args.min_length, args.max_length))

    if args.compress:
        if args.compress < 0.001 or args.compress > 1:
            logging.warning(
                'You are using an error rate of {}.\nWe recommend setting it '
                'between 0.001 and 1.\n0.001 will do almost nothing to the '
                'tracts while 1 will higly compress/linearize the tracts'.
                format(args.compress))

    if args.npv and args.npv <= 0:
        parser.error('Number of seeds per voxel must be > 0.')

    if args.nt and args.nt <= 0:
        parser.error('Total number of seeds must be > 0.')

    mask_img = nib.load(args.mask_file)
    mask_data = mask_img.get_fdata()

    # Make sure the mask is isotropic. Else, the strategy used
    # when providing information to dipy (i.e. working as if in voxel space)
    # will not yield correct results.
    fodf_sh_img = nib.load(args.sh_file)
    if not np.allclose(np.mean(fodf_sh_img.header.get_zooms()[:3]),
                       fodf_sh_img.header.get_zooms()[0],
                       atol=1.e-3):
        parser.error(
            'SH file is not isotropic. Tracking cannot be ran robustly.')

    if args.npv:
        nb_seeds = args.npv
        seed_per_vox = True
    elif args.nt:
        nb_seeds = args.nt
        seed_per_vox = False
    else:
        nb_seeds = 1
        seed_per_vox = True

    voxel_size = fodf_sh_img.header.get_zooms()[0]
    vox_step_size = args.step_size / voxel_size
    seed_img = nib.load(args.seed_file)
    seeds = track_utils.random_seeds_from_mask(
        seed_img.get_fdata(),
        np.eye(4),
        seeds_count=nb_seeds,
        seed_count_per_voxel=seed_per_vox,
        random_seed=args.seed)

    # Tracking is performed in voxel space
    max_steps = int(args.max_length / args.step_size) + 1
    streamlines = LocalTracking(_get_direction_getter(args, mask_data),
                                BinaryStoppingCriterion(mask_data),
                                seeds,
                                np.eye(4),
                                step_size=vox_step_size,
                                max_cross=1,
                                maxlen=max_steps,
                                fixedstep=True,
                                return_all=True,
                                random_seed=args.seed,
                                save_seeds=args.save_seeds)

    scaled_min_length = args.min_length / voxel_size
    scaled_max_length = args.max_length / voxel_size

    if args.save_seeds:
        filtered_streamlines, seeds = \
            zip(*((s, p) for s, p in streamlines
                  if scaled_min_length <= length(s) <= scaled_max_length))
        data_per_streamlines = {'seeds': lambda: seeds}
    else:
        filtered_streamlines = \
            (s for s in streamlines
             if scaled_min_length <= length(s) <= scaled_max_length)
        data_per_streamlines = {}

    if args.compress:
        filtered_streamlines = (compress_streamlines(s, args.compress)
                                for s in filtered_streamlines)

    tractogram = LazyTractogram(lambda: filtered_streamlines,
                                data_per_streamlines,
                                affine_to_rasmm=seed_img.affine)

    filetype = nib.streamlines.detect_format(args.output_file)
    header = create_header_from_anat(seed_img, base_filetype=filetype)

    # Use generator to save the streamlines on-the-fly
    nib.streamlines.save(tractogram, args.output_file, header=header)
コード例 #18
0
def main():
    parser = _build_arg_parser()
    args = parser.parse_args()

    if args.verbose:
        logging.basicConfig(level=logging.DEBUG)

    assert_inputs_exist(parser, [args.in_odf, args.in_seed, args.in_mask])
    assert_outputs_exist(parser, args, args.out_tractogram)

    if not nib.streamlines.is_supported(args.out_tractogram):
        parser.error('Invalid output streamline file format (must be trk or ' +
                     'tck): {0}'.format(args.out_tractogram))

    verify_streamline_length_options(parser, args)
    verify_compression_th(args.compress)
    verify_seed_options(parser, args)

    mask_img = nib.load(args.in_mask)
    mask_data = get_data_as_mask(mask_img, dtype=bool)

    # Make sure the data is isotropic. Else, the strategy used
    # when providing information to dipy (i.e. working as if in voxel space)
    # will not yield correct results.
    odf_sh_img = nib.load(args.in_odf)
    if not np.allclose(np.mean(odf_sh_img.header.get_zooms()[:3]),
                       odf_sh_img.header.get_zooms()[0], atol=1e-03):
        parser.error(
            'ODF SH file is not isotropic. Tracking cannot be ran robustly.')

    if args.npv:
        nb_seeds = args.npv
        seed_per_vox = True
    elif args.nt:
        nb_seeds = args.nt
        seed_per_vox = False
    else:
        nb_seeds = 1
        seed_per_vox = True

    voxel_size = odf_sh_img.header.get_zooms()[0]
    vox_step_size = args.step_size / voxel_size
    seed_img = nib.load(args.in_seed)
    seeds = track_utils.random_seeds_from_mask(
        seed_img.get_fdata(dtype=np.float32),
        np.eye(4),
        seeds_count=nb_seeds,
        seed_count_per_voxel=seed_per_vox,
        random_seed=args.seed)

    # Tracking is performed in voxel space
    max_steps = int(args.max_length / args.step_size) + 1
    streamlines_generator = LocalTracking(
        _get_direction_getter(args),
        BinaryStoppingCriterion(mask_data),
        seeds, np.eye(4),
        step_size=vox_step_size, max_cross=1,
        maxlen=max_steps,
        fixedstep=True, return_all=True,
        random_seed=args.seed,
        save_seeds=args.save_seeds)

    scaled_min_length = args.min_length / voxel_size
    scaled_max_length = args.max_length / voxel_size

    if args.save_seeds:
        filtered_streamlines, seeds = \
            zip(*((s, p) for s, p in streamlines_generator
                  if scaled_min_length <= length(s) <= scaled_max_length))
        data_per_streamlines = {'seeds': lambda: seeds}
    else:
        filtered_streamlines = \
            (s for s in streamlines_generator
             if scaled_min_length <= length(s) <= scaled_max_length)
        data_per_streamlines = {}

    if args.compress:
        filtered_streamlines = (
            compress_streamlines(s, args.compress)
            for s in filtered_streamlines)

    tractogram = LazyTractogram(lambda: filtered_streamlines,
                                data_per_streamlines,
                                affine_to_rasmm=seed_img.affine)

    filetype = nib.streamlines.detect_format(args.out_tractogram)
    reference = get_reference_info(seed_img)
    header = create_tractogram_header(filetype, *reference)

    # Use generator to save the streamlines on-the-fly
    nib.streamlines.save(tractogram, args.out_tractogram, header=header)
コード例 #19
0
def test_bootstap_peak_tracker():
    """This tests that the Bootstrat Peak Direction Getter plays nice
    LocalTracking and produces reasonable streamlines in a simple example.
    """
    sphere = get_sphere('repulsion100')

    # A simple image with three possible configurations, a vertical tract,
    # a horizontal tract and a crossing
    simple_image = np.array([
        [0, 1, 0, 0, 0, 0],
        [0, 1, 0, 0, 0, 0],
        [2, 3, 2, 2, 2, 0],
        [0, 1, 0, 0, 0, 0],
        [0, 1, 0, 0, 0, 0],
    ])
    simple_image = simple_image[..., None]

    bvecs = sphere.vertices
    bvals = np.ones(len(bvecs)) * 1000
    bvecs = np.insert(bvecs, 0, np.array([0, 0, 0]), axis=0)
    bvals = np.insert(bvals, 0, 0)
    gtab = gradient_table(bvals, bvecs)
    angles = [(90, 90), (90, 0)]
    fracs = [50, 50]
    mevals = np.array([[1.5, 0.4, 0.4], [1.5, 0.4, 0.4]]) * 1e-3
    mevecs = [
        np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]]),
        np.array([[0, 1, 0], [1, 0, 0], [0, 0, 1]])
    ]
    voxel1 = single_tensor(gtab, 1, mevals[0], mevecs[0], snr=None)
    voxel2 = single_tensor(gtab, 1, mevals[0], mevecs[1], snr=None)
    voxel3, _ = multi_tensor(gtab,
                             mevals,
                             fractions=fracs,
                             angles=angles,
                             snr=None)
    data = np.tile(voxel3, [5, 6, 1, 1])
    data[simple_image == 1] = voxel1
    data[simple_image == 2] = voxel2

    response = (np.array(mevals[1]), 1)
    csd_model = ConstrainedSphericalDeconvModel(gtab, response, sh_order=6)

    seeds = [np.array([0., 1., 0.]), np.array([2., 4., 0.])]

    sc = BinaryStoppingCriterion((simple_image > 0).astype(float))
    sphere = HemiSphere.from_sphere(get_sphere('symmetric724'))
    boot_dg = BootDirectionGetter.from_data(data, csd_model, 60, sphere=sphere)

    streamlines_generator = LocalTracking(boot_dg, sc, seeds, np.eye(4), 1.)
    streamlines = Streamlines(streamlines_generator)
    expected = [
        np.array([[0., 1., 0.], [1., 1., 0.], [2., 1., 0.], [3., 1., 0.],
                  [4., 1., 0.]]),
        np.array([
            [2., 4., 0.],
            [2., 3., 0.],
            [2., 2., 0.],
            [2., 1., 0.],
            [2., 0., 0.],
        ])
    ]

    def allclose(x, y):
        return x.shape == y.shape and np.allclose(x, y, atol=0.5)

    if not allclose(streamlines[0], expected[0]):
        raise AssertionError()
    if not allclose(streamlines[1], expected[1]):
        raise AssertionError()
コード例 #20
0
def tracking(shm_file, mask_file, outdir, force_overwrite, particles,
             step_size, max_lenght, max_angle, algorithm, wpid_seeds_info):
    ''' Tracking function that will run in parallel

        Params:
            shm_file: SHM file computed from the dwi file
            mask_file: mask were to perform tractography
            outdir: Directory were to save streamlines
            force_overwrite: if True, existing files will be overwriten
            step_size: size in mm of each step in the tracking
            max_lenght: maximum lenght of each streamline
            max_angle: maximum angle at each step of tracking
            algoright: either 'probabilistic' or 'deterministic'
            wpid_seeds_info: tuple which contains:
                - wpid: The id of this worker
                - seeds: One list for each seed with points to track from
                - info: CIFTI information for each seed:
                    -mtype: A valid CIFTI MODELTYPE
                    -name: A valid CIFTI BRAINSTRUCTURE
                    -coord: Voxel or vertex to which the seed makes reference
                    -size: size of the CIFTI SURFACE (if applies)
        Returns:
            list of streamlines '''
    import citrix
    import streamlines as sl

    from dipy.data import default_sphere
    from dipy.tracking.local_tracking import LocalTracking
    from dipy.tracking.stopping_criterion import BinaryStoppingCriterion

    wpid, (seeds, cifti_info) = wpid_seeds_info

    logging.debug("Worker {} started".format(wpid))

    # Check if file exists
    outfile = os.path.join(outdir, "stream_{}.trk".format(wpid))

    if os.path.isfile(outfile) and not force_overwrite:
        print("File already exists, use the -f flag to overwrite it")
        return

    shm = citrix.load(shm_file)
    shm_data = shm.get_data()

    mask_nib = citrix.load(mask_file)
    mask = mask_nib.get_data()

    if algorithm == 'deterministic':
        directions = deterministic.from_shcoeff(shm_data, max_angle,
                                                default_sphere)
    else:
        directions = probabilistic.from_shcoeff(shm_data, max_angle,
                                                default_sphere)

    stop_criterion = BinaryStoppingCriterion(mask)

    percent = max(1, len(seeds) / 5)
    streamlines = []
    used_seeds = []

    for i, s in enumerate(seeds):
        if i % percent == 0:
            logging.debug("{}, {}/{} seeds".format(wpid, i, len(seeds)))

        # Repeat the seeds as long as needed
        if len(s) == 3:
            # It's one point
            s = [s]

        repeated_seeds = [ss for ss in s for _ in range(2 * particles)]

        res = LocalTracking(directions,
                            stop_criterion,
                            repeated_seeds,
                            shm.affine,
                            step_size=step_size,
                            maxlen=max_lenght,
                            return_all=False)

        for streamline in itertools.islice(res, particles * len(s)):
            if streamline is not None and len(streamline) > 1:
                streamlines.append(streamline)

            if cifti_info[i][0] == 'CIFTI_MODEL_TYPE_SURFACE':
                used_seeds.append(cifti_info[i][2])
            else:
                used_seeds.append([int(cf) for cf in cifti_info[i][2]])

    streamlines = sl.Streamlines(streamlines, shm.affine, shm.shape[:3],
                                 shm.header.get_zooms()[:3])

    numpy.savetxt(os.path.join(outdir, "info_{}.txt".format(wpid)), used_seeds)

    sl.io.save(streamlines, outfile)

    logging.debug("Worker {} finished".format(wpid))
    return
コード例 #21
0
- mask: numpy array [:, :, :]

**Stopping States**

- 'ENDPOINT': stops at a position where mask = 0; the streamline
reached the target stopping area.
- 'OUTSIDEIMAGE': stops at a position outside of metric_map; the streamline
reached an area outside the image where no direction data is available.
- 'TRACKPOINT': stops at a position because no direction is available; the
streamline is stopping where mask > 0, but there is no valid direction to
follow.
- 'INVALIDPOINT': N/A.
"""

binary_criterion = BinaryStoppingCriterion(white_matter == 1)

fig = plt.figure()
plt.xticks([])
plt.yticks([])
fig.tight_layout()
plt.imshow(white_matter[:, :, data.shape[2] // 2].T,
           cmap='gray',
           origin='lower',
           interpolation='nearest')

fig.savefig('white_matter_mask.png')
"""
.. figure:: white_matter_mask.png
 :align: center
コード例 #22
0
def prep_tissues(t1_mask,
                 gm_in_dwi,
                 vent_csf_in_dwi,
                 wm_in_dwi,
                 tiss_class,
                 cmc_step_size=0.2):
    """
    Estimate a tissue classifier for tractography.

    Parameters
    ----------
    t1_mask : str
        File path to a T1w mask.
    gm_in_dwi : str
        File path to grey-matter tissue segmentation Nifti1Image.
    vent_csf_in_dwi : str
        File path to ventricular CSF tissue segmentation Nifti1Image.
    wm_in_dwi : str
        File path to white-matter tissue segmentation Nifti1Image.
    tiss_class : str
        Tissue classification method.
    cmc_step_size : float
        Step size from CMC tissue classification method.

    Returns
    -------
    tiss_classifier : obj
        Tissue classifier object.
    """
    try:
        import cPickle as pickle
    except ImportError:
        import _pickle as pickle
    from dipy.tracking.stopping_criterion import ActStoppingCriterion, CmcStoppingCriterion, BinaryStoppingCriterion
    from nilearn.masking import intersect_masks
    from nilearn.image import math_img

    # Loads mask
    mask_img = nib.load(t1_mask)
    # Load tissue maps and prepare tissue classifier
    wm_img = nib.load(wm_in_dwi)
    gm_img = nib.load(gm_in_dwi)
    gm_mask_data = np.asarray(gm_img.dataobj)
    wm_mask_data = np.asarray(wm_img.dataobj)
    vent_csf_in_dwi_data = np.asarray(nib.load(vent_csf_in_dwi).dataobj)
    if tiss_class == 'act':
        background = np.ones(mask_img.shape)
        background[(gm_mask_data + wm_mask_data +
                    vent_csf_in_dwi_data) > 0] = 0
        gm_mask_data[background > 0] = 1
        tiss_classifier = ActStoppingCriterion(gm_mask_data,
                                               vent_csf_in_dwi_data)
        del background
    elif tiss_class == 'bin':
        tiss_classifier = BinaryStoppingCriterion(
            np.asarray(
                intersect_masks([
                    math_img('img > 0.0', img=mask_img),
                    math_img('img > 0.0', img=wm_img)
                ],
                                threshold=1,
                                connected=False).dataobj))
    elif tiss_class == 'cmc':
        voxel_size = np.average(mask_img.header['pixdim'][1:4])
        tiss_classifier = CmcStoppingCriterion.from_pve(
            wm_mask_data,
            gm_mask_data,
            vent_csf_in_dwi_data,
            step_size=cmc_step_size,
            average_voxel_size=voxel_size)
    elif tiss_class == 'wb':
        tiss_classifier = BinaryStoppingCriterion(
            np.asarray(mask_img.dataobj).astype('bool'))
    else:
        raise ValueError('Tissue Classifier cannot be none.')

    del gm_mask_data, wm_mask_data, vent_csf_in_dwi_data
    mask_img.uncache()
    gm_img.uncache()
    wm_img.uncache()

    return tiss_classifier