def create_database(database_directory, ontology='brainvisa-3.2.0', allow_ro=False, persistent=False): if not os.path.exists(database_directory): os.makedirs(database_directory) database_settings = neuroConfig.DatabaseSettings(database_directory) database = neuroHierarchy.SQLDatabase(os.path.join( database_directory, "database-%s.sqlite" % databaseVersion), database_directory, ontology, context=processes.defaultContext(), settings=database_settings) neuroHierarchy.databases.add(database) neuroConfig.dataPath.append(database_settings) try: database.clear(context=processes.defaultContext()) database.update(context=processes.defaultContext()) except: if not allow_ro: raise if persistent: configuration = Application().configuration configuration.databases.fso.append( databases_configuration.DatabasesConfiguration.FileSystemOntology( database_directory, selected=True, read_only=allow_ro)) configuration.save(neuroConfig.userOptionFile) return database
def on_action_brainvisa_configuration_triggered(self): from soma.wip.application.api import Application from soma.qtgui.api import ApplicationQtGUI from brainvisa.configuration import neuroConfig configuration = Application().configuration appGUI = ApplicationQtGUI() dialog = appGUI.createEditionDialog(configuration, parent=None, live=False, modal=True) from soma.qt4gui.configuration_qt4gui import ConfigurationWidget from soma.qt_gui.qt_backend import QtGui # remove the database panel and icon stackw = dialog.findChild(QtGui.QStackedWidget) dbwidget = stackw.widget(1) stackw.removeWidget(dbwidget) listw = dialog.findChild(QtGui.QSplitter).findChild(QtGui.QListWidget) listw.takeItem(1) result = dialog.exec_() if result: dialog.setObject(configuration) appGUI.closeEditionDialog(dialog) # if appGUI.edit(configuration, live=False, modal=True): if result: # from brainvisa.configuration import axon_capsul_config_link # axon_capsul_config_link.axon_to_capsul_config_sync(self.study) configuration.save(neuroConfig.userOptionFile) try: self.study.save_to_backup_file() except StudySerializationError as e: pass # study is not saved, don't notify
def validation(): from soma.wip.application.api import Application from distutils.spawn import find_executable configuration = Application().configuration fsl_prefix = configuration.FSL.fsl_commands_prefix #checking for Niftyreg commands cmds = ['reg_f3d', 'reg_resample', 'reg_transform'] for i, cmd in enumerate(cmds): executable = find_executable(cmd) if not executable: raise ValidationError( cmd + 'command was not found.Please check your Niftyreg installation and/or version' ) #checking for FSl's commands cmds = ['bet', 'flirt', 'dtifit'] for i, cmd in enumerate(cmds): executable = find_executable(fsl_prefix + cmd) if not executable: raise ValidationError( cmd + 'FSL command was not found.Please check your FSL installation and/or fsldir and fsl_commands_prefix setting in BranVISA' ) pass
def validation(): from distutils.spawn import find_executable as find_exec configuration = Application().configuration #fsldir = configuration.FSL.fsldir #check for eddy implementations (two for fsl>5.0.10) eddy_cpu = find_exec('eddy_openmp') #pb ! executable can exist even if no GPU on the system (dont consider GPU for now) #eddy_gpu_old = os.path.join(fsldir ,'bin','eddy.gpu') #eddy_gpu_new = find_exec('eddy_cuda') eddy_base = find_exec('eddy') #For now we consider that there is a problem if no CPU implementation of eddy is found if eddy_cpu is None and eddy_base is None: raise ValidationError( _t_('NO CPU implementation of eddy was found ! Check fsldir and fsl_command_prefix values into Brainvisa Preferences FSL menu !' )) cmds = [ 'fslmaths', 'fslroi', 'fsl_anat', 'fslmerge', 'topup', 'applytopup' ] for cmd in cmds: if not find_exec(configuration.FSL.fsl_commands_prefix + cmd): raise ValidationError( _t_(' FSL ' + cmd + ' commandline could not be found. Check fsldir and fsl_command_prefix values into Brainvisa Preferences FSL menu !' )) pass
def validation(): from distutils.spawn import find_executable as find_exec configuration = Application().configuration cmds = ['fslmaths', 'fugue', 'flirt'] for cmd in cmds: if not find_exec(configuration.FSL.fsl_commands_prefix + cmd): raise ValidationError( _t_(' FSL ' + cmd + ' commandline could not be found. Check fsldir and fsl_command_prefix values into Brainvisa Preferences FSL menu !' )) pass
def validation(): from soma.wip.application.api import Application from distutils.spawn import find_executable as find_exec configuration = Application().configuration cmds = ['flseyes', 'fslview'] viewers = [ find_exec(configuration.FSL.fsl_commands_prefix + cmd) for cmd in cmds ] if not viewers[0] and not viewers[1]: raise ValidationError( _t_(' FSL ' + ' fsleyes and fslview ' + ' commandline could not be found. Check fsldir and fsl_command_prefix values into Brainvisa Preferences FSL menu !' )) pass
def validation(): from soma.wip.application.api import Application from distutils.spawn import find_executable configuration = Application().configuration fsl_prefix = configuration.FSL.fsl_commands_prefix cmds = ['fslsplit'] for i, cmd in enumerate(cmds): executable = find_executable(fsl_prefix + cmd) if not executable: raise ValidationError( 'FSL command ' + cmd + ' could not be located on your system. Please check you FSL installation and/or fsldir , fsl_commands_prefix variables in BrainVISA preferences' ) pass
def bvecRotation(ECpath, bvecs_in, bvecs_out): configuration = Application().configuration fsldir = configuration.FSL.fsldir log = os.path.splitext(os.path.splitext(ECpath)[0])[0] + '.ecclog' if not os.path.isfile(log): raise RuntimeError(_t_('Log file does not exist!')) if not os.path.isfile(bvecs_in): raise RuntimeError(_t_('Bvecs file does not exist!')) tmp_file = os.path.dirname(log) + '/tmp.mat' flog = open(log, 'r') lines = flog.readlines() bvecs = numpy.loadtxt(bvecs_in) cmd1 = '. ' + fsldir + '/etc/fslconf/fsl.sh' newX = [] newY = [] newZ = [] line_count = 0 file_count = 0 print lines for l in lines: if l[:10] == "processing": line_count = 0 mat_file = open(tmp_file, 'w+') elif l != '\n' and l != "Final result:\n": mat_file.writelines(l) if line_count == 7: mat_file.close() cmd2 = fsldir + '/bin/avscale --allparams ' + mat_file.name output = os.popen(cmd1 + ';' + cmd2).readlines() rX = float(output[1].split()[0]) * bvecs[0, file_count] + float( output[1].split()[1]) * bvecs[1, file_count] + float( output[1].split()[2]) * bvecs[2, file_count] rY = float(output[2].split()[0]) * bvecs[0, file_count] + float( output[2].split()[1]) * bvecs[1, file_count] + float( output[2].split()[2]) * bvecs[2, file_count] rZ = float(output[3].split()[0]) * bvecs[0, file_count] + float( output[3].split()[1]) * bvecs[1, file_count] + float( output[3].split()[2]) * bvecs[2, file_count] newX.append(rX) newY.append(rY) newZ.append(rZ) file_count += 1 line_count += 1 numpy.savetxt(bvecs_out, [newX, newY, newZ]) flog.close() os.remove(tmp_file) return 0
def execution(self, context): configuration = Application().configuration old_spm_configuration = configuration.SPM if platform.system() == 'Linux': detectPathsForLinuxPlatform(context, configuration) elif platform.system() == 'Windows': context.warning( 'The SPM paths auto detect is not yet configured for Windows platform' ) else: context.error('Platform used is unvalid for this process') return 0 if configuration.SPM.spm8_standalone_command: context.write('\nSetting up SPM templates database') # remove previous spm databases if any for old_spm_path in [ old_spm_configuration.spm5_path, old_spm_configuration.spm8_standalone_path, old_spm_configuration.spm8_path ]: if old_spm_path: if neuroHierarchy.databases.hasDatabase(old_spm_path): neuroHierarchy.databases.remove(old_spm_path) for settings in neuroConfig.dataPath: if settings.directory == old_spm_path: neuroConfig.dataPath.remove(settings) dbs = neuroConfig.DatabaseSettings( configuration.SPM.spm8_standalone_command) dbs.expert_settings.ontology = 'spm' dbs.expert_settings.sqliteFileName = ':temporary:' dbs.expert_settings.uuid = 'a91fd1bf-48cf-4759-896e-afea136c0549' dbs.builtin = True neuroConfig.dataPath.insert(1, dbs) db = neuroHierarchy.SQLDatabase( dbs.expert_settings.sqliteFileName, configuration.SPM.spm8_standalone_command, 'spm', settings=dbs) neuroHierarchy.databases.add(db) db.clear() db.update(context=defaultContext()) neuroHierarchy.update_soma_workflow_translations()
def validation(): from soma.wip.application.api import Application from distutils.spawn import find_executable #checking for niftyreg #niftyreg_resample = find_executable('reg_resample') #if not niftyreg_resample: #raise ValidationError(_t_('Niftyreg executable NOT found !')) configuration = Application().configuration fsl_prefix = configuration.FSL.fsl_commands_prefix cmds = ['fslsplit', 'fnirt'] for i, cmd in enumerate(cmds): executable = find_executable(fsl_prefix + cmd) if not executable: raise ValidationError( 'FSL command ' + cmd + ' could not be located on your system. Please check you FSL installation and/or fsldir , fsl_commands_prefix variables in BrainVISA preferences' ) pass
def tensorFitting(context, dwi_path, gtab): configuration = Application().configuration cmds = ['fsleyes', 'fslview'] viewers = [ find_executable(configuration.FSL.fsl_commands_prefix + cmd) for cmd in cmds ] img = nib.load(dwi_path) data = img.get_data() tenmodel = dti.TensorModel(gtab) # instantiate tensor model tenfit = tenmodel.fit(data) # fit data to tensor model FA = dti.fractional_anisotropy(tenfit.evals) FA[np.isnan(FA)] = 0 # correct for background value evecs = tenfit.evecs.astype(np.float32) e1 = evecs[..., 0] rgb = dti.color_fa(FA, evecs) tensor_fa = context.temporary('NIFTI-1 image') tensor_evecs = context.temporary('NIFTI-1 image') path_fa = tensor_fa.fullPath() + '_' + 'FA.nii.gz' path_e1 = tensor_evecs.fullPath() + '_' + 'first_eigenvector.nii.gz' fa_img = nib.Nifti1Image(FA.astype(np.float32), img.get_affine()) nib.save(fa_img, path_fa) e1_img = nib.Nifti1Image(e1, img.get_affine()) nib.save(e1_img, path_e1) context.write( 'If color coding of FA map is not right, swap axes and run again') context.write( 'If orientation of principal diffusion direction does not look right, flip the axis along which slices look good' ) if viewers[0]: #display first eigen vector as line coloured by orientation and modulated by FA superimposed onto the FA volume (fsleyes only) cmd = [ 'fsleyes', path_fa, path_e1, '-ot', 'linevector', '-mr', '0 1', '-mo', path_fa ] else: #display FA and First Eigen vector as volumes (old way, display needs to be done by hand) cmd = ['fslview', path_fa, path_e1] context.system(*cmd) return FA, evecs, rgb
def checkSPMCommand(context, cmd): configuration = Application().configuration spm_path = None mexe = distutils.spawn.find_executable(configuration.matlab.executable) if mexe == None: context.write('The Matlab executable was not found.') return matlab_script_diskitem = context.temporary('Matlab Script') spm_path_saving_text_file_diskitem = context.temporary('Text File') matlab_script_path = matlab_script_diskitem.fullPath() matlab_script = '''try a = which( \'''' + cmd + '''\' ); if ~isempty( a ) try ''' + cmd + '''; catch me end end spm_path = which( 'spm' ); f = fopen( ''' + "'" + spm_path_saving_text_file_diskitem.fullPath( ) + "'" + ''', 'w' ); fprintf( f, '%s\\n', spm_path ); catch me end exit; ''' open(matlab_script_path, 'w').write(matlab_script) cmd = [ mexe ] + configuration.matlab.options.split(' ') \ + ['-r', os.path.basename(matlab_script_diskitem.fullName())] context.write('Attempt to run the matlab command: ' + repr(cmd)) # print('running matlab command: ', cmd) try: context.system(*cmd, cwd=os.path.dirname(matlab_script_path)) except Exception as e: return None spm_path = open( spm_path_saving_text_file_diskitem.fullPath()).read().strip() spm_directory = os.path.dirname(spm_path) return spm_directory
def execution(self, context): # Create gradient table bvals = np.loadtxt(self.bvals.fullPath()) bvecs = np.loadtxt(self.bvecs.fullPath()) if self.swap_axes != "": bvecs = swapBvecs(bvecs, self.swap_axes) context.write(self.swap_axes[0], 'and', self.swap_axes[2], 'axes have been swapped !') if self.flip_axis != "": bvecs = flipBvecs(bvecs, self.flip_axis) context.write(self.flip_axis, 'axis has been flipped !') if self.visual_check == True: context.write('Tensor fitting...') data_path = context.temporary('gz compressed NIFTI-1 image') dimx = self.dwi_data.get('volume_dimension', search_header=True)[0] dimy = self.dwi_data.get('volume_dimension', search_header=True)[1] dimz = self.dwi_data.get('volume_dimension', search_header=True)[2] configuration = Application().configuration cmd = [ configuration.FSL.fsl_commands_prefix + 'fslroi', self.dwi_data.fullPath(), data_path.fullPath(), str(dimx / 4), str(dimx / 2), str(dimy / 4), str(dimy / 2), str(dimz / 4), str(dimz / 2), '0', '-1' ] context.system(*cmd) gtab = gradient_table(bvals, bvecs) [FA, evecs, rgb] = tensorFitting(context, data_path.fullPath(), gtab) np.savetxt(self.reoriented_bvecs.fullPath(), bvecs)
def execution(self, context): configuration = Application().configuration transformManager = getTransformationManager() t1_brain = context.temporary('NIFTI-1 image') context.system('AimsMask', '-i', self.T1_volume, '-m', self.T1_mask, '-o', t1_brain) diff_to_t1_xfm = context.temporary('File') # t1_to_diff_xfm = context.temporary('File') fast_seg = context.temporary('File') context.write( 'Registration of DWI to T1 space using FSL-epi_reg... [~15mn]') # cmd = [ configuration.FSL.fsl_commands_prefix + 'epi_reg', '-v', '--epi=' + self.b0_volume.fullPath(), '--t1=' + self.T1_volume.fullPath(), '--t1brain=' + t1_brain.fullPath(), '--out=' + diff_to_t1_xfm.fullPath() ] # context.system( *cmd ) # context.system( 'cp', diff_to_t1_xfm.fullPath() + '.nii.gz', self.b0_to_T1 ) context.write('- FAST segmentation') cmd = [ configuration.FSL.fsl_commands_prefix + 'fast', '-o', fast_seg.fullPath(), t1_brain.fullPath() ] context.system(*cmd) cmd = [ configuration.FSL.fsl_commands_prefix + 'fslmaths', fast_seg.fullPath() + '_pve_2.nii.gz', '-thr', '0.5', '-bin', fast_seg.fullPath() + '_wmseg.nii.gz' ] context.system(*cmd) context.write('- pre-alignment 3dof') cmd = [ configuration.FSL.fsl_commands_prefix + 'flirt', '-ref', t1_brain.fullPath(), '-in', self.b0_volume.fullPath(), '-dof', '3', '-omat', diff_to_t1_xfm.fullPath() + '_init.mat' ] context.system(*cmd) context.write('- flirt 6dof') cmd = [ configuration.FSL.fsl_commands_prefix + 'flirt', '-ref', self.T1_volume.fullPath(), '-in', self.b0_volume.fullPath(), '-dof', '6', '-cost', 'bbr', '-wmseg', fast_seg.fullPath() + '_wmseg.nii.gz', '-init', diff_to_t1_xfm.fullPath() + '_init.mat', '-omat', diff_to_t1_xfm.fullPath() + '.mat', '-out', diff_to_t1_xfm.fullPath(), '-schedule', configuration.FSL.fsldir + '/etc/flirtsch/bbr.sch' ] context.system(*cmd) context.write('- applywarp') cmd = [ configuration.FSL.fsl_commands_prefix + 'applywarp', '-i', self.b0_volume.fullPath(), '-r', self.T1_volume.fullPath(), '-o', self.b0_to_T1, '--premat=' + diff_to_t1_xfm.fullPath() + '.mat', '--interp=spline' ] context.system(*cmd) transformManager.copyReferential(self.T1_volume, self.b0_to_T1) context.write('Conversion from .mat to .trm') trm = fslTransformation.fslMatToTrm(diff_to_t1_xfm.fullPath() + '.mat', self.b0_volume.fullPath(), diff_to_t1_xfm.fullPath()) aims.write(trm, self.diff_to_T1_linear_xfm.fullPath()) context.write('Invert transformation...') cmd = [ 'AimsInvertTransformation', '-i', self.diff_to_T1_linear_xfm, '-o', self.T1_to_diff_linear_xfm ] context.system(*cmd) context.write('Registration of T1 to DWI space...') cmd = [ 'AimsResample', '-i', self.T1_volume, '-m', self.T1_to_diff_linear_xfm, '-t', self.T1_to_b0_interpolation, '-o', self.T1_to_b0 ] if self.T1_to_b0_resampling == True: cmd += ['-r', self.b0_volume] elif self.T1_to_b0_resampling == False: dim = self.b0_volume.get('volume_dimension', search_header=True) context.write(dim) vox_ref = self.b0_volume.get('voxel_size', search_header=True) vox_in = self.T1_volume.get('voxel_size', search_header=True) context.write(vox_ref) context.write(vox_in) cmd += [ '--dx', str(int(dim[0] * vox_ref[0] / vox_in[0]) + 1), '--dy', str(int(dim[1] * vox_ref[1] / vox_in[1]) + 1), '--dz', str(int(dim[2] * vox_ref[2] / vox_in[2]) + 1) ] context.system(*cmd) transformManager.copyReferential(self.b0_volume, self.T1_to_b0) context.write('Registration of T1 brain mask to DWI space...') cmd = [ 'AimsResample', '-i', self.T1_mask, '-m', self.T1_to_diff_linear_xfm, '-t', self.T1_to_b0_interpolation, '-o', self.T1_to_b0_mask ] ## if self.T1_to_b0_resampling == True: cmd += ['-r', self.b0_volume] ## elif self.T1_to_b0_resampling == False: ## cmd+=[ '--dx', str(dim[0]*vox_ref[0]/vox_in[0]), '--dy', str(dim[1]*vox_ref[1]/vox_in[1]), '--dz', str(dim[2]*vox_ref[2]/vox_in[2]) ] context.system(*cmd) transformManager.copyReferential(self.b0_volume, self.T1_to_b0_mask) cmd = [ 'AimsThreshold', '-i', self.T1_to_b0_mask, '-o', self.T1_to_b0_mask, '-t', '1', '-b', '--fg', '1' ] context.system(*cmd) context.write('Recompile left-right grey-matter and white-matter...') Left = aims.read(self.T1_grey_white_left.fullPath()) Right = aims.read(self.T1_grey_white_right.fullPath()) Left_Right = Left + Right GM = Left.arraydata() GM[:, :, :, :] = 0 GM[numpy.where(Left_Right.arraydata() == 100)] = 100 WM = Right.arraydata() WM[:, :, :, :] = 0 WM[numpy.where(Left_Right.arraydata() == 200)] = 100 GM_vol = aims.Volume(GM) WM_vol = aims.Volume(WM) GM_vol.copyHeaderFrom(Left.header()) WM_vol.copyHeaderFrom(Left.header()) GM_file = context.temporary('NIFTI-1 image') WM_file = context.temporary('NIFTI-1 image') aims.write(GM_vol, GM_file.fullPath()) aims.write(WM_vol, WM_file.fullPath()) context.write( 'Registration of white-matter and grey-matter masks to DWI space...') cmd = [ 'AimsResample', '-i', GM_file.fullPath(), '-m', self.T1_to_diff_linear_xfm, '-t', '0', '-o', self.T1_to_b0_GM, '-d', '1' ] ## if self.T1_to_b0_resampling == True: cmd += ['-r', self.b0_volume] ## elif self.T1_to_b0_resampling == False: ## dim = self.b0_volume.get( 'volume_dimension', search_header=True ) ## vox_ref = self.b0_volume.get( 'voxel_size', search_header=True ) ## vox_in = self.T1_volume.get( 'voxel_size', search_header=True ) ## cmd+=[ '--dx', str(dim[0]*vox_ref[0]/vox_in[0]), '--dy', str(dim[1]*vox_ref[1]/vox_in[1]), '--dz', str(dim[2]*vox_ref[2]/vox_in[2]) ] context.system(*cmd) transformManager.copyReferential(self.b0_volume, self.T1_to_b0_GM) cmd = [ 'AimsThreshold', '-i', self.T1_to_b0_GM, '-o', self.T1_to_b0_GM, '-t', '2', '-b', '--fg', '1' ] context.system(*cmd) cmd = [ 'AimsResample', '-i', WM_file.fullPath(), '-m', self.T1_to_diff_linear_xfm, '-t', '0', '-o', self.T1_to_b0_WM, '-d', '1' ] ## if self.T1_to_b0_resampling == True: cmd += ['-r', self.b0_volume] ## elif self.T1_to_b0_resampling == False: ## cmd+=[ '--dx', str(dim[0]*vox_ref[0]/vox_in[0]), '--dy', str(dim[1]*vox_ref[1]/vox_in[1]), '--dz', str(dim[2]*vox_ref[2]/vox_in[2]) ] context.system(*cmd) transformManager.copyReferential(self.b0_volume, self.T1_to_b0_WM) cmd = [ 'AimsThreshold', '-i', self.T1_to_b0_WM, '-o', self.T1_to_b0_WM, '-t', '2', '-b', '--fg', '1' ] context.system(*cmd) context.write('Recompile T1 left-right skeletons...') Left = aims.read(self.T1_skeleton_left.fullPath()) Right = aims.read(self.T1_skeleton_right.fullPath()) Lskeleton = Left.arraydata() Rskeleton = Right.arraydata() Lskeleton[Lskeleton < 20] = 0 Lskeleton[Lskeleton > 20] = 1 Rskeleton[Rskeleton < 20] = 0 Rskeleton[Rskeleton > 20] = 1 Lskeleton_vol = aims.Volume(Lskeleton) Rskeleton_vol = aims.Volume(Rskeleton) skeleton = Lskeleton_vol + Rskeleton_vol skeleton.copyHeaderFrom(Left.header()) skeleton_file = context.temporary('NIFTI-1 image') aims.write(skeleton, skeleton_file.fullPath()) context.write('Registration of T1 skeleton mask to DWI space...') cmd = [ 'AimsResample', '-i', skeleton_file.fullPath(), '-m', self.T1_to_diff_linear_xfm, '-t', '0', '-o', self.T1_to_b0_skeleton, '-d', '1' ] ## if self.T1_to_b0_resampling == True: cmd += ['-r', self.b0_volume] ## elif self.T1_to_b0_resampling == False: ## cmd+=[ '--dx', str(dim[0]*vox_ref[0]/vox_in[0]), '--dy', str(dim[1]*vox_ref[1]/vox_in[1]), '--dz', str(dim[2]*vox_ref[2]/vox_in[2]) ] context.system(*cmd) transformManager.copyReferential(self.b0_volume, self.T1_to_b0_skeleton) cmd = [ 'AimsThreshold', '-i', self.T1_to_b0_skeleton, '-o', self.T1_to_b0_skeleton, '-t', '1', '-b', '--fg', '1' ] context.system(*cmd) cmd = [ 'AimsMask', '-i', self.T1_to_b0_skeleton, '-o', self.T1_to_b0_skeleton, '-m', self.T1_to_b0_WM, '--inv', 'True' ] context.system(*cmd) context.write('Finished')
def execution( self, context ): configuration = Application().configuration FSL_eddy_directory = os.path.dirname(self.eddy_b0_volumes.fullPath()) context.write('Setting acquisition parameters') img = aims.read(self.dwi_data.fullPath()) dwi_data = img.arraydata() Nvol = self.dwi_data.get('volume_dimension', search_header=True)[3] bvals = numpy.loadtxt(self.bvals.fullPath()) b0_index = numpy.where(bvals < 100)[0] ## bvals==0 not possible when bvalues take values +-5 or +-10 b0_sum = dwi_data[b0_index,:,:,:] b0_vol = aims.Volume(b0_sum) b0_vol.copyHeaderFrom(img.header()) aims.write(b0_vol, self.eddy_b0_volumes.fullPath()) PE_parameters = self.eddy_parameters.fullPath() PE_index = self.eddy_index.fullPath() PE_list = ["AP", "PA", "LR", "RL"] vector_list = ['0 1 0 ', '0 -1 0 ', '1 0 0 ', '-1 0 0 '] indx = PE_list.index(self.phase_encoding_direction) f_param = open(PE_parameters, 'w') f_index = open(PE_index, 'w') [f_param.write(vector_list[indx] + str(self.readout_time) + '\n') for i in range(len(b0_index))] val = 1 for i in range(len(bvals)): if i in b0_index[1:]: val += 1 f_index.write(str(val) + ' ') # tmp = [f_index.write('1 ') for i in range(len(bvals))] f_param.close() f_index.close() context.write('Eddy current estimation and correction... [can take several hours]') cmd = [ configuration.FSL.fsl_commands_prefix + 'fslmaths', self.eddy_b0_volumes.fullPath(), '-Tmean', self.eddy_b0_mean.fullPath() ] context.system( *cmd ) BrainExtraction.defaultBrainExtraction(self.eddy_b0_mean.fullPath(), self.eddy_b0_mean_brain.fullPath(), f=str(self.brain_extraction_factor)) fsldir = configuration.FSL.fsldir eddyExec = find_executable('eddy_openmp') if eddyExec: context.write('CPU-multithread version of eddy found') else: context.write('No CPU-multithread version of eddy found') eddyExec = find_executable('eddy') #eddyExec = fsldir + '/bin/eddy.gpu' #if os.path.isfile(eddyExec) == True: #context.write('GPU-multithread version of eddy found') #else: #eddyExec = fsldir + '/bin/eddy_cuda' #if os.path.isfile(eddyExec) == True: #context.write('GPU-multithread version of eddy found') #else: #context.write('CPU/GPU-multithread version of eddy NOT found') #eddyExec = fsldir + '/bin/eddy' #if not os.path.isfile(eddyExec): #raise if self.entire_sphere_sampling == False or Nvol < 60: if Nvol < 30: context.write('WARNING: For eddy to work well, data should contain more than 30 directions!') slm = "linear" else: slm = "none" cmd1 = '. ' + fsldir + '/etc/fslconf/fsl.sh' cmd2 = eddyExec + ' --imain=' + self.dwi_data.fullPath() + ' --mask=' + self.eddy_b0_mean_brain_mask.fullPath() + ' --acqp=' + self.eddy_parameters.fullPath() + ' --index=' + self.eddy_index.fullPath() + ' --bvecs=' + self.bvecs.fullPath() + ' --bvals=' + self.bvals.fullPath() + ' --out=' + FSL_eddy_directory + '/eddy' cmd2 += ' --flm=' + str(self.flm) + ' --slm=' + slm + ' --fwhm=' + str(self.fwhm) + ',0,0,0,0' + ' --niter=' + str(self.niter) + ' --fep --interp=spline --resamp=jac --nvoxhp=' + str(self.nvoxhp) + ' --ff=10 --very_verbose' if not self.multi_shell: cmd2 += " --dont_peas" else: cmd2 += " --data_is_shelled" # option does NOT exist in FSL version under 5.0.10 (how to test an option exist in a command) cmd = cmd1 + ' ; ' + cmd2 os.system( cmd ) context.system(configuration.FSL.fsl_commands_prefix + 'fslmaths', FSL_eddy_directory + '/eddy.nii.gz', '-abs', self.dwi_eddy_corrected.fullPath()) # remove negative values shutil.copy2(FSL_eddy_directory + '/eddy.eddy_rotated_bvecs', self.corrected_bvecs.fullPath()) transformManager = getTransformationManager() transformManager.copyReferential( self.dwi_data, self.dwi_eddy_corrected ) context.write('Finished')
def execution(self, context): configuration = Application().configuration tmp_file = context.temporary('File') tmp_deform = context.temporary('File') #if self.registration_method == 'niftyreg': # new niftyreg deformation volume is X,Y,Z,1,3 instead of X,Y,Z,3 deform_vol = nib.load(self.diff_to_T1_nonlinear_dfm.fullPath()) if len(deform_vol.shape) == 5: deform = deform_vol.get_data() deform = deform[..., 0, :] nib.save(nib.Nifti1Image(deform, deform_vol.affine), tmp_deform.fullPath() + '.nii.gz') else: nib.save(deform_vol, tmp_deform.fullPath() + '.nii.gz') #reuse Lucile code to split volume cause dont want to mess with orientations as it worked cmd = [ configuration.FSL.fsl_commands_prefix + 'fslsplit', tmp_deform.fullPath() + '.nii.gz', tmp_file.fullPath(), '-t' ] context.system(*cmd) context.write(tmp_file.fullPath()) f1 = aims.read(tmp_file.fullPath() + '0000.nii.gz') f2 = aims.read(tmp_file.fullPath() + '0001.nii.gz') f3 = aims.read(tmp_file.fullPath() + '0002.nii.gz') f = np.concatenate((f1.arraydata(), f2.arraydata(), f3.arraydata())) field = np.swapaxes(f, 0, 3) field = np.swapaxes(field, 1, 2) vxsize = np.array(f1.header()['voxel_size'][:3]) affine = f1.header()['transformations'] affine_mm = np.reshape(affine[0], (4, 4)) mesh = aims.read(self.WM_mesh_in_T1.fullPath()) new_mesh = meshTransform(mesh, field, vxsize, affine_mm) aims.write(new_mesh, self.WM_mesh_in_DWI.fullPath()) cmd = [ 'AimsMeshTransform', '-i', self.WM_mesh_in_DWI, '-t', self.T1_to_diff_linear_xfm, '-o', self.WM_mesh_in_DWI ] context.system(*cmd) transformManager = getTransformationManager() transformManager.copyReferential(self.b0_volume, self.WM_mesh_in_DWI) mesh = aims.read(self.GM_mesh_in_T1.fullPath()) new_mesh = meshTransform(mesh, field, vxsize, affine_mm) aims.write(new_mesh, self.GM_mesh_in_DWI.fullPath()) cmd = [ 'AimsMeshTransform', '-i', self.GM_mesh_in_DWI, '-t', self.T1_to_diff_linear_xfm, '-o', self.GM_mesh_in_DWI ] context.system(*cmd) transformManager = getTransformationManager() transformManager.copyReferential(self.b0_volume, self.GM_mesh_in_DWI) # elif self.registration_method == 'fnirt': # field_file = context.temporary('gz compressed NIFTI-1 image') # # cmd = [configuration.FSL.fsl_commands_prefix + 'fnirtfileutils', '-i', self.diff_to_T1_nonlinear_dfm.fullPath(), '-r', self.T1_volume.fullPath(), '-o', field_file.fullPath()] # # context.system(*cmd) # cmd = [configuration.FSL.fsl_commands_prefix + 'fslsplit', self.diff_to_T1_nonlinear_dfm.fullPath(), tmp_file.fullPath(), '-t'] # context.system(*cmd) # f1 = aims.read(tmp_file.fullPath() + '0000.nii.gz') # f2 = aims.read(tmp_file.fullPath() + '0001.nii.gz') # f3 = aims.read(tmp_file.fullPath() + '0002.nii.gz') # f = np.concatenate((f1.arraydata(), f2.arraydata(), f3.arraydata())) # field = np.swapaxes(f, 0, 3) # field = np.swapaxes(field, 1, 2) # t1 = aims.read(self.T1_volume.fullPath()) # vxsize = np.array(f1.header()['voxel_size'][:3]) # affine = t1.header()['transformations'] # # affine = f1.header()['transformations'] # affine_mm = np.reshape(affine[0], (4, 4)) # # mesh = aims.read(self.WM_mesh_in_T1.fullPath()) # new_mesh = meshTransform(mesh, field, vxsize, affine_mm) # aims.write(new_mesh, self.WM_mesh_in_DWI.fullPath()) # transformManager = getTransformationManager() # transformManager.copyReferential(self.b0_volume, self.WM_mesh_in_DWI) # # mesh = aims.read(self.GM_mesh_in_T1.fullPath()) # new_mesh = meshTransform(mesh, field, vxsize, affine_mm) # aims.write(new_mesh, self.GM_mesh_in_DWI.fullPath()) # transformManager = getTransformationManager() # transformManager.copyReferential(self.b0_volume, self.GM_mesh_in_DWI) context.write('Finished')
def execution(self, context): configuration = Application().configuration transformManager = getTransformationManager() niftyreg_resample = find_executable('reg_resample') #no longer needed since validation check ! #if not niftyreg_resample: #raise RuntimeError(_t_('Niftyreg executable NOT found !')) reg = context.temporary('File') tmp_file = context.temporary('gz compressed NIFTI-1 image') cmd = [ configuration.FSL.fsl_commands_prefix + 'fslmaths', self.ROI_in_T1.fullPath() ] if self.lower_thresh is not None: cmd += ['-thr', self.lower_thresh] if self.upper_thresh is not None: cmd += ['-uthr', self.upper_thresh] cmd += ['-bin', tmp_file.fullPath()] context.system(*cmd) ## A SUPPRIMER EN DEHORS DU HCP : A CAUSE ORIENTATION RAS A POSTERIORI # tmp_b0 = context.temporary('gz compressed NIFTI-1 image') # os.system(' '.join(['AimsFileConvert', '-i', self.b0_volume.fullPath(), '-o', tmp_b0.fullPath(), '--orient', '"abs: 1 -1 -1"'])) ## if self.T1_to_b0_registration_method == 'niftyreg': cmd = [ niftyreg_resample, '-ref', self.T1_volume.fullPath(), '-flo', tmp_file.fullPath(), '-trans', self.T1_to_diff_nonlinear_dfm.fullPath(), '-res', reg.fullPath() + '_ROI.nii.gz', '-inter', '0' ] context.system(*cmd) cmd = [ 'AimsResample', '-i', reg.fullPath() + '_ROI.nii.gz', '-m', self.T1_to_diff_linear_xfm, '-t', '0', '-o', self.ROI_in_DWI, '-d', '1', '-r', self.b0_volume.fullPath() ] context.system(*cmd) elif self.T1_to_b0_registration_method == 'fnirt': cmd = [ configuration.FSL.fsl_commands_prefix + 'applywarp', '-i', tmp_file.fullPath(), '-r', self.b0_volume.fullPath(), '-o', self.ROI_in_DWI.fullPath(), '-w', self.T1_to_diff_nonlinear_dfm.fullPath(), '--interp=nn' ] context.system(*cmd) if self.binarise: cmd = [ configuration.FSL.fsl_commands_prefix + 'fslmaths', self.ROI_in_DWI.fullPath(), '-thr', self.threshold, '-bin', self.ROI_in_DWI.fullPath() ] # , '--fg', '1'] else: cmd = [ configuration.FSL.fsl_commands_prefix + 'fslmaths', self.ROI_in_DWI.fullPath(), '-thr', self.threshold, self.ROI_in_DWI.fullPath() ] # , '--fg', '1'] context.system(*cmd) # ref = self.b0_volume.get('storage_to_memory', search_header=True) # transformManager.copyReferential(self.b0_volume, self.ROI_in_DWI) ## A SUPPRIMER EN DEHORS DU HCP : A CAUSE ORIENTATION RAS A POSTERIORI # os.system(' '.join(['AimsFileConvert', '-i', self.ROI_in_DWI.fullPath(), '-o', self.ROI_in_DWI.fullPath(), '--orient', '"abs: -1 -1 -1"'])) ## context.write('Finished')
def execution(self, context): configuration = Application().configuration transformManager = getTransformationManager() context.write('Fractional anisotropy temporary estimation') dtifit = context.temporary('File') mask = context.temporary('File') cmd = [ configuration.FSL.fsl_commands_prefix + 'bet', self.b0_volume.fullPath(), mask.fullPath(), '-f', '0.3', '-m' ] context.system(*cmd) cmd = [ configuration.FSL.fsl_commands_prefix + 'dtifit', '-k', self.dwi_data.fullPath(), '-o', dtifit.fullPath(), '-m', mask.fullPath() + '_mask.nii.gz', '-r', self.bvecs.fullPath(), '-b', self.bvals.fullPath() ] context.system(*cmd) FA = dtifit.fullPath() + '_FA.nii.gz' context.write('Fractional anisotropy bias correction') bias_corr = context.temporary('File') cmd = [ configuration.FSL.fsl_commands_prefix + 'fsl_anat', '-i', FA, '-o', bias_corr.fullPath(), '-t', 'T2', '--clobber', '--strongbias', '--noreorient', '--nocrop', '--noreg', '--nononlinreg', '--noseg', '--nosubcortseg' ] context.system(*cmd) FA_biascorr = bias_corr.fullPath() + '.anat/T2_biascorr.nii.gz' context.write('T1 white-matter segmentation') t1_brain = context.temporary('NIFTI-1 image') fast_seg = context.temporary('File') T1_mask_bin = context.temporary('NIFTI-1 image') cmd = [ configuration.FSL.fsl_commands_prefix + 'fslmaths', self.T1_mask.fullPath(), '-bin', T1_mask_bin ] context.system(*cmd) context.system('AimsMask', '-i', self.T1_volume, '-m', T1_mask_bin.fullPath(), '-o', t1_brain.fullPath()) cmd = [ configuration.FSL.fsl_commands_prefix + 'fast', '-o', fast_seg.fullPath(), t1_brain.fullPath() ] context.system(*cmd) T1_white_matter = fast_seg.fullPath() + '_pve_2.nii.gz' T1_grey_matter = fast_seg.fullPath() + '_pve_1.nii.gz' T1_csf = fast_seg.fullPath() + '_pve_0.nii.gz' context.write('Affine pre-alignment') diff_to_t1_lin = context.temporary('File') cmd = [ configuration.FSL.fsl_commands_prefix + 'flirt', '-ref', T1_white_matter, '-in', FA_biascorr, '-dof', '6', '-omat', diff_to_t1_lin.fullPath() ] context.system(*cmd) context.write('Non linear registration') cmd = [ configuration.FSL.fsl_commands_prefix + 'fnirt', '--ref=' + T1_white_matter, '--in=' + FA_biascorr, '--aff=' + diff_to_t1_lin.fullPath(), '--cout=' + self.diff_to_T1_nonlinear_dfm.fullPath(), '--refmask=' + T1_mask_bin.fullPath(), '--intmod=global_linear' ] context.system(*cmd) cmd = [ configuration.FSL.fsl_commands_prefix + 'applywarp', '-i', self.b0_volume.fullPath(), '-r', T1_white_matter, '-o', self.b0_to_T1.fullPath(), '-w', self.diff_to_T1_nonlinear_dfm.fullPath(), '--interp=spline' ] context.system(*cmd) transformManager.copyReferential(self.T1_volume, self.b0_to_T1) ## Non applicable to non-linear warp image ## To compute only for anatomist to load files in the same referential context.write('Conversion from .mat to .trm') trm = fslTransformation.fslMatToTrm(diff_to_t1_lin.fullPath(), self.b0_volume.fullPath(), self.b0_to_T1.fullPath()) aims.write(trm, self.diff_to_T1_linear_xfm.fullPath()) context.write('Invert transformation...') cmd = [ 'AimsInvertTransformation', '-i', self.diff_to_T1_linear_xfm, '-o', self.T1_to_diff_linear_xfm ] context.system(*cmd) cmd = [ configuration.FSL.fsl_commands_prefix + 'invwarp', '--ref=' + self.b0_volume.fullPath(), '--warp=' + self.diff_to_T1_nonlinear_dfm.fullPath(), '--out=' + self.T1_to_diff_nonlinear_dfm.fullPath() ] context.system(*cmd) ## Transport T1 space maps to DWI context.write('Registration of T1 to DWI space...') print(self.T1_to_b0_interpolation) cmd = [ configuration.FSL.fsl_commands_prefix + 'applywarp', '-i', self.T1_volume.fullPath(), '-r', self.b0_volume.fullPath(), '-o', self.T1_to_b0.fullPath(), '-w', self.T1_to_diff_nonlinear_dfm.fullPath(), '--interp=' + self.T1_to_b0_interpolation ] context.system(*cmd) transformManager.copyReferential(self.b0_volume, self.T1_to_b0) context.write('Registration of T1 PVE maps to DWI space...') context.write('White matter Partial Volume Estimation Map') cmd = [ configuration.FSL.fsl_commands_prefix + 'applywarp', '-i', T1_white_matter, '-r', self.b0_volume.fullPath(), '-o', self.T1_to_b0_WM_pve.fullPath(), '-w', self.T1_to_diff_nonlinear_dfm.fullPath(), '--interp=' + self.T1_to_b0_interpolation ] context.system(*cmd) transformManager.copyReferential(self.b0_volume, self.T1_to_b0_WM_pve) context.write('Grey matter Partial Volume Estimation Map') cmd = [ configuration.FSL.fsl_commands_prefix + 'applywarp', '-i', T1_grey_matter, '-r', self.b0_volume.fullPath(), '-o', self.T1_to_b0_GM_pve.fullPath(), '-w', self.T1_to_diff_nonlinear_dfm.fullPath(), '--interp=' + self.T1_to_b0_interpolation ] context.system(*cmd) transformManager.copyReferential(self.b0_volume, self.T1_to_b0_GM_pve) context.write('CSF Partial Volume Estimation Map') cmd = [ configuration.FSL.fsl_commands_prefix + 'applywarp', '-i', T1_csf, '-r', self.b0_volume.fullPath(), '-o', self.T1_to_b0_CSF_pve.fullPath(), '-w', self.T1_to_diff_nonlinear_dfm.fullPath(), '--interp=' + self.T1_to_b0_interpolation ] context.system(*cmd) transformManager.copyReferential(self.b0_volume, self.T1_to_b0_CSF_pve) context.write('Registration of T1 brain mask to DWI space...') cmd = [ configuration.FSL.fsl_commands_prefix + 'applywarp', '-i', self.T1_mask.fullPath(), '-r', self.b0_volume.fullPath(), '-o', self.T1_to_b0_mask.fullPath(), '-w', self.T1_to_diff_nonlinear_dfm.fullPath(), '--interp=' + self.T1_to_b0_interpolation ] context.system(*cmd) cmd = [ configuration.FSL.fsl_commands_prefix + 'fslmaths', self.T1_to_b0_mask.fullPath(), '-bin', self.T1_to_b0_mask.fullPath() ] context.system(*cmd) transformManager.copyReferential(self.b0_volume, self.T1_to_b0_mask) context.write('Recompile left-right grey-matter and white-matter...') Left = aims.read(self.T1_grey_white_left.fullPath()) Right = aims.read(self.T1_grey_white_right.fullPath()) Left_Right = Left + Right GM = Left.arraydata() GM[:, :, :, :] = 0 GM[numpy.where(Left_Right.arraydata() == 100)] = 100 WM = Right.arraydata() WM[:, :, :, :] = 0 WM[numpy.where(Left_Right.arraydata() == 200)] = 100 GM_vol = aims.Volume(GM) WM_vol = aims.Volume(WM) GM_vol.copyHeaderFrom(Left.header()) WM_vol.copyHeaderFrom(Left.header()) GM_file = context.temporary('NIFTI-1 image') WM_file = context.temporary('NIFTI-1 image') aims.write(GM_vol, GM_file.fullPath()) aims.write(WM_vol, WM_file.fullPath()) context.write( 'Registration of white-matter and grey-matter masks to DWI space...') cmd = [ configuration.FSL.fsl_commands_prefix + 'applywarp', '-i', GM_file.fullPath(), '-r', self.b0_volume.fullPath(), '-o', self.T1_to_b0_GM.fullPath(), '-w', self.T1_to_diff_nonlinear_dfm.fullPath(), '--interp=nn' ] context.system(*cmd) cmd = [ configuration.FSL.fsl_commands_prefix + 'fslmaths', self.T1_to_b0_GM.fullPath(), '-thr', '50', '-bin', self.T1_to_b0_GM.fullPath() ] context.system(*cmd) transformManager.copyReferential(self.b0_volume, self.T1_to_b0_GM) cmd = [ configuration.FSL.fsl_commands_prefix + 'applywarp', '-i', WM_file.fullPath(), '-r', self.b0_volume.fullPath(), '-o', self.T1_to_b0_WM.fullPath(), '-w', self.T1_to_diff_nonlinear_dfm.fullPath(), '--interp=nn' ] context.system(*cmd) cmd = [ configuration.FSL.fsl_commands_prefix + 'fslmaths', self.T1_to_b0_WM.fullPath(), '-thr', '50', '-bin', self.T1_to_b0_WM.fullPath() ] context.system(*cmd) transformManager.copyReferential(self.b0_volume, self.T1_to_b0_WM) context.write('Recompile T1 left-right skeletons...') Left = aims.read(self.T1_skeleton_left.fullPath()) Right = aims.read(self.T1_skeleton_right.fullPath()) Lskeleton = Left.arraydata() Rskeleton = Right.arraydata() Lskeleton[Lskeleton < 20] = 0 Lskeleton[Lskeleton > 20] = 1 Rskeleton[Rskeleton < 20] = 0 Rskeleton[Rskeleton > 20] = 1 Lskeleton_vol = aims.Volume(Lskeleton) Rskeleton_vol = aims.Volume(Rskeleton) skeleton = Lskeleton_vol + Rskeleton_vol skeleton.copyHeaderFrom(Left.header()) skeleton_file = context.temporary('NIFTI-1 image') aims.write(skeleton, skeleton_file.fullPath()) context.write('Registration of T1 skeleton mask to DWI space...') cmd = [ configuration.FSL.fsl_commands_prefix + 'applywarp', '-i', skeleton_file.fullPath(), '-r', self.b0_volume.fullPath(), '-o', self.T1_to_b0_skeleton.fullPath(), '-w', self.T1_to_diff_nonlinear_dfm.fullPath(), '--interp=nn' ] context.system(*cmd) cmd = [ configuration.FSL.fsl_commands_prefix + 'fslmaths', self.T1_to_b0_skeleton.fullPath(), '-bin', self.T1_to_b0_skeleton.fullPath() ] context.system(*cmd) transformManager.copyReferential(self.b0_volume, self.T1_to_b0_skeleton) cmd = [ 'AimsMask', '-i', self.T1_to_b0_skeleton, '-o', self.T1_to_b0_skeleton, '-m', self.T1_to_b0_WM, '--inv', 'True' ] context.system(*cmd) context.write('Finished')
def execution(self, context): context.write( 'Susceptibility induced distortion correction using Fieldmap... [~1mn]' ) context.write('- Identification of first b0 volume') img = aims.read(self.dwi_data.fullPath()) dwi_data = img.arraydata() bvals = numpy.loadtxt(self.bvals.fullPath()) b0_index = numpy.where(bvals < 100)[ 0] ## bvals==0 not possible when bvalues take values +-5 or +-10 b0 = dwi_data[b0_index[0], :, :, :] b0_vol = aims.Volume(b0) b0_vol.copyHeaderFrom(img.header()) b0_tmp = context.temporary('NIFTI-1 image') aims.write(b0_vol, b0_tmp.fullPath()) configuration = Application().configuration FSL_directory = os.path.dirname(self.fieldmap_brain.fullPath()) PE_list = ["AP", "PA", "LR", "RL"] dir_list = ["y-", "y", "x-", "x"] warping_direction = dir_list[PE_list.index(self.phase_encoding_direction)] context.write('- Brain extraction of magnitude image') BrainExtraction.defaultBrainExtraction(self.magnitude.fullPath(), self.magnitude_brain.fullPath(), f=str(self.brain_extraction_factor)) # cmd = [ configuration.FSL.fsl_commands_prefix + 'fslmaths', self.fieldmap.fullPath(), '-mas', self.magnitude_brain.fullPath(), self.fieldmap_brain.fullPath() ] # context.system( *cmd ) # unmask the fieldmap (necessary to avoid edge effects) cmd = [ configuration.FSL.fsl_commands_prefix + 'fslmaths', self.magnitude_brain.fullPath(), '-bin', self.magnitude_brain_mask.fullPath() ] # context.system(*cmd) # cmd = [ configuration.FSL.fsl_commands_prefix + 'fugue', '--loadfmap=' + self.fieldmap.fullPath(), '--mask=' + self.magnitude_brain_mask.fullPath(), '--unmaskfmap', '--savefmap=' + self.fieldmap_brain.fullPath(), '--unwarpdir=' + warping_direction ] # context.system(*cmd) # context.write('- Fieldmap smoothing') cmd = [ configuration.FSL.fsl_commands_prefix + 'fugue', '--loadfmap=' + self.fieldmap_brain.fullPath(), '--despike', '--smooth3=' + str(self.fieldmap_smoothing), '--savefmap=' + self.fieldmap_brain.fullPath() ] context.system(*cmd) context.write('- Magnitude image warping using fieldmap') cmd = [ configuration.FSL.fsl_commands_prefix + 'fugue', '-v', '-i', self.magnitude_brain.fullPath(), '--dwell=' + str(self.echo_spacing), '--unwarpdir=' + warping_direction, '--loadfmap=' + self.fieldmap_brain.fullPath(), '-w', self.magnitude_warped.fullPath() ] context.system(*cmd) context.write('- Registration of fieldmap into diffusion space') cmd1 = [ configuration.FSL.fsl_commands_prefix + 'flirt', '-dof', '12', '-in', self.magnitude_warped.fullPath(), '-ref', b0_tmp.fullPath(), '-out', self.magnitude_warped_to_dwi.fullPath(), '-omat', self.fieldmap_to_dwi_mat.fullPath() ] cmd2 = [ configuration.FSL.fsl_commands_prefix + 'flirt', '-dof', '12', '-in', self.fieldmap_brain.fullPath(), '-ref', b0_tmp.fullPath(), '-applyxfm', '-init', self.fieldmap_to_dwi_mat.fullPath(), '-out', self.fieldmap_to_dwi.fullPath() ] context.system(*cmd1) context.system(*cmd2) transformManager = getTransformationManager() transformManager.copyReferential(self.dwi_data, self.magnitude_warped_to_dwi) transformManager.copyReferential(self.dwi_data, self.fieldmap_to_dwi) context.write('- Unwarping of dwi image using fieldmap') cmd = [ configuration.FSL.fsl_commands_prefix + 'fugue', '-v', '-i', self.dwi_data.fullPath(), '--dwell=' + str(self.echo_spacing), '--unwarpdir=' + warping_direction, '--loadfmap=' + self.fieldmap_to_dwi.fullPath(), '-u', self.dwi_unwarped.fullPath(), '--icorr', '--saveshift=' + FSL_directory + '/pixel_shift.nii.gz' ] #'--mask=' + self.magnitude_warped_to_dwi_brain_mask.fullPath(), '--smooth3=' + str(self.fieldmap_smoothing), context.system(*cmd) cmd = [ configuration.FSL.fsl_commands_prefix + 'fslmaths', self.dwi_unwarped.fullPath(), '-abs', self.dwi_unwarped.fullPath() ] context.system(*cmd) transformManager.copyReferential(self.dwi_data, self.dwi_unwarped) context.write('Finished')
def execution( self, context ): configuration = Application().configuration tmp_directory = configuration.brainvisa.temporaryDirectory context.write(tmp_directory) # Dicom converter -> to nifti #if self.mricron_program=='dcm2niix': # mricron = find_executable('dcm2niix') # if not mricron: #context.write('MRICRON dcm2nii program not found. Will use dcm2niix instead' ) #mricron = find_executable('dcm2niix') #self.mricron_program = 'dcm2niix' # if not mricron: #raise RuntimeError(_t_('dcm2nii or dcm2niix executable NOT found !')) DicomToNifti.dicom_to_nifti(self.dwi_directory, self.mricron_program, context) #outputFiles = glob.glob(os.path.join(self.dwi_directory.fullPath(), '*.nii.gz')) context.write("OK") context.system( 'mv', glob.glob(os.path.join(self.dwi_directory.fullPath(), '*.nii.gz'))[0], tmp_directory + '/dwi.nii.gz' ) #data context.system( 'mv', glob.glob(os.path.join(self.dwi_directory.fullPath(), '*.bvec'))[0], tmp_directory + '/bvec.txt' ) #data context.system( 'mv', glob.glob(os.path.join(self.dwi_directory.fullPath(), '*.bval'))[0], tmp_directory + '/bval.txt' ) #data list_metadata = glob.glob(os.path.join(self.dwi_directory.fullPath(), '*.json')) context.write("OK1") if list_metadata: context.system('mv', glob.glob(os.path.join(self.dwi_directory.fullPath(), '*.json'))[0], tmp_directory + '/dwi_metadata.json') context.write("OK2") if self.additional_acquisition=="Fieldmap": DicomToNifti.dicom_to_nifti(self.fieldmap_directory, self.mricron_program, context) context.system( 'mv', glob.glob(os.path.join(self.fieldmap_directory.fullPath(), '*.nii.gz'))[0], tmp_directory + '/phase.nii.gz' ) #_e2phdata for f in glob.glob(os.path.join(self.fieldmap_directory.fullPath(), '*.nii.gz')): context.system( 'rm', f) #_e2data DicomToNifti.dicom_to_nifti(self.magnitude_directory, self.mricron_program, context) context.system( 'mv', glob.glob(os.path.join(self.magnitude_directory.fullPath(), '*.nii.gz'))[0], tmp_directory + '/mag.nii.gz' ) #data for f in glob.glob(os.path.join(self.magnitude_directory.fullPath(), '*.nii.gz')): context.system( 'rm', f) #_e2data context.write("OK3") elif self.additional_acquisition=="Blip-reversed images": DicomToNifti.dicom_to_nifti(self.blip_reversed_directory, self.mricron_program, context) context.system( 'mv', glob.glob(os.path.join(self.blip_reversed_directory.fullPath(), '*.nii.gz'))[0], tmp_directory + '/blip_reversed.nii.gz' ) #data list_metadata = glob.glob(os.path.join(self.blip_reversed_directory.fullPath(), '*.json')) if list_metadata: context.system( 'mv', glob.glob(os.path.join(self.blip_reversed_directory.fullPath(), '*.json'))[0], tmp_directory + '/blip_reversed_metadata.json' ) context.write("OK4") #for f in glob.glob(os.path.join(self.magnitude_directory.fullPath(), '*')): #context.system('rm', f) # _e2data context.write("OK5") # Import data if self.additional_acquisition=="None": context.runProcess( 'Import', dwi_data=tmp_directory + '/dwi.nii.gz', bvals=tmp_directory + '/bval.txt', bvecs=tmp_directory + '/bvec.txt', dwi_metadata=tmp_directory + '/dwi_metadata.json', additional_acquisition=self.additional_acquisition, output_dwi_data=self.output_dwi_data, output_bvals=self.output_bvals, output_bvecs=self.output_bvecs, output_dwi_metadata=self.output_dwi_metadata) context.write("OK6") #context.runProcess('Import', dwi_data=tmp_directory + '/dwi.nii.gz', bvals=tmp_directory + '/bval.txt', bvecs=tmp_directory + '/bvec.txt', additional_acquisition=self.additional_acquisition, output_dwi_data=self.output_dwi_data, output_bvals=self.output_bvals, output_bvecs=self.output_bvecs) if self.additional_acquisition=="Fieldmap": context.runProcess( 'Import', dwi_data=tmp_directory + '/dwi.nii.gz', bvals=tmp_directory + '/bval.txt', bvecs=tmp_directory + '/bvec.txt',dwi_metadata=tmp_directory + '/dwi_metadata.json', additional_acquisition=self.additional_acquisition, output_dwi_data=self.output_dwi_data, output_bvals=self.output_bvals, output_bvecs=self.output_bvecs, output_dwi_metadata=self.output_dwi_metadata, fieldmap=tmp_directory + '/phase.nii.gz', magnitude=tmp_directory + '/mag.nii.gz', output_fieldmap=self.output_fieldmap, output_magnitude=self.output_magnitude ) if self.additional_acquisition=="Blip-reversed images": context.runProcess( 'Import', dwi_data=tmp_directory + '/dwi.nii.gz', bvals=tmp_directory + '/bval.txt', bvecs=tmp_directory + '/bvec.txt', dwi_metadata=tmp_directory + '/dwi_metadata.json', additional_acquisition=self.additional_acquisition, output_dwi_data=self.output_dwi_data, output_bvals=self.output_bvals, output_bvecs=self.output_bvecs, output_dwi_metadata=self.output_dwi_metadata, blip_reversed_data=tmp_directory + '/blip_reversed.nii.gz', blip_reversed_metada=tmp_directory + '/blip_reversed_metadata.json', output_blip_reversed_data=self.output_blip_reversed_data, output_blip_reversed_metadata=self.output_blip_reversed_metadata) # Dicom header info files = os.listdir(self.dwi_directory.fullPath()) file0 = files[0] header = dicom.read_file(self.dwi_directory.fullPath() + '/' + file0) print header manufact = header['0008','0070'].value acqMat = header.get('AcquisitionMatrix') # acqMat: Dimensions of the acquired frequency /phase data before reconstruction. Multi-valued: frequency rows\frequency columns\phase rows\phase columns if acqMat[0]==0 & acqMat[3]==0: # phase-encoding LR/RL PE = 'x axis or LR/RL' dimx = acqMat[2] dimy = acqMat[1] Nvox = dimx elif acqMat[1]==0 & acqMat[2]==0: # phase-encoding AP/PA PE = 'y axis or AP/PA' dimx = acqMat[0] dimy = acqMat[3] Nvox = dimy dimz = header['0019','100a'].value TR = header.get('RepetitionTime') TE = header.get('EchoTime') BdWpp = header['0019','1028'].value ESeff = 1/(BdWpp*Nvox) RT = 1/BdWpp context.write('Manufacturer: ' + manufact) context.write('TR = ' + str(TR)) context.write('TE = ' + str(TE)) context.write('BandwidthPerPixelPhaseEncode (Hz) = ' + str(BdWpp)) context.write('Effective Echo Spacing (s) = ' + str(ESeff)) context.write('Readout Time (s) = ' + str(RT)) context.write('Matrix Size (voxels) = ' + str(dimx) + ' x ' + str(dimy) + ' x ' + str(dimz)) context.write('Phase-encoding direction along ' + PE)
from brainvisa.processes import * from soma.wip.application.api import Application from distutils.spawn import find_executable from soma import aims import os import nibabel configuration = Application().configuration def defaultBrainExtraction(data_path, bet_output, f='0.3'): """ brain extraction using FSL-bet function, with recursive searching of image center """ data = nibabel.load(data_path).get_data() cmd = ' '.join([ configuration.FSL.fsl_commands_prefix + 'bet ', data_path, bet_output, ' -R -m -f ', f ]) os.system(cmd) return 0 def interactiveBrainExtraction(context, data_path, bet_output, f='0.3'): """ Iterative and interactive brain extraction using FSL-bet function """ cmds = ['fsleyes', 'fslview'] viewers = [ find_executable(configuration.FSL.fsl_commands_prefix + cmd) for cmd in cmds ]
def execution(self, context): configuration = Application().configuration transformManager = getTransformationManager() niftyreg_f3d = find_executable('reg_f3d') niftyreg_resample = find_executable('reg_resample') niftyreg_transform = find_executable('reg_transform') context.write('Fractional anisotropy temporary estimation') dtifit = context.temporary('File') mask = context.temporary('File') cmd = [ configuration.FSL.fsl_commands_prefix + 'bet', self.b0_volume.fullPath(), mask.fullPath(), '-f', '0.3', '-m' ] context.system(*cmd) cmd = [ configuration.FSL.fsl_commands_prefix + 'dtifit', '-k', self.dwi_data.fullPath(), '-o', dtifit.fullPath(), '-m', mask.fullPath() + '_mask.nii.gz', '-r', self.bvecs.fullPath(), '-b', self.bvals.fullPath() ] context.system(*cmd) FA = dtifit.fullPath() + '_FA.nii.gz' context.write('Affine pre-alignment') diff_to_t1_xfm = context.temporary('File') #'/tmp/diff_to_t1_xfm' # reg = context.temporary('File') #'/tmp/reg' # t1_brain = context.temporary('NIFTI-1 image') context.system('AimsMask', '-i', self.T1_volume, '-m', self.T1_mask.fullPath(), '-o', t1_brain.fullPath()) cmd = [ configuration.FSL.fsl_commands_prefix + 'flirt', '-ref', t1_brain.fullPath(), '-in', FA, '-omat', diff_to_t1_xfm.fullPath() + '_init.mat', '-out', reg.fullPath() + '_FA_to_t1_affine.nii.gz' ] context.system(*cmd) #diff_to_t1_xfm.fullPath() is an affine 4X4 matrix cmd = [ configuration.FSL.fsl_commands_prefix + 'flirt', '-ref', t1_brain.fullPath(), '-in', self.b0_volume.fullPath(), '-applyxfm', '-init', diff_to_t1_xfm.fullPath() + '_init.mat', '-out', reg.fullPath() + '_b0_to_t1_affine.nii.gz' ] context.system(*cmd) #register the bo into the T1 space using affine transformation tmp_file = context.temporary('gz compressed NIFTI-1 image') context.write('Non linear registration') cmd = [ niftyreg_f3d, '-ref', self.T1_volume.fullPath(), '-flo', reg.fullPath() + '_FA_to_t1_affine.nii.gz', '-sym', '-cpp', diff_to_t1_xfm.fullPath() + '_cpp.nii', '-res', reg.fullPath() + '_FA_to_t1_nonlinear.nii.gz' ] context.system(*cmd) cmd = [ niftyreg_resample, '-ref', self.T1_volume.fullPath(), '-flo', reg.fullPath() + '_b0_to_t1_affine.nii.gz', '-trans', diff_to_t1_xfm.fullPath() + '_cpp.nii', '-res', tmp_file.fullPath() ] context.system(*cmd) ref = self.T1_volume.get('storage_to_memory', search_header=True) context.system('AimsFileConvert', '-i', tmp_file.fullPath(), '-o', self.b0_to_T1.fullPath(), '--orient', '"abs: ' + ' '.join(map(str, ref)) + '"') transformManager.copyReferential(self.T1_volume, self.b0_to_T1) context.write('Invert transformation...') cmd = [ niftyreg_transform, '-ref', self.T1_volume.fullPath(), '-def', diff_to_t1_xfm.fullPath() + '_cpp.nii', self.diff_to_T1_nonlinear_dfm.fullPath() ] context.system(*cmd) cmd = [ niftyreg_transform, '-ref', self.T1_volume.fullPath(), '-def', diff_to_t1_xfm.fullPath() + '_cpp_backward.nii', self.T1_to_diff_nonlinear_dfm.fullPath() ] #reg.fullPath()+'_FA_to_t1_affine.nii.gz' context.system(*cmd) # cmd = [configuration.FSL.fsl_commands_prefix + 'convert_xfm', '-omat', diff_to_t1_xfm.fullPath() + '_init_inv.mat', '-inverse', diff_to_t1_xfm.fullPath() + '_init.mat'] # context.system(*cmd) context.write( 'Conversion from .mat to .trm' ) # Non applicable to non-linear warp image. To compute only for anatomist to load files in the same referential trm = fslTransformation.fslMatToTrm( diff_to_t1_xfm.fullPath() + '_init.mat', self.b0_volume.fullPath(), self.b0_to_T1.fullPath()) aims.write(trm, self.diff_to_T1_linear_xfm.fullPath()) cmd = [ 'AimsInvertTransformation', '-i', self.diff_to_T1_linear_xfm, '-o', self.T1_to_diff_linear_xfm ] context.system(*cmd) context.write('Registration of T1 to DWI space...') cmd = [ niftyreg_resample, '-ref', self.T1_volume.fullPath(), '-flo', self.T1_volume.fullPath(), '-trans', self.T1_to_diff_nonlinear_dfm.fullPath(), '-res', tmp_file.fullPath() ] #reg.fullPath()+'_FA_to_t1_affine.nii.gz' context.system(*cmd) cmd = [ 'AimsResample', '-i', tmp_file, '-m', self.T1_to_diff_linear_xfm, '-t', self.T1_to_b0_interpolation, '-o', self.T1_to_b0 ] if self.T1_to_b0_resampling == True: cmd += ['-r', self.b0_volume] elif self.T1_to_b0_resampling == False: dim = self.b0_volume.get('volume_dimension', search_header=True) vox_ref = self.b0_volume.get('voxel_size', search_header=True) vox_in = self.T1_volume.get('voxel_size', search_header=True) cmd += [ '--dx', str(int(dim[0] * vox_ref[0] / vox_in[0]) + 1), '--dy', str(int(dim[1] * vox_ref[1] / vox_in[1]) + 1), '--dz', str(int(dim[2] * vox_ref[2] / vox_in[2]) + 1) ] context.system(*cmd) ref = self.b0_volume.get('storage_to_memory', search_header=True) os.system(' '.join([ 'AimsFileConvert', '-i', self.T1_to_b0.fullPath(), '-o', self.T1_to_b0.fullPath(), '--orient', '"abs: ' + ' '.join(map(str, ref)) + '"' ])) transformManager.copyReferential(self.b0_volume, self.T1_to_b0) context.write('Registration of T1 brain mask to DWI space...') cmd = [ niftyreg_resample, '-ref', self.T1_volume.fullPath(), '-flo', self.T1_mask.fullPath(), '-trans', self.T1_to_diff_nonlinear_dfm.fullPath(), '-res', tmp_file.fullPath() ] #reg.fullPath()+'_FA_to_t1_affine.nii.gz' context.system(*cmd) cmd = [ 'AimsResample', '-i', tmp_file, '-m', self.T1_to_diff_linear_xfm, '-t', self.T1_to_b0_interpolation, '-o', self.T1_to_b0_mask, '-r', self.b0_volume ] context.system(*cmd) cmd = [ 'AimsThreshold', '-i', self.T1_to_b0_mask, '-o', self.T1_to_b0_mask, '-t', '1', '-b', '--fg', '1' ] context.system(*cmd) os.system(' '.join([ 'AimsFileConvert', '-i', self.T1_to_b0_mask.fullPath(), '-o', self.T1_to_b0_mask.fullPath(), '--orient', '"abs: ' + ' '.join(map(str, ref)) + '"' ])) transformManager.copyReferential(self.dwi_data, self.T1_to_b0_mask) context.write('Recompile left-right grey-matter and white-matter...') Left = aims.read(self.T1_grey_white_left.fullPath()) Right = aims.read(self.T1_grey_white_right.fullPath()) Left_Right = Left + Right GM = Left.arraydata() GM[:, :, :, :] = 0 GM[numpy.where(Left_Right.arraydata() == 100)] = 100 WM = Right.arraydata() WM[:, :, :, :] = 0 WM[numpy.where(Left_Right.arraydata() == 200)] = 100 GM_vol = aims.Volume(GM) WM_vol = aims.Volume(WM) GM_vol.copyHeaderFrom(Left.header()) WM_vol.copyHeaderFrom(Left.header()) GM_file = context.temporary('NIFTI-1 image') WM_file = context.temporary('NIFTI-1 image') aims.write(GM_vol, GM_file.fullPath()) aims.write(WM_vol, WM_file.fullPath()) context.write( 'Registration of white-matter and grey-matter masks to DWI space...') cmd = [ niftyreg_resample, '-ref', self.T1_volume.fullPath(), '-flo', GM_file.fullPath(), '-trans', self.T1_to_diff_nonlinear_dfm.fullPath(), '-res', tmp_file.fullPath(), '-inter', 0 ] #reg.fullPath()+'_FA_to_t1_affine.nii.gz' context.system(*cmd) cmd = [ 'AimsResample', '-i', tmp_file, '-m', self.T1_to_diff_linear_xfm, '-t', '0', '-o', self.T1_to_b0_GM, '-d', '1', '-r', self.b0_volume ] context.system(*cmd) cmd = [ 'AimsThreshold', '-i', self.T1_to_b0_GM, '-o', self.T1_to_b0_GM, '-t', '50', '-b', '--fg', '1' ] context.system(*cmd) os.system(' '.join([ 'AimsFileConvert', '-i', self.T1_to_b0_GM.fullPath(), '-o', self.T1_to_b0_GM.fullPath(), '--orient', '"abs: ' + ' '.join(map(str, ref)) + '"' ])) transformManager.copyReferential(self.dwi_data, self.T1_to_b0_GM) cmd = [ niftyreg_resample, '-ref', self.T1_volume.fullPath(), '-flo', WM_file.fullPath(), '-trans', self.T1_to_diff_nonlinear_dfm.fullPath(), '-res', tmp_file.fullPath(), '-inter', '0' ] #reg.fullPath()+'_FA_to_t1_affine.nii.gz' context.system(*cmd) cmd = [ 'AimsResample', '-i', tmp_file, '-m', self.T1_to_diff_linear_xfm, '-t', '0', '-o', self.T1_to_b0_WM, '-d', '1', '-r', self.b0_volume ] # cmd = [configuration.FSL.fsl_commands_prefix + 'fslmaths', self.T1_to_b0_WM.fullPath(), '-thr', '50', '-bin', self.T1_to_b0_WM.fullPath()] context.system(*cmd) cmd = [ 'AimsThreshold', '-i', self.T1_to_b0_WM, '-o', self.T1_to_b0_WM, '-t', '50', '-b', '--fg', '1' ] context.system(*cmd) os.system(' '.join([ 'AimsFileConvert', '-i', self.T1_to_b0_WM.fullPath(), '-o', self.T1_to_b0_WM.fullPath(), '--orient', '"abs: ' + ' '.join(map(str, ref)) + '"' ])) transformManager.copyReferential(self.dwi_data, self.T1_to_b0_WM) context.write('Recompile T1 left-right skeletons...') Left = aims.read(self.T1_skeleton_left.fullPath()) Right = aims.read(self.T1_skeleton_right.fullPath()) Lskeleton = Left.arraydata() Rskeleton = Right.arraydata() Lskeleton[Lskeleton < 20] = 0 Lskeleton[Lskeleton > 20] = 1 Rskeleton[Rskeleton < 20] = 0 Rskeleton[Rskeleton > 20] = 1 Lskeleton_vol = aims.Volume(Lskeleton) Rskeleton_vol = aims.Volume(Rskeleton) skeleton = Lskeleton_vol + Rskeleton_vol skeleton.copyHeaderFrom(Left.header()) skeleton_file = context.temporary('NIFTI-1 image') aims.write(skeleton, skeleton_file.fullPath()) context.write('Registration of T1 skeleton mask to DWI space...') cmd = [ niftyreg_resample, '-ref', self.T1_volume.fullPath(), '-flo', skeleton_file.fullPath(), '-trans', self.T1_to_diff_nonlinear_dfm.fullPath(), '-res', tmp_file.fullPath() ] #reg.fullPath()+'_FA_to_t1_affine.nii.gz' context.system(*cmd) cmd = [ 'AimsResample', '-i', tmp_file, '-m', self.T1_to_diff_linear_xfm, '-t', '0', '-o', self.T1_to_b0_skeleton, '-r', self.b0_volume ] context.system(*cmd) cmd = [ 'AimsThreshold', '-i', self.T1_to_b0_skeleton, '-o', self.T1_to_b0_skeleton, '-m', 'gt', '-t', '0', '-b', '--fg', '1' ] context.system(*cmd) cmd = [ 'AimsMask', '-i', self.T1_to_b0_skeleton, '-o', self.T1_to_b0_skeleton, '-m', self.T1_to_b0_WM, '--inv', 'True' ] context.system(*cmd) os.system(' '.join([ 'AimsFileConvert', '-i', self.T1_to_b0_skeleton.fullPath(), '-o', self.T1_to_b0_skeleton.fullPath(), '--orient', '"abs: ' + ' '.join(map(str, ref)) + '"' ])) transformManager.copyReferential(self.dwi_data, self.T1_to_b0_skeleton) context.write('Finished')
def execution(self, context): configuration = Application().configuration img = aims.read(self.dwi_data.fullPath()) dwi_data = img.arraydata() bvals = numpy.loadtxt(self.bvals.fullPath()) b0_index = numpy.where(bvals < 100)[ 0] ## bvals==0 not possible when bvalues take values +-5 or +-10 if self.data_are_distortion_corrected: ## Average of all b0 volumes (after affine registration done by eddy-current correction) context.write('Average of all b0 volumes') b0_sum = dwi_data[b0_index[0], :, :, :] for ind in b0_index[1:]: b0_sum = b0_sum + dwi_data[ind, :, :, :] b0_sum = b0_sum / len(b0_index) else: ## Affine alignment and average of all b0 volumes refvol = context.temporary('NIFTI-1 image') invol = context.temporary('NIFTI-1 image') outvol = context.temporary('NIFTI-1 image') context.write('Extraction of first b0 volume') cmd = [ configuration.FSL.fsl_commands_prefix + 'fslroi', self.dwi_data.fullPath(), refvol.fullPath(), str(b0_index[0]), '1' ] context.system(*cmd) b0_sum = dwi_data[b0_index[0], :, :, :] context.write( 'Affine co-registration of all b0 volumes to the first one...') for ind in b0_index[1:]: cmd = [ configuration.FSL.fsl_commands_prefix + 'fslroi', self.dwi_data.fullPath(), invol.fullPath(), str(ind), '1' ] context.system(*cmd) cmd = [ configuration.FSL.fsl_commands_prefix + 'flirt', '-interp', 'spline', '-cost', 'mutualinfo', '-in', invol.fullPath(), '-ref', refvol.fullPath(), '-out', outvol.fullPath() ] context.system(*cmd) b0_reg = aims.read(outvol.fullPath()) b0_reg_data = b0_reg.arraydata() b0_sum = b0_sum + b0_reg_data b0_sum = b0_sum / len(b0_index) # b0_sum = dwi_data[b0_index[0], :, :, :] b0_vol = aims.Volume(b0_sum) b0_vol.copyHeaderFrom(img.header()) aims.write(b0_vol, self.b0_volume.fullPath()) transformManager = getTransformationManager() transformManager.copyReferential(self.dwi_data, self.b0_volume) context.write('Finished')
def execution(self, context): ## Validation bvals = numpy.loadtxt(self.bvals.fullPath()) a = numpy.array(bvals) / 100 b = numpy.round(a) c = numpy.unique(b) d = c[c != 0] * 100 Nshell = len(d) if Nshell > 1: context.write('Multi-shell acquisition with ', str(Nshell) + ' shells: b=' + str(d.astype(int))) raise RuntimeError( _t_('Global Tractograhy is NOT YET COMPATIBLE with multishell acquisitions ! Please modify your data accordingly.' )) elif Nshell == 1: bvalue = d[0].astype(int) configuration = Application().configuration spm = configuration.SPM.spm8_path matlab_exe = configuration.matlab.executable tractoScriptPath = fibertool.define_toolpath() transformManager = getTransformationManager() tempDir = configuration.brainvisa.temporaryDirectory timesec = str(int(time.time() * 1000)) MITK_bvecs = tempDir + '/MITK_bvecs.txt' #context.temporary('Text file') # MITK_mask = tempDir + '/MITK_mask' #context.temporary('File') # MITK_raw_data = tempDir + '/MITK_raw_data.mat' #context.temporary('Matlab File') # MITK_hardi_data = tempDir + '/MITK_hardi_data.mat' #context.temporary('Matlab File') MITK_tract_data = tempDir + '/MITK_tract_data_' + self.reconstruction_density + '.mat' #context.temporary('Matlab File') context.write("Reorganize bvecs according to MITK convention") # orientation: Xnew=-Y Ynew=X Znew=Z # b0 at the begining # array of shape (Nvol, 3) vecs = numpy.loadtxt(self.bvecs.fullPath()) vecs[[0, 1]] = vecs[[1, 0]] vecs[0] = -vecs[0] vals = numpy.loadtxt(self.bvals.fullPath()) b0 = numpy.where(vals < 100)[0] nb0 = len(b0) step = 0 vecs_reorganized = numpy.copy(vecs) for i in range(len(vals)): if vals[i] < 100: vecs_reorganized[:, step] = vecs[:, i] step += 1 else: vecs_reorganized[:, len(b0) + i - step] = vecs[:, i] new_vecs = vecs_reorganized.T numpy.savetxt(MITK_bvecs, new_vecs, fmt='%6f') context.write("Split and unzip the input 4D volume into 3D volumes") splitpath = tempDir + '/split_volumes_' + timesec if os.path.exists(splitpath): shutil.rmtree(splitpath) os.makedirs(splitpath) cmd = [ configuration.FSL.fsl_commands_prefix + 'fslsplit', self.dwi_data.fullPath(), splitpath + '/vol_', '-t' ] context.system(*cmd) os.system('gunzip {0}/*'.format(splitpath)) os.system('cp ' + self.binary_mask.fullPath() + ' ' + MITK_mask + '.nii.gz') os.system('gunzip -f ' + MITK_mask + '.nii.gz') context.write('Convert data to matlab structure') matfilepath = tempDir + '/fibertool_main' + timesec matfile = file(matfilepath + '.m', 'w') matfile.write("addpath(genpath('%s'));\n" % (tractoScriptPath)) matfile.write("addpath(genpath('%s/release'));\n" % (self.tractographyPackage.fullPath())) matfile.write("addpath('%s');\n" % spm) matfile.write("fibertool_importData('%s/', '%s', '%s.nii', '%s')\n" % (splitpath, self.bvals.fullPath(), MITK_mask, tempDir)) matfile.write("exit\n") matfile.close() os.system(matlab_exe + ' -nodisplay -r "run %s.m"' % matfilepath) # os.system('rm ' + matfilepath + '.m') context.write("Compute HARDI model and matlab structure") # WARNING: in calcutate_dti.m, if bvecs of b0 volumes are not equal to [0, 0, 0], then the script adds null vectors to the DE scheme artificially ! # So size of tables are no longer equivalent. Note: It probably needs only indices in the table so it's not necessary to force them null. Actually there is even no need to reorder the bvec with b0 at the begining... # This issue is taken into account in our process computeDT = '0' matfilepath = tempDir + '/fibertool_hardi' + timesec matfile = file(matfilepath + '.m', 'w') matfile.write("addpath(genpath('%s'));\n" % (tractoScriptPath)) matfile.write("addpath(genpath('%s/release'));\n" % (self.tractographyPackage.fullPath())) matfile.write( "addpath('%s');\n" % spm ) # Fibertool is not compatible with SPM12. Need to change path in Matlab to use SPM8 matfile.write("fibertool_computeHardi('%s', '%s', '%s', '%s', '%s')\n" % (tempDir, str(bvalue), MITK_bvecs, str(nb0), computeDT)) matfile.write("exit\n") matfile.close() os.system(matlab_exe + ' -nodisplay -r "run %s.m"' % matfilepath) # os.system('rm ' + matfilepath + '.m') context.write("Global fiber tracking") threshold = '0' matfilepath = tempDir + '/fibertool_tracking' + timesec matfile = file(matfilepath + '.m', 'w') matfile.write("addpath(genpath('%s'));\n" % (tractoScriptPath)) matfile.write("addpath(genpath('%s/release'));\n" % (self.tractographyPackage.fullPath())) matfile.write("addpath('%s');\n" % spm) matfile.write("fibertool_globalTracking('%s', '%s', '%s')\n" % (tempDir, threshold, self.reconstruction_density)) matfile.write("exit\n") matfile.close() os.system(matlab_exe + ' -nodisplay -r "run %s.m"' % matfilepath) # os.system('rm ' + matfilepath + '.m') context.write('Convert .mat into .trk format') mask_img = nibabel.load(self.binary_mask.fullPath()) mask = mask_img.get_data() print(mask.shape) mask_affine = mask_img.get_affine() if self.data_source == "HCP": affine = numpy.array([[1, 0, 0, 34], [0, -1, 0, 144 - 29], [0, 0, 1, -23], [0, 0, 0, 1]]) elif self.data_source == "CerimedMRI": affine = numpy.array([[1, 0, 0, 47], [0, 1, 0, -48], [0, 0, 1, -30], [0, 0, 0, 1]]) ## To be set else: affine = numpy.eye(4) voxel_size = mask_img.header['pixdim'][1:4] scaling = numpy.array( [[0, voxel_size[0], 0, 0], [-voxel_size[1], 0, 0, voxel_size[1] * (mask.shape[1])], [0, 0, voxel_size[2], 0], [0, 0, 0, 1]]) inStruct = scipy.io.loadmat(MITK_tract_data) context.write('tracks loaded') context.write(str(inStruct['curveSegCell'].shape[0]) + ' fibers detected') sl = [] for s in inStruct['curveSegCell']: s = s[0] s = nibabel.affines.apply_affine(affine, s) s = nibabel.affines.apply_affine(scaling, s) sl.append(s) save_trk(self.streamlines.fullPath(), sl, numpy.eye(4), mask.shape) context.write('tractogram saved !') context.write('Create density map') translation = [[1, 0, 0, 0], [0, 1, 0, -1], [0, 0, 1, -1], [0, 0, 0, 1]] sl = [] for s in inStruct['curveSegCell']: s = s[0] s = nibabel.affines.apply_affine(translation, s) s = nibabel.affines.apply_affine( scaling, s ) # scaling pas obligatoire seulement reorient => affine=np.eye(4) pour density map sl.append(s) dm = utils.density_map( sl, mask.shape, affine=numpy.diag([voxel_size[0], voxel_size[1], voxel_size[2], 1])) nibabel.save(nibabel.Nifti1Image(dm.astype(numpy.float32), mask_affine), self.density_map.fullPath()) context.write('density map saved !')
def execution(self, context): context.write('Distortion correction using blip-reversed images') configuration = Application().configuration fsldir = configuration.FSL.fsldir FSL_topup_directory = os.path.dirname(self.topup_b0_volumes.fullPath()) tmp_directory = configuration.brainvisa.temporaryDirectory context.write('- Reading data') up_img = aims.read(self.dwi_data.fullPath()) up_data = up_img.arraydata() up_bvals = numpy.loadtxt(self.bvals.fullPath()) up_bvecs = numpy.loadtxt(self.bvecs.fullPath()) context.write(up_bvals.shape) context.write(up_bvecs.shape) down_img = aims.read(self.blip_reversed_data.fullPath()) down_data = down_img.arraydata() Nvol_up = self.dwi_data.get('volume_dimension', search_header=True)[3] Nvol_down = self.blip_reversed_data.get('volume_dimension', search_header=True)[3] if Nvol_up == Nvol_down: blip_down_scheme = 'full_sequence' context.write( 'Full acquisition with opposite phase-encode direction DETECTED') else: blip_down_scheme = 'b0_volumes_only' context.write( 'Only b0 volumes with opposite phase-encode direction DETECTED') # # context.write('- Correcting number of slices') # dimx = self.dwi_data.get( 'volume_dimension', search_header=True )[0] # dimy = self.dwi_data.get( 'volume_dimension', search_header=True )[1] # dimz = self.dwi_data.get( 'volume_dimension', search_header=True )[2] # if dimz % 2 != 0: # context.write('ODD number of slices') # up_data = up_data[:,1:,:,:] # down_data = down_data[:,1:,:,:] # dimz = dimz -1 # # context.write('- b0 volumes extraction') # up_b0_index = numpy.where(up_bvals < 50)[0] ## bvals==0 not possible when bvalues take values +-5 or +-10 # ## if len(up_b0_index)>3: # ## up_b0_index=up_b0_index[::2] # up_b0 = up_data[up_b0_index, :, :, :] # if blip_down_scheme == 'b0_volumes_only': # down_bvals = numpy.zeros((1, Nvol_down))+up_bvals[up_b0_index[0]] # down_bvals = down_bvals[0] # down_b0_index = numpy.arange(Nvol_down) # down_bvecs = numpy.zeros((3, Nvol_down))+up_bvecs[:,up_b0_index[0]].reshape((3,1)) # else: # down_bvals = up_bvals # down_b0_index = up_b0_index # down_bvecs = up_bvecs # # down_b0 = down_data[down_b0_index, :, :, :] # # context.write('- Merging blip-up and blip-down b0 images') # up_down_b0 = numpy.concatenate((up_b0, down_b0)) # up_down_b0_vol = aims.Volume(up_down_b0) # up_down_b0_vol.copyHeaderFrom(up_img.header()) # aims.write(up_down_b0_vol, self.topup_b0_volumes.fullPath()) # # if self.b0_bias_correction: # context.write('- Intensity bias correction of b0 images') # biais_corrected_img = context.temporary('gz compressed NIFTI-1 image' ) # sec = int(time.time()) # for i in range(len(up_b0_index)+len(down_b0_index)): # context.write('volume '+str(i)) # context.system( configuration.FSL.fsl_commands_prefix + 'fslroi', self.topup_b0_volumes.fullPath(), tmp_directory+'/bias_img_'+str(sec)+'.nii.gz', str(i), '1' ) # context.system( configuration.FSL.fsl_commands_prefix + 'fsl_anat', '--noreorient', '--nocrop', '--noreg', '--nononlinreg', '--noseg', '--nosubcortseg', '-t', 'T2', '-i', tmp_directory+'/bias_img_'+str(sec)+'.nii.gz') # if i==0: # context.system( 'cp', tmp_directory + '/bias_img_'+str(sec)+'.anat/T2_biascorr.nii.gz', biais_corrected_img.fullPath()) # else: # context.system( configuration.FSL.fsl_commands_prefix + 'fslmerge', '-t', biais_corrected_img.fullPath(), biais_corrected_img.fullPath(), tmp_directory + '/bias_img_'+str(sec)+'.anat/T2_biascorr.nii.gz') # context.system( 'rm', '-r', tmp_directory + '/bias_img_'+str(sec)+'.anat/' ) # context.system( 'mv', biais_corrected_img.fullPath(), self.topup_b0_volumes.fullPath()) # # context.write('- Merging blip-up and blip-down dwi images') # ## context.system( configuration.FSL.fsl_commands_prefix + 'fslmerge', '-t', self.topup_data.fullPath(), self.dwi_data.fullPath(), self.blip_reversed_data.fullPath() ) # up_down_data = numpy.concatenate((up_data, down_data)) # up_down_data_vol = aims.Volume(up_down_data) # up_down_data_vol.copyHeaderFrom(up_img.header()) # aims.write(up_down_data_vol, self.topup_data.fullPath()) # context.write('- Merging bvals and bvecs') # up_down_bvals = numpy.concatenate((up_bvals, down_bvals), axis=0) # up_down_bvals = up_down_bvals.reshape((1,len(up_down_bvals))) # numpy.savetxt(self.topup_bvals.fullPath(), up_down_bvals, fmt='%d') # up_down_bvecs = numpy.concatenate((up_bvecs, down_bvecs), axis=1) # up_down_bvecs = up_down_bvecs # numpy.savetxt(self.topup_bvecs.fullPath(), up_down_bvecs, fmt='%.15f') # # context.write('- Setting acquisition parameters') # PE_parameters = self.topup_parameters.fullPath() # PE_index = self.topup_index.fullPath() # f_param = open(PE_parameters, 'w') # f_index = open(PE_index, 'w') # PE_list = ["AP", "PA", "LR", "RL"] # vector_list_up = ['0 1 0 ', '0 -1 0 ', '1 0 0 ', '-1 0 0 '] # vector_list_down = ['0 -1 0 ', '0 1 0 ', '-1 0 0 ', '1 0 0 '] # indx = PE_list.index(self.phase_encoding_direction) # [f_param.write(vector_list_up[indx] + str(self.readout_time) + '\n') for i in range(len(up_b0_index))] # [f_param.write(vector_list_down[indx] + str(self.readout_time) + '\n') for i in range(len(down_b0_index))] # val=1 # for i in range(len(up_data)+len(down_data)): # if i in up_b0_index[1:] or i in down_b0_index+len(up_bvals): # val+=1 # f_index.write(str(val)+' ') # f_param.close() # f_index.close() # # context.write('- Estimation of the susceptibility off-resonance field...') # topup_config = fsldir + '/etc/flirtsch/b02b0.cnf' # cmd = [ configuration.FSL.fsl_commands_prefix + 'topup', '--imain=' + self.topup_b0_volumes.fullPath(), '--datain=' + self.topup_parameters.fullPath(), '--config=' + topup_config, '--out=' + FSL_topup_directory+ '/topup', '--iout=' + self.topup_b0_volumes_unwarped.fullPath(), '--verbose' ] # context.system( *cmd ) # # context.write('- Apply fieldcoeff to b0 volumes') # up_b01 = context.temporary('gz compressed NIFTI-1 image' ) # down_b01 = context.temporary('gz compressed NIFTI-1 image' ) # up_b01_vol = aims.Volume(up_b0[0,:,:,:]) # up_b01_vol.copyHeaderFrom(up_img.header()) # aims.write(up_b01_vol, up_b01.fullPath()) # down_b01_vol = aims.Volume(down_b0[0,:,:,:]) # down_b01_vol.copyHeaderFrom(down_img.header()) # aims.write(down_b01_vol, down_b01.fullPath()) # cmd = [ configuration.FSL.fsl_commands_prefix + 'applytopup', '--imain=' + up_b01.fullPath() + ',' + down_b01.fullPath(), '--inindex='+ '1' + ',' + str(len(up_b0_index)+1), '--datain=' + self.topup_parameters.fullPath(), '--topup=' + FSL_topup_directory + '/topup', '--out=' + self.topup_b0_mean.fullPath()] # context.system( *cmd ) # BrainExtraction.defaultBrainExtraction(self.topup_b0_mean.fullPath(), self.topup_b0_mean_brain.fullPath(), f=str(self.brain_extraction_factor)) context.write( '- Eddy current estimation and correction... [can take several hours]') #memoryUse = 2*8*(len(up_data)+len(down_data))*dimx*dimy*dimz/1000000 #context.write('Estimated memory usage: '+str(memoryUse)+' MB') # if oldORnew == "old": # context.write('INFO: FSL version is anterior to 5.0.9') # eddyExec = fsldir + '/bin/eddy.gpu' # else: # context.write('INFO: FSL version is 5.0.9 or newer') # eddyExec = fsldir + '/bin/eddy_cuda' eddyExec = find_executable('eddy_openmp') if eddyExec: context.write('CPU-multithread version of eddy found') else: context.write('CPU/GPU-multithread version of eddy NOT found') eddyExec = find_executable('eddy') #else: #eddyExec = fsldir + '/bin/eddy.gpu' #if os.path.isfile(eddyExec) == True: # context.write('GPU-multithread version of eddy found') #else: # eddyExec = fsldir + '/bin/eddy_cuda' #if os.path.isfile(eddyExec) == True: # context.write('GPU-multithread version of eddy found') #else: # context.write('CPU/GPU-multithread version of eddy NOT found') # eddyExec = fsldir + '/bin/eddy' ## default parameters for eddy #--fep # Fill Empty Planes by duplication or interpolation, can occur depending on scanner #--dont_peas # Post-Eddy-Alignment of Shell. To use only if single shell acquisition #--data_is_shelled # To use only if multi-shell, to force uncheck in case of special acquisition with "mini-shell" (a few dir with low bval) #--dont_sep_offs_move # should not be used #--interp = "spline" # interpolation model used during estimation phase and final resampling, use default #--ff = "10" # cannot be higher than default 10, safe value if self.entire_sphere_sampling == False or Nvol_up < 60: slm = "linear" else: slm = "none" if blip_down_scheme == 'b0_volumes_only': resamp = "jac" else: resamp = "lsr" cmd1 = '. ' + fsldir + '/etc/fslconf/fsl.sh' cmd2 = eddyExec + ' --imain=' + self.topup_data.fullPath( ) + ' --mask=' + self.topup_b0_mean_brain_mask.fullPath( ) + ' --acqp=' + self.topup_parameters.fullPath( ) + ' --index=' + self.topup_index.fullPath( ) + ' --bvecs=' + self.topup_bvecs.fullPath( ) + ' --bvals=' + self.topup_bvals.fullPath( ) + ' --topup=' + FSL_topup_directory + '/topup' + ' --out=' + FSL_topup_directory + '/topup_eddy' cmd2 += ' --flm=' + str(self.flm) + ' --slm=' + slm + ' --fwhm=' + str( self.fwhm) + ',0,0,0,0' + ' --niter=' + str( self.niter ) + ' --fep --interp=spline --resamp=' + resamp + ' --nvoxhp=' + str( self.nvoxhp) + ' --ff=10 --very_verbose' if not self.multi_shell: cmd2 += " --dont_peas" else: cmd2 += " --data_is_shelled" # option does NOT exist cmd = cmd1 + ' ; ' + cmd2 os.system(cmd) context.write('- Save corrected images and bvecs') context.system( configuration.FSL.fsl_commands_prefix + 'fslmaths', FSL_topup_directory + '/topup_eddy.nii.gz', '-abs', '-uthr', '65535', FSL_topup_directory + '/topup_eddy.nii.gz' ) # manage pb of type FLOAT and negative values become infinite values, data from Centre IRMf are in U16 [0,65535] context.write('threshold') if blip_down_scheme == 'b0_volumes_only': context.system(configuration.FSL.fsl_commands_prefix + 'fslroi', FSL_topup_directory + '/topup_eddy.nii.gz', self.dwi_unwarped.fullPath(), 0, str(len(up_bvals))) else: context.system('cp', FSL_topup_directory + '/topup_eddy.nii.gz', self.dwi_unwarped.fullPath()) new_bvecs = numpy.loadtxt(FSL_topup_directory + '/topup_eddy.eddy_rotated_bvecs') new_bvecs = new_bvecs[:, :up_bvecs.shape[1]] numpy.savetxt(self.corrected_bvecs.fullPath(), new_bvecs, fmt='%.15f') transformManager = getTransformationManager() transformManager.copyReferential(self.dwi_data, self.dwi_unwarped) context.write('Finished')