Exemple #1
0
    def gen_tissue(self, wm_mask_existing, gm_mask_existing, overwrite):
        """
        A function to segment and threshold tissue types from T1w.
        """
        import time

        # Segment the t1w brain into probability maps
        if (
            wm_mask_existing is not None
            and gm_mask_existing is not None
            and overwrite is False
        ):
            print("Existing segmentations detected...")
            gm_mask = regutils.check_orient_and_dims(
                gm_mask_existing, self.basedir_path, self.vox_size,
                overwrite=False)
            wm_mask = regutils.check_orient_and_dims(
                wm_mask_existing, self.basedir_path, self.vox_size,
                overwrite=False)
        else:
            try:
                maps = regutils.segment_t1w(self.t1w_brain, self.map_name)
                gm_mask = maps["gm_prob"]
                wm_mask = maps["wm_prob"]
            except RuntimeError as e:
                import sys
                print(e,
                    "Segmentation failed. Does the input anatomical image "
                    "still contained skull?"
                )
                sys.exit(1)

        # Threshold GM to binary in func space
        t_img = nib.load(gm_mask)
        mask = math_img("img > 0.01", img=t_img)
        mask.to_filename(self.gm_mask_thr)
        self.gm_mask = regutils.apply_mask_to_image(gm_mask,
                                                    self.gm_mask_thr,
                                                    self.gm_mask)
        time.sleep(0.5)
        # Threshold WM to binary in dwi space
        t_img = nib.load(wm_mask)
        mask = math_img("img > 0.50", img=t_img)
        mask.to_filename(self.wm_mask_thr)
        time.sleep(0.5)
        self.wm_mask = regutils.apply_mask_to_image(wm_mask,
                                                    self.wm_mask_thr,
                                                    self.wm_mask)
        # Extract wm edge
        time.sleep(0.5)
        self.wm_edge = regutils.get_wm_contour(wm_mask, self.wm_mask_thr,
                                               self.wm_edge)

        return
Exemple #2
0
def waymask2dwi_align(
    waymask,
    t1w_brain,
    ap_path,
    mni2t1w_warp,
    mni2t1_xfm,
    t1wtissue2dwi_xfm,
    waymask_in_t1w,
    waymask_in_dwi,
    B0_mask_tmp_path,
    template,
    simple,
):
    """
    A function to perform alignment of a waymask from
    MNI space --> T1w --> dwi.
    """
    import time
    from pynets.registration import reg_utils as regutils
    from nilearn.image import resample_to_img

    # Apply warp or transformer resulting from the inverse MNI->T1w created
    # earlier
    waymask_img = nib.load(waymask)
    template_img = nib.load(template)

    waymask_img_res = resample_to_img(
        waymask_img,
        template_img,
    )
    waymask_res = f"{waymask.split('.nii')[0]}_res.nii.gz"
    nib.save(waymask_img_res, waymask_res)

    if simple is False:
        regutils.apply_warp(t1w_brain,
                            waymask_res,
                            waymask_in_t1w,
                            warp=mni2t1w_warp)
    else:
        regutils.applyxfm(t1w_brain, waymask_res, mni2t1_xfm, waymask_in_t1w)

    time.sleep(0.5)
    # Apply transform from t1w to native dwi space
    regutils.applyxfm(ap_path, waymask_in_t1w, t1wtissue2dwi_xfm,
                      waymask_in_dwi)

    time.sleep(0.5)

    waymask_in_dwi = regutils.apply_mask_to_image(waymask_in_dwi,
                                                  B0_mask_tmp_path,
                                                  waymask_in_dwi)

    return waymask_in_dwi
Exemple #3
0
def gen_mask(t1w_head, t1w_brain, mask):
    import time
    import os.path as op
    from pynets.registration import reg_utils as regutils
    from nilearn.image import math_img

    t1w_brain_mask = f"{op.dirname(t1w_head)}/t1w_brain_mask.nii.gz"

    img = nib.load(t1w_head)

    if mask is not None and op.isfile(mask):
        from nilearn.image import resample_to_img

        print(f"Using {mask}...")
        mask_img = nib.load(mask)
        nib.save(resample_to_img(mask_img, img), t1w_brain_mask)
    else:
        # Perform skull-stripping if mask not provided.
        img = nib.load(t1w_head)
        t1w_data = img.get_fdata().astype('float32')
        try:
            t1w_brain_mask = deep_skull_strip(t1w_data, t1w_brain_mask, img)
        except RuntimeError:
            try:
                print('Deepbrain extraction failed...')
            except ValueError:
                import sys
                sys.exit(1)
        del t1w_data

    # Threshold T1w brain to binary in anat space
    t_img = nib.load(t1w_brain_mask)
    img = math_img("img > 0.0", img=t_img)
    img.to_filename(t1w_brain_mask)
    t_img.uncache()
    time.sleep(0.5)

    t1w_brain = regutils.apply_mask_to_image(t1w_head, t1w_brain_mask,
                                             t1w_brain)
    time.sleep(0.5)

    assert op.isfile(t1w_brain)
    assert op.isfile(t1w_brain_mask)

    return t1w_brain, t1w_brain_mask
Exemple #4
0
    def tissue2dwi_align(self):
        """
        A function to perform alignment of ventricle ROI's from MNI
        space --> dwi and CSF from T1w space --> dwi. First generates and
        performs dwi space alignment of avoidance/waypoint masks for
        tractography. First creates ventricle ROI. Then creates transforms
        from stock MNI template to dwi space. For this to succeed, must first
        have called both t1w2dwi_align.
        """
        import sys
        import time
        import os.path as op

        # Register Lateral Ventricles and Corpus Callosum rois to t1w
        if not op.isfile(self.mni_atlas):
            raise FileNotFoundError("FSL atlas for ventricle reference not"
                                    " found!")

        # Create transform to MNI atlas to T1w using flirt. This will be use to
        # transform the ventricles to dwi space.
        regutils.align(
            self.mni_atlas,
            self.input_mni_brain,
            xfm=self.xfm_roi2mni_init,
            init=None,
            bins=None,
            dof=6,
            cost="mutualinfo",
            searchrad=True,
            interp="spline",
            out=None,
        )
        time.sleep(0.5)

        if sys.platform.startswith('win') is False:
            try:
                nib.load(self.mni_vent_loc)
            except indexed_gzip.ZranError as e:
                print(e,
                      f"\nCannot load ventricle ROI. Do you have git-lfs "
                      f"installed?")
                sys.exit(1)
        else:
            try:
                nib.load(self.mni_vent_loc)
            except ImportError as e:
                print(e, f"\nCannot load ventricle ROI. Do you have git-lfs "
                      f"installed?")
                sys.exit(1)

        # Create transform to align roi to mni and T1w using flirt
        regutils.applyxfm(
            self.input_mni_brain,
            self.mni_vent_loc,
            self.xfm_roi2mni_init,
            self.vent_mask_mni,
        )
        time.sleep(0.5)
        if self.simple is False:
            # Apply warp resulting from the inverse MNI->T1w created earlier
            regutils.apply_warp(
                self.t1w_brain,
                self.vent_mask_mni,
                self.vent_mask_t1w,
                warp=self.mni2t1w_warp,
                interp="nn",
                sup=True,
            )
            time.sleep(0.5)

            if sys.platform.startswith('win') is False:
                try:
                    nib.load(self.corpuscallosum)
                except indexed_gzip.ZranError as e:
                    print(e,
                          f"\nCannot load Corpus Callosum ROI. "
                          f"Do you have git-lfs installed?")
                    sys.exit(1)
            else:
                try:
                    nib.load(self.corpuscallosum)
                except ImportError as e:
                    print(e, f"\nCannot load Corpus Callosum ROI. "
                          f"Do you have git-lfs installed?")
                    sys.exit(1)

            regutils.apply_warp(
                self.t1w_brain,
                self.corpuscallosum,
                self.corpuscallosum_mask_t1w,
                warp=self.mni2t1w_warp,
                interp="nn",
                sup=True,
            )

        else:
            regutils.applyxfm(
                self.vent_mask_mni,
                self.t1w_brain,
                self.mni2t1_xfm,
                self.vent_mask_t1w)
            time.sleep(0.5)
            regutils.applyxfm(
                self.corpuscallosum,
                self.t1w_brain,
                self.mni2t1_xfm,
                self.corpuscallosum_mask_t1w,
            )
            time.sleep(0.5)

        # Applyxfm tissue maps to dwi space
        if self.t1w_brain_mask is not None:
            regutils.applyxfm(
                self.ap_path,
                self.t1w_brain_mask,
                self.t1wtissue2dwi_xfm,
                self.t1w_brain_mask_in_dwi,
            )
            time.sleep(0.5)
        regutils.applyxfm(
            self.ap_path,
            self.vent_mask_t1w,
            self.t1wtissue2dwi_xfm,
            self.vent_mask_dwi)
        time.sleep(0.5)
        regutils.applyxfm(
            self.ap_path,
            self.csf_mask,
            self.t1wtissue2dwi_xfm,
            self.csf_mask_dwi)
        time.sleep(0.5)
        regutils.applyxfm(
            self.ap_path, self.gm_mask, self.t1wtissue2dwi_xfm, self.gm_in_dwi
        )
        time.sleep(0.5)
        regutils.applyxfm(
            self.ap_path, self.wm_mask, self.t1wtissue2dwi_xfm, self.wm_in_dwi
        )
        time.sleep(0.5)

        regutils.applyxfm(
            self.ap_path,
            self.corpuscallosum_mask_t1w,
            self.t1wtissue2dwi_xfm,
            self.corpuscallosum_dwi,
        )
        time.sleep(0.5)

        # Threshold WM to binary in dwi space
        thr_img = nib.load(self.wm_in_dwi)
        thr_img = math_img("img > 0.10", img=thr_img)
        nib.save(thr_img, self.wm_in_dwi_bin)

        # Threshold GM to binary in dwi space
        thr_img = nib.load(self.gm_in_dwi)
        thr_img = math_img("img > 0.15", img=thr_img)
        nib.save(thr_img, self.gm_in_dwi_bin)

        # Threshold CSF to binary in dwi space
        thr_img = nib.load(self.csf_mask_dwi)
        thr_img = math_img("img > 0.95", img=thr_img)
        nib.save(thr_img, self.csf_mask_dwi_bin)

        # Threshold WM to binary in dwi space
        self.wm_in_dwi = regutils.apply_mask_to_image(self.wm_in_dwi,
                                                      self.wm_in_dwi_bin,
                                                      self.wm_in_dwi)
        time.sleep(0.5)
        # Threshold GM to binary in dwi space
        self.gm_in_dwi = regutils.apply_mask_to_image(self.gm_in_dwi,
                                                      self.gm_in_dwi_bin,
                                                      self.gm_in_dwi)
        time.sleep(0.5)
        # Threshold CSF to binary in dwi space
        self.csf_mask = regutils.apply_mask_to_image(self.csf_mask_dwi,
                                                     self.csf_mask_dwi_bin,
                                                     self.csf_mask_dwi)
        time.sleep(0.5)
        # Create ventricular CSF mask
        print("Creating Ventricular CSF mask...")
        os.system(
            f"fslmaths {self.vent_mask_dwi} -kernel sphere 10 -ero "
            f"-bin {self.vent_mask_dwi}"
        )
        time.sleep(1)
        os.system(
            f"fslmaths {self.csf_mask_dwi} -add {self.vent_mask_dwi} "
            f"-bin {self.vent_csf_in_dwi}"
        )
        time.sleep(1)
        print("Creating Corpus Callosum mask...")
        os.system(
            f"fslmaths {self.corpuscallosum_dwi} -mas {self.wm_in_dwi_bin} "
            f"-sub {self.vent_csf_in_dwi} "
            f"-bin {self.corpuscallosum_dwi}")
        time.sleep(1)
        # Create gm-wm interface image
        os.system(
            f"fslmaths {self.gm_in_dwi_bin} -mul {self.wm_in_dwi_bin} "
            f"-add {self.corpuscallosum_dwi} "
            f"-mas {self.B0_mask} -bin {self.wm_gm_int_in_dwi}")
        time.sleep(1)
        return
Exemple #5
0
def atlas2t1w2dwi_align(
    uatlas,
    uatlas_parcels,
    atlas,
    t1w_brain,
    t1w_brain_mask,
    mni2t1w_warp,
    t1_aligned_mni,
    ap_path,
    t1w2dwi_bbr_xfm,
    mni2t1_xfm,
    t1w2dwi_xfm,
    wm_gm_int_in_dwi,
    aligned_atlas_t1mni,
    aligned_atlas_skull,
    dwi_aligned_atlas,
    dwi_aligned_atlas_wmgm_int,
    B0_mask,
    mni2dwi_xfm,
    simple,
):
    """
    A function to perform atlas alignment atlas --> T1 --> dwi.
    Tries nonlinear registration first, and if that fails, does a linear
    registration instead. For this to succeed, must first have called
    t1w2dwi_align.
    """
    import time
    from nilearn.image import resample_to_img
    from pynets.core.utils import checkConsecutive
    from pynets.registration import reg_utils as regutils
    from nilearn.image import math_img
    from nilearn.masking import intersect_masks

    template_img = nib.load(t1_aligned_mni)
    if uatlas_parcels:
        atlas_img_orig = nib.load(uatlas_parcels)
    else:
        atlas_img_orig = nib.load(uatlas)

    old_count = len(np.unique(np.asarray(atlas_img_orig.dataobj)))

    uatlas_res_template = resample_to_img(atlas_img_orig,
                                          template_img,
                                          interpolation="nearest")

    uatlas_res_template = nib.Nifti1Image(
        np.asarray(uatlas_res_template.dataobj).astype('uint16'),
        affine=uatlas_res_template.affine,
        header=uatlas_res_template.header,
    )
    nib.save(uatlas_res_template, aligned_atlas_t1mni)

    if simple is False:
        try:
            regutils.apply_warp(
                t1w_brain,
                aligned_atlas_t1mni,
                aligned_atlas_skull,
                warp=mni2t1w_warp,
                interp="nn",
                sup=True,
                mask=t1w_brain_mask,
            )
            time.sleep(0.5)

            # Apply linear transformation from template to dwi space
            regutils.applyxfm(ap_path,
                              aligned_atlas_skull,
                              t1w2dwi_bbr_xfm,
                              dwi_aligned_atlas,
                              interp="nearestneighbour")
            time.sleep(0.5)
        except BaseException:
            print(
                "Warning: Atlas is not in correct dimensions, or input is low"
                " quality,\nusing linear template registration.")

            combine_xfms(mni2t1_xfm, t1w2dwi_bbr_xfm, mni2dwi_xfm)
            time.sleep(0.5)
            regutils.applyxfm(ap_path,
                              aligned_atlas_t1mni,
                              mni2dwi_xfm,
                              dwi_aligned_atlas,
                              interp="nearestneighbour")
            time.sleep(0.5)
    else:
        combine_xfms(mni2t1_xfm, t1w2dwi_xfm, mni2dwi_xfm)
        time.sleep(0.5)
        regutils.applyxfm(ap_path,
                          aligned_atlas_t1mni,
                          mni2dwi_xfm,
                          dwi_aligned_atlas,
                          interp="nearestneighbour")
        time.sleep(0.5)

    atlas_img = nib.load(dwi_aligned_atlas)
    wm_gm_img = nib.load(wm_gm_int_in_dwi)
    wm_gm_mask_img = math_img("img > 0", img=wm_gm_img)
    atlas_mask_img = math_img("img > 0", img=atlas_img)

    atlas_img_corr = nib.Nifti1Image(
        np.asarray(atlas_img.dataobj).astype('uint16'),
        affine=atlas_img.affine,
        header=atlas_img.header,
    )

    # Get the union of masks
    dwi_aligned_atlas_wmgm_int_img = intersect_masks(
        [wm_gm_mask_img, atlas_mask_img], threshold=0, connected=False)

    nib.save(atlas_img_corr, dwi_aligned_atlas)
    nib.save(dwi_aligned_atlas_wmgm_int_img, dwi_aligned_atlas_wmgm_int)

    dwi_aligned_atlas = regutils.apply_mask_to_image(dwi_aligned_atlas,
                                                     B0_mask,
                                                     dwi_aligned_atlas)

    time.sleep(0.5)

    dwi_aligned_atlas_wmgm_int = regutils.apply_mask_to_image(
        dwi_aligned_atlas_wmgm_int, B0_mask, dwi_aligned_atlas_wmgm_int)

    time.sleep(0.5)
    final_dat = atlas_img_corr.get_fdata()
    unique_a = sorted(set(np.array(final_dat.flatten().tolist())))

    if not checkConsecutive(unique_a):
        print("Warning! Non-consecutive integers found in parcellation...")

    new_count = len(unique_a)
    diff = np.abs(np.int(float(new_count) - float(old_count)))
    print(f"Previous label count: {old_count}")
    print(f"New label count: {new_count}")
    print(f"Labels dropped: {diff}")

    atlas_img.uncache()
    atlas_img_corr.uncache()
    atlas_img_orig.uncache()
    atlas_mask_img.uncache()
    wm_gm_img.uncache()
    wm_gm_mask_img.uncache()

    return dwi_aligned_atlas_wmgm_int, dwi_aligned_atlas, aligned_atlas_t1mni
Exemple #6
0
def atlas2t1w_align(uatlas,
                    uatlas_parcels,
                    atlas,
                    t1w_brain,
                    t1w_brain_mask,
                    t1_aligned_mni,
                    mni2t1w_warp,
                    mni2t1_xfm,
                    gm_mask,
                    aligned_atlas_t1mni,
                    aligned_atlas_skull,
                    aligned_atlas_gm,
                    simple,
                    gm_fail_tol=5):
    """
    A function to perform atlas alignment from atlas --> T1w.
    """
    import time
    from pynets.registration import reg_utils as regutils
    from nilearn.image import resample_to_img
    # from pynets.core.utils import checkConsecutive

    template_img = nib.load(t1_aligned_mni)
    if uatlas_parcels:
        atlas_img_orig = nib.load(uatlas_parcels)
    else:
        atlas_img_orig = nib.load(uatlas)

    # old_count = len(np.unique(np.asarray(atlas_img_orig.dataobj)))

    uatlas_res_template = resample_to_img(atlas_img_orig,
                                          template_img,
                                          interpolation="nearest")

    uatlas_res_template = nib.Nifti1Image(
        np.asarray(uatlas_res_template.dataobj).astype('uint16'),
        affine=uatlas_res_template.affine,
        header=uatlas_res_template.header,
    )
    nib.save(uatlas_res_template, aligned_atlas_t1mni)

    if simple is False:
        try:
            regutils.apply_warp(
                t1w_brain,
                aligned_atlas_t1mni,
                aligned_atlas_skull,
                warp=mni2t1w_warp,
                interp="nn",
                sup=True,
                mask=t1w_brain_mask,
            )
            time.sleep(0.5)
        except BaseException:
            print(
                "Warning: Atlas is not in correct dimensions, or input is low "
                "quality,\nusing linear template registration.")

            regutils.applyxfm(t1w_brain,
                              aligned_atlas_t1mni,
                              mni2t1_xfm,
                              aligned_atlas_skull,
                              interp="nearestneighbour")
            time.sleep(0.5)
    else:
        regutils.applyxfm(t1w_brain,
                          aligned_atlas_t1mni,
                          mni2t1_xfm,
                          aligned_atlas_skull,
                          interp="nearestneighbour")
        time.sleep(0.5)

    # aligned_atlas_gm = regutils.apply_mask_to_image(aligned_atlas_skull,
    #                                                 gm_mask,
    #                                                 aligned_atlas_gm)
    aligned_atlas_gm = regutils.apply_mask_to_image(aligned_atlas_skull,
                                                    t1w_brain_mask,
                                                    aligned_atlas_gm)

    time.sleep(0.5)
    atlas_img = nib.load(aligned_atlas_gm)

    atlas_img_corr = nib.Nifti1Image(
        np.asarray(atlas_img.dataobj).astype('uint16'),
        affine=atlas_img.affine,
        header=atlas_img.header,
    )
    nib.save(atlas_img_corr, aligned_atlas_gm)
    # final_dat = atlas_img_corr.get_fdata()
    # unique_a = sorted(set(np.array(final_dat.flatten().tolist())))
    #
    # if not checkConsecutive(unique_a):
    #     print("\nWarning! non-consecutive integers found in parcellation...")
    # new_count = len(unique_a)
    # diff = np.abs(np.int(float(new_count) - float(old_count)))
    # print(f"Previous label count: {old_count}")
    # print(f"New label count: {new_count}")
    # print(f"Labels dropped: {diff}")
    # if diff > gm_fail_tol:
    #     print(f"Grey-Matter mask too restrictive >{str(gm_fail_tol)} for this "
    #           f"parcellation. Falling back to the T1w mask...")
    #     aligned_atlas_gm = regutils.apply_mask_to_image(aligned_atlas_skull,
    #                                                     t1w_brain_mask,
    #                                                     aligned_atlas_gm)
    #     time.sleep(5)
    template_img.uncache()
    atlas_img_orig.uncache()
    atlas_img.uncache()
    atlas_img_corr.uncache()

    return aligned_atlas_gm, aligned_atlas_skull
Exemple #7
0
    def t1w2dwi_align(self):
        """
        A function to perform alignment from T1w_MNI --> DWI. Uses a local
        optimization cost function to get the two images close, and then uses
        bbr to obtain a good alignment of brain boundaries.
        Assumes input dwi is already preprocessed and brain extracted.
        """
        import time

        self.ap_path = regutils.apply_mask_to_image(self.ap_path,
                                                    self.B0_mask,
                                                    self.ap_path)

        self.fa_path = regutils.apply_mask_to_image(self.fa_path,
                                                    self.B0_mask,
                                                    self.fa_path)

        # Align T1w-->DWI
        regutils.align(
            self.ap_path,
            self.t1w_brain,
            xfm=self.t1w2dwi_xfm,
            bins=None,
            interp="spline",
            dof=6,
            cost="mutualinfo",
            out=None,
            searchrad=True,
            sch=None,
        )
        time.sleep(0.5)
        self.dwi2t1w_xfm = regutils.invert_xfm(self.t1w2dwi_xfm,
                                               self.dwi2t1w_xfm)
        time.sleep(0.5)
        if self.simple is False:
            # Flirt bbr
            try:
                print("Learning a Boundary-Based Mapping from T1w-->DWI ...")
                regutils.align(
                    self.fa_path,
                    self.t1w_brain,
                    wmseg=self.wm_edge,
                    xfm=self.dwi2t1w_bbr_xfm,
                    init=self.dwi2t1w_xfm,
                    bins=256,
                    dof=7,
                    searchrad=True,
                    interp="spline",
                    out=None,
                    cost="bbr",
                    sch="${FSLDIR}/etc/flirtsch/bbr.sch",
                )
                time.sleep(0.5)
                self.t1w2dwi_bbr_xfm = regutils.invert_xfm(
                    self.dwi2t1w_bbr_xfm, self.t1w2dwi_bbr_xfm)
                time.sleep(0.5)
                # Apply the alignment
                regutils.align(
                    self.t1w_brain,
                    self.ap_path,
                    init=self.t1w2dwi_bbr_xfm,
                    xfm=self.t1wtissue2dwi_xfm,
                    bins=None,
                    interp="spline",
                    dof=7,
                    cost="mutualinfo",
                    out=self.t1w2dwi,
                    searchrad=True,
                    sch=None,
                )
                time.sleep(0.5)
            except BaseException:
                # Apply the alignment
                regutils.align(
                    self.t1w_brain,
                    self.ap_path,
                    init=self.t1w2dwi_xfm,
                    xfm=self.t1wtissue2dwi_xfm,
                    bins=None,
                    interp="spline",
                    dof=7,
                    cost="mutualinfo",
                    out=self.t1w2dwi,
                    searchrad=True,
                    sch=None,
                )
                time.sleep(0.5)
        else:
            # Apply the alignment
            regutils.align(
                self.t1w_brain,
                self.ap_path,
                init=self.t1w2dwi_xfm,
                xfm=self.t1wtissue2dwi_xfm,
                bins=None,
                interp="spline",
                dof=6,
                cost="mutualinfo",
                out=self.t1w2dwi,
                searchrad=True,
                sch=None,
            )
            time.sleep(0.5)

        self.t1w2dwi = regutils.apply_mask_to_image(self.t1w2dwi,
                                                    self.B0_mask,
                                                    self.t1w2dwi)
        return