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
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')
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