Ejemplo n.º 1
0
def test_compute_brain_mask():
    img, _ = data_gen.generate_mni_space_img(res=8, random_state=0)
    brain_mask = compute_brain_mask(img, threshold=.2)
    gm_mask = compute_brain_mask(img, threshold=.2, mask_type="gm")
    wm_mask = compute_brain_mask(img, threshold=.2, mask_type="wm")
    brain_data, gm_data, wm_data = map(get_data,
                                       (brain_mask, gm_mask, wm_mask))
    # Check that whole-brain mask is non-empty
    assert (brain_data != 0).any()
    for subset in gm_data, wm_data:
        # Test that gm and wm masks are included in the whole-brain mask
        assert (np.logical_and(brain_data,
                               subset) == subset.astype(bool)).all()
        # Test that gm and wm masks are non-empty
        assert (subset != 0).any()
    # Test that gm and wm masks have empty intersection
    assert (np.logical_and(gm_data, wm_data) == 0).all()
    # Check that we get a useful warning for empty masks
    with pytest.warns(masking.MaskWarning):
        compute_brain_mask(img, threshold=1)
    # Check that masks obtained from same FOV are the same
    img1, _ = data_gen.generate_mni_space_img(res=8, random_state=1)
    mask_img1 = compute_brain_mask(img1, verbose=1, threshold=.2)
    assert (brain_data == get_data(mask_img1)).all()
    # Check that error is raised if mask type is unknown
    with pytest.raises(ValueError, match='Unknown mask type foo.'):
        compute_brain_mask(img, verbose=1, mask_type='foo')
Ejemplo n.º 2
0
def test_compute_brain_mask():
    image = Nifti1Image(np.ones((9, 9, 9)), np.eye(4))

    mask = compute_brain_mask(image, threshold=-1)
    mask1 = np.zeros((9, 9, 9))
    mask1[2:-2, 2:-2, 2:-2] = 1

    np.testing.assert_array_equal(mask1, get_data(mask))

    # Check that we get a useful warning for empty masks
    with pytest.warns(masking.MaskWarning):
        compute_brain_mask(image, threshold=1)

    # Check that masks obtained from same FOV are the same
    img1 = Nifti1Image(np.full((9, 9, 9), np.random.rand()), np.eye(4))
    img2 = Nifti1Image(np.full((9, 9, 9), np.random.rand()), np.eye(4))

    mask_img1 = compute_brain_mask(img1)
    mask_img2 = compute_brain_mask(img2)
    np.testing.assert_array_equal(get_data(mask_img1),
                                  get_data(mask_img2))
Ejemplo n.º 3
0
def t1_pipeline(do_normalise_before=False,
                do_segment=True,
                do_normalise_after=False,
                do_plot=True,
                keep_tmp=True,
                sub_name='sub-11',
                sess_num='ses-17',
                root_path='/neurospin/ibc'):
    """
    Preprocess qMRI t1 images and then run estimation to generate t1-maps,
    more details in scripts/qmri_README.md,
    only one of do_normalise_before and do_normalise_after should be True,
    both can be False
    """
    DATA_LOC = join(root_path, 'sourcedata', sub_name, sess_num)
    SAVE_TO = join(root_path, 'derivatives', sub_name, sess_num)

    if do_normalise_before or do_normalise_after:
        space = "MNI152"
    else:
        space = "individual"

    if not exists(SAVE_TO):
        makedirs(SAVE_TO)

    start_time = time.time()

    # data files
    data_dir = DATA_LOC

    niftis = []
    jsons = []
    for fi in listdir(join(data_dir, 'anat')):
        if fi.split('_')[-1] == 'T1map.nii.gz':
            niftis.append(join(data_dir, 'anat', fi))
        elif fi.split('_')[-1] == 'T1map.json':
            jsons.append(join(data_dir, 'anat', fi))
        elif fi.split('_')[-1] == 'B1map.nii.gz':
            b1_map_nifti = join(data_dir, 'anat', fi)
        elif fi.split('_')[-1] == 'B1map.json':
            b1_map_json = join(data_dir, 'anat', fi)
        else:
            continue
    niftis.sort()
    jsons.sort()

    # preprocessing directory setup
    time_elapsed = time.time() - start_time
    print('[INFO,  t={:.2f}s] copying necessary files...'.format(time_elapsed))
    cwd = SAVE_TO
    preproc_dir = join(cwd, 'tmp_t1', 'preproc')
    if not exists(preproc_dir):
        makedirs(preproc_dir)

    # copy data files to tmp_t1 directory
    cnt = 0
    for nii, json in zip(niftis, jsons):
        system('cp {} {}'.format(nii, preproc_dir))
        niftis[cnt] = join(preproc_dir, nii.split(sep)[-1])
        system('gunzip -df {}'.format(niftis[cnt]))
        niftis[cnt] = join(preproc_dir,
                           nii.split(sep)[-1].split('.')[0] + '.nii')
        system('cp {} {}'.format(json, preproc_dir))
        jsons[cnt] = join(preproc_dir, json.split(sep)[-1])
        cnt += 1
    system('cp {} {}'.format(b1_map_nifti, preproc_dir))
    b1_map_nifti = join(preproc_dir, b1_map_nifti.split(sep)[-1])
    system('gunzip -df {}'.format(b1_map_nifti))
    b1_map_nifti = join(preproc_dir,
                        b1_map_nifti.split(sep)[-1].split('.')[0] + '.nii')
    system('cp {} {}'.format(b1_map_json, preproc_dir))
    b1_map_json = join(preproc_dir, b1_map_json.split(sep)[-1])

    # preprocessing step: spatial normalization to MNI space
    # of T1 maps
    if do_normalise_before:
        time_elapsed = time.time() - start_time
        print('[INFO,  t={:.2f}s] segmenting highest flip angle image'.format(
            time_elapsed))
        image = niftis[-1]
        out_info = segment(image, True)
        # save normalised segments
        segments = [
            join(preproc_dir, f"w{out_info[segment].split('/')[-1]}")
            for segment in ['gm', 'wm']
        ]
        time_elapsed = time.time() - start_time
        print('[INFO,  t={:.2f}s] transforming images to MNI space...'.format(
            time_elapsed))
        normed_niftis = []
        cnt = 0
        for nii in niftis:
            image = nii
            if cnt == len(niftis) - 1:
                b1_map = b1_map_nifti
                out_info = to_MNI(image, data=out_info, func=b1_map)
                normed_b1_map = out_info['func'][0]
            else:
                out_info = to_MNI(image, data=out_info)
            normed_niftis.append(out_info['anat'])
            time_elapsed = time.time() - start_time
            print('[INFO,  t={:.2f}s] \t transformed {}'.format(
                time_elapsed,
                nii.split(sep)[-1]))
            cnt = cnt + 1

    # preprocessing step: segmenting largest flip angle image
    if do_segment:
        time_elapsed = time.time() - start_time
        if do_normalise_before:
            print('[INFO,  t={:.2f}s] creating a mask'.format(time_elapsed))
            image = normed_niftis[-1]
            mni = compute_brain_mask(image)
            closed_mni = closing(mni, 12)
            union = intersect_masks([mni, closed_mni], threshold=0)
        else:
            print('[INFO,  t={:.2f}s] segmenting highest flip angle image'.
                  format(time_elapsed))
            image = niftis[-1]
            out_info = segment(image, True)
            segments = [out_info['gm'], out_info['wm']]
            time_elapsed = time.time() - start_time
            print('[INFO,  t={:.2f}s] \t segmented {}'.format(
                time_elapsed,
                image.split(sep)[-1]))

            # preprocessing step: creating a mask
            print('[INFO,  t={:.2f}s] creating a mask using segments'.format(
                time_elapsed))
            add = math_img("img1 + img2", img1=segments[0], img2=segments[1])
            if sub_name == 'sub-08':
                full = compute_epi_mask(add, exclude_zeros=True)
            else:
                full = compute_epi_mask(add)
            insides = compute_background_mask(full, opening=12)
            union = intersect_masks([full, insides], threshold=0)

        mask_file = join(preproc_dir, 'mask.nii')
        union.to_filename(mask_file)

    # estimation directory setup
    time_elapsed = time.time() - start_time
    print('[INFO,  t={:.2f}s] starting estimation...'.format(time_elapsed))
    recon_dir = join(cwd, 'tmp_t1', 'recon')
    if not exists(recon_dir):
        makedirs(recon_dir)
    jsons_str = ' '.join(jsons)

    if do_normalise_before:
        niftis_str = ' '.join(normed_niftis)
        b1_map_str = normed_b1_map
    else:
        niftis_str = ' '.join(niftis)
        b1_map_str = b1_map_nifti

    if do_segment == False:
        mask_file = None

    # estimation: parameter extraction
    system(f"python3 ../scripts/qmri_t1_map_b1_params.py\
        -v 1\
        -s {sub_name}\
        -o {recon_dir}\
        -g {jsons_str}\
        -b {b1_map_json}")

    # estimation: t1 estimation
    system(f"python3 ../scripts/qmri_t1_map_b1.py\
        -v 1\
        -s {sub_name}\
        -o {recon_dir}\
        -g {niftis_str}\
        -b {b1_map_str}\
        -r {join(recon_dir,f'{sub_name}_t1_map_b1.json')}\
        -d fit\
        -m {mask_file}")

    recon_map = join(recon_dir, f'{sub_name}_T1map.nii.gz')

    # postprocessing: normalization of reconstructed t1 map
    if do_normalise_after:
        postproc_dir = join(cwd, 'tmp_t1', 'postproc')
        if not exists(postproc_dir):
            makedirs(postproc_dir)
        recon_map = join(recon_dir, f'{sub_name}_T1map.nii.gz')
        system('cp {} {}'.format(recon_map, postproc_dir))
        time_elapsed = time.time() - start_time
        print('[INFO,  t={:.2f}s] normalizing reconstructed t1 map...'.format(
            time_elapsed))
        image = join(postproc_dir, f'{sub_name}_T1map.nii.gz')
        system('gunzip -df {}'.format(image))
        image = join(postproc_dir, f'{sub_name}_T1map.nii')
        out_info = to_MNI(image, segmented=out_info.nipype_results['segment'])
        norm_recon_map = out_info['anat']

    # doing the plots
    if do_plot:
        time_elapsed = time.time() - start_time
        print('\n[INFO,  t={:.2f}s] plotting the map...'.format(time_elapsed))
        plot_dir = join(cwd, 'tmp_t1', 'plot')
        if not exists(plot_dir):
            makedirs(plot_dir)
        if do_normalise_after:
            t1_img = norm_recon_map
        else:
            t1_img = join(recon_dir, f'{sub_name}_T1map.nii.gz')
        plot_thresholded_qmap(img=t1_img,
                              thresh="99",
                              map=f"{sub_name}_T1map_fit",
                              interactive=True,
                              coords=(10, 56, 43),
                              output_folder=plot_dir)

    time_elapsed = time.time() - start_time
    print('\n[INFO,  t={:.2f}s] DONE'.format(time_elapsed))

    # move derived files out and delete tmp_t1 directory
    final_recon_map = join(SAVE_TO, f'{sub_name}_space-{space}_T1map.nii.gz')
    if do_normalise_after:
        system('gzip {}'.format(norm_recon_map))
        recon_map = norm_recon_map + '.gz'
    shutil.move(recon_map, final_recon_map)

    if do_plot:
        for fi in listdir(plot_dir):
            plot_name = join(plot_dir, fi)
            final_plot_name = join(
                SAVE_TO,
                final_recon_map.split(sep)[-1].split('.')[0] + '_' +
                fi.split('_')[-1])
            shutil.move(plot_name, final_plot_name)

    if not keep_tmp:
        shutil.rmtree(join(SAVE_TO, 'tmp_t1'))

    time_elapsed = time.time() - start_time
    print('\n[INFO,  t={:.2f}s] created {} \n\n'.format(
        time_elapsed, final_recon_map))
Ejemplo n.º 4
0
def t2_pipeline(do_coreg=True,
                do_normalise_before=False,
                do_segment=True,
                do_normalise_after=False,
                do_plot=True,
                keep_tmp=True,
                sub_name='sub-11',
                sess_num='ses-17',
                root_path='/neurospin/ibc'):
    """
    Preprocess qMRI t2 images and then run estimation to generate t2-maps,
    more details in scripts/qmri_README.md,
    only one of do_normalise_before and do_normalise_after should be True,
    both can be False
    """
    DATA_LOC = join(root_path, 'sourcedata', sub_name, sess_num)
    SAVE_TO = join(root_path, 'derivatives', sub_name, sess_num)

    if do_normalise_before or do_normalise_after:
        space = "MNI152"
    else:
        space = "individual"

    if not exists(SAVE_TO):
        makedirs(SAVE_TO)

    start_time = time.time()

    # data files
    data_dir = DATA_LOC

    niftis = []
    jsons = []
    for fi in listdir(join(data_dir, 'anat')):
        if fi.split('_')[-1] == 'T2map.nii.gz':
            niftis.append(join(data_dir, 'anat', fi))
        elif fi.split('_')[-1] == 'T2map.json':
            jsons.append(join(data_dir, 'anat', fi))
        else:
            continue
    niftis.sort()
    jsons.sort()

    run_count = 0
    for nifti in niftis:
        # preprocessing directory setup
        time_elapsed = time.time() - start_time
        print('[INFO,  t={:.2f}s] copying necessary files...'.format(
            time_elapsed))
        cwd = SAVE_TO
        preproc_dir = join(cwd, 'tmp_t2', 'preproc')
        if not exists(preproc_dir):
            makedirs(preproc_dir)

        system('cp {} {}'.format(nifti, preproc_dir))
        nifti = join(preproc_dir, nifti.split(sep)[-1])
        system('gunzip -df {}'.format(nifti))
        nifti = join(preproc_dir, nifti.split(sep)[-1].split('.')[0] + '.nii')

        if do_coreg:
            # t1 image as an anatomical image
            t1_niftis = []
            for fi in listdir(join(data_dir, 'anat')):
                if fi.split('_')[-1] == 'T1map.nii.gz':
                    t1_niftis.append(join(data_dir, 'anat', fi))
            t1_niftis.sort()
            t1_nifti = t1_niftis[-1]
            system('cp {} {}'.format(t1_nifti, preproc_dir))
            t1_nifti = join(preproc_dir, t1_nifti.split(sep)[-1])
            system('gunzip -df {}'.format(t1_nifti))
            t1_nifti = join(preproc_dir,
                            t1_nifti.split(sep)[-1].split('.')[0] + '.nii')

        # preprocessing step: spatial normalization to MNI space
        # of T1 maps
        if do_normalise_before:
            image = nifti
            if do_coreg:
                t1_img = t1_nifti
                time_elapsed = time.time() - start_time
                print('[INFO,  t={:.2f}s] segmenting the t1 image'.format(
                    time_elapsed))
                out_info = segment(t1_img, False)
                time_elapsed = time.time() - start_time
                print('[INFO,  t={:.2f}s] transforming images to MNI space...'.
                      format(time_elapsed))
                out_info = to_MNI(image=t1_img, data=out_info, func=image)
                normed_t1_img = out_info['anat']
                normed_nifti = out_info['func'][0]
            else:
                time_elapsed = time.time() - start_time
                print('[INFO,  t={:.2f}s] segmenting the t2 image'.format(
                    time_elapsed))
                out_info = segment(image, False)
                time_elapsed = time.time() - start_time
                print('[INFO,  t={:.2f}s] transforming images to MNI space...'.
                      format(time_elapsed))
                out_info = to_MNI(image, data=out_info)
                normed_nifti = out_info['anat']
            time_elapsed = time.time() - start_time
            print('[INFO,  t={:.2f}s] \t transformed {}'.format(
                time_elapsed,
                nifti.split(sep)[-1]))

        # preprocessing step: transform t1 image to t2 space
        if do_coreg:
            time_elapsed = time.time() - start_time
            print('[INFO,  t={:.2f}s] transforming t1 image to t2 space...'.
                  format(time_elapsed))
            if do_normalise_before:
                t2_img = normed_nifti
                t1_img = normed_t1_img
            else:
                t2_img = nifti
                t1_img = t1_nifti
            mean_t2 = mean_img(t2_img)
            mean_t2_img = join(preproc_dir,
                               'mean_{}'.format(t2_img.split(sep)[-1]))
            mean_t2.to_filename(mean_t2_img)
            out_info = to_T2space(t2_img=mean_t2_img,
                                  t1_img=t1_img,
                                  output_dir=preproc_dir)
            print('[INFO,  t={:.2f}s] \t transformed {} to {} space'.format(
                time_elapsed,
                t1_img.split(sep)[-1],
                mean_t2_img.split(sep)[-1]))

        # preprocessing step: segmenting largest flip angle image
        if do_segment:
            if do_normalise_before:
                time_elapsed = time.time() - start_time
                print(
                    '[INFO,  t={:.2f}s] creating a mask'.format(time_elapsed))
                if do_coreg:
                    image = normed_t1_img
                else:
                    image = normed_nifti
                mni = compute_brain_mask(image)
                closed_mni = closing(mni, 12)
                union = intersect_masks([mni, closed_mni], threshold=0)
            else:
                if do_coreg:
                    image = t1_img
                else:
                    image = nifti
                time_elapsed = time.time() - start_time
                print(
                    '[INFO,  t={:.2f}s] segmenting the image for creating a mask'
                    .format(time_elapsed))
                out_info = segment(image, False)
                segments = [out_info['gm'], out_info['wm']]
                time_elapsed = time.time() - start_time
                print('[INFO,  t={:.2f}s] \t segmented {}'.format(
                    time_elapsed,
                    image.split(sep)[-1]))

                # preprocessing step: creating a mask
                time_elapsed = time.time() - start_time
                print(
                    '[INFO,  t={:.2f}s] creating a mask using segments'.format(
                        time_elapsed))
                add = math_img("img1 + img2",
                               img1=segments[0],
                               img2=segments[1])
                if sub_name == 'sub-08':
                    full = compute_epi_mask(add, exclude_zeros=True)
                else:
                    full = compute_epi_mask(add)
                insides = compute_background_mask(full, opening=12)
                union = intersect_masks([full, insides], threshold=0)

            mask_file = join(preproc_dir, 'mask.nii')
            union.to_filename(mask_file)

            if do_coreg:
                resampled_mask = resample_to_img(mask_file,
                                                 mean_t2_img,
                                                 clip=True)
                rounded_resampled_mask = math_img('np.around(img1)',
                                                  img1=resampled_mask)
                resampled_mask_img = join(preproc_dir, 'resampled_mask.nii')
                rounded_resampled_mask.to_filename(resampled_mask_img)
            else:
                resampled_mask_img = mask_file

        # estimation directory setup
        time_elapsed = time.time() - start_time
        print('[INFO,  t={:.2f}s] starting estimation...'.format(time_elapsed))
        recon_dir = join(cwd, 'tmp_t2', 'recon')
        if not exists(recon_dir):
            makedirs(recon_dir)

        if do_normalise_before:
            niftis_str = normed_nifti
        else:
            niftis_str = nifti

        if do_segment == False:
            mask_file = None

        # estimation: t2 estimation
        system(f"python3 ../scripts/qmri_t2_map.py\
            -v 1\
            -s {sub_name}\
            -o {recon_dir}\
            -n {niftis_str}\
            -m {resampled_mask_img}")

        recon_map = join(recon_dir, f'{sub_name}_T2map.nii.gz')

        # postprocessing: normalization of reconstructed t1 map
        if do_normalise_after:
            postproc_dir = join(cwd, 'tmp_t2', 'postproc')
            if not exists(postproc_dir):
                makedirs(postproc_dir)

            system('cp {} {}'.format(recon_map, postproc_dir))
            time_elapsed = time.time() - start_time
            print('[INFO,  t={:.2f}s] normalizing reconstructed map...'.format(
                time_elapsed))
            image = join(postproc_dir, f'{sub_name}_T2map.nii.gz')
            system('gunzip -df {}'.format(image))
            image = join(postproc_dir, f'{sub_name}_T2map.nii')
            out_info = to_MNI(image,
                              segmented=out_info.nipype_results['segment'])
            norm_recon_map = out_info['anat']

        # doing the plots
        if do_plot:
            time_elapsed = time.time() - start_time
            print('\n[INFO,  t={:.2f}s] plotting the map...'.format(
                time_elapsed))
            plot_dir = join(cwd, 'tmp_t2', 'plot')
            if not exists(plot_dir):
                makedirs(plot_dir)
            if do_normalise_after:
                t2_img = norm_recon_map
            else:
                t2_img = recon_map
            plot_thresholded_qmap(img=t2_img,
                                  thresh="95",
                                  map=f"{sub_name}_T2map",
                                  interactive=True,
                                  coords=(10, 56, 43),
                                  output_folder=plot_dir)

        time_elapsed = time.time() - start_time
        print('\n[INFO,  t={:.2f}s] DONE'.format(time_elapsed))

        # move derived files out and delete tmp_t2 directory
        final_recon_map = join(
            SAVE_TO,
            f'{sub_name}_run-0{run_count+1}_space-{space}_T2map.nii.gz')
        if do_normalise_after:
            system('gzip {}'.format(norm_recon_map))
            recon_map = norm_recon_map + '.gz'
        shutil.move(recon_map, final_recon_map)

        if do_plot:
            for fi in listdir(plot_dir):
                plot_name = join(plot_dir, fi)
                final_plot_name = join(
                    SAVE_TO,
                    final_recon_map.split(sep)[-1].split('.')[0] + '_' +
                    fi.split('_')[-1])
                shutil.move(plot_name, final_plot_name)

        if not keep_tmp:
            shutil.rmtree(join(SAVE_TO, 'tmp_t2'))

        time_elapsed = time.time() - start_time
        print('\n[INFO,  t={:.2f}s] created {} \n\n'.format(
            time_elapsed, final_recon_map))
        run_count = run_count + 1