def main(argv=None):
    parser = get_parser()
    arguments = parser.parse_args(argv)
    verbose = arguments.v
    set_loglevel(verbose=verbose)

    fname_bval_list = arguments.i
    # Build fname_out
    if arguments.o is not None:
        fname_out = arguments.o
    else:
        path_in, file_in, ext_in = extract_fname(fname_bval_list[0])
        fname_out = path_in + 'bvals_concat' + ext_in

    # Open bval files and concatenate
    bvals_concat = ''
    # for file_i in fname_bval_list:
    #     f = open(file_i, 'r')
    #     for line in f:
    #         bvals_concat += line
    #     f.close()
    from dipy.data.fetcher import read_bvals_bvecs
    for i_fname in fname_bval_list:
        bval_i, bvec_i = read_bvals_bvecs(i_fname, None)
        bvals_concat += ' '.join(str(v) for v in bval_i)
        bvals_concat += ' '

    # Write new bval
    new_f = open(fname_out, 'w')
    new_f.write(bvals_concat)
    new_f.close()
def test_sct_analyze_lesion_matches_expected_dummy_lesion_measurements(dummy_lesion, rtol, tmp_path):
    """Run the CLI script and verify that the lesion measurements match
    expected values."""
    # Run the analysis on the dummy lesion file
    path_lesion, expected_measurements = dummy_lesion
    sct_analyze_lesion.main(argv=['-m', path_lesion,
                                  '-s', sct_test_path("t2", "t2_seg-manual.nii.gz"),
                                  '-ofolder', str(tmp_path)])

    # Load analysis results from pickled pandas.Dataframe
    _, fname, _ = extract_fname(path_lesion)
    with open(tmp_path/f"{fname}_analyzis.pkl", 'rb') as f:
        measurements = pickle.load(f)['measures']

    # Validate analysis results
    for key, expected_value in expected_measurements.items():
        if key == 'volume [mm3]':
            np.testing.assert_equal(measurements.at[0, key], expected_value)
        else:
            # The length/diameter won't match exactly due to angle adjustment
            # from spinal cord centerline curvature
            np.testing.assert_allclose(measurements.at[0, key],
                                       expected_value, rtol=rtol)
            # The values will be adjusted according to the cos of the angle
            # between the spinal cord centerline and the S-I axis, as per:
            # https://github.com/spinalcordtoolbox/spinalcordtoolbox/pull/3681#discussion_r804822552
            if key == 'max_equivalent_diameter [mm]':
                assert measurements.at[0, key] < expected_value
            elif key == 'length [mm]':
                assert measurements.at[0, key] > expected_value
def main(argv=None):
    parser = get_parser()
    arguments = parser.parse_args(argv)
    verbose = arguments.v
    set_loglevel(verbose=verbose)

    fname_in = arguments.bvec
    fname_out = arguments.o

    # get bvecs in proper orientation
    from dipy.io import read_bvals_bvecs
    bvals, bvecs = read_bvals_bvecs(None, fname_in)

    # # Transpose bvecs
    # printv('Transpose bvecs...', verbose)
    # # from numpy import transpose
    # bvecs = bvecs.transpose()

    # Write new file
    if fname_out == '':
        path_in, file_in, ext_in = extract_fname(fname_in)
        fname_out = path_in + file_in + ext_in
    fid = open(fname_out, 'w')
    for iLine in range(bvecs.shape[0]):
        fid.write(' '.join(str(i) for i in bvecs[iLine, :]) + '\n')
    fid.close()

    # display message
    printv('Created file:\n--> ' + fname_out + '\n', verbose, 'info')
Exemplo n.º 4
0
def main(args=None):

    parser = get_parser()
    if args:
        arguments = parser.parse_args(args)
    else:
        arguments = parser.parse_args(
            args=None if sys.argv[1:] else ['--help'])

    fname_in = arguments.bvec
    fname_out = arguments.o
    verbose = int(arguments.v)
    init_sct(log_level=verbose, update=True)  # Update log level

    # get bvecs in proper orientation
    from dipy.io import read_bvals_bvecs
    bvals, bvecs = read_bvals_bvecs(None, fname_in)

    # # Transpose bvecs
    # printv('Transpose bvecs...', verbose)
    # # from numpy import transpose
    # bvecs = bvecs.transpose()

    # Write new file
    if fname_out == '':
        path_in, file_in, ext_in = extract_fname(fname_in)
        fname_out = path_in + file_in + ext_in
    fid = open(fname_out, 'w')
    for iLine in range(bvecs.shape[0]):
        fid.write(' '.join(str(i) for i in bvecs[iLine, :]) + '\n')
    fid.close()

    # display message
    printv('Created file:\n--> ' + fname_out + '\n', verbose, 'info')
def test_sct_image_split_dmri(dmri_t_slices):
    """Verify the output of '-split' matches reference image. Note: CLI script is run by the 'dmri_t_slices' fixture."""
    _, filename, ext = extract_fname(dmri_t_slices[0])
    ref = Image(
        f'dmri/{filename}{ext}'
    )  # Reference image should exist inside working directory (sct_testing_data)
    new = Image(
        dmri_t_slices[0])  # New image should be generated inside tmp directory
    assert np.linalg.norm(ref.data - new.data) == 0
Exemplo n.º 6
0
    def __init__(self,
                 input_file,
                 command,
                 args,
                 orientation,
                 dest_folder,
                 dpi=300,
                 dataset=None,
                 subject=None):
        """

        :param input_file: str: the input nifti file name
        :param command: str: command name
        :param args: str: the command's arguments
        :param orientation: str: The anatomical orientation
        :param dest_folder: str: The absolute path of the QC root
        :param dpi: int: Output resolution of the image
        :param dataset: str: Dataset name
        :param subject: str: Subject name
        """
        path_in, file_in, ext_in = extract_fname(os.path.abspath(input_file))
        # Assuming BIDS convention, we derive the value of the dataset, subject and contrast from the `input_file`
        # by splitting it into `[dataset]/[subject]/[contrast]/input_file`
        abs_input_path, contrast = os.path.split(path_in)
        abs_input_path, subject_tmp = os.path.split(abs_input_path)
        _, dataset_tmp = os.path.split(abs_input_path)
        if dataset is None:
            dataset = dataset_tmp
        if subject is None:
            subject = subject_tmp
        if isinstance(args, list):
            args = list2cmdline(args)
        self.fname_in = file_in + ext_in
        self.dataset = dataset
        self.subject = subject
        self.cwd = os.getcwd()
        self.contrast = contrast
        self.command = command
        self.sct_version = __version__
        self.args = args
        self.orientation = orientation
        self.dpi = dpi
        self.root_folder = dest_folder
        self.mod_date = datetime.datetime.strftime(datetime.datetime.now(),
                                                   '%Y_%m_%d_%H%M%S.%f')
        self.qc_results = os.path.join(dest_folder, '_json',
                                       f'qc_{self.mod_date}.json')
        if command in ['sct_fmri_moco', 'sct_dmri_moco']:
            ext = "gif"
        else:
            ext = "png"
        self.bkg_img_path = os.path.join(dataset, subject, contrast, command,
                                         self.mod_date, f"bkg_img.{ext}")
        self.overlay_img_path = os.path.join(dataset, subject, contrast,
                                             command, self.mod_date,
                                             f"overlay_img.{ext}")
def test_integrity(param_test):
    """
    Test integrity of function
    """
    # find the test that is performed and check the integrity of the output
    index_args = param_test.default_args.index(param_test.args)

    # checking the integrity of padding an image
    if index_args == 0:
        nx, ny, nz, nt, px, py, pz, pt = Image(
            os.path.join(param_test.folder_data[0],
                         param_test.file_data[0])).dim
        nx2, ny2, nz2, nt2, px2, py2, pz2, pt2 = Image(
            'sct_image_out.nii.gz').dim

        if nz2 != nz + 2 * param_test.pad:
            param_test.status = 99
            param_test.output += '\nResulting pad image\'s dimension differs from expected:\n'
            param_test.output += 'dim : ' + str(nx2) + 'x' + str(
                ny2) + 'x' + str(nz2) + '\n'
            param_test.output += 'expected : ' + str(nx) + 'x' + str(
                ny) + 'x' + str(nz + 2 * param_test.pad) + '\n'

    elif index_args == 3:
        threshold = 1e-3
        try:
            path_fname, file_fname, ext_fname = extract_fname(
                os.path.join(param_test.folder_data[2],
                             param_test.file_data[2]))
            ref = Image(param_test.dmri_t_slices[0])
            new = Image(file_fname + '_T0000' + ext_fname)
            diff = ref.data - new.data
            if np.sum(diff) > threshold:
                param_test.status = 99
                param_test.output += '\nResulting split image differs from gold-standard.\n'
        except Exception as e:
            param_test.status = 99
            param_test.output += 'ERROR: ' + str(e)

    elif index_args == 4:
        try:
            threshold = 1e-3
            ref = Image(
                os.path.join(param_test.folder_data[2],
                             param_test.file_data[2]))
            new = Image('dmri_concat.nii.gz')
            diff = ref.data - new.data
            if np.sum(diff) > threshold:
                param_test.status = 99
                param_test.output += '\nResulting concatenated image differs from gold-standard (original dmri image).\n'
        except Exception as e:
            param_test.status = 99
            param_test.output += 'ERROR: ' + str(e)

    return param_test
def dmri_t_slices(tmp_path, dmri_in):
    """Filepaths for 4D dMRI image split across t axis."""
    fname_out = str(tmp_path / 'dmri.nii.gz')
    sct_image.main(argv=['-i', dmri_in, '-split', 't', '-o', fname_out])

    parent, filename, ext = extract_fname(fname_out)
    fname_slices = [
        os.path.join(parent, filename + '_T' + str(i).zfill(4) + ext)
        for i in range(7)
    ]
    return fname_slices
Exemplo n.º 9
0
def main(argv=None):
    parser = get_parser()
    arguments = parser.parse_args(argv if argv else ['--help'])
    verbose = arguments.v
    set_global_loglevel(verbose=verbose)

    fname_bvecs_list = arguments.i
    # Build fname_out
    if arguments.o is not None:
        fname_out = arguments.o
    else:
        path_in, file_in, ext_in = extract_fname(fname_bvecs_list[0])
        fname_out = path_in + 'bvecs_concat' + ext_in

    # # Open bvec files and collect values
    # nb_files = len(fname_bvecs_list)
    # bvecs_all = []
    # for i_fname in fname_bvecs_list:
    #     bvecs = []
    #     with open(i_fname) as f:
    #         for line in f:
    #             bvec_line = map(float, line.split())
    #             bvecs.append(bvec_line)
    #     bvecs_all.append(bvecs)
    #     f.close()
    # # Concatenate
    # bvecs_concat = ''
    # for i in range(0, 3):
    #     for j in range(0, nb_files):
    #         bvecs_concat += ' '.join(str(v) for v in bvecs_all[j][i])
    #         bvecs_concat += ' '
    #     bvecs_concat += '\n'
    #

    # Open bvec files and collect values
    bvecs_all = ['', '', '']
    for i_fname in fname_bvecs_list:
        from dipy.data.fetcher import read_bvals_bvecs
        bval_i, bvec_i = read_bvals_bvecs(None, i_fname)
        for i in range(0, 3):
            bvecs_all[i] += ' '.join(
                str(v) for v in map(lambda n: '%.16f' % n, bvec_i[:, i]))
            bvecs_all[i] += ' '

    # Concatenate
    bvecs_concat = '\n'.join(str(v) for v in bvecs_all)

    # Write new bvec
    new_f = open(fname_out, 'w')
    new_f.write(bvecs_concat)
    new_f.close()
def init(param_test):
    """
    Initialize class: param_test
    """
    # initialization
    param_test.folder_data = ['mt/', 't2/', 'dmri/']
    param_test.file_data = ['mtr.nii.gz', 't2.nii.gz', 'dmri.nii.gz']

    # test padding
    param_test.pad = 2

    # test concatenation of data
    path_fname, file_fname, ext_fname = extract_fname(param_test.file_data[2])
    param_test.dmri_t_slices = [
        os.path.join(param_test.folder_data[2],
                     file_fname + '_T' + str(i).zfill(4) + ext_fname)
        for i in range(7)
    ]
    input_concat = ' '.join(param_test.dmri_t_slices)

    default_args = [
        '-i ' +
        os.path.join(param_test.folder_data[0], param_test.file_data[0]) +
        ' -o sct_image_out.nii.gz' + ' -pad 0,0,' + str(param_test.pad),
        '-i ' +
        os.path.join(param_test.folder_data[1], param_test.file_data[1]) +
        ' -getorient',  # 3D
        '-i ' +
        os.path.join(param_test.folder_data[2], param_test.file_data[2]) +
        ' -getorient',  # 4D
        '-i ' +
        os.path.join(param_test.folder_data[2], param_test.file_data[2]) +
        ' -split t -o dmri.nii.gz',
        '-i ' + input_concat + ' -concat t -o dmri_concat.nii.gz'
    ]

    # assign default params
    if not param_test.args:
        param_test.args = default_args

    return param_test
Exemplo n.º 11
0
def main(argv=None):
    parser = get_parser()
    arguments = parser.parse_args(argv)
    verbose = arguments.v
    set_loglevel(verbose=verbose)

    model = arguments.model
    if "," in arguments.radius:
        patch_radius = list_type(",", int)(arguments.radius)
    else:
        patch_radius = int(arguments.radius)

    file_to_denoise = arguments.i
    bval_file = arguments.b
    output_file_name = arguments.o

    path, file, ext = extract_fname(file_to_denoise)

    img = nib.load(file_to_denoise)
    bvals = np.loadtxt(bval_file)
    hdr_0 = img.get_header()
    data = img.get_data()

    printv('Applying Patch2Self Denoising...')
    den = patch2self(data,
                     bvals,
                     patch_radius=patch_radius,
                     model=model,
                     verbose=True)

    if verbose == 2:
        import matplotlib.pyplot as plt
        fig, ax = plt.subplots(1, 3)
        axial_middle = int(data.shape[2] / 2)
        middle_vol = int(data.shape[3] / 2)
        before = data[:, :, axial_middle, middle_vol].T
        ax[0].imshow(before, cmap='gray', origin='lower')
        ax[0].set_title('before')
        after = den[:, :, axial_middle, middle_vol].T
        ax[1].imshow(after, cmap='gray', origin='lower')
        ax[1].set_title('after')
        difference = np.absolute(after.astype('f8') - before.astype('f8'))
        ax[2].imshow(difference, cmap='gray', origin='lower')
        ax[2].set_title('difference')
        for i in range(3):
            ax[i].set_axis_off()
        plt.show()

    # Save files
    img_denoise = nib.Nifti1Image(den, None, hdr_0)
    diff_4d = np.absolute(den.astype('f8') - data.astype('f8'))
    img_diff = nib.Nifti1Image(diff_4d, None, hdr_0)
    if output_file_name is not None:
        output_file_name_den = output_file_name
        output_file_name_diff = add_suffix(output_file_name, "_difference")
    else:
        output_file_name_den = file + '_patch2self_denoised' + ext
        output_file_name_diff = file + '_patch2self_difference' + ext
    nib.save(img_denoise, output_file_name_den)
    nib.save(img_diff, output_file_name_diff)

    printv('\nDone! To view results, type:', verbose)
    printv('fsleyes ' + file_to_denoise + ' ' + output_file_name + ' & \n',
           verbose, 'info')
Exemplo n.º 12
0
def main(argv=None):
    parser = get_parser()
    arguments = parser.parse_args(argv)
    verbose = arguments.v
    set_global_loglevel(verbose=verbose)

    parameter = arguments.p
    remove_temp_files = arguments.r
    noise_threshold = arguments.d

    file_to_denoise = arguments.i
    output_file_name = arguments.o
    std_noise = arguments.std

    param = Param()
    param.verbose = verbose
    param.remove_temp_files = remove_temp_files
    param.parameter = parameter

    path, file, ext = extract_fname(file_to_denoise)

    img = nib.load(file_to_denoise)
    hdr_0 = img.get_header()

    data = img.get_data()
    aff = img.get_affine()

    if min(data.shape) <= 5:
        printv('One of the image dimensions is <= 5 : reducing the size of the block radius.')
        block_radius = min(data.shape) - 1
    else:
        block_radius = 5  # default value

    # Process for manual detecting of background
    # mask = data[:, :, :] > noise_threshold
    # data = data[:, :, :]

    from dipy.denoise.nlmeans import nlmeans

    if arguments.std is not None:
        sigma = std_noise
        # Application of NLM filter to the image
        printv('Applying Non-local mean filter...')
        if param.parameter == 'Rician':
            den = nlmeans(data, sigma=sigma, mask=None, rician=True, block_radius=block_radius)
        else:
            den = nlmeans(data, sigma=sigma, mask=None, rician=False, block_radius=block_radius)
    else:
        # # Process for manual detecting of background
        mask = data > noise_threshold
        sigma = np.std(data[~mask])
        # Application of NLM filter to the image
        printv('Applying Non-local mean filter...')
        if param.parameter == 'Rician':
            den = nlmeans(data, sigma=sigma, mask=mask, rician=True, block_radius=block_radius)
        else:
            den = nlmeans(data, sigma=sigma, mask=mask, rician=False, block_radius=block_radius)

    t = time()
    printv("total time: %s" % (time() - t))
    printv("vol size", den.shape)

    axial_middle = int(data.shape[2] / 2)

    before = data[:, :, axial_middle].T
    after = den[:, :, axial_middle].T

    diff_3d = np.absolute(den.astype('f8') - data.astype('f8'))
    difference = np.absolute(after.astype('f8') - before.astype('f8'))
    if arguments.std is None:
        difference[~mask[:, :, axial_middle].T] = 0

    if param.verbose == 2:
        import matplotlib.pyplot as plt
        fig, ax = plt.subplots(1, 3)
        ax[0].imshow(before, cmap='gray', origin='lower')
        ax[0].set_title('before')
        ax[1].imshow(after, cmap='gray', origin='lower')
        ax[1].set_title('after')
        ax[2].imshow(difference, cmap='gray', origin='lower')
        ax[2].set_title('difference')
        for i in range(3):
            ax[i].set_axis_off()

        plt.show()

    # Save files
    img_denoise = nib.Nifti1Image(den, None, hdr_0)
    img_diff = nib.Nifti1Image(diff_3d, None, hdr_0)
    if output_file_name is not None:
        output_file_name = output_file_name
    else:
        output_file_name = file + '_denoised' + ext
    nib.save(img_denoise, output_file_name)
    nib.save(img_diff, file + '_difference' + ext)

    printv('\nDone! To view results, type:', param.verbose)
    printv('fsleyes ' + file_to_denoise + ' ' + output_file_name + ' & \n', param.verbose, 'info')