Example #1
0
def gq_tn_calc_save():

    for simfile in simdata:
    
        dataname = simfile
        print dataname

        sim_data=np.loadtxt(simdir+dataname)

        marta_table_fname='/home/ian/Data/SimData/Dir_and_bvals_DSI_marta.txt'
        b_vals_dirs=np.loadtxt(marta_table_fname)
        bvals=b_vals_dirs[:,0]*1000
        gradients=b_vals_dirs[:,1:]

        gq = dgqs.GeneralizedQSampling(sim_data,bvals,gradients)
        gqfile = simdir+'gq/'+dataname+'.pkl'
        pkl.save_pickle(gqfile,gq)

        '''
        gq.IN               gq.__doc__          gq.glob_norm_param
        gq.QA               gq.__init__         gq.odf              
        gq.__class__        gq.__module__       gq.q2odf_params
        '''

        tn = ddti.Tensor(sim_data,bvals,gradients)
        tnfile = simdir+'tn/'+dataname+'.pkl'
        pkl.save_pickle(tnfile,tn)


        '''
        tn.ADC               tn.__init__          tn._getevals
        tn.B                 tn.__module__        tn._getevecs
        tn.D                 tn.__new__           tn._getndim
        tn.FA                tn.__reduce__        tn._getshape
        tn.IN                tn.__reduce_ex__     tn._setevals
        tn.MD                tn.__repr__          tn._setevecs
        tn.__class__         tn.__setattr__       tn.adc
        tn.__delattr__       tn.__sizeof__        tn.evals
        tn.__dict__          tn.__str__           tn.evecs
        tn.__doc__           tn.__subclasshook__  tn.fa
        tn.__format__        tn.__weakref__       tn.md
        tn.__getattribute__  tn._evals            tn.ndim
        tn.__getitem__       tn._evecs            tn.shape
        tn.__hash__          tn._getD             
        '''

        ''' file  has one row for every voxel, every voxel is repeating 1000
Example #2
0
def test_gqi_small():

    #read bvals,gradients and data
    bvals=np.load(opj(os.path.dirname(__file__), \
                          'data','small_64D.bvals.npy'))
    gradients=np.load(opj(os.path.dirname(__file__), \
                              'data','small_64D.gradients.npy'))    
    img =ni.load(os.path.join(os.path.dirname(__file__),\
                                  'data','small_64D.nii'))
    data=img.get_data()    

    print(bvals.shape)
    print(gradients.shape)
    print(data.shape)


    t1=time.clock()
    
    gqs = gq.GeneralizedQSampling(data,bvals,gradients)

    t2=time.clock()
    print('GQS in %d' %(t2-t1))
        
    eds=np.load(opj(os.path.dirname(__file__),\
                        '..','matrices',\
                        'evenly_distributed_sphere_362.npz'))

    
    odf_vertices=eds['vertices']
    odf_faces=eds['faces']

    #Yeh et.al, IEEE TMI, 2010
    #calculate the odf using GQI

    scaling=np.sqrt(bvals*0.01506) # 0.01506 = 6*D where D is the free
    #water diffusion coefficient 
    #l_values sqrt(6 D tau) D free water
    #diffusion coefficiet and tau included in the b-value

    tmp=np.tile(scaling,(3,1))
    b_vector=gradients.T*tmp
    Lambda = 1.2 # smoothing parameter - diffusion sampling length
    
    q2odf_params=np.sinc(np.dot(b_vector.T, odf_vertices.T) * Lambda/np.pi)
    #implements equation no. 9 from Yeh et.al.

    S=data.copy()

    x,y,z,g=S.shape
    S=S.reshape(x*y*z,g)
    QA = np.zeros((x*y*z,5))
    IN = np.zeros((x*y*z,5))

    fwd = 0
    
    #Calculate Quantitative Anisotropy and find the peaks and the indices
    #for every voxel

    for (i,s) in enumerate(S):

        odf = Q2odf(s,q2odf_params)
        peaks,inds=rp.peak_finding(odf,odf_faces)
        fwd=max(np.max(odf),fwd)
        peaks = peaks - np.min(odf)
        l=min(len(peaks),5)
        QA[i][:l] = peaks[:l]
        IN[i][:l] = inds[:l]

    QA/=fwd
    QA=QA.reshape(x,y,z,5)    
    IN=IN.reshape(x,y,z,5)
    
    print('Old %d secs' %(time.clock() - t2))
    
    assert_equal((gqs.QA-QA).max(),0.,'Frank QA different than dipy QA')
    assert_equal((gqs.QA.shape),QA.shape, 'Frank QA shape is different')  

    assert_equal(len(tp.FACT_Delta(QA,IN,seeds_no=100).tracks),100,
                 'FACT_Delta is not generating the right number of '
                 'tracks for this dataset')
Example #3
0
def test_gqiodf():

    #read bvals,gradients and data
    bvals=np.load(opj(os.path.dirname(__file__), \
                          'data','small_64D.bvals.npy'))
    gradients=np.load(opj(os.path.dirname(__file__), \
                              'data','small_64D.gradients.npy'))    
    img =ni.load(os.path.join(os.path.dirname(__file__),\
                                  'data','small_64D.nii'))
    data=img.get_data()    

    #print(bvals.shape)
    #print(gradients.shape)
    #print(data.shape)


    # t1=time.clock()
    
    gq.GeneralizedQSampling(data,bvals,gradients)
    ten = dt.Tensor(data,bvals,gradients,thresh=50)

    
    ten.fa()

    x,y,z,a,b=ten.evecs.shape
    evecs=ten.evecs
    xyz=x*y*z
    evecs = evecs.reshape(xyz,3,3)
    #vs = np.sign(evecs[:,2,:])
    #print vs.shape
    #print np.hstack((vs,vs,vs)).reshape(1000,3,3).shape
    #evecs = np.hstack((vs,vs,vs)).reshape(1000,3,3)
    #print evecs.shape
    evals=ten.evals
    evals = evals.reshape(xyz,3)
    #print evals.shape

    #print('GQS in %d' %(t2-t1))
        
    eds=np.load(opj(os.path.dirname(__file__),\
                        '..','matrices',\
                        'evenly_distributed_sphere_362.npz'))

    
    odf_vertices=eds['vertices']
    odf_faces=eds['faces']

    #Yeh et.al, IEEE TMI, 2010
    #calculate the odf using GQI

    scaling=np.sqrt(bvals*0.01506) # 0.01506 = 6*D where D is the free
    #water diffusion coefficient 
    #l_values sqrt(6 D tau) D free water
    #diffusion coefficiet and tau included in the b-value

    tmp=np.tile(scaling,(3,1))
    b_vector=gradients.T*tmp
    Lambda = 1.2 # smoothing parameter - diffusion sampling length
    
    q2odf_params=np.sinc(np.dot(b_vector.T, odf_vertices.T) * Lambda/np.pi)
    #implements equation no. 9 from Yeh et.al.

    S=data.copy()

    x,y,z,g=S.shape
    S=S.reshape(x*y*z,g)
    QA = np.zeros((x*y*z,5))
    IN = np.zeros((x*y*z,5))

    fwd = 0
    
    #Calculate Quantitative Anisotropy and find the peaks and the indices
    #for every voxel

    summary = {}

    summary['vertices'] = odf_vertices
    v = odf_vertices.shape[0]
    summary['faces'] = odf_faces
    f = odf_faces.shape[0]

    '''
    If e = number_of_edges
    the Euler formula says f-e+v = 2 for a mesh on a sphere
    Here, assuming we have a healthy triangulation
    every face is a triangle, all 3 of whose edges should belong to
    exactly two faces = so 2*e = 3*f
    to avoid division we test whether 2*f - 3*f + 2*v == 4
    or equivalently 2*v - f == 4
    '''

    assert_equal(2*v-f, 4,'Direct Euler test fails')
    assert_true(meshes.euler_characteristic_check(odf_vertices, odf_faces,chi=2),'euler_characteristic_check fails')
    
    coarse = meshes.coarseness(odf_faces)
    print 'coarseness: ', coarse

    for (i,s) in enumerate(S):

        #print 'Volume %d' % i

        istr = str(i)

        summary[istr] = {}

        odf = Q2odf(s,q2odf_params)
        peaks,inds=rp.peak_finding(odf,odf_faces)
        fwd=max(np.max(odf),fwd)
        peaks = peaks - np.min(odf)
        l=min(len(peaks),5)
        QA[i][:l] = peaks[:l]
        IN[i][:l] = inds[:l]

        summary[istr]['odf'] = odf
        summary[istr]['peaks'] = peaks
        summary[istr]['inds'] = inds
        summary[istr]['evecs'] = evecs[i,:,:]
        summary[istr]['evals'] = evals[i,:]
   
    QA /= fwd
    # QA=QA.reshape(x,y,z,5)
    # IN=IN.reshape(x,y,z,5)
    
    #print('Old %d secs' %(time.clock() - t2))
    # assert_equal((gqs.QA-QA).max(),0.,'Frank QA different than our QA')

    # assert_equal((gqs.QA.shape),QA.shape, 'Frank QA shape is different')
       
    # assert_equal((gqs.QA-QA).max(), 0.)

    #import dipy.core.track_propagation as tp

    #tp.FACT_Delta(QA,IN)

    #return tp.FACT_Delta(QA,IN,seeds_no=10000).tracks

    peaks_1 = [i for i in range(1000) if len(summary[str(i)]['inds'])==1]
    peaks_2 = [i for i in range(1000) if len(summary[str(i)]['inds'])==2]
    peaks_3 = [i for i in range(1000) if len(summary[str(i)]['inds'])==3]

    # correct numbers of voxels with respectively 1,2,3 ODF/QA peaks
    assert_array_equal((len(peaks_1),len(peaks_2),len(peaks_3)), (790,196,14),
                       'error in numbers of QA/ODF peaks')

    # correct indices of odf directions for voxels 0,10,44
    # with respectively 1,2,3 ODF/QA peaks
    assert_array_equal(summary['0']['inds'],[116],
                       'wrong peak indices for voxel 0')
    assert_array_equal(summary['10']['inds'],[105, 78],
                       'wrong peak indices for voxel 10')
    assert_array_equal(summary['44']['inds'],[95, 84, 108],
                       'wrong peak indices for voxel 44')

    assert_equal(np.argmax(summary['0']['odf']), 116)
    assert_equal(np.argmax(summary['10']['odf']), 105)
    assert_equal(np.argmax(summary['44']['odf']), 95)

    # pole_1 = summary['vertices'][116]
    #print 'pole_1', pole_1
    # pole_2 = summary['vertices'][105]
    #print 'pole_2', pole_2
    # pole_3 = summary['vertices'][95]
    #print 'pole_3', pole_3

    vertices = summary['vertices']

    width = 0.02#0.3 #0.05
    
    '''
    print 'pole_1 equator contains:', len([i for i,v in enumerate(vertices) if np.abs(np.dot(v,pole_1)) < width])
    print 'pole_2 equator contains:', len([i for i,v in enumerate(vertices) if np.abs(np.dot(v,pole_2)) < width])
    print 'pole_3 equator contains:', len([i for i,v in enumerate(vertices) if np.abs(np.dot(v,pole_3)) < width])
    '''
    
    #print 'pole_1 equator contains:', len(meshes.equatorial_vertices(vertices,pole_1,width))
    #print 'pole_2 equator contains:', len(meshes.equatorial_vertices(vertices,pole_2,width))
    #print 'pole_3 equator contains:', len(meshes'equatorial_vertices(vertices,pole_3,width))

    #print triple_odf_maxima(vertices,summary['0']['odf'],width)
    #print triple_odf_maxima(vertices,summary['10']['odf'],width)
    #print triple_odf_maxima(vertices,summary['44']['odf'],width)
    #print summary['0']['evals']
    '''

    pole=np.array([0,0,1])

    from dipy.viz import fos
    r=fos.ren()
    fos.add(r,fos.point(pole,fos.green))
    for i,ev in enumerate(vertices):        
        if np.abs(np.dot(ev,pole))<width:
            fos.add(r,fos.point(ev,fos.red))
    fos.show(r)

    '''

    triple = triple_odf_maxima(vertices, summary['10']['odf'], width)
    
    indmax1, odfmax1 = triple[0]
    indmax2, odfmax2 = triple[1]
    indmax3, odfmax3 = triple[2] 

    '''
    from dipy.viz import fos
    r=fos.ren()
    for v in vertices:
        fos.add(r,fos.point(v,fos.cyan))
    fos.add(r,fos.sphere(upper_hemi_map(vertices[indmax1]),radius=0.1,color=fos.red))
    #fos.add(r,fos.line(np.array([0,0,0]),vertices[indmax1]))
    fos.add(r,fos.sphere(upper_hemi_map(vertices[indmax2]),radius=0.05,color=fos.green))
    fos.add(r,fos.sphere(upper_hemi_map(vertices[indmax3]),radius=0.025,color=fos.blue))
    fos.add(r,fos.sphere(upper_hemi_map(summary['0']['evecs'][:,0]),radius=0.1,color=fos.red,opacity=0.7))
    fos.add(r,fos.sphere(upper_hemi_map(summary['0']['evecs'][:,1]),radius=0.05,color=fos.green,opacity=0.7))
    fos.add(r,fos.sphere(upper_hemi_map(summary['0']['evecs'][:,2]),radius=0.025,color=fos.blue,opacity=0.7))
    fos.add(r,fos.sphere([0,0,0],radius=0.01,color=fos.white))
    fos.show(r)
    '''
    
    mat = np.vstack([vertices[indmax1],vertices[indmax2],vertices[indmax3]])

    print np.dot(mat,np.transpose(mat))
    # this is to assess how othogonal the triple is/are
    print np.dot(summary['0']['evecs'],np.transpose(mat))
"""
**Read the b-vectors**, the unit gradient directions.
"""

gradients = np.loadtxt(fbvecs).T
"""
Crossings and Generalized Q-Sampling
------------------------------------
You probably have heard about the problem of crossings in diffusion MRI.
The single tensor model cannot detect a simple crossing of two fibres.
However with *Generalized Q-Sampling (GQS)* this is possible even up to a quadruple crossing
or higher depending on the resolution of your datasets. Resolution will
typically depend on signal-to-noise ratio and voxel-size.
"""

gqs = gqi.GeneralizedQSampling(data, bvals, gradients)
"""
A useful metric derived from GQS is *Quantitative Anisotropy* (QA).
"""

QA = gqs.qa()
print('QA.shape (%d,%d,%d,%d)' % QA.shape)
"""
QA is a 4-d array with up to 5 peak QA values for each voxel::

  QA.shape (6,10,10,5)

The QA array is
significantly different in shape from the FA array,
however it too can be directly input to the EuDX class:
def run_small_data():

    smalldir = '/home/eg309/Devel/dipy/dipy/data/'
    bvals=np.load(smalldir+'small_64D.bvals.npy')
    gradients=np.load(smalldir+'small_64D.gradients.npy')
    img=nibabel.load(smalldir+'small_64D.nii')
    small_data=img.get_data()    

    print 'real_data', small_data.shape
    gqsmall = dgqs.GeneralizedQSampling(small_data,bvals,gradients)
    tnsmall = ddti.Tensor(small_data,bvals,gradients)

    x,y,z,a,b=tnsmall.evecs.shape
    evecs=tnsmall.evecs
    xyz=x*y*z
    evecs = evecs.reshape(xyz,3,3)
    evals=tnsmall.evals
    evals = evals.reshape(xyz,3)
        
    """
    eds=np.load(opj(os.path.dirname(__file__),\
                        '..','matrices',\
                        'evenly_distributed_sphere_362.npz'))
    """
    from dipy.data import get_sphere

    odf_vertices,odf_faces=get_sphere('symmetric362')

    scaling=np.sqrt(bvals*0.01506) # 0.01506 = 6*D where D is the free
    #water diffusion coefficient 
    #l_values sqrt(6 D tau) D free water
    #diffusion coefficiet and tau included in the b-value

    tmp=np.tile(scaling,(3,1))
    b_vector=gradients.T*tmp
    Lambda = 1.2 # smoothing parameter - diffusion sampling length
    
    q2odf_params=np.sinc(np.dot(b_vector.T, odf_vertices.T) * Lambda/np.pi)
    #implements equation no. 9 from Yeh et.al.

    S=small_data.copy()

    x,y,z,g=S.shape
    S=S.reshape(x*y*z,g)
    # QA = np.zeros((x*y*z,5))
    IN = np.zeros((x*y*z,5))
    FA = tnsmall.fa().reshape(x*y*z)

    fwd = 0
    
    #Calculate Quantitative Anisotropy and find the peaks and the indices
    #for every voxel

    summary = {}

    summary['vertices'] = odf_vertices
    # v = odf_vertices.shape[0]
    summary['faces'] = odf_faces
    # f = odf_faces.shape[0]

    for (i,s) in enumerate(S):

        istr = str(i)

        summary[istr] = {}

        t0, t1, t2, npa = gqsmall.npa(s, width = 5)
        summary[istr]['triple']=(t0,t1,t2)
        summary[istr]['npa']=npa

        odf = Q2odf(s,q2odf_params)
        peaks,inds=rp.peak_finding(odf,odf_faces)
        fwd=max(np.max(odf),fwd)
        n_peaks=min(len(peaks),5)
        peak_heights = [odf[i] for i in inds[:n_peaks]]
        IN[i][:n_peaks] = inds[:n_peaks]

        summary[istr]['odf'] = odf
        summary[istr]['peaks'] = peaks
        summary[istr]['inds'] = inds
        summary[istr]['evecs'] = evecs[i,:,:]
        summary[istr]['evals'] = evals[i,:]
        summary[istr]['n_peaks'] = n_peaks
        summary[istr]['peak_heights'] = peak_heights
        summary[istr]['fa'] = FA[i]
    """
    QA/=fwd
    QA=QA.reshape(x,y,z,5)    
    IN=IN.reshape(x,y,z,5)
    """
    
    peaks_1 = [i for i in range(1000) if summary[str(i)]['n_peaks']==1]
    peaks_2 = [i for i in range(1000) if summary[str(i)]['n_peaks']==2]
    peaks_3 = [i for i in range(1000) if summary[str(i)]['n_peaks']==3]

    print '#voxels with 1, 2, 3 peaks', len(peaks_1),len(peaks_2),len(peaks_3)

    return FA, summary