Esempio n. 1
0
    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))
Esempio n. 2
0
    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 )
Esempio n. 3
0
    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 ))