def load_data(self, dwi_filename='DWI.nii', scheme_filename='DWI.scheme', mask_filename=None, b0_thr=0): """Load the diffusion signal and its corresponding acquisition scheme. Parameters ---------- dwi_filename : string The file name of the DWI data, relative to the subject folder (default : 'DWI.nii') scheme_filename : string The file name of the corresponding acquisition scheme (default : 'DWI.scheme') mask_filename : string The file name of the (optional) binary mask (default : None) b0_thr : float The threshold below which a b-value is considered a b0 (default : 0) """ # Loading data, acquisition scheme and mask (optional) LOG('\n-> Loading data:') tic = time.time() print('\t* DWI signal') if not isfile(pjoin(self.get_config('DATA_path'), dwi_filename)): ERROR('DWI file not found') self.set_config('dwi_filename', dwi_filename) self.niiDWI = nibabel.load( pjoin(self.get_config('DATA_path'), dwi_filename)) self.niiDWI_img = self.niiDWI.get_data().astype(np.float32) hdr = self.niiDWI.header if nibabel.__version__ >= '2.0.0' else self.niiDWI.get_header( ) self.set_config('dim', self.niiDWI_img.shape[:3]) self.set_config('pixdim', tuple(hdr.get_zooms()[:3])) print('\t\t- dim = %d x %d x %d x %d' % self.niiDWI_img.shape) print('\t\t- pixdim = %.3f x %.3f x %.3f' % self.get_config('pixdim')) # Scale signal intensities (if necessary) if (np.isfinite(hdr['scl_slope']) and np.isfinite(hdr['scl_inter']) and hdr['scl_slope'] != 0 and (hdr['scl_slope'] != 1 or hdr['scl_inter'] != 0)): print('\t\t- rescaling data ', end='') self.niiDWI_img = self.niiDWI_img * hdr['scl_slope'] + hdr[ 'scl_inter'] print('[OK]') print('\t* Acquisition scheme') if not isfile(pjoin(self.get_config('DATA_path'), scheme_filename)): ERROR('SCHEME file not found') self.set_config('scheme_filename', scheme_filename) self.set_config('b0_thr', b0_thr) self.scheme = amico.scheme.Scheme( pjoin(self.get_config('DATA_path'), scheme_filename), b0_thr) print('\t\t- %d samples, %d shells' % (self.scheme.nS, len(self.scheme.shells))) print('\t\t- %d @ b=0' % (self.scheme.b0_count), end=' ') for i in range(len(self.scheme.shells)): print(', %d @ b=%.1f' % (len( self.scheme.shells[i]['idx']), self.scheme.shells[i]['b']), end=' ') print() if self.scheme.nS != self.niiDWI_img.shape[3]: ERROR('Scheme does not match with DWI data') print('\t* Binary mask') if mask_filename is not None: if not isfile(pjoin(self.get_config('DATA_path'), mask_filename)): ERROR('MASK file not found') self.niiMASK = nibabel.load( pjoin(self.get_config('DATA_path'), mask_filename)) self.niiMASK_img = self.niiMASK.get_data().astype(np.uint8) niiMASK_hdr = self.niiMASK.header if nibabel.__version__ >= '2.0.0' else self.niiMASK.get_header( ) print('\t\t- dim = %d x %d x %d' % self.niiMASK_img.shape[:3]) print('\t\t- pixdim = %.3f x %.3f x %.3f' % niiMASK_hdr.get_zooms()[:3]) if self.niiMASK.ndim != 3: ERROR('The provided MASK if 4D, but a 3D dataset is expected') if self.get_config('dim') != self.niiMASK_img.shape[:3]: ERROR('MASK geometry does not match with DWI data') else: self.niiMASK = None self.niiMASK_img = np.ones(self.get_config('dim')) print('\t\t- not specified') print('\t\t- voxels = %d' % np.count_nonzero(self.niiMASK_img)) LOG(' [ %.1f seconds ]' % (time.time() - tic)) # Preprocessing LOG('\n-> Preprocessing:') tic = time.time() if self.get_config('doDebiasSignal'): print('\t* Debiasing signal... ', end='') sys.stdout.flush() if self.get_config('DWI-SNR') == None: ERROR( "Set noise variance for debiasing (eg. ae.set_config('RicianNoiseSigma', sigma))" ) self.niiDWI_img = debiasRician(self.niiDWI_img, self.get_config('DWI-SNR'), self.niiMASK_img, self.scheme) print(' [OK]') if self.get_config('doNormalizeSignal'): print('\t* Normalizing to b0... ', end='') sys.stdout.flush() if self.scheme.b0_count > 0: self.mean_b0s = np.mean(self.niiDWI_img[:, :, :, self.scheme.b0_idx], axis=3) else: ERROR('No b0 volume to normalize signal with') norm_factor = self.mean_b0s.copy() idx = self.mean_b0s <= 0 norm_factor[idx] = 1 norm_factor = 1 / norm_factor norm_factor[idx] = 0 for i in range(self.scheme.nS): self.niiDWI_img[:, :, :, i] *= norm_factor print('[ min=%.2f, mean=%.2f, max=%.2f ]' % (self.niiDWI_img.min(), self.niiDWI_img.mean(), self.niiDWI_img.max())) if self.get_config('doMergeB0'): print('\t* Merging multiple b0 volume(s)') mean = np.expand_dims(np.mean(self.niiDWI_img[:, :, :, self.scheme.b0_idx], axis=3), axis=3) self.niiDWI_img = np.concatenate( (mean, self.niiDWI_img[:, :, :, self.scheme.dwi_idx]), axis=3) else: print('\t* Keeping all b0 volume(s)') if self.get_config('doDirectionalAverage'): print( '\t* Performing the directional average on the signal of each shell... ' ) numShells = len(self.scheme.shells) dir_avg_img = self.niiDWI_img[:, :, :, :(numShells + 1)] scheme_table = np.zeros([numShells + 1, 7]) id_bval = 0 dir_avg_img[:, :, :, id_bval] = np.mean(self.niiDWI_img[:, :, :, self.scheme.b0_idx], axis=3) scheme_table[id_bval, :] = np.array([1, 0, 0, 0, 0, 0, 0]) bvals = [] for shell in self.scheme.shells: bvals.append(shell['b']) sort_idx = np.argsort(bvals) for shell_idx in sort_idx: shell = self.scheme.shells[shell_idx] id_bval = id_bval + 1 dir_avg_img[:, :, :, id_bval] = np.mean(self.niiDWI_img[:, :, :, shell['idx']], axis=3) scheme_table[id_bval, :] = np.array([ 1, 0, 0, shell['G'], shell['Delta'], shell['delta'], shell['TE'] ]) self.niiDWI_img = dir_avg_img.astype(np.float32) self.set_config('dim', self.niiDWI_img.shape[:3]) print('\t\t- dim = %d x %d x %d x %d' % self.niiDWI_img.shape) print('\t\t- pixdim = %.3f x %.3f x %.3f' % self.get_config('pixdim')) print('\t* Acquisition scheme') self.scheme = amico.scheme.Scheme(scheme_table, b0_thr) print('\t\t- %d samples, %d shells' % (self.scheme.nS, len(self.scheme.shells))) print('\t\t- %d @ b=0' % (self.scheme.b0_count), end=' ') for i in range(len(self.scheme.shells)): print(', %d @ b=%.1f' % (len( self.scheme.shells[i]['idx']), self.scheme.shells[i]['b']), end=' ') print() if self.scheme.nS != self.niiDWI_img.shape[3]: ERROR('Scheme does not match with DWI data') LOG(' [ %.1f seconds ]' % (time.time() - tic))
def load_data( self, dwi_filename = 'DWI.nii', scheme_filename = 'DWI.scheme', mask_filename = None, b0_thr = 0 ) : """Load the diffusion signal and its corresponding acquisition scheme. Parameters ---------- dwi_filename : string The file name of the DWI data, relative to the subject folder (default : 'DWI.nii') scheme_filename : string The file name of the corresponding acquisition scheme (default : 'DWI.scheme') mask_filename : string The file name of the (optional) binary mask (default : None) b0_thr : float The threshold below which a b-value is considered a b0 (default : 0) """ # Loading data, acquisition scheme and mask (optional) tic = time.time() print '\n-> Loading data:' print '\t* DWI signal...' self.set_config('dwi_filename', dwi_filename) self.niiDWI = nibabel.load( pjoin( self.get_config('DATA_path'), dwi_filename) ) self.niiDWI_img = self.niiDWI.get_data().astype(np.float32) hdr = self.niiDWI.header if nibabel.__version__ >= '2.0.0' else self.niiDWI.get_header() self.set_config('dim', self.niiDWI_img.shape[:3]) self.set_config('pixdim', tuple( hdr.get_zooms()[:3] )) print '\t\t- dim = %d x %d x %d x %d' % self.niiDWI_img.shape print '\t\t- pixdim = %.3f x %.3f x %.3f' % self.get_config('pixdim') # Scale signal intensities (if necessary) if ( np.isfinite(hdr['scl_slope']) and np.isfinite(hdr['scl_inter']) and hdr['scl_slope'] != 0 and ( hdr['scl_slope'] != 1 or hdr['scl_inter'] != 0 ) ): print '\t\t- rescaling data', self.niiDWI_img = self.niiDWI_img * hdr['scl_slope'] + hdr['scl_inter'] print "[OK]" print '\t* Acquisition scheme...' self.set_config('scheme_filename', scheme_filename) self.set_config('b0_thr', b0_thr) self.scheme = amico.scheme.Scheme( pjoin( self.get_config('DATA_path'), scheme_filename), b0_thr ) print '\t\t- %d samples, %d shells' % ( self.scheme.nS, len(self.scheme.shells) ) print '\t\t- %d @ b=0' % ( self.scheme.b0_count ), for i in xrange(len(self.scheme.shells)) : print ', %d @ b=%.1f' % ( len(self.scheme.shells[i]['idx']), self.scheme.shells[i]['b'] ), print if self.scheme.nS != self.niiDWI_img.shape[3] : raise ValueError( 'Scheme does not match with DWI data' ) print '\t* Binary mask...' if mask_filename is not None : self.niiMASK = nibabel.load( pjoin( self.get_config('DATA_path'), mask_filename) ) self.niiMASK_img = self.niiMASK.get_data().astype(np.uint8) niiMASK_hdr = self.niiMASK.header if nibabel.__version__ >= '2.0.0' else self.niiMASK.get_header() print '\t\t- dim = %d x %d x %d' % self.niiMASK_img.shape[:3] print '\t\t- pixdim = %.3f x %.3f x %.3f' % niiMASK_hdr.get_zooms()[:3] if self.get_config('dim') != self.niiMASK_img.shape[:3] : raise ValueError( 'MASK geometry does not match with DWI data' ) else : self.niiMASK = None self.niiMASK_img = np.ones( self.get_config('dim') ) print '\t\t- not specified' print '\t\t- voxels = %d' % np.count_nonzero(self.niiMASK_img) # Preprocessing print '\n-> Preprocessing:' if self.get_config('doDebiasSignal') : print '\t* Debiasing signal...\n', sys.stdout.flush() if self.get_config('DWI-SNR') == None: raise ValueError( "Set noise variance for debiasing (eg. ae.set_config('RicianNoiseSigma', sigma))" ) self.niiDWI_img = debiasRician(self.niiDWI_img,self.get_config('DWI-SNR'),self.niiMASK_img,self.scheme) if self.get_config('doNormalizeSignal') : print '\t* Normalizing to b0...', sys.stdout.flush() if self.scheme.b0_count > 0 : self.mean_b0s = np.mean( self.niiDWI_img[:,:,:,self.scheme.b0_idx], axis=3 ) else: raise ValueError( 'No b0 volume to normalize signal with' ) norm_factor = self.mean_b0s.copy() idx = self.mean_b0s <= 0 norm_factor[ idx ] = 1 norm_factor = 1 / norm_factor norm_factor[ idx ] = 0 for i in xrange(self.scheme.nS) : self.niiDWI_img[:,:,:,i] *= norm_factor print '[ min=%.2f, mean=%.2f, max=%.2f ]' % ( self.niiDWI_img.min(), self.niiDWI_img.mean(), self.niiDWI_img.max() ) if self.get_config('doMergeB0') : print '\t* Merging multiple b0 volume(s)...', mean = np.expand_dims( np.mean( self.niiDWI_img[:,:,:,self.scheme.b0_idx], axis=3 ), axis=3 ) self.niiDWI_img = np.concatenate( (mean, self.niiDWI_img[:,:,:,self.scheme.dwi_idx]), axis=3 ) else : print '\t* Keeping all b0 volume(s)...' print ' [ %.1f seconds ]' % ( time.time() - tic )
def load_data( self, dwi_filename = 'DWI.nii', scheme_filename = 'DWI.scheme', mask_filename = None, b0_thr = 0 ) : """Load the diffusion signal and its corresponding acquisition scheme. Parameters ---------- dwi_filename : string The file name of the DWI data, relative to the subject folder (default : 'DWI.nii') scheme_filename : string The file name of the corresponding acquisition scheme (default : 'DWI.scheme') mask_filename : string The file name of the (optional) binary mask (default : None) b0_thr : float The threshold below which a b-value is considered a b0 (default : 0) """ # Loading data, acquisition scheme and mask (optional) tic = time.time() print('\n-> Loading data:') print('\t* DWI signal...') self.set_config('dwi_filename', dwi_filename) self.niiDWI = nibabel.load( pjoin( self.get_config('DATA_path'), dwi_filename) ) self.niiDWI_img = self.niiDWI.get_data().astype(np.float32) hdr = self.niiDWI.header if nibabel.__version__ >= '2.0.0' else self.niiDWI.get_header() self.set_config('dim', self.niiDWI_img.shape[:3]) self.set_config('pixdim', tuple( hdr.get_zooms()[:3] )) print('\t\t- dim = %d x %d x %d x %d' % self.niiDWI_img.shape) print('\t\t- pixdim = %.3f x %.3f x %.3f' % self.get_config('pixdim')) # Scale signal intensities (if necessary) if ( np.isfinite(hdr['scl_slope']) and np.isfinite(hdr['scl_inter']) and hdr['scl_slope'] != 0 and ( hdr['scl_slope'] != 1 or hdr['scl_inter'] != 0 ) ): print('\t\t- rescaling data', end=' ') self.niiDWI_img = self.niiDWI_img * hdr['scl_slope'] + hdr['scl_inter'] print("[OK]") print('\t* Acquisition scheme...') self.set_config('scheme_filename', scheme_filename) self.set_config('b0_thr', b0_thr) self.scheme = amico.scheme.Scheme( pjoin( self.get_config('DATA_path'), scheme_filename), b0_thr ) print('\t\t- %d samples, %d shells' % ( self.scheme.nS, len(self.scheme.shells) )) print('\t\t- %d @ b=0' % ( self.scheme.b0_count ), end=' ') for i in xrange(len(self.scheme.shells)) : print(', %d @ b=%.1f' % ( len(self.scheme.shells[i]['idx']), self.scheme.shells[i]['b'] ), end=' ') print() if self.scheme.nS != self.niiDWI_img.shape[3] : raise ValueError( 'Scheme does not match with DWI data' ) print('\t* Binary mask...') if mask_filename is not None : self.niiMASK = nibabel.load( pjoin( self.get_config('DATA_path'), mask_filename) ) self.niiMASK_img = self.niiMASK.get_data().astype(np.uint8) niiMASK_hdr = self.niiMASK.header if nibabel.__version__ >= '2.0.0' else self.niiMASK.get_header() print('\t\t- dim = %d x %d x %d' % self.niiMASK_img.shape[:3]) print('\t\t- pixdim = %.3f x %.3f x %.3f' % niiMASK_hdr.get_zooms()[:3]) if self.get_config('dim') != self.niiMASK_img.shape[:3] : raise ValueError( 'MASK geometry does not match with DWI data' ) else : self.niiMASK = None self.niiMASK_img = np.ones( self.get_config('dim') ) print('\t\t- not specified') print('\t\t- voxels = %d' % np.count_nonzero(self.niiMASK_img)) # Preprocessing print('\n-> Preprocessing:') if self.get_config('doDebiasSignal') : print('\t* Debiasing signal...\n') sys.stdout.flush() if self.get_config('DWI-SNR') == None: raise ValueError( "Set noise variance for debiasing (eg. ae.set_config('RicianNoiseSigma', sigma))" ) self.niiDWI_img = debiasRician(self.niiDWI_img,self.get_config('DWI-SNR'),self.niiMASK_img,self.scheme) if self.get_config('doNormalizeSignal') : print('\t* Normalizing to b0...', end=' ') sys.stdout.flush() if self.scheme.b0_count > 0 : self.mean_b0s = np.mean( self.niiDWI_img[:,:,:,self.scheme.b0_idx], axis=3 ) else: raise ValueError( 'No b0 volume to normalize signal with' ) norm_factor = self.mean_b0s.copy() idx = self.mean_b0s <= 0 norm_factor[ idx ] = 1 norm_factor = 1 / norm_factor norm_factor[ idx ] = 0 for i in xrange(self.scheme.nS) : self.niiDWI_img[:,:,:,i] *= norm_factor print('[ min=%.2f, mean=%.2f, max=%.2f ]' % ( self.niiDWI_img.min(), self.niiDWI_img.mean(), self.niiDWI_img.max() )) if self.get_config('doMergeB0') : print('\t* Merging multiple b0 volume(s)...', end=' ') mean = np.expand_dims( np.mean( self.niiDWI_img[:,:,:,self.scheme.b0_idx], axis=3 ), axis=3 ) self.niiDWI_img = np.concatenate( (mean, self.niiDWI_img[:,:,:,self.scheme.dwi_idx]), axis=3 ) else : print('\t* Keeping all b0 volume(s)...') print(' [ %.1f seconds ]' % ( time.time() - tic ))