Esempio n. 1
0
def test_subsample():
    """
    Test subsampling
    """

    # Sub-sampling 100 out of a random collection of 150 unit-vectors:
    bvecs = np.array([ozu.unit_vector(x) for x in np.random.randn(3,150)])

    # The following runs through most of the module w/o verifying correctness:
    sub_sample = ozb.subsample(bvecs, 100)

    # optionally, you can provide elec_points as input. Here we test this with
    # the same points
    sub_sample = ozb.subsample(bvecs, 100, elec_points=ozu.get_camino_pts(100).T)
Esempio n. 2
0
def test_subsample():
    """
    Test subsampling
    """

    # Sub-sampling 100 out of a random collection of 150 unit-vectors:
    bvecs = np.array([ozu.unit_vector(x) for x in np.random.randn(3, 150)])

    # The following runs through most of the module w/o verifying correctness:
    sub_sample = ozb.subsample(bvecs, 100)

    # optionally, you can provide elec_points as input. Here we test this with
    # the same points
    sub_sample = ozb.subsample(bvecs,
                               100,
                               elec_points=ozu.get_camino_pts(100).T)
Esempio n. 3
0
    def __init__(self,
                 data,
                 bvecs,
                 bvals,
                 affine=None,
                 mask=None,
                 scaling_factor=SCALE_FACTOR,
                 sub_sample=None,
                 verbose=True,
                 b0_tol=0.005):
        """
        Initialize a DWI object

        Parameters
        ----------
        data: str or array
            The diffusion weighted mr data provided either as a full path to a
            nifti file containing the data, or as a 4-d array.

        bvecs: str or array
            The unit vectors describing the directions of data
            acquisition. Either an 3 by n array, or a full path to a text file
            containing the 3 by n data.

        bvals: str or array
            The values of b weighting in the data acquisition. Either a 1 by n
            array, or a full path to a text file containing the values.
        
        affine: optional, 4 by 4 array
            The affine provided in the file can be overridden by explicitely
            setting this input variable. If this is left as None, one of two
            things will happen. If the 'data' input was a file-name, the affine
            will be read from that file. Otherwise, a warning will be issued
            and affine will default to np.eye(4).

        mask: optional, 3-d array
            When provided, used as a boolean mask into the data for access. 

        sub_sample: int or array of ints.
           If we want to sub-sample the DWI data on the sphere (in the bvecs),
           we can do one of two things: 
           
        1. If sub_sample is an integer, that number of random bvecs will be
           chosen from the data.

        2. If an array of indices is provided, these will serve as indices into
        the last dimension of the data and only that part of the data will be
        used

        verbose: boolean, optional.
           Whether or not to print out various messages as you go
           along. Default: True

        """
        self.verbose = verbose
        self.b0_tol = b0_tol
        self.scaling_factor = scaling_factor
        # All inputs are handled essentially the same. Inputs can be either
        # strings, in which case file reads are required, or arrays, in which
        # case no file reads are needed and we assign these arrays into the
        # attributes:
        for name, val in zip(['data', 'bvecs', 'bvals'], [data, bvecs, bvals]):
            if val is None:
                exec("self.%s = None" % name)
            elif isinstance(val, str):
                exec("self.%s_file = '%s'" % (name, val))
            elif isinstance(val, np.ndarray):
                # This time we need to give it the name-space:
                exec("self.%s = val" % name, dict(self=self, val=val))
            else:
                e_s = "%s seems to be neither an array, " % name
                e_s += "nor a file-name\n"
                e_s += "The value provided was: %s" % val
                raise ValueError(e_s)

        # You might have to scale the bvalues by some factor, so that the units
        # come out correctly in the adc calculation:
        if self.bvals is not None:
            self.bvals = self.bvals.copy() / scaling_factor

        # You can provide your own affine, if you want and that bypasses the
        # class method provided below as an auto-attr:
        if affine is not None:
            self.affine = np.matrix(affine)

        # If a mask is provided, we will use it to access the data
        if mask is not None:
            # If it's a string, assume it's the full-path to a nifti file with
            # a binary mask:
            if isinstance(mask, str):
                mask = ni.load(mask).get_data()
            else:
                self.mask = np.array(mask, dtype=bool)

            pre_mask = np.array(mask, dtype=bool)
            ravel_mask = np.ravel(pre_mask)

            # Eliminate the voxels where self.S0 == 0.
            ravel_mask[np.where(ravel_mask)[0][np.where(
                self.S0[pre_mask] == 0)]] = False
            self.mask = np.reshape(ravel_mask, pre_mask.shape)

        else:
            # If only one voxel was provided, we will assume that all the data
            # in the voxel should be taken
            if len(self.shape) == 1:
                self.mask = slice(0, None, None)
            # Otherwise, we make a 3D mask, with all the voxels in the volume:
            else:
                # Spatial mask (take only the spatial dimensions):
                self.mask = np.ones(self.shape[:3], dtype=bool)

        if sub_sample is not None:
            if np.iterable(sub_sample):
                idx = sub_sample
            else:
                idx = boot.subsample(self.bvecs[:, self.b_idx], sub_sample)[1]

            self.b_idx = self.b_idx[idx]
            # At this point, signal will be taken according to these
            # sub-sampled indices:
            self.data = np.concatenate(
                [self.signal, self.data[:, :, :, self.b0_idx]], -1)

            self.b0_idx = np.arange(len(self.b0_idx))

            self.bvecs = np.concatenate(
                [np.zeros(
                    (3, len(self.b0_idx))), self.bvecs[:, self.b_idx]], -1)

            self.bvals = np.concatenate(
                [np.zeros(len(self.b0_idx)), self.bvals[self.b_idx]])
            self.b_idx = np.arange(len(self.b0_idx),
                                   len(self.b0_idx) + len(idx))
Esempio n. 4
0
    def __init__(self,
                 data,
                 bvecs,
                 bvals,
                 affine=None,
                 mask=None,
                 scaling_factor=SCALE_FACTOR,
                 sub_sample=None,
                 verbose=True
                 ):
        """
        Initialize a DWI object

        Parameters
        ----------
        data: str or array
            The diffusion weighted mr data provided either as a full path to a
            nifti file containing the data, or as a 4-d array.

        bvecs: str or array
            The unit vectors describing the directions of data
            acquisition. Either an 3 by n array, or a full path to a text file
            containing the 3 by n data.

        bvals: str or array
            The values of b weighting in the data acquisition. Either a 1 by n
            array, or a full path to a text file containing the values.
        
        affine: optional, 4 by 4 array
            The affine provided in the file can be overridden by explicitely
            setting this input variable. If this is left as None, one of two
            things will happen. If the 'data' input was a file-name, the affine
            will be read from that file. Otherwise, a warning will be issued
            and affine will default to np.eye(4).

        mask: optional, 3-d array
            When provided, used as a boolean mask into the data for access. 

        sub_sample: int or array of ints.
           If we want to sub-sample the DWI data on the sphere (in the bvecs),
           we can do one of two things: 
           
        1. If sub_sample is an integer, that number of random bvecs will be
           chosen from the data.

        2. If an array of indices is provided, these will serve as indices into
        the last dimension of the data and only that part of the data will be
        used

        verbose: boolean, optional.
           Whether or not to print out various messages as you go
           along. Default: True

        """
        self.verbose=verbose
        
        # All inputs are handled essentially the same. Inputs can be either
        # strings, in which case file reads are required, or arrays, in which
        # case no file reads are needed and we assign these arrays into the
        # attributes:
        for name, val in zip(['data', 'bvecs', 'bvals'],
                             [data, bvecs, bvals]): 
            if val is None:
                exec("self.%s = None"%name)
            elif isinstance(val, str):
                exec("self.%s_file = '%s'"% (name, val))
            elif isinstance(val, np.ndarray):
                # This time we need to give it the name-space:
                exec("self.%s = val"% name, dict(self=self, val=val))
            else:
                e_s = "%s seems to be neither an array, "% name
                e_s += "nor a file-name\n"
                e_s += "The value provided was: %s" % val
                raise ValueError(e_s)

        # You might have to scale the bvalues by some factor, so that the units
        # come out correctly in the adc calculation:
        if self.bvals is not None:
            self.bvals = self.bvals.copy() / scaling_factor
        
        # You can provide your own affine, if you want and that bypasses the
        # class method provided below as an auto-attr:
        if affine is not None:
            self.affine = np.matrix(affine)

        # If a mask is provided, we will use it to access the data
        if mask is not None:
            # If it's a string, assume it's the full-path to a nifti file with
            # a binary mask: 
            if isinstance(mask, str):
                mask = ni.load(mask).get_data()
            self.mask = np.array(mask, dtype=bool)

        else:
            # If only one voxel was provided, we will assume that all the data
            # in the voxel should be taken
            if len(self.shape)==1:
                self.mask = slice(0,None,None)
            # Otherwise, we make a 3D mask, with all the voxels in the volume: 
            else:
                # Spatial mask (take only the spatial dimensions):
                self.mask = np.ones(self.shape[:3], dtype=bool)
            
        if sub_sample is not None:
            if np.iterable(sub_sample):
                idx = sub_sample
            else:
                idx = boot.subsample(self.bvecs[:,self.b_idx].T, sub_sample)[1]
            
            self.b_idx = self.b_idx[idx]
            # At this point, signal will be taken according to these
            # sub-sampled indices:
            self.data = np.concatenate([self.signal,
                                        self.data[:,:,:,self.b0_idx]],-1)
            
            self.b0_idx = np.arange(len(self.b0_idx))

            self.bvecs = np.concatenate([np.zeros((3,len(self.b0_idx))),
                                        self.bvecs[:, self.b_idx]],-1)

            self.bvals = np.concatenate([np.zeros(len(self.b0_idx)),
                                         self.bvals[self.b_idx]])
            self.b_idx = np.arange(len(self.b0_idx), len(self.b0_idx) + len(idx))