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')
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
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
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
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')
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')