def _run_interface(self, runtime): # resampling the reference image to the dimension of the EPI import SimpleITK as sitk import os from rabies.preprocess_pkg.utils import run_command img = sitk.ReadImage(self.inputs.in_file, self.inputs.rabies_data_type) if not self.inputs.resampling_dim == 'origin': shape = self.inputs.resampling_dim.split('x') spacing = (float(shape[0]), float(shape[1]), float(shape[2])) else: spacing = img.GetSpacing()[:3] resampled = resample_image_spacing( sitk.ReadImage(self.inputs.ref_file, self.inputs.rabies_data_type), spacing) sitk.WriteImage(resampled, 'resampled.nii.gz') # tranforms is a list of transform files, set in order of call within antsApplyTransforms transform_string = "" for transform, inverse in zip(self.inputs.transforms, self.inputs.inverses): if bool(inverse): transform_string += "-t [%s,1] " % (transform, ) else: transform_string += "-t %s " % (transform, ) print("Splitting bold file into lists of single volumes") [bold_volumes, num_volumes] = split_volumes(self.inputs.in_file, "bold_", self.inputs.rabies_data_type) if self.inputs.apply_motcorr: motcorr_params = self.inputs.motcorr_params ref_img = os.path.abspath('resampled.nii.gz') warped_volumes = [] for x in range(0, num_volumes): warped_vol_fname = os.path.abspath("deformed_volume" + str(x) + ".nii.gz") warped_volumes.append(warped_vol_fname) if self.inputs.apply_motcorr: command = 'antsMotionCorrStats -m %s -o motcorr_vol%s.mat -t %s' % ( motcorr_params, x, x) rc = run_command(command) command = 'antsApplyTransforms -i %s %s-t motcorr_vol%s.mat -n BSpline[5] -r %s -o %s' % ( bold_volumes[x], transform_string, x, ref_img, warped_vol_fname) rc = run_command(command) else: command = 'antsApplyTransforms -i %s %s-n BSpline[5] -r %s -o %s' % ( bold_volumes[x], transform_string, ref_img, warped_vol_fname) rc = run_command(command) # change image to specified data type sitk.WriteImage( sitk.ReadImage(warped_vol_fname, self.inputs.rabies_data_type), warped_vol_fname) setattr(self, 'out_files', warped_volumes) return runtime
def _run_interface(self, runtime): import os import SimpleITK as sitk from rabies.preprocess_pkg.utils import run_command # check the size of the lowest dimension, and make sure that the first shrinking factor allow for at least 4 slices shrinking_factor = 4 img = sitk.ReadImage(self.inputs.in_file, self.inputs.rabies_data_type) low_dim = np.asarray(img.GetSize()[:3]).min() if shrinking_factor > int(low_dim / 4): shrinking_factor = int(low_dim / 4) # change the name of the first iteration directory to prevent overlap of files with second iteration if self.inputs.second: command = 'mv ants_mc_tmp first_ants_mc_tmp' rc = run_command(command) # make a tmp directory to store the files os.makedirs('ants_mc_tmp', exist_ok=True) command = 'antsMotionCorr -d 3 -o [ants_mc_tmp/motcorr,ants_mc_tmp/motcorr.nii.gz,ants_mc_tmp/motcorr_avg.nii.gz] \ -m MI[ %s , %s , 1 , 20 , Regular, 0.2 ] -t Rigid[ 0.1 ] -i 100x50x30 -u 1 -e 1 -l 1 -s 2x1x0 -f %sx2x1 -n 10' % ( self.inputs.ref_file, self.inputs.in_file, str(shrinking_factor)) rc = run_command(command) setattr(self, 'csv_params', 'ants_mc_tmp/motcorrMOCOparams.csv') setattr(self, 'mc_corrected_bold', 'ants_mc_tmp/motcorr.nii.gz') setattr(self, 'avg_image', 'ants_mc_tmp/motcorr_avg.nii.gz') return runtime
def _run_interface(self, runtime): import os import numpy as np import SimpleITK as sitk from rabies.preprocess_pkg.utils import resample_image_spacing, run_command cwd = os.getcwd() out_dir = '%s/anat_preproc/' % (cwd, ) command = 'mkdir -p %s' % (out_dir, ) rc = run_command(command) import pathlib # Better path manipulation filename_split = pathlib.Path(self.inputs.nii_anat).name.rsplit(".nii") dir_path = os.path.dirname(os.path.realpath(__file__)) output_anat = '%s%s_preproc.nii.gz' % ( out_dir, filename_split[0], ) # resample the anatomical image to the resolution of the provided template anat_image = sitk.ReadImage(self.inputs.nii_anat, self.inputs.rabies_data_type) anat_dim = anat_image.GetSpacing() template_image = sitk.ReadImage(self.inputs.template_anat, self.inputs.rabies_data_type) template_dim = template_image.GetSpacing() if not (np.array(anat_dim) == np.array(template_dim)).sum() == 3: print('Anat image will be resampled to the template resolution.') resampled_anat = resample_image_spacing(anat_image, template_dim) input_anat = out_dir + filename_split[0] + '_resampled.nii.gz' sitk.WriteImage(resampled_anat, input_anat) else: input_anat = self.inputs.nii_anat if self.inputs.disable_anat_preproc: # resample image to specified data format sitk.WriteImage( sitk.ReadImage(input_anat, self.inputs.rabies_data_type), output_anat) else: command = 'bash %s/../shell_scripts/anat_preproc.sh %s %s %s %s %s' % ( dir_path, input_anat, self.inputs.template_anat, self.inputs.template_mask, output_anat, self.inputs.reg_script) rc = run_command(command) # resample image to specified data format sitk.WriteImage( sitk.ReadImage(output_anat, self.inputs.rabies_data_type), output_anat) setattr(self, 'preproc_anat', output_anat) return runtime
def _run_interface(self, runtime): import os import SimpleITK as sitk import pathlib # Better path manipulation filename_split = pathlib.Path( self.inputs.name_source).name.rsplit(".nii") if self.inputs.name_spec is None: new_mask_path = os.path.abspath('%s_EPI_mask.nii.gz' % (filename_split[0], )) else: new_mask_path = os.path.abspath('%s_%s.nii.gz' % ( filename_split[0], self.inputs.name_spec, )) command = 'antsApplyTransforms -i ' + self.inputs.mask + ' -r ' + \ self.inputs.ref_EPI + ' -o ' + new_mask_path + ' -n GenericLabel' from rabies.preprocess_pkg.utils import run_command rc = run_command(command) sitk.WriteImage(sitk.ReadImage(new_mask_path, sitk.sitkInt16), new_mask_path) setattr(self, 'EPI_mask', new_mask_path) return runtime
def run_antsRegistration(reg_method, moving_image='NULL', fixed_image='NULL', anat_mask='NULL', rabies_data_type=8): import os import pathlib # Better path manipulation filename_split = pathlib.Path(moving_image).name.rsplit(".nii") from rabies.preprocess_pkg.registration import define_reg_script reg_call = define_reg_script(reg_method) if reg_method == 'Rigid' or reg_method == 'Affine' or reg_method == 'SyN': command = "%s --fixed-mask %s --resampled-output %s_output_warped_image.nii.gz %s %s %s_output_" % ( reg_call, anat_mask, filename_split[0], moving_image, fixed_image, filename_split[0]) else: command = '%s %s %s %s %s' % (reg_call, moving_image, fixed_image, anat_mask, filename_split[0]) from rabies.preprocess_pkg.utils import run_command rc = run_command(command) cwd = os.getcwd() warped_image = '%s/%s_output_warped_image.nii.gz' % ( cwd, filename_split[0], ) affine = '%s/%s_output_0GenericAffine.mat' % ( cwd, filename_split[0], ) warp = '%s/%s_output_1Warp.nii.gz' % ( cwd, filename_split[0], ) inverse_warp = '%s/%s_output_1InverseWarp.nii.gz' % ( cwd, filename_split[0], ) if not os.path.isfile(warped_image) or not os.path.isfile(affine): raise ValueError( 'REGISTRATION ERROR: OUTPUT FILES MISSING. Make sure the provided registration script runs properly.' ) if not os.path.isfile(warp) or not os.path.isfile(inverse_warp): import logging log = logging.getLogger('root') log.debug( 'No non-linear warp files as output. Assumes linear registration.') warp = 'NULL' inverse_warp = 'NULL' import SimpleITK as sitk sitk.WriteImage(sitk.ReadImage(warped_image, rabies_data_type), warped_image) return [affine, warp, inverse_warp, warped_image]
def resample_IC_file(in_file, ref_file): transforms = [] inverses = [] # resampling the reference image to the dimension of the EPI import SimpleITK as sitk import os from rabies.preprocess_pkg.utils import run_command, split_volumes, copyInfo_4DImage import pathlib # Better path manipulation filename_split = pathlib.Path(in_file).name.rsplit(".nii") out_file = os.path.abspath(filename_split[0]) + '_resampled.nii.gz' # tranforms is a list of transform files, set in order of call within antsApplyTransforms transform_string = "" for transform, inverse in zip(transforms, inverses): if transform == 'NULL': continue elif bool(inverse): transform_string += "-t [%s,1] " % (transform, ) else: transform_string += "-t %s " % (transform, ) # Splitting bold file into lists of single volumes [volumes_list, num_volumes] = split_volumes(in_file, "bold_", sitk.sitkFloat32) warped_volumes = [] for x in range(0, num_volumes): warped_vol_fname = os.path.abspath("deformed_volume" + str(x) + ".nii.gz") warped_volumes.append(warped_vol_fname) command = 'antsApplyTransforms -i %s %s-n BSpline[5] -r %s -o %s' % ( volumes_list[x], transform_string, ref_file, warped_vol_fname) rc = run_command(command) sample_volume = sitk.ReadImage(warped_volumes[0]) shape = sitk.GetArrayFromImage(sample_volume).shape combined = np.zeros((num_volumes, shape[0], shape[1], shape[2])) i = 0 for file in warped_volumes: combined[i, :, :, :] = sitk.GetArrayFromImage( sitk.ReadImage(file))[:, :, :] i = i + 1 if (i != num_volumes): raise ValueError("Error occured with Merge.") combined_image = sitk.GetImageFromArray(combined, isVector=False) # set metadata and affine for the newly constructed 4D image header_source = sitk.ReadImage(in_file) combined_image = copyInfo_4DImage(combined_image, sample_volume, header_source) sitk.WriteImage(combined_image, out_file) return out_file
def resample_template(template_file, mask_file, file_list, spacing='inputs_defined', rabies_data_type=8): import os import SimpleITK as sitk import numpy as np from rabies.preprocess_pkg.utils import resample_image_spacing, run_command import logging log = logging.getLogger('root') if spacing == 'inputs_defined': file_list = list(np.asarray(file_list).flatten()) img = sitk.ReadImage(file_list[0], rabies_data_type) low_dim = np.asarray(img.GetSpacing()[:3]).min() for file in file_list[1:]: img = sitk.ReadImage(file, rabies_data_type) new_low_dim = np.asarray(img.GetSpacing()[:3]).min() if new_low_dim < low_dim: low_dim = new_low_dim spacing = (low_dim, low_dim, low_dim) template_image = sitk.ReadImage(template_file, rabies_data_type) template_dim = template_image.GetSpacing() if np.asarray(template_dim[:3]).min() > low_dim: log.info("The template retains its original resolution.") return template_file else: shape = spacing.split('x') spacing = (float(shape[0]), float(shape[1]), float(shape[2])) log.info("Resampling template to %sx%sx%smm dimensions." % ( spacing[0], spacing[1], spacing[2], )) resampled_template = os.path.abspath("resampled_template.nii.gz") sitk.WriteImage( resample_image_spacing(sitk.ReadImage(template_file, rabies_data_type), spacing), resampled_template) # also resample the brain mask to ensure stable registrations further down resampled_mask = os.path.abspath("resampled_mask.nii.gz") command = 'antsApplyTransforms -d 3 -i %s -r %s -o %s --verbose -n GenericLabel' % ( mask_file, resampled_template, resampled_mask, ) rc = run_command(command) return resampled_template, resampled_mask
def run_antsRegistration(reg_script, moving_image='NULL', fixed_image='NULL', anat_mask='NULL', rabies_data_type=8): import os import pathlib # Better path manipulation filename_split = pathlib.Path(moving_image).name.rsplit(".nii") if os.path.isfile(reg_script): reg_script_path = reg_script else: raise ValueError( 'REGISTRATION ERROR: THE REG SCRIPT FILE DOES NOT EXISTS') command = 'bash %s %s %s %s %s' % (reg_script_path, moving_image, fixed_image, anat_mask, filename_split[0]) from rabies.preprocess_pkg.utils import run_command rc = run_command(command) cwd = os.getcwd() warped_image = '%s/%s_output_warped_image.nii.gz' % ( cwd, filename_split[0], ) affine = '%s/%s_output_0GenericAffine.mat' % ( cwd, filename_split[0], ) warp = '%s/%s_output_1Warp.nii.gz' % ( cwd, filename_split[0], ) inverse_warp = '%s/%s_output_1InverseWarp.nii.gz' % ( cwd, filename_split[0], ) if not os.path.isfile(warped_image) or not os.path.isfile(affine): raise ValueError( 'REGISTRATION ERROR: OUTPUT FILES MISSING. Make sure the provided registration script runs properly.' ) if not os.path.isfile(warp) or not os.path.isfile(inverse_warp): print( 'No non-linear warp files as output. Assumes linear registration.') warp = 'NULL' inverse_warp = 'NULL' import SimpleITK as sitk sitk.WriteImage(sitk.ReadImage(warped_image, rabies_data_type), warped_image) return [affine, warp, inverse_warp, warped_image]
def _run_interface(self, runtime): import os import pathlib filename_template = pathlib.Path(self.inputs.name_source).name.rsplit(".nii")[0] script_path = 'plot_overlap.sh' os.makedirs(self.inputs.out_dir, exist_ok=True) out_name = self.inputs.out_dir+'/' + \ filename_template+'_registration.png' from rabies.preprocess_pkg.utils import run_command command = '%s %s %s %s' % ( script_path, self.inputs.moving, self.inputs.fixed, out_name) rc = run_command(command) setattr(self, 'out_png', out_name) return runtime
def run_group_ICA(bold_file_list, mask_file, dim, tr): import os import pandas as pd # create a filelist.txt file_path = os.path.abspath('filelist.txt') from rabies.preprocess_pkg.utils import flatten_list merged = flatten_list(list(bold_file_list)) df = pd.DataFrame(data=merged) df.to_csv(file_path, header=False, sep=',', index=False) from rabies.preprocess_pkg.utils import run_command out_dir = os.path.abspath('group_melodic.ica') command = 'melodic -i %s -m %s -o %s --tr=%s -d %s --report' % ( file_path, mask_file, out_dir, tr, dim) rc = run_command(command) IC_file = out_dir + '/melodic_IC.nii.gz' return out_dir, IC_file
def mouse_preprocess_func(input_ref_EPI, anat, anat_mask, name_source): import os import pathlib # Better path manipulation filename_split = pathlib.Path(name_source).name.rsplit(".nii") cwd = os.getcwd() corrected_EPI = '%s/%s_bias_cor.nii.gz' % ( cwd, filename_split[0], ) import rabies dir_path = os.path.dirname(os.path.realpath(rabies.__file__)) from rabies.preprocess_pkg.utils import run_command command = 'rabies-mouse-preprocessing-v5.sh %s %s %s %s' % ( input_ref_EPI, corrected_EPI, anat, anat_mask) rc = run_command(command) denoise_mask = corrected_EPI.split('.nii.gz')[0] + '_mask.nii.gz' init_denoise = corrected_EPI.split( '.nii.gz')[0] + '_init_denoise.nii.gz' return corrected_EPI, denoise_mask, init_denoise
def resample_4D(input_4d, ref_file): import os import pathlib # Better path manipulation import SimpleITK as sitk from rabies.preprocess_pkg.utils import run_command, split_volumes, Merge, copyInfo_3DImage rabies_data_type = sitk.sitkFloat32 # check if the IC_file has the same dimensions as bold_file img_array = sitk.GetArrayFromImage(sitk.ReadImage(ref_file))[0, :, :, :] image_3d = copyInfo_3DImage( sitk.GetImageFromArray(img_array, isVector=False), sitk.ReadImage(ref_file)) new_ref = 'temp_ref.nii.gz' sitk.WriteImage(image_3d, 'temp_ref.nii.gz') filename_split = pathlib.Path(input_4d).name.rsplit(".nii") # Splitting into list of single volumes [split_volumes_files, num_volumes] = split_volumes(input_4d, "split_", rabies_data_type) resampled_volumes = [] for x in range(0, num_volumes): resampled_vol_fname = os.path.abspath("resampled_volume" + str(x) + ".nii.gz") resampled_volumes.append(resampled_vol_fname) command = 'antsApplyTransforms -i %s -n BSpline[5] -r %s -o %s' % ( split_volumes_files[x], new_ref, resampled_vol_fname) rc = run_command(command) # change image to specified data type sitk.WriteImage(sitk.ReadImage(resampled_vol_fname, rabies_data_type), resampled_vol_fname) out = Merge(in_files=resampled_volumes, header_source=input_4d, rabies_data_type=rabies_data_type, clip_negative=False).run() return out.outputs.out_file
def install_DSURQE(log): install=False # verifies whether default template files are installed and installs them otherwise if not os.path.isfile("%s/DSURQE_40micron_average.nii.gz" % (rabies_path)): install=True elif not os.path.isfile("%s/DSURQE_40micron_mask.nii.gz" % (rabies_path)): install=True elif not os.path.isfile("%s/DSURQE_40micron_eroded_WM_mask.nii.gz" % (rabies_path)): install=True elif not os.path.isfile("%s/DSURQE_40micron_eroded_CSF_mask.nii.gz" % (rabies_path)): install=True elif not os.path.isfile("%s/DSURQE_40micron_labels.nii.gz" % (rabies_path)): install=True elif not os.path.isfile("%s/vascular_mask.nii.gz" % (rabies_path)): install=True elif not os.path.isfile("%s/melodic_IC.nii.gz" % (rabies_path)): install=True if install: from rabies.preprocess_pkg.utils import run_command log.info("SOME FILES FROM THE DEFAULT TEMPLATE ARE MISSING. THEY WILL BE INSTALLED BEFORE FURTHER PROCESSING.") rc = run_command('install_DSURQE.sh %s' % (rabies_path), verbose = True)
def _run_interface(self, runtime): import os import pathlib folder_template = pathlib.Path( self.inputs.split_name).name.rsplit(".nii")[0] filename_template = pathlib.Path( self.inputs.name_source).name.rsplit(".nii")[0] import pandas as pd def csv2par(in_confounds): df = pd.read_csv(in_confounds) new_df = pd.DataFrame( columns=['mov1', 'mov2', 'mov3', 'rot1', 'rot2', 'rot3']) new_df['mov1'] = df['mov1'] new_df['mov2'] = df['mov2'] new_df['mov3'] = df['mov3'] new_df['rot1'] = df['rot1'] new_df['rot2'] = df['rot2'] new_df['rot3'] = df['rot3'] out_confounds = os.path.abspath( (os.path.basename(in_confounds).split('.')[0]) + ('.par')) new_df.to_csv(out_confounds, sep='\t', index=False, header=False) return out_confounds par_file = csv2par(self.inputs.confounds_csv) import rabies dir_path = os.path.dirname(os.path.realpath(rabies.__file__)) script_path = dir_path + '/shell_scripts/plot_motion_traces.sh' os.makedirs(self.inputs.out_dir + '/' + folder_template, exist_ok=True) prefix = self.inputs.out_dir+'/'+folder_template+'/' + \ filename_template command = 'bash %s %s %s' % (script_path, par_file, prefix) from rabies.preprocess_pkg.utils import run_command rc = run_command(command) setattr(self, 'out_png', '%s_motion_traces.png' % (prefix)) return runtime
def _run_interface(self, runtime): import os import pathlib folder_template = pathlib.Path( self.inputs.split_name).name.rsplit(".nii")[0] filename_template = pathlib.Path( self.inputs.name_source).name.rsplit(".nii")[0] import rabies dir_path = os.path.dirname(os.path.realpath(rabies.__file__)) script_path = dir_path + '/shell_scripts/plot_overlap.sh' os.makedirs(self.inputs.out_dir + '/' + folder_template, exist_ok=True) out_name = self.inputs.out_dir+'/'+folder_template+'/' + \ filename_template+'_'+self.inputs.reg_name+'.png' from rabies.preprocess_pkg.utils import run_command command = 'bash %s %s %s %s' % (script_path, self.inputs.moving, self.inputs.fixed, out_name) rc = run_command(command) setattr(self, 'out_png', out_name) return runtime
def otsu_scaling(image): import numpy as np import SimpleITK as sitk img = sitk.ReadImage(image) array = sitk.GetArrayFromImage(img) # select a smart vmax for the image display to enhance contrast from rabies.preprocess_pkg.utils import run_command command = 'ThresholdImage 3 %s otsu_weight.nii.gz Otsu 4' % (image) rc = run_command(command) # clip off the background mask = sitk.GetArrayFromImage(sitk.ReadImage('otsu_weight.nii.gz')) voxel_subset=array[mask>1.0] # select a maximal value which encompasses 90% of the voxels in the mask voxel_subset.sort() vmax=voxel_subset[int(len(voxel_subset)*0.9)] scaled = array/vmax scaled_img=sitk.GetImageFromArray(scaled, isVector=False) scaled_img.CopyInformation(img) return scaled_img
def resample_mask(in_file, ref_file): transforms = [] inverses = [] # resampling the reference image to the dimension of the EPI from rabies.preprocess_pkg.utils import run_command import pathlib # Better path manipulation filename_split = pathlib.Path(in_file).name.rsplit(".nii") out_file = os.path.abspath(filename_split[0]) + '_resampled.nii.gz' # tranforms is a list of transform files, set in order of call within antsApplyTransforms transform_string = "" for transform, inverse in zip(transforms, inverses): if transform == 'NULL': continue elif bool(inverse): transform_string += "-t [%s,1] " % (transform, ) else: transform_string += "-t %s " % (transform, ) command = 'antsApplyTransforms -i %s %s-n GenericLabel -r %s -o %s' % ( in_file, transform_string, ref_file, out_file) rc = run_command(command) return out_file
def transform_masks_anat(brain_mask_in, WM_mask_in, CSF_mask_in, vascular_mask_in, atlas_labels_in, reference_image, anat_to_template_inverse_warp, anat_to_template_affine, template_to_common_affine, template_to_common_inverse_warp): # function to transform atlas masks to individual anatomical scans import os from rabies.preprocess_pkg.utils import run_command cwd = os.getcwd() import pathlib # Better path manipulation filename_template = pathlib.Path(reference_image).name.rsplit(".nii")[0] input_image = brain_mask_in brain_mask = '%s/%s_%s' % (cwd, filename_template, 'anat_mask.nii.gz') command = 'antsApplyTransforms -d 3 -i %s -t %s -t [%s,1] -t %s -t [%s,1] -r %s -o %s --verbose -n GenericLabel' % ( input_image, anat_to_template_inverse_warp, anat_to_template_affine, template_to_common_inverse_warp, template_to_common_affine, reference_image, brain_mask, ) rc = run_command(command) if not os.path.isfile(brain_mask): raise ValueError("Missing output mask. Transform call failed: " + command) input_image = WM_mask_in WM_mask = '%s/%s_%s' % (cwd, filename_template, 'WM_mask.nii.gz') command = 'antsApplyTransforms -d 3 -i %s -t %s -t [%s,1] -t %s -t [%s,1] -r %s -o %s --verbose -n GenericLabel' % ( input_image, anat_to_template_inverse_warp, anat_to_template_affine, template_to_common_inverse_warp, template_to_common_affine, reference_image, WM_mask, ) rc = run_command(command) if not os.path.isfile(WM_mask): raise ValueError("Missing output mask. Transform call failed: " + command) input_image = CSF_mask_in CSF_mask = '%s/%s_%s' % (cwd, filename_template, 'CSF_mask.nii.gz') command = 'antsApplyTransforms -d 3 -i %s -t %s -t [%s,1] -t %s -t [%s,1] -r %s -o %s --verbose -n GenericLabel' % ( input_image, anat_to_template_inverse_warp, anat_to_template_affine, template_to_common_inverse_warp, template_to_common_affine, reference_image, CSF_mask, ) rc = run_command(command) if not os.path.isfile(CSF_mask): raise ValueError("Missing output mask. Transform call failed: " + command) input_image = vascular_mask_in vascular_mask = '%s/%s_%s' % (cwd, filename_template, 'vascular_mask.nii.gz') command = 'antsApplyTransforms -d 3 -i %s -t %s -t [%s,1] -t %s -t [%s,1] -r %s -o %s --verbose -n GenericLabel' % ( input_image, anat_to_template_inverse_warp, anat_to_template_affine, template_to_common_inverse_warp, template_to_common_affine, reference_image, vascular_mask, ) rc = run_command(command) if not os.path.isfile(vascular_mask): raise ValueError("Missing output mask. Transform call failed: " + command) input_image = atlas_labels_in anat_labels = '%s/%s_%s' % (cwd, filename_template, 'atlas_labels.nii.gz') command = 'antsApplyTransforms -d 3 -i %s -t %s -t [%s,1] -t %s -t [%s,1] -r %s -o %s --verbose -n GenericLabel' % ( input_image, anat_to_template_inverse_warp, anat_to_template_affine, template_to_common_inverse_warp, template_to_common_affine, reference_image, anat_labels, ) rc = run_command(command) if not os.path.isfile(anat_labels): raise ValueError("Missing output mask. Transform call failed: " + command) return brain_mask, WM_mask, CSF_mask, vascular_mask, anat_labels
def _run_interface(self, runtime): import os import numpy as np import SimpleITK as sitk import pathlib # Better path manipulation filename_split = pathlib.Path( self.inputs.name_source).name.rsplit(".nii") from rabies.preprocess_pkg.utils import run_command, resample_image_spacing from rabies.preprocess_pkg.registration import run_antsRegistration cwd = os.getcwd() resampled = '%s/%s_resampled.nii.gz' % (cwd, filename_split[0]) resampled_mask = '%s/%s_resampled_mask.nii.gz' % (cwd, filename_split[0]) biascor_EPI = '%s/%s_bias_cor.nii.gz' % ( cwd, filename_split[0], ) input_ref_EPI_img = sitk.ReadImage(self.inputs.input_ref_EPI, self.inputs.rabies_data_type) # the -b will be rounded up to the nearest multiple of 10 of the image largest dimension largest_dim = (np.array(input_ref_EPI_img.GetSize()) * np.array(input_ref_EPI_img.GetSpacing())).max() b_value = int(np.ceil(largest_dim / 10) * 10) bias_cor_input = self.inputs.input_ref_EPI otsu_bias_cor(target=bias_cor_input, otsu_ref=bias_cor_input, out_name=cwd + '/corrected_iter1.nii.gz', b_value=b_value) otsu_bias_cor(target=bias_cor_input, otsu_ref=cwd + '/corrected_iter1.nii.gz', out_name=cwd + '/corrected_iter2.nii.gz', b_value=b_value) [affine, warp, inverse_warp, warped_image ] = run_antsRegistration(reg_method='Rigid', moving_image=cwd + '/corrected_iter2.nii.gz', fixed_image=self.inputs.anat, anat_mask=self.inputs.anat_mask) command = 'antsApplyTransforms -d 3 -i %s -t [%s,1] -r %s -o %s -n GenericLabel' % ( self.inputs.anat_mask, affine, cwd + '/corrected_iter2.nii.gz', resampled_mask) rc = run_command(command) otsu_bias_cor(target=bias_cor_input, otsu_ref=cwd + '/corrected_iter2.nii.gz', out_name=cwd + '/final_otsu.nii.gz', b_value=b_value, mask=resampled_mask) # resample to anatomical image resolution dim = sitk.ReadImage(self.inputs.anat, self.inputs.rabies_data_type).GetSpacing() low_dim = np.asarray(dim).min() sitk.WriteImage( resample_image_spacing( sitk.ReadImage(cwd + '/final_otsu.nii.gz', self.inputs.rabies_data_type), (low_dim, low_dim, low_dim)), biascor_EPI) sitk.WriteImage( sitk.ReadImage(cwd + '/corrected_iter2.nii.gz', self.inputs.rabies_data_type), cwd + '/corrected_iter2.nii.gz') sitk.WriteImage( sitk.ReadImage(biascor_EPI, self.inputs.rabies_data_type), biascor_EPI) sitk.WriteImage( sitk.ReadImage(warped_image, self.inputs.rabies_data_type), warped_image) sitk.WriteImage( sitk.ReadImage(resampled_mask, self.inputs.rabies_data_type), resampled_mask) setattr(self, 'init_denoise', cwd + '/corrected_iter2.nii.gz') setattr(self, 'corrected_EPI', biascor_EPI) setattr(self, 'warped_EPI', warped_image) setattr(self, 'denoise_mask', resampled_mask) return runtime
def _run_interface(self, runtime): import os import numpy as np import SimpleITK as sitk import pathlib # Better path manipulation filename_split = pathlib.Path( self.inputs.name_source).name.rsplit(".nii") import rabies from rabies.preprocess_pkg.utils import run_command, resample_image_spacing dir_path = os.path.dirname(os.path.realpath(rabies.__file__)) reg_script_path = dir_path + '/shell_scripts/antsRegistration_rigid.sh' cwd = os.getcwd() warped_image = '%s/%s_output_warped_image.nii.gz' % (cwd, filename_split[0]) resampled = '%s/%s_resampled.nii.gz' % (cwd, filename_split[0]) resampled_mask = '%s/%s_resampled_mask.nii.gz' % (cwd, filename_split[0]) biascor_EPI = '%s/%s_bias_cor.nii.gz' % ( cwd, filename_split[0], ) # resample to isotropic resolution based on lowest dimension input_ref_EPI_img = sitk.ReadImage(self.inputs.input_ref_EPI, self.inputs.rabies_data_type) dim = input_ref_EPI_img.GetSpacing() low_dim = np.asarray(dim).min() #sitk.WriteImage(resample_image_spacing( # input_ref_EPI_img, (low_dim, low_dim, low_dim)), resampled) # the -b will be rounded up to the nearest multiple of 10 of the image largest dimension largest_dim = (np.array(input_ref_EPI_img.GetSize()) * np.array(input_ref_EPI_img.GetSpacing())).max() b_value = int(np.ceil(largest_dim / 10) * 10) bias_cor_input = self.inputs.input_ref_EPI otsu_bias_cor(target=bias_cor_input, otsu_ref=bias_cor_input, out_name='corrected_iter1.nii.gz', b_value=b_value) otsu_bias_cor(target=bias_cor_input, otsu_ref='corrected_iter1.nii.gz', out_name='corrected_iter2.nii.gz', b_value=b_value) command = 'bash %s %s %s %s %s' % ( reg_script_path, 'corrected_iter2.nii.gz', self.inputs.anat, self.inputs.anat_mask, filename_split[0], ) rc = run_command(command) command = 'antsApplyTransforms -d 3 -i %s -t [%s_output_0GenericAffine.mat,1] -r %s -o %s -n GenericLabel' % ( self.inputs.anat_mask, filename_split[0], 'corrected_iter2.nii.gz', resampled_mask) rc = run_command(command) otsu_bias_cor(target=bias_cor_input, otsu_ref='corrected_iter2.nii.gz', out_name=cwd + '/final_otsu.nii.gz', b_value=b_value, mask=resampled_mask) # resample to anatomical image resolution dim = sitk.ReadImage(self.inputs.anat, self.inputs.rabies_data_type).GetSpacing() low_dim = np.asarray(dim).min() sitk.WriteImage( resample_image_spacing( sitk.ReadImage(cwd + '/final_otsu.nii.gz', self.inputs.rabies_data_type), (low_dim, low_dim, low_dim)), biascor_EPI) sitk.WriteImage( sitk.ReadImage(biascor_EPI, self.inputs.rabies_data_type), biascor_EPI) sitk.WriteImage( sitk.ReadImage(warped_image, self.inputs.rabies_data_type), warped_image) sitk.WriteImage( sitk.ReadImage(resampled_mask, self.inputs.rabies_data_type), resampled_mask) setattr(self, 'corrected_EPI', biascor_EPI) setattr(self, 'warped_EPI', warped_image) setattr(self, 'resampled_mask', resampled_mask) return runtime
def _run_interface(self, runtime): import os import numpy as np import SimpleITK as sitk import pathlib # Better path manipulation filename_split = pathlib.Path( self.inputs.name_source).name.rsplit(".nii") import rabies from rabies.preprocess_pkg.utils import run_command, resample_image_spacing dir_path = os.path.dirname(os.path.realpath(rabies.__file__)) reg_script_path = dir_path + '/shell_scripts/antsRegistration_rigid.sh' bias_cor_script_path = dir_path + '/shell_scripts/iter_bias_cor.sh' cwd = os.getcwd() warped_image = '%s/%s_output_warped_image.nii.gz' % (cwd, filename_split[0]) resampled_mask = '%s/%s_resampled_mask.nii.gz' % (cwd, filename_split[0]) biascor_EPI = '%s/%s_bias_cor.nii.gz' % ( cwd, filename_split[0], ) # resample to isotropic resolution based on lowest dimension input_ref_EPI = sitk.ReadImage(self.inputs.input_ref_EPI, self.inputs.rabies_data_type) dim = input_ref_EPI.GetSpacing() low_dim = np.asarray(dim).min() from rabies.preprocess_pkg.utils import resample_image_spacing sitk.WriteImage( resample_image_spacing(input_ref_EPI, (low_dim, low_dim, low_dim)), cwd + '/resampled.nii.gz') command = 'bash %s %s %s %s %s %s' % ( bias_cor_script_path, self.inputs.input_ref_EPI, self.inputs.anat, self.inputs.anat_mask, filename_split[0], reg_script_path) from rabies.preprocess_pkg.utils import run_command rc = run_command(command) # resample to anatomical image resolution dim = sitk.ReadImage(self.inputs.anat, self.inputs.rabies_data_type).GetSpacing() low_dim = np.asarray(dim).min() sitk.WriteImage( resample_image_spacing( sitk.ReadImage(cwd + '/iter_corrected.nii.gz', self.inputs.rabies_data_type), (low_dim, low_dim, low_dim)), biascor_EPI) sitk.WriteImage( sitk.ReadImage(biascor_EPI, self.inputs.rabies_data_type), biascor_EPI) sitk.WriteImage( sitk.ReadImage(warped_image, self.inputs.rabies_data_type), warped_image) sitk.WriteImage( sitk.ReadImage(resampled_mask, self.inputs.rabies_data_type), resampled_mask) setattr(self, 'corrected_EPI', biascor_EPI) setattr(self, 'warped_EPI', warped_image) setattr(self, 'resampled_mask', resampled_mask) return runtime
def otsu_bias_cor(target, otsu_ref, out_name, b_value, mask=None, n_iter=200): import SimpleITK as sitk from rabies.preprocess_pkg.utils import run_command command = 'ImageMath 3 null_mask.nii.gz ThresholdAtMean %s 0' % (otsu_ref) rc = run_command(command) command = 'ThresholdImage 3 %s otsu_weight.nii.gz Otsu 4' % (otsu_ref) rc = run_command(command) otsu_img = sitk.ReadImage('otsu_weight.nii.gz', sitk.sitkUInt8) otsu_array = sitk.GetArrayFromImage(otsu_img) if mask is not None: resampled_mask_img = sitk.ReadImage(mask, sitk.sitkUInt8) resampled_mask_array = sitk.GetArrayFromImage(resampled_mask_img) otsu_array = otsu_array * resampled_mask_array combined_mask = (otsu_array == 1.0) + (otsu_array == 2.0) mask_img = sitk.GetImageFromArray(combined_mask.astype('uint8'), isVector=False) mask_img.CopyInformation(otsu_img) sitk.WriteImage(mask_img, 'mask12.nii.gz') combined_mask = (otsu_array == 3.0) + (otsu_array == 4.0) mask_img = sitk.GetImageFromArray(combined_mask.astype('uint8'), isVector=False) mask_img.CopyInformation(otsu_img) sitk.WriteImage(mask_img, 'mask34.nii.gz') combined_mask = (otsu_array == 1.0) + (otsu_array == 2.0) + (otsu_array == 3.0) mask_img = sitk.GetImageFromArray(combined_mask.astype('uint8'), isVector=False) mask_img.CopyInformation(otsu_img) sitk.WriteImage(mask_img, 'mask123.nii.gz') combined_mask = (otsu_array == 2.0) + (otsu_array == 3.0) + (otsu_array == 4.0) mask_img = sitk.GetImageFromArray(combined_mask.astype('uint8'), isVector=False) mask_img.CopyInformation(otsu_img) sitk.WriteImage(mask_img, 'mask234.nii.gz') combined_mask = (otsu_array == 1.0) + (otsu_array == 2.0) + ( otsu_array == 3.0) + (otsu_array == 4.0) mask_img = sitk.GetImageFromArray(combined_mask.astype('uint8'), isVector=False) mask_img.CopyInformation(otsu_img) sitk.WriteImage(mask_img, 'mask1234.nii.gz') command = 'N4BiasFieldCorrection -d 3 -i %s -b %s -s 1 -c [%sx%sx%s,1e-4] -w mask12.nii.gz -x null_mask.nii.gz -o corrected1.nii.gz' % ( target, str(b_value), str(n_iter), str(n_iter), str(n_iter), ) rc = run_command(command) command = 'N4BiasFieldCorrection -d 3 -i corrected1.nii.gz -b %s -s 1 -c [%sx%sx%s,1e-4] -w mask34.nii.gz -x null_mask.nii.gz -o corrected2.nii.gz' % ( str(b_value), str(n_iter), str(n_iter), str(n_iter), ) rc = run_command(command) command = 'N4BiasFieldCorrection -d 3 -i corrected2.nii.gz -b %s -s 1 -c [%sx%sx%s,1e-4] -w mask123.nii.gz -x null_mask.nii.gz -o corrected3.nii.gz' % ( str(b_value), str(n_iter), str(n_iter), str(n_iter), ) rc = run_command(command) command = 'N4BiasFieldCorrection -d 3 -i corrected3.nii.gz -b %s -s 1 -c [%sx%sx%s,1e-4] -w mask234.nii.gz -x null_mask.nii.gz -o corrected4.nii.gz' % ( str(b_value), str(n_iter), str(n_iter), str(n_iter), ) rc = run_command(command) command = 'N4BiasFieldCorrection -d 3 -i corrected4.nii.gz -b %s -s 1 -c [%sx%sx%s,1e-4] -w mask1234.nii.gz -x null_mask.nii.gz -o %s' % ( str(b_value), str(n_iter), str(n_iter), str(n_iter), out_name, ) rc = run_command(command)
def _run_interface(self, runtime): import os import numpy as np import SimpleITK as sitk import pathlib # Better path manipulation filename_split = pathlib.Path( self.inputs.name_source).name.rsplit(".nii") from rabies.preprocess_pkg.utils import run_command, resample_image_spacing from rabies.preprocess_pkg.registration import run_antsRegistration cwd = os.getcwd() resampled_mask = '%s/%s_resampled_mask.nii.gz' % (cwd, filename_split[0]) biascor_EPI = '%s/%s_bias_cor.nii.gz' % ( cwd, filename_split[0], ) command = 'ImageMath 3 null_mask.nii.gz ThresholdAtMean %s 0' % ( self.inputs.input_ref_EPI) rc = run_command(command) command = 'ImageMath 3 thresh_mask.nii.gz ThresholdAtMean %s 2' % ( self.inputs.input_ref_EPI) rc = run_command(command) command = 'N4BiasFieldCorrection -d 3 -s 4 -i %s -b 20 -s 1 -c [100x100x100x100,1e-6] -w thresh_mask.nii.gz -x null_mask.nii.gz -o corrected.nii.gz' % ( self.inputs.input_ref_EPI) rc = run_command(command) command = 'DenoiseImage -d 3 -i corrected.nii.gz -o denoise.nii.gz' rc = run_command(command) [affine, warp, inverse_warp, warped_image ] = run_antsRegistration(reg_method='Rigid', moving_image=cwd + '/denoise.nii.gz', fixed_image=self.inputs.anat, anat_mask=self.inputs.anat_mask) command = 'antsApplyTransforms -d 3 -i %s -t [%s,1] -r %s -o %s -n GenericLabel' % ( self.inputs.anat_mask, affine, self.inputs.input_ref_EPI, resampled_mask) rc = run_command(command) command = 'N4BiasFieldCorrection -d 3 -s 2 -i %s -b 20 -s 1 -c [100x100x100x100,1e-6] -w %s -x null_mask.nii.gz -o %s' % ( self.inputs.input_ref_EPI, resampled_mask, cwd + '/iter_corrected.nii.gz') rc = run_command(command) command = 'DenoiseImage -d 3 -i iter_corrected.nii.gz -o iter_corrected_denoise.nii.gz' rc = run_command(command) # resample to anatomical image resolution dim = sitk.ReadImage(self.inputs.anat, self.inputs.rabies_data_type).GetSpacing() low_dim = np.asarray(dim).min() sitk.WriteImage( resample_image_spacing( sitk.ReadImage(cwd + '/iter_corrected_denoise.nii.gz', self.inputs.rabies_data_type), (low_dim, low_dim, low_dim)), biascor_EPI) sitk.WriteImage( sitk.ReadImage(biascor_EPI, self.inputs.rabies_data_type), biascor_EPI) sitk.WriteImage( sitk.ReadImage(warped_image, self.inputs.rabies_data_type), warped_image) sitk.WriteImage( sitk.ReadImage(resampled_mask, self.inputs.rabies_data_type), resampled_mask) setattr(self, 'corrected_EPI', biascor_EPI) setattr(self, 'warped_EPI', warped_image) setattr(self, 'denoise_mask', resampled_mask) setattr(self, 'init_denoise', cwd + '/denoise.nii.gz') return runtime
def slice_timing_correction(in_file, tr='1.0s', tpattern='alt', rabies_data_type=8): ''' This functions applies slice-timing correction on the anterior-posterior slice acquisition direction. The input image, assumed to be in RAS orientation (accoring to nibabel; note that the nibabel reading of RAS corresponds to LPI for AFNI). The A and S dimensions will be swapped to apply AFNI's 3dTshift STC with a quintic fitting function, which can only be applied to the Z dimension of the data matrix. The corrected image is then re-created with proper axes and the corrected timeseries. **Inputs** in_file BOLD series NIfTI file in RAS orientation. ignore Number of non-steady-state volumes detected at beginning of ``bold_file`` tr TR of the BOLD image. tpattern Input to AFNI's 3dTshift -tpattern option, which specifies the directionality of slice acquisition, or whether it is sequential or interleaved. **Outputs** out_file Slice-timing corrected BOLD series NIfTI file ''' import os import SimpleITK as sitk import numpy as np if tpattern == "alt": tpattern = 'alt-z' elif tpattern == "seq": tpattern = 'seq-z' else: raise ValueError('Invalid --tpattern provided.') img = sitk.ReadImage(in_file, rabies_data_type) # get image data img_array = sitk.GetArrayFromImage(img) shape = img_array.shape new_array = np.zeros([shape[0], shape[2], shape[1], shape[3]]) for i in range(shape[2]): new_array[:, i, :, :] = img_array[:, :, i, :] image_out = sitk.GetImageFromArray(new_array, isVector=False) sitk.WriteImage(image_out, 'STC_temp.nii.gz') command = '3dTshift -quintic -prefix temp_tshift.nii.gz -tpattern %s -TR %s STC_temp.nii.gz' % ( tpattern, tr, ) from rabies.preprocess_pkg.utils import run_command rc = run_command(command) tshift_img = sitk.ReadImage('temp_tshift.nii.gz', rabies_data_type) tshift_array = sitk.GetArrayFromImage(tshift_img) new_array = np.zeros(shape) for i in range(shape[2]): new_array[:, :, i, :] = tshift_array[:, i, :, :] image_out = sitk.GetImageFromArray(new_array, isVector=False) from rabies.preprocess_pkg.utils import copyInfo_4DImage image_out = copyInfo_4DImage(image_out, img, img) import pathlib # Better path manipulation filename_split = pathlib.Path(in_file).name.rsplit(".nii") out_file = os.path.abspath(filename_split[0] + '_tshift.nii.gz') sitk.WriteImage(image_out, out_file) return out_file
def _run_interface(self, runtime): import os import numpy as np import SimpleITK as sitk from rabies.preprocess_pkg.utils import resample_image_spacing, run_command import pathlib # Better path manipulation filename_split = pathlib.Path(self.inputs.nii_anat).name.rsplit(".nii") cwd = os.getcwd() output_anat = '%s/%s_preproc.nii.gz' % ( cwd, filename_split[0], ) # resample the anatomical image to the resolution of the provided template anat_image = sitk.ReadImage(self.inputs.nii_anat, self.inputs.rabies_data_type) anat_dim = anat_image.GetSpacing() template_image = sitk.ReadImage(self.inputs.template_anat, self.inputs.rabies_data_type) template_dim = template_image.GetSpacing() if not (np.array(anat_dim) == np.array(template_dim)).sum() == 3: import logging log = logging.getLogger('root') log.debug( 'Anat image will be resampled to the template resolution.') resampled_anat = resample_image_spacing(anat_image, template_dim) input_anat = '%s/%s_resampled.nii.gz' % ( cwd, filename_split[0], ) sitk.WriteImage(resampled_anat, input_anat) else: input_anat = self.inputs.nii_anat if self.inputs.disable_anat_preproc: # resample image to specified data format sitk.WriteImage( sitk.ReadImage(input_anat, self.inputs.rabies_data_type), output_anat) init_denoise = output_anat resampled_mask = self.inputs.template_mask init_denoise = cwd + '/denoise.nii.gz' resampled_mask = cwd + '/resampled_mask.nii.gz' else: if self.inputs.bias_cor_method == 'otsu_reg': bias_correction = OtsuEPIBiasCorrection( input_ref_EPI=input_anat, anat=self.inputs.template_anat, anat_mask=self.inputs.template_mask, name_source=self.inputs.nii_anat, rabies_data_type=self.inputs.rabies_data_type) out = bias_correction.run() output_anat = out.outputs.corrected_EPI resampled_mask = out.outputs.denoise_mask init_denoise = out.outputs.init_denoise elif self.inputs.bias_cor_method == 'thresh_reg': bias_correction = ThreshBiasCorrection( input_ref_EPI=input_anat, anat=self.inputs.template_anat, anat_mask=self.inputs.template_mask, name_source=self.inputs.nii_anat, rabies_data_type=self.inputs.rabies_data_type) out = bias_correction.run() output_anat = out.outputs.corrected_EPI resampled_mask = out.outputs.denoise_mask init_denoise = out.outputs.init_denoise elif self.inputs.bias_cor_method == 'mouse-preprocessing-v5.sh': command = 'rabies-mouse-preprocessing-v5.sh %s %s %s %s' % ( input_anat, output_anat, self.inputs.template_anat, self.inputs.template_mask) rc = run_command(command) resampled_mask = output_anat.split( '.nii.gz')[0] + '_mask.nii.gz' init_denoise = output_anat.split( '.nii.gz')[0] + '_init_denoise.nii.gz' else: raise ValueError("Wrong --anat_bias_cor_method.") # resample image to specified data format sitk.WriteImage( sitk.ReadImage(output_anat, self.inputs.rabies_data_type), output_anat) setattr(self, 'anat_preproc', output_anat) setattr(self, 'init_denoise', init_denoise) setattr(self, 'denoise_mask', resampled_mask) return runtime
def _run_interface(self, runtime): import os import pandas as pd import pathlib cwd = os.getcwd() template_folder = self.inputs.output_folder + '/ants_dbm_outputs/' if os.path.isdir(template_folder): print( 'Previous ants_dbm_outputs/ folder detected. Inputs from a previous run may cause issues for the commonspace registration, so consider removing the previous folder before running again.' ) command = 'mkdir -p %s' % (template_folder, ) from rabies.preprocess_pkg.utils import run_command rc = run_command(command) # create a csv file of the input image list csv_path = cwd + '/commonspace_input_files.csv' from rabies.preprocess_pkg.utils import flatten_list merged = flatten_list(list(self.inputs.moving_image)) if len(merged) == 1: print( "Only a single scan was provided as input for commonspace registration. Commonspace registration " "won't be run, and the output template will be the input scan." ) # create an identity transform as a surrogate for the commonspace transforms import SimpleITK as sitk dimension = 3 identity = sitk.Transform(dimension, sitk.sitkIdentity) file = merged[0] filename_template = pathlib.Path(file).name.rsplit(".nii")[0] transform_file = template_folder + filename_template + '_identity.mat' sitk.WriteTransform(identity, transform_file) setattr(self, 'warped_image', file) setattr(self, 'affine_list', [transform_file]) setattr(self, 'warp_list', [transform_file]) setattr(self, 'inverse_warp_list', [transform_file]) setattr(self, 'warped_anat_list', [file]) return runtime df = pd.DataFrame(data=merged) df.to_csv(csv_path, header=False, sep=',', index=False) import rabies dir_path = os.path.dirname(os.path.realpath(rabies.__file__)) model_script_path = dir_path + '/shell_scripts/ants_dbm.sh' command = 'cd %s ; bash %s %s %s %s %s %s %s' % ( template_folder, model_script_path, csv_path, self.inputs.template_anat, self.inputs.cluster_type, self.inputs.walltime, self.inputs.memory_request, self.inputs.local_threads) import subprocess try: process = subprocess.run( command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, check=True, shell=True, ) except Exception as e: print(e.output.decode("utf-8")) #log.warning(e.output.decode("utf-8")) #rc = run_command(command) # verify that all outputs are present ants_dbm_template = template_folder + \ '/output/secondlevel/secondlevel_template0.nii.gz' if not os.path.isfile(ants_dbm_template): raise ValueError(ants_dbm_template + " doesn't exists.") affine_list = [] warp_list = [] inverse_warp_list = [] warped_anat_list = [] i = 0 for file in merged: file = str(file) filename_template = pathlib.Path(file).name.rsplit(".nii")[0] anat_to_template_inverse_warp = '%s/output/secondlevel/secondlevel_%s%s1InverseWarp.nii.gz' % ( template_folder, filename_template, str(i), ) if not os.path.isfile(anat_to_template_inverse_warp): raise ValueError(anat_to_template_inverse_warp + " file doesn't exists.") anat_to_template_warp = '%s/output/secondlevel/secondlevel_%s%s1Warp.nii.gz' % ( template_folder, filename_template, str(i), ) if not os.path.isfile(anat_to_template_warp): raise ValueError(anat_to_template_warp + " file doesn't exists.") anat_to_template_affine = '%s/output/secondlevel/secondlevel_%s%s0GenericAffine.mat' % ( template_folder, filename_template, str(i), ) if not os.path.isfile(anat_to_template_affine): raise ValueError(anat_to_template_affine + " file doesn't exists.") warped_anat = '%s/output/secondlevel/secondlevel_template0%s%sWarpedToTemplate.nii.gz' % ( template_folder, filename_template, str(i), ) if not os.path.isfile(warped_anat): raise ValueError(warped_anat + " file doesn't exists.") inverse_warp_list.append(anat_to_template_inverse_warp) warp_list.append(anat_to_template_warp) affine_list.append(anat_to_template_affine) warped_anat_list.append(warped_anat) i += 1 setattr(self, 'warped_image', ants_dbm_template) setattr(self, 'affine_list', affine_list) setattr(self, 'warp_list', warp_list) setattr(self, 'inverse_warp_list', inverse_warp_list) setattr(self, 'warped_anat_list', warped_anat_list) return runtime
def _run_interface(self, runtime): import numpy as np import os from rabies.preprocess_pkg.utils import run_command import pathlib # Better path manipulation filename_split = pathlib.Path(self.inputs.bold).name.rsplit(".nii") # generate a .nii file representing the positioning or framewise displacement for each voxel within the brain_mask # first the voxelwise positioning map command = 'antsMotionCorrStats -m %s -o %s_pos_file.csv -x %s \ -d %s -s %s_pos_voxelwise.nii.gz' % ( self.inputs.movpar_file, filename_split[0], self.inputs.brain_mask, self.inputs.bold, filename_split[0]) rc = run_command(command) pos_voxelwise = os.path.abspath("%s_pos_file.nii.gz" % filename_split[0]) # then the voxelwise framewise displacement map command = 'antsMotionCorrStats -m %s -o %s_FD_file.csv -x %s \ -d %s -s %s_FD_voxelwise.nii.gz -f 1' % ( self.inputs.movpar_file, filename_split[0], self.inputs.brain_mask, self.inputs.bold, filename_split[0]) rc = run_command(command) FD_csv = os.path.abspath("%s_FD_file.csv" % filename_split[0]) FD_voxelwise = os.path.abspath("%s_FD_file.nii.gz" % filename_split[0]) confounds = [] csv_columns = [] WM_signal = extract_mask_trace(self.inputs.bold, self.inputs.WM_mask) confounds.append(WM_signal) csv_columns += ['WM_signal'] CSF_signal = extract_mask_trace(self.inputs.bold, self.inputs.CSF_mask) confounds.append(CSF_signal) csv_columns += ['CSF_signal'] vascular_signal = extract_mask_trace(self.inputs.bold, self.inputs.vascular_mask) confounds.append(vascular_signal) csv_columns += ['vascular_signal'] [aCompCor, num_comp ] = compute_aCompCor(self.inputs.bold, self.inputs.WM_mask, self.inputs.CSF_mask, method=self.inputs.aCompCor_method, rabies_data_type=self.inputs.rabies_data_type) for param in range(aCompCor.shape[1]): confounds.append(aCompCor[:, param]) comp_column = [] for comp in range(num_comp): comp_column.append('aCompCor' + str(comp + 1)) csv_columns += comp_column global_signal = extract_mask_trace(self.inputs.bold, self.inputs.brain_mask) confounds.append(global_signal) csv_columns += ['global_signal'] motion_24 = motion_24_params(self.inputs.movpar_file) for param in range(motion_24.shape[1]): confounds.append(motion_24[:, param]) csv_columns += [ 'mov1', 'mov2', 'mov3', 'rot1', 'rot2', 'rot3', 'mov1_der', 'mov2_der', 'mov3_der', 'rot1_der', 'rot2_der', 'rot3_der', 'mov1^2', 'mov2^2', 'mov3^2', 'rot1^2', 'rot2^2', 'rot3^2', 'mov1_der^2', 'mov2_der^2', 'mov3_der^2', 'rot1_der^2', 'rot2_der^2', 'rot3_der^2' ] confounds_csv = write_confound_csv(np.transpose(np.asarray(confounds)), csv_columns, filename_split[0]) setattr(self, 'FD_csv', FD_csv) setattr(self, 'FD_voxelwise', FD_voxelwise) setattr(self, 'pos_voxelwise', pos_voxelwise) setattr(self, 'confounds_csv', confounds_csv) return runtime
def _run_interface(self, runtime): import SimpleITK as sitk import numpy as np import logging log = logging.getLogger('root') in_nii = sitk.ReadImage(self.inputs.in_file, self.inputs.rabies_data_type) data_slice = sitk.GetArrayFromImage(in_nii)[:50, :, :, :] n_volumes_to_discard = _get_vols_to_discard(in_nii) import pathlib # Better path manipulation filename_split = pathlib.Path(self.inputs.in_file).name.rsplit(".nii") out_ref_fname = os.path.abspath('%s_bold_ref.nii.gz' % (filename_split[0], )) if (not n_volumes_to_discard == 0) and self.inputs.detect_dummy: log.info( "Detected " + str(n_volumes_to_discard) + " dummy scans. Taking the median of these volumes as reference EPI." ) median_image_data = np.median( data_slice[:n_volumes_to_discard, :, :, :], axis=0) out_bold_file = os.path.abspath('%s_cropped_dummy.nii.gz' % (filename_split[0], )) img_array = sitk.GetArrayFromImage(in_nii)[ n_volumes_to_discard:, :, :, :] sitk.WriteImage(img_array, out_bold_file) else: out_bold_file = self.inputs.in_file n_volumes_to_discard = 0 if self.inputs.detect_dummy: log.info( "Detected no dummy scans. Generating the ref EPI based on multiple volumes." ) # if no dummy scans, will generate a median from a subset of max 100 # slices of the time series if in_nii.GetSize()[-1] > 100: slice_fname = os.path.abspath("slice.nii.gz") image_4d = copyInfo_4DImage( sitk.GetImageFromArray(data_slice[20:100, :, :, :], isVector=False), in_nii, in_nii) sitk.WriteImage(image_4d, slice_fname) median_fname = os.path.abspath("median.nii.gz") image_3d = copyInfo_3DImage( sitk.GetImageFromArray(np.median( data_slice[20:100, :, :, :], axis=0), isVector=False), in_nii) sitk.WriteImage(image_3d, median_fname) else: slice_fname = self.inputs.in_file median_fname = os.path.abspath("median.nii.gz") image_3d = copyInfo_3DImage( sitk.GetImageFromArray(np.median(data_slice, axis=0), isVector=False), in_nii) sitk.WriteImage(image_3d, median_fname) # First iteration to generate reference image. res = antsMotionCorr( in_file=slice_fname, ref_file=median_fname, prebuilt_option=self.inputs.HMC_option, transform_type='Rigid', second=False, rabies_data_type=self.inputs.rabies_data_type).run() median = np.median(sitk.GetArrayFromImage( sitk.ReadImage(res.outputs.mc_corrected_bold, self.inputs.rabies_data_type)), axis=0) tmp_median_fname = os.path.abspath("tmp_median.nii.gz") image_3d = copyInfo_3DImage( sitk.GetImageFromArray(median, isVector=False), in_nii) sitk.WriteImage(image_3d, tmp_median_fname) # Second iteration to generate reference image. res = antsMotionCorr( in_file=slice_fname, ref_file=tmp_median_fname, prebuilt_option=self.inputs.HMC_option, transform_type='Rigid', second=True, rabies_data_type=self.inputs.rabies_data_type).run() # evaluate a trimmed mean instead of a median, trimming the 5% extreme values from scipy import stats median_image_data = stats.trim_mean(sitk.GetArrayFromImage( sitk.ReadImage(res.outputs.mc_corrected_bold, self.inputs.rabies_data_type)), 0.05, axis=0) # median_image_data is a 3D array of the median image, so creates a new nii image # saves it image_3d = copyInfo_3DImage( sitk.GetImageFromArray(median_image_data, isVector=False), in_nii) sitk.WriteImage(image_3d, out_ref_fname) # denoise the resulting reference image through non-local mean denoising # Denoising reference image. command = 'DenoiseImage -d 3 -i %s -o %s' % (out_ref_fname, out_ref_fname) from rabies.preprocess_pkg.utils import run_command rc = run_command(command) setattr(self, 'ref_image', out_ref_fname) setattr(self, 'bold_file', out_bold_file) return runtime
def _run_interface(self, runtime): import os import pandas as pd import pathlib from rabies.preprocess_pkg.utils import run_command cwd = os.getcwd() template_folder = self.inputs.output_folder + '/ants_dbm_outputs/' if os.path.isdir(template_folder): # remove previous run command = 'rm -r %s' % (template_folder, ) rc = run_command(command) command = 'mkdir -p %s' % (template_folder, ) rc = run_command(command) # create a csv file of the input image list csv_path = cwd + '/commonspace_input_files.csv' from rabies.preprocess_pkg.utils import flatten_list merged = flatten_list(list(self.inputs.moving_image)) if len(merged) == 1: import logging log = logging.getLogger('root') log.info( "Only a single scan was provided as input for commonspace registration. Commonspace registration " "won't be run, and the output template will be the input scan." ) # create an identity transform as a surrogate for the commonspace transforms import SimpleITK as sitk dimension = 3 identity = sitk.Transform(dimension, sitk.sitkIdentity) file = merged[0] filename_template = pathlib.Path(file).name.rsplit(".nii")[0] transform_file = template_folder + filename_template + '_identity.mat' sitk.WriteTransform(identity, transform_file) setattr(self, 'warped_image', file) setattr(self, 'affine_list', [transform_file]) setattr(self, 'warp_list', [transform_file]) setattr(self, 'inverse_warp_list', [transform_file]) setattr(self, 'warped_anat_list', [file]) return runtime df = pd.DataFrame(data=merged) df.to_csv(csv_path, header=False, sep=',', index=False) command = 'cd %s ; ants_dbm.sh %s %s %s %s %s %s' % ( template_folder, csv_path, self.inputs.template_anat, self.inputs.cluster_type, self.inputs.walltime, self.inputs.memory_request, self.inputs.local_threads) rc = run_command(command) # verify that all outputs are present ants_dbm_template = template_folder + \ '/output/secondlevel/secondlevel_template0.nii.gz' if not os.path.isfile(ants_dbm_template): raise ValueError(ants_dbm_template + " doesn't exists.") affine_list = [] warp_list = [] inverse_warp_list = [] warped_anat_list = [] i = 0 for file in merged: file = str(file) filename_template = pathlib.Path(file).name.rsplit(".nii")[0] anat_to_template_inverse_warp = '%s/output/secondlevel/secondlevel_%s%s1InverseWarp.nii.gz' % ( template_folder, filename_template, str(i), ) if not os.path.isfile(anat_to_template_inverse_warp): raise ValueError(anat_to_template_inverse_warp + " file doesn't exists.") anat_to_template_warp = '%s/output/secondlevel/secondlevel_%s%s1Warp.nii.gz' % ( template_folder, filename_template, str(i), ) if not os.path.isfile(anat_to_template_warp): raise ValueError(anat_to_template_warp + " file doesn't exists.") anat_to_template_affine = '%s/output/secondlevel/secondlevel_%s%s0GenericAffine.mat' % ( template_folder, filename_template, str(i), ) if not os.path.isfile(anat_to_template_affine): raise ValueError(anat_to_template_affine + " file doesn't exists.") warped_anat = '%s/output/secondlevel/secondlevel_template0%s%sWarpedToTemplate.nii.gz' % ( template_folder, filename_template, str(i), ) if not os.path.isfile(warped_anat): raise ValueError(warped_anat + " file doesn't exists.") inverse_warp_list.append(anat_to_template_inverse_warp) warp_list.append(anat_to_template_warp) affine_list.append(anat_to_template_affine) warped_anat_list.append(warped_anat) i += 1 setattr(self, 'warped_image', ants_dbm_template) setattr(self, 'affine_list', affine_list) setattr(self, 'warp_list', warp_list) setattr(self, 'inverse_warp_list', inverse_warp_list) setattr(self, 'warped_anat_list', warped_anat_list) return runtime
def _run_interface(self, runtime): import os import SimpleITK as sitk from rabies.preprocess_pkg.utils import run_command # change the name of the first iteration directory to prevent overlap of files with second iteration if self.inputs.second: command = 'mv ants_mc_tmp first_ants_mc_tmp' rc = run_command(command) # make a tmp directory to store the files os.makedirs('ants_mc_tmp', exist_ok=True) # adaptation from https://github.com/ANTsX/ANTsR/blob/60eefd96fedd16bceb4703ecd2cd5730e6843807/R/ants_motion_estimation.R moving = self.inputs.in_file fixed = self.inputs.ref_file txtype = self.inputs.transform_type moreaccurate = self.inputs.prebuilt_option verbose = 0 if txtype not in ['Rigid', 'Affine']: raise ValueError("Wrong transform type provided.") if not moreaccurate == "intraSubjectBOLD": moreaccurate = int(moreaccurate) if moreaccurate not in [0, 1, 2, 3]: raise ValueError("Wrong pre-built option provided.") img = sitk.ReadImage(self.inputs.in_file, self.inputs.rabies_data_type) n = img.GetSize()[3] if (n > 10): n = 10 mibins = 20 if (moreaccurate == 3): # check the size of the lowest dimension, and make sure that the first shrinking factor allow for at least 4 slices shrinking_factor = 4 low_dim = np.asarray(img.GetSize()[:3]).min() if shrinking_factor > int(low_dim / 4): shrinking_factor = int(low_dim / 4) command = "antsMotionCorr -d 3 -o [ants_mc_tmp/motcorr,ants_mc_tmp/motcorr.nii.gz,ants_mc_tmp/motcorr_avg.nii.gz] -m MI[ %s , \ %s , 1 , %s ] -t %s[0.1,3,0] -i 100x50x30 -s 2x1x0 -f %sx2x1 -u 1 -e 1 -l 1 -n %s -v %s" % ( fixed, moving, str(mibins), txtype, str(shrinking_factor), str(n), str(verbose)) elif (moreaccurate == 2): # check the size of the lowest dimension, and make sure that the first shrinking factor allow for at least 4 slices shrinking_factor = 4 img = sitk.ReadImage(self.inputs.in_file, self.inputs.rabies_data_type) low_dim = np.asarray(img.GetSize()[:3]).min() if shrinking_factor > int(low_dim / 4): shrinking_factor = int(low_dim / 4) command = "antsMotionCorr -d 3 -o [ants_mc_tmp/motcorr,ants_mc_tmp/motcorr.nii.gz,ants_mc_tmp/motcorr_avg.nii.gz] -m MI[ %s , \ %s , 1 , %s , regular, 0.25 ] -t %s[ 0.1 ] -i 100x50x30 -s 2x1x0 -f %sx2x1 -u 1 -e 1 -l 1 -n %s -v %s" % ( fixed, moving, str(mibins), txtype, str(shrinking_factor), str(n), str(verbose)) elif (moreaccurate == "intraSubjectBOLD"): command = "antsMotionCorr -d 3 -o [ants_mc_tmp/motcorr,ants_mc_tmp/motcorr.nii.gz,ants_mc_tmp/motcorr_avg.nii.gz] -m MI[ %s , \ %s , 1 , %s , regular, 0.2 ] -t %s[ 0.25 ] -i 50x20 -s 1x0 -f 2x1 -u 1 -e 1 -l 1 -n %s -v %s" % ( fixed, moving, str(mibins), txtype, str(n), str(verbose)) elif (moreaccurate == 1): command = "antsMotionCorr -d 3 -o [ants_mc_tmp/motcorr,ants_mc_tmp/motcorr.nii.gz,ants_mc_tmp/motcorr_avg.nii.gz] -m MI[ %s , \ %s , 1 , %s , regular, 0.25 ] -t %s[ 0.1 ] -i 100 -s 0 -f 1 -u 1 -e 1 -l 1 -n %s -v %s" % ( fixed, moving, str(mibins), txtype, str(n), str(verbose)) elif (moreaccurate == 0): command = "antsMotionCorr -d 3 -o [ants_mc_tmp/motcorr,ants_mc_tmp/motcorr.nii.gz,ants_mc_tmp/motcorr_avg.nii.gz] -m MI[ %s , \ %s , 1 , %s , regular, 0.02 ] -t %s[ 0.1 ] -i 3 -s 0 -f 1 -u 1 -e 1 -l 1 -n %s -v %s" % ( fixed, moving, str(mibins), txtype, str(n), str(verbose)) else: raise ValueError("Wrong moreaccurate provided.") rc = run_command(command) setattr(self, 'csv_params', os.path.abspath('ants_mc_tmp/motcorrMOCOparams.csv')) setattr(self, 'mc_corrected_bold', os.path.abspath('ants_mc_tmp/motcorr.nii.gz')) setattr(self, 'avg_image', os.path.abspath('ants_mc_tmp/motcorr_avg.nii.gz')) return runtime