Esempio n. 1
0
def pdd_reliability(model1, model2):
    """

    Compute the angle between the first PDD in two models.

    Parameters
    ----------
    model1, model2: two objects from a class inherited from BaseModel.
       Must implement an auto_attr class method 'principal_diffusion_direction',
       which returns arrays of 3-vectors representing a direction in three space
       which is the principal diffusion direction in each voxel. Some models
       will have more than one principal diffusion direction in each voxel. In
       that case, the first direction in each voxel will be used to represent
       that voxel. 
    
    """
    vol_shape = model1.shape[:3]
    pdd1 = model1.principal_diffusion_direction[model1.mask]
    pdd2 = model2.principal_diffusion_direction[model2.mask]

    # Some models create not only the first PDD, but subsequent directions as
    # well, so If we have a lot of PDD, we take only the first one:
    if len(pdd1.shape) == 3:
        pdd1 = pdd1[:, 0]
    if len(pdd2.shape) == 3:
        pdd2 = pdd2[:, 0]

    out_flat = np.empty(pdd1.shape[0])
    for vox in xrange(pdd1.shape[0]):
        this_ang = np.rad2deg(ozu.vector_angle(pdd1[vox], pdd2[vox]))
        out_flat[vox] = np.min([this_ang, 180 - this_ang])

    out = ozu.nans(vol_shape)
    out[model1.mask] = out_flat
    return out
Esempio n. 2
0
    def fit_angle(self):
        """
        The angle between the two primary peaks in the ODF
        
        """
        out_flat = np.zeros(self._flat_signal.shape[0])
        flat_odf = self.odf[self.mask]
        for vox in xrange(out_flat.shape[0]):
            if np.any(np.isnan(flat_odf[vox])):
                out_flat[vox] = np.nan
            else:
                p, i = recspeed.local_maxima(flat_odf[vox], self.odf_verts[1])
                mask = p > 0.5 * np.max(p)
                p = p[mask]
                i = i[mask]

                if len(p) < 2:
                    out_flat[vox] = np.nan
                else:
                    out_flat[vox] = np.rad2deg(ozu.vector_angle(
                                        self.odf_verts[0][i[0]],
                                        self.odf_verts[0][i[1]]))

        out = ozu.nans(self.signal.shape[:3])
        out[self.mask] = out_flat
        return out
Esempio n. 3
0
    def fit_angle(self):
        """
        The angle between the two primary peaks in the ODF
        
        """
        out_flat = np.zeros(self._flat_signal.shape[0])
        flat_odf = self.odf[self.mask]
        for vox in xrange(out_flat.shape[0]):
            if np.any(np.isnan(flat_odf[vox])):
                out_flat[vox] = np.nan
            else:
                p, i = recspeed.local_maxima(flat_odf[vox], self.odf_verts[1])
                mask = p > 0.5 * np.max(p)
                p = p[mask]
                i = i[mask]

                if len(p) < 2:
                    out_flat[vox] = np.nan
                else:
                    out_flat[vox] = np.rad2deg(
                        ozu.vector_angle(self.odf_verts[0][i[0]],
                                         self.odf_verts[0][i[1]]))

        out = ozu.nans(self.signal.shape[:3])
        out[self.mask] = out_flat
        return out
Esempio n. 4
0
def pdd_reliability(model1, model2):
    """

    Compute the angle between the first PDD in two models.

    Parameters
    ----------
    model1, model2: two objects from a class inherited from BaseModel.
       Must implement an auto_attr class method 'principal_diffusion_direction',
       which returns arrays of 3-vectors representing a direction in three space
       which is the principal diffusion direction in each voxel. Some models
       will have more than one principal diffusion direction in each voxel. In
       that case, the first direction in each voxel will be used to represent
       that voxel. 
    
    """
    vol_shape = model1.shape[:3]
    pdd1 = model1.principal_diffusion_direction[model1.mask]
    pdd2 = model2.principal_diffusion_direction[model2.mask]

    # Some models create not only the first PDD, but subsequent directions as
    # well, so If we have a lot of PDD, we take only the first one: 
    if len(pdd1.shape) == 3:
        pdd1 = pdd1[:, 0]
    if len(pdd2.shape) == 3:
        pdd2 = pdd2[:, 0]

    out_flat = np.empty(pdd1.shape[0])    
    for vox in xrange(pdd1.shape[0]):
        this_ang = np.rad2deg(ozu.vector_angle(pdd1[vox], pdd2[vox]))
        out_flat[vox] = np.min([this_ang, 180-this_ang])

    out = ozu.nans(vol_shape)
    out[model1.mask] = out_flat
    return out
    def fit_angle(self):
        """
        The angle between the tensors that were fitted
        """
        out_flat = np.empty(self._flat_signal.shape[0])
        flat_params = self.model_params[self.mask]
        for vox in xrange(out_flat.shape[0]):
            if ~np.isnan(flat_params[vox][0]):
                idx = [i for i in self.rot_idx[int(flat_params[vox][0])]]
                # Sort them according to their weight and take the two
                # weightiest ones:
                w = flat_params[vox, 1:1 + self.n_canonicals]
                idx = np.array(idx)[np.argsort(w)]
                ang = np.rad2deg(
                    ozu.vector_angle(self.rot_vecs.T[idx[-1]],
                                     self.rot_vecs.T[idx[-2]]))

                ang = np.min([ang, 180 - ang])

                out_flat[vox] = ang

            else:
                out_flat[vox] = np.nan

        out = ozu.nans(self.signal.shape[:3])
        out[self.mask] = out_flat

        return out
    def fit_angle(self):
        """
        The angle between the tensors that were fitted
        """
        out_flat = np.empty(self._flat_signal.shape[0])
        flat_params = self.model_params[self.mask]
        for vox in xrange(out_flat.shape[0]):
            if ~np.isnan(flat_params[vox][0]):
                idx = [i for i in self.rot_idx[int(flat_params[vox][0])]]
                # Sort them according to their weight and take the two
                # weightiest ones:
                w = flat_params[vox,1:1+self.n_canonicals]
                idx = np.array(idx)[np.argsort(w)]
                ang = np.rad2deg(ozu.vector_angle(
                    self.rot_vecs.T[idx[-1]],
                    self.rot_vecs.T[idx[-2]]))

                ang = np.min([ang, 180-ang])
                
                out_flat[vox] = ang
                
            else:
                out_flat[vox] = np.nan

        
        out = ozu.nans(self.signal.shape[:3])
        out[self.mask] = out_flat

        return out
Esempio n. 7
0
def subsample(bvecs, n_dirs, elec_points=None):
    """

    Generate a sub-sample of size n of directions from the provided bvecs

    Parameters
    ----------
    bvecs: int array (n by 3), a set of cartesian coordinates for a set of
    bvecs 
    n_dirs: int, how many bvecs to sub-sample from this set. 
    elec_points: optional, a set of points read from the camino points, using
    Jones (2003) algorithm for electro-static repulsion
    
    Returns 
    -------
    [x,y,z]: The coordinates of the sub-sample
    bvec_idx: The indices into the original bvecs that would give this
        sub-sample 
 
    Notes
    -----
    Directions are chosen from the camino-generated electro-static repulsion
    points in the directory camino_pts.

    """
    
    if elec_points is None:
        # We need a n by 3 here:
        xyz = ozu.get_camino_pts(n_dirs).T
    else:
        xyz = elec_points.copy()
            
    # Rotate all the points to align with the seed, the bvec relative to which
    # all the rest are chosen (lots going on in this one line):
    new_points = np.array(bvecs *
                          ozu.calculate_rotation(
                              bvecs[np.ceil(np.random.rand() *
                                            xyz.shape[0]).astype(int)],
                              xyz[0]))

    sample_bvecs = np.zeros((3, n_dirs))
    bvec_idx = []
    
    for vec in xrange(n_dirs):
        this = new_points[vec]
        delta = np.zeros(bvecs.shape[0])
        for j in xrange(bvecs.shape[0]):
            delta[j] = ozu.vector_angle(this, bvecs[j])

        this_idx = np.where(delta==np.min(delta))
        
        bvec_idx.append(this_idx)    
        sample_bvecs[:, vec] = bvecs[this_idx]

    return sample_bvecs, np.array(bvec_idx).squeeze()
Esempio n. 8
0
def test_vector_angle():
    """

    Test that calculation of angles between vectors makes sense. 

    """

    a = [1, 0, 0]
    b = [0, 0, 1]

    npt.assert_equal(ozu.vector_angle(a, b), np.pi / 2)

    a = [1, 0, 0]
    b = [-1, 0, 0]

    npt.assert_equal(ozu.vector_angle(a, b), np.pi)

    a = [1, 0, 0]
    b = [1, 0, 0]

    npt.assert_equal(ozu.vector_angle(a, b), 0)
Esempio n. 9
0
def test_vector_angle():
    """

    Test that calculation of angles between vectors makes sense. 

    """

    a = [1, 0, 0]
    b = [0, 0, 1]

    npt.assert_equal(ozu.vector_angle(a,b), np.pi/2)

    a = [1,0,0]
    b = [-1,0,0]
    
    npt.assert_equal(ozu.vector_angle(a,b), np.pi)

    a = [1,0,0]
    b = [1,0,0]
    
    npt.assert_equal(ozu.vector_angle(a,b), 0)
Esempio n. 10
0
def model_params_reliability(model1, model2):
    """
    Compute the vector angle between the sets of model params for two model
    instances in each voxel as a measure of model reliability.
    """
    vol_shape = model1.shape[:3]

    mp1 = model1.model_params[model1.mask]
    mp2 = model2.model_params[model1.mask]

    out_flat = np.empty(mp1.shape[0])

    for vox in xrange(out_flat.shape[0]):
        out_flat[vox] = np.rad2deg(ozu.vector_angle(mp1[vox], mp2[vox]))

    out = ozu.nans(vol_shape)
    out[model1.mask] = out_flat
    return out
Esempio n. 11
0
def model_params_reliability(model1, model2):
    """
    Compute the vector angle between the sets of model params for two model
    instances in each voxel as a measure of model reliability.
    """
    vol_shape = model1.shape[:3]

    mp1 = model1.model_params[model1.mask]
    mp2 = model2.model_params[model1.mask]
    
    out_flat = np.empty(mp1.shape[0])
    
    for vox in xrange(out_flat.shape[0]):
        out_flat[vox]= np.rad2deg(ozu.vector_angle(mp1[vox], mp2[vox]))

    out = ozu.nans(vol_shape)
    out[model1.mask] = out_flat
    return out
Esempio n. 12
0
    def odf_peak_angles(self):
        """
        Calculate the angle between the two largest peaks in the odf peak
        distribution
        """
        out_flat = ozu.nans(self._flat_signal.shape[0])
        flat_odf_peaks = self.odf_peaks[self.mask]
        for vox in xrange(out_flat.shape[0]):
            if ~np.isnan(flat_odf_peaks[vox][0]):
                idx1 = np.argsort(flat_odf_peaks[vox])[-1]
                idx2 = np.argsort(flat_odf_peaks[vox])[-2]
                if idx1 != idx2:
                    ang = np.rad2deg(ozu.vector_angle(
                        self.bvecs[:,self.b_idx].T[idx1],
                        self.bvecs[:,self.b_idx].T[idx2]))

                    ang = np.min([ang, 180-ang])
                
                    out_flat[vox] = ang
                        
        out = ozu.nans(self.signal.shape[:3])
        out[self.mask] = out_flat
        return out
Esempio n. 13
0
    def fit_angle(self):
        """
        The angle between the tensors that were fitted
        """
        out_flat = np.empty(self._flat_signal.shape[0])
        for vox in xrange(out_flat.shape[0]):
            if ~np.isnan(self._flat_params[vox][0]):
                idx1 = np.argsort(self._flat_params[vox])[-1]
                idx2 = np.argsort(self._flat_params[vox])[-2]
                ang = np.rad2deg(ozu.vector_angle(
                    self.bvecs[:,self.b_idx].T[idx1],
                    self.bvecs[:,self.b_idx].T[idx2]))

                ang = np.min([ang, 180-ang])
                
                out_flat[vox] = ang
                
        else:
            out_flat[vox] = np.nan
        
        out = ozu.nans(self.signal.shape[:3])
        out[self.mask] = out_flat

        return out
Esempio n. 14
0
                     [
        'TensorModel',
        'CanonicalTensorModel',
        #'MultiCanonicalTensorModel',
        #'SparseDeconvolutionModel',
        #'SphereModel',
        #'PointyMultiCanonicalTensorModel',
                         ])
    angles = []
    for Model1,Model2,model_name in ModelFest:      
        PDD1 = Model1.principal_diffusion_direction
        PDD2 = Model2.principal_diffusion_direction
        PDD1_flat = PDD1[Model1.mask]
        PDD2_flat = PDD2[Model2.mask]
        n_vox = PDD1_flat.shape[0]
        angles_flat = np.empty(n_vox)
        prog_bar = viz.ProgressBar(n_vox)
        for vox in xrange(n_vox):
            
            angles_flat[vox] = ozu.vector_angle(PDD1_flat[vox],
                                                PDD2_flat[vox])
            prog_bar.animate(vox)

        this_angles = ozu.nans(PDD1.shape[:3])
        this_angles[Model1.mask] = angles_flat

        angles.append(this_angles)
    


Esempio n. 15
0
            #SparseDeconvolutionModel2,
            #SphereModel2,
            #PointyMultiCanonicalTensorModel2
        ],
        [
            'TensorModel',
            'CanonicalTensorModel',
            #'MultiCanonicalTensorModel',
            #'SparseDeconvolutionModel',
            #'SphereModel',
            #'PointyMultiCanonicalTensorModel',
        ])
    angles = []
    for Model1, Model2, model_name in ModelFest:
        PDD1 = Model1.principal_diffusion_direction
        PDD2 = Model2.principal_diffusion_direction
        PDD1_flat = PDD1[Model1.mask]
        PDD2_flat = PDD2[Model2.mask]
        n_vox = PDD1_flat.shape[0]
        angles_flat = np.empty(n_vox)
        prog_bar = viz.ProgressBar(n_vox)
        for vox in xrange(n_vox):

            angles_flat[vox] = ozu.vector_angle(PDD1_flat[vox], PDD2_flat[vox])
            prog_bar.animate(vox)

        this_angles = ozu.nans(PDD1.shape[:3])
        this_angles[Model1.mask] = angles_flat

        angles.append(this_angles)
Esempio n. 16
0
def subsample(bvecs, n_dirs, elec_points=None):
    """

    Generate a sub-sample of size n of directions from the provided bvecs

    Parameters
    ----------
    bvecs: int array (n by 3), a set of cartesian coordinates for a set of
    bvecs 
    n_dirs: int, how many bvecs to sub-sample from this set. 
    elec_points: optional, a set of points read from the camino points, using
    Jones (2003) algorithm for electro-static repulsion
    
    Returns 
    -------
    [x,y,z]: The coordinates of the sub-sample
    bvec_idx: The indices into the original bvecs that would give this
        sub-sample 
 
    Notes
    -----
    Directions are chosen from the camino-generated electro-static repulsion
    points in the directory camino_pts.

    """
    
    if elec_points is None:
        # We need a n by 3 here:
        xyz = ozu.get_camino_pts(n_dirs).T
    else:
        xyz = elec_points.copy()
            
    # Rotate all the points to align with the seed, the bvec relative to which
    # all the rest are chosen (lots going on in this one line):
    rot_to_first = ozu.calculate_rotation(
                              bvecs[:, np.ceil(np.random.randint(xyz.shape[0]))],
                              xyz[0])

    new_points = np.dot(rot_to_first, bvecs).T

    sample_bvecs = np.zeros((3, n_dirs))
    bvec_idx = []

    potential_indices = np.arange(bvecs.shape[-1])
    for vec in xrange(n_dirs):
        this = new_points[vec]
        delta = np.zeros(potential_indices.shape)
        for j in range(delta.shape[0]):
            delta[j] = ozu.vector_angle(this, bvecs[:, j])

        this_idx = np.where(delta==np.min(delta))
        
        bvec_idx.append(potential_indices[this_idx])    
        sample_bvecs[:, vec] = np.squeeze(bvecs[:, this_idx])

        # Remove bvecs that you've used, so that you don't have them more than
        # once: 
        bvecs = np.hstack([bvecs[:, :this_idx[0]],bvecs[:, this_idx[0]+1:]])
        potential_indices = np.hstack([potential_indices[:this_idx[0]],
                                            potential_indices[this_idx[0]+1:]])
        
    return sample_bvecs, np.array(bvec_idx).squeeze()
Esempio n. 17
0
def subsample(bvecs, n_dirs, elec_points=None):
    """

    Generate a sub-sample of size n of directions from the provided bvecs

    Parameters
    ----------
    bvecs: int array (n by 3), a set of cartesian coordinates for a set of
    bvecs 
    n_dirs: int, how many bvecs to sub-sample from this set. 
    elec_points: optional, a set of points read from the camino points, using
    Jones (2003) algorithm for electro-static repulsion
    
    Returns 
    -------
    [x,y,z]: The coordinates of the sub-sample
    bvec_idx: The indices into the original bvecs that would give this
        sub-sample 
 
    Notes
    -----
    Directions are chosen from the camino-generated electro-static repulsion
    points in the directory camino_pts.

    """

    if elec_points is None:
        # We need a n by 3 here:
        xyz = ozu.get_camino_pts(n_dirs).T
    else:
        xyz = elec_points.copy()

    # Rotate all the points to align with the seed, the bvec relative to which
    # all the rest are chosen (lots going on in this one line):
    rot_to_first = ozu.calculate_rotation(
        bvecs[:, np.ceil(np.random.randint(xyz.shape[0]))], xyz[0])

    new_points = np.dot(rot_to_first, bvecs).T

    sample_bvecs = np.zeros((3, n_dirs))
    bvec_idx = []

    potential_indices = np.arange(bvecs.shape[-1])
    for vec in xrange(n_dirs):
        this = new_points[vec]
        delta = np.zeros(potential_indices.shape)
        for j in range(delta.shape[0]):
            delta[j] = ozu.vector_angle(this, bvecs[:, j])

        this_idx = np.where(delta == np.min(delta))

        bvec_idx.append(potential_indices[this_idx])
        sample_bvecs[:, vec] = np.squeeze(bvecs[:, this_idx])

        # Remove bvecs that you've used, so that you don't have them more than
        # once:
        bvecs = np.hstack([bvecs[:, :this_idx[0]], bvecs[:, this_idx[0] + 1:]])
        potential_indices = np.hstack([
            potential_indices[:this_idx[0]],
            potential_indices[this_idx[0] + 1:]
        ])

    return sample_bvecs, np.array(bvec_idx).squeeze()