loadData.py 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. import SimpleITK
  2. import config
  3. import os
  4. import re
  5. import numpy
  6. import sklearn.cluster
  7. import fitData
  8. import getData
  9. import geometry
  10. def loadTime(r,xsetup):
  11. tempDir=config.getTempDir(xsetup)
  12. code=config.getCode(r,xsetup)
  13. timeFile=os.path.join(tempDir,code,f'{code}_Dummy.csv')
  14. if not os.path.isfile(timeFile):
  15. timeFile=os.path.join(tempDir,code,f'{code}_Dummy.mcsv')
  16. with open(timeFile,'r') as f:
  17. lines=[re.sub('\n','',x) for x in f.readlines()]
  18. lines=[x for x in lines if x[0]!='#']
  19. v=[[float(x) for x in y.split(',')] for y in lines]
  20. t=numpy.array([x[0] for x in v])
  21. dt=numpy.array([x[1] for x in v])
  22. #convert to seconds from miliseconds
  23. t*=1e-3
  24. #convert to seconds from miliseconds
  25. dt*=1e-3
  26. return t,dt
  27. def loadData(r,xsetup,returnGeometry=False):
  28. #load data from nrrd
  29. t,dt=loadTime(r,xsetup)
  30. c1=len(t)
  31. nodes=[config.getNodeName(r,xsetup,'NM',i) for i in range(0,c1)]
  32. files=[f'{x}.nrrd' for x in nodes]
  33. files=[os.path.join(config.getLocalDir(r,xsetup),x) for x in files]
  34. filesPresent=[os.path.isfile(x) for x in files]
  35. #possible side exit when missing files are encountered
  36. xdata=[SimpleITK.ReadImage(x) for x in files]
  37. geo=geometry.getGeometry(xdata[0])
  38. xdata=[SimpleITK.GetArrayFromImage(x) for x in xdata]
  39. #create new array to hold all data
  40. data=numpy.zeros((*xdata[0].shape,len(xdata)))
  41. for i in range(len(xdata)):
  42. data[...,i]=numpy.array(xdata[i])/dt[i]
  43. if returnGeometry:
  44. return data,geo
  45. return data
  46. def getTACAtPixels(data,loc):
  47. #data is 4D array, loc are indices as returned by numpy.nonzero()
  48. #return nxm array where n is number of time points and m is number of locations
  49. #to get TAC for i-th location, do v[:,i]
  50. loc1=[loc+(numpy.array([i,i,i,i]),) for i in range(data.shape[3])]
  51. v=[data[x] for x in loc1]
  52. return numpy.vstack(v)
  53. def loadCT(r,xsetup,returnGeometry=False):
  54. file='{}.nrrd'.format(config.getNodeName(r,xsetup,'CT'))
  55. file=getData.getLocalPath(r,xsetup,file)
  56. xd=SimpleITK.ReadImage(file)
  57. geo=geometry.getGeometry(xd)
  58. xd=SimpleITK.GetArrayFromImage(xd)
  59. if returnGeometry:
  60. return xd,geo
  61. return xd
  62. def saveCenters(r,xsetup,data=None,ir=0):
  63. #if not data:
  64. spect,gSPECT=loadData(r,xsetup,returnGeometry=True)
  65. ct,gCT=loadCT(r,xsetup,returnGeometry=True)
  66. A=spect.reshape(-1,spect.shape[3])
  67. nclass=xsetup['nclass'][0]
  68. #kmeans0 = sklearn.cluster.KMeans(n_clusters=k, random_state=0, n_init="auto").fit(A)
  69. #cmeans = sklearn.mixture.GaussianMixture(n_components=k, random_state=0, n_init=1).fit(A)
  70. kmeans = sklearn.cluster.BisectingKMeans(n_clusters=nclass, random_state=0, n_init=1).fit(A)
  71. centers=kmeans.cluster_centers_
  72. u=kmeans.labels_
  73. u=u.reshape(spect.shape[0:3])
  74. print(u.shape)
  75. code=config.getCode(r,xsetup)
  76. for i in range(nclass):
  77. #ui=(u==i)*numpy.ones(u.shape)
  78. #file=getData.getLocalPath(r,xsetup,config.getPattern('centerWeight',code=code,nclass=nclass,ir=ir,ic=i))
  79. #img=SimpleITK.GetImageFromArray(ui)
  80. #SimpleITK.WriteImage(img, file)
  81. cFile=getData.getLocalPath(r,xsetup,config.getPattern('center',code=code,nclass=nclass,ir=ir,ic=i))
  82. numpy.savetxt(cFile,centers[i:i+1,:],delimiter=',')
  83. #write center map as NRRD file in spect geometry:
  84. file=getData.getLocalPath(r,xsetup,config.getPattern('centerNRRD',code=code,nclass=nclass,ir=ir,qaName='SPECT'))
  85. img=SimpleITK.GetImageFromArray(u)
  86. img.SetOrigin(gSPECT.origin)
  87. img.SetSpacing(gSPECT.spacing)
  88. img.SetDirection(numpy.ravel(gSPECT.direction))
  89. SimpleITK.WriteImage(img, file)
  90. #also in CT geometry
  91. if True:
  92. file1=getData.getLocalPath(r,xsetup,config.getPattern('centerNRRD',code=code,nclass=nclass,ir=ir,qaName='CT'))
  93. #method nearest perservse content, which should be id of the k-means group center
  94. u1=geometry.toSpace2(u,gSPECT,ct,gCT,method='nearest')
  95. img1=SimpleITK.GetImageFromArray(u1)
  96. img1.SetOrigin(gCT.origin)
  97. img1.SetSpacing(gCT.spacing)
  98. img1.SetDirection(numpy.ravel(gCT.direction))
  99. SimpleITK.WriteImage(img1, file1)
  100. #write center map as numpy array
  101. qFile=getData.getLocalPath(r,xsetup,config.getPattern('centerMap',code=code,nclass=nclass,ir=ir,ic=i))
  102. usave=numpy.zeros(kmeans.labels_.shape[0]+3)
  103. usave[0:3]=spect.shape[0:3]
  104. usave[3:]=kmeans.labels_
  105. numpy.savetxt(qFile,usave,delimiter=',')
  106. def loadCenters(r,xsetup,ir=0):
  107. nclass=xsetup['nclass'][0]
  108. centers=numpy.array(0)
  109. for i in range(nclass):
  110. cFile=os.path.join(config.getLocalDir(r,xsetup),config.getCenter(r,xsetup,nclass,ir,i))
  111. #row
  112. c=numpy.loadtxt(cFile,delimiter=',')
  113. if len(centers.shape)==0:
  114. centers=numpy.zeros((nclass,len(c)))
  115. centers[i,:]=c
  116. return centers
  117. def loadCenterMap(r,xsetup,ir=0):
  118. nclass=xsetup['nclass'][0]
  119. code=config.getCode(r,xsetup)
  120. qFile=getData.getLocalPath(r,xsetup,config.getPattern('centerMap',code=code,nclass=nclass,ir=ir))
  121. usave=numpy.loadtxt(qFile,delimiter=',')
  122. shape=[int(x) for x in usave[0:3]]
  123. u=numpy.reshape(usave[3:],shape)
  124. return u
  125. def loadCenterMapNRRD(r,xsetup,ir=0):
  126. nclass=xsetup['nclass'][0]
  127. code=config.getCode(r,xsetup)
  128. md=['CT','SPECT']
  129. files={x:getData.getLocalPath(r,xsetup,config.getPattern('centerNRRD',code=code,nclass=nclass,ir=ir,qaName=x)) for x in md}
  130. xd={x:SimpleITK.ReadImage(files[x]) for x in files}
  131. nd={x:SimpleITK.GetArrayFromImage(xd[x]) for x in xd}
  132. return nd['SPECT'],nd['CT']
  133. def saveIVF(r,xsetup,ir=0,nfit=30,nbatch=30,qLambda=0):
  134. #fit IVF from centers in realization ir, perform nfit optimized fits where nbatch is used
  135. #to find best among nbatch trials (in total, nfit*nbatch fits will be made)
  136. #requires saveCenters to be run prior to execution
  137. nclass=xsetup['nclass'][0]
  138. code=config.getCode(r,xsetup)
  139. t,dt=loadTime(r,xsetup)
  140. centers=loadCenters(r,xsetup,ir)
  141. m,samples=fitData.fitIVFGlobal(t,centers,nfit=nfit,qLambda=qLambda)
  142. fm=m*numpy.ones(samples.shape[1])
  143. fw=numpy.vstack((fm,samples))
  144. f=getData.getLocalPath(r,xsetup,config.getPattern('fitIVF',code=code,nclass=nclass,ir=ir,qLambda=qLambda))
  145. print(f'Saving to {f}')
  146. numpy.savetxt(f,fw,delimiter=',')
  147. def readIVF(r,xsetup,ir=0,qLambda=0):
  148. nclass=xsetup['nclass'][0]
  149. code=config.getCode(r,xsetup)
  150. f=getData.getLocalPath(r,xsetup,config.getPattern('fitIVF',code=code,nclass=nclass,ir=ir,qLambda=qLambda))
  151. fw=numpy.loadtxt(f,delimiter=',')
  152. m=int(fw[0,0])
  153. samples=fw[1:,:]
  154. return m,samples
  155. def saveSamples(r,xsetup,samples,m,name,iseg=0,ir=0,qLambda=0,qLambdaC=0):
  156. nclass=xsetup['nclass'][0]
  157. code=config.getCode(r,xsetup)
  158. fm=numpy.zeros(samples.shape[1])
  159. n=numpy.min(numpy.array([len(m),samples.shape[0]]))
  160. for i in range(n):
  161. fm[i]=m[i]+1
  162. fw=numpy.vstack((fm,samples))
  163. pat=config.getPattern('fitCompartment',code=code,nclass=nclass,ir=ir,qaName=name,iseg=iseg,qLambda=qLambda,qLambdaC=qLambdaC)
  164. f=getData.getLocalPath(r,xsetup,pat)
  165. print(f'Saving samples to {f}')
  166. numpy.savetxt(f,fw,delimiter=',')
  167. def readSamples(r,xsetup,name,iseg=0,ir=0,qLambda=0,qLambdaC=0):
  168. m=[]
  169. nclass=xsetup['nclass'][0]
  170. code=config.getCode(r,xsetup)
  171. pat=config.getPattern('fitCompartment',code=code,nclass=nclass,ir=ir,qaName=name,iseg=iseg,qLambda=qLambda,qLambdaC=qLambdaC)
  172. f=getData.getLocalPath(r,xsetup,pat)
  173. print(f'Reading from {f}')
  174. fw=numpy.loadtxt(f,delimiter=',')
  175. samples=fw[1:,:]
  176. fm=samples[0,:]
  177. for i in range(fm.shape[0]):
  178. if fm[i]==0:
  179. break
  180. m.append(fm[i]-1)
  181. return m,samples
  182. def saveTAC(r,xsetup,tac,name,iseg=0,ir=0,qLambda=0,qLambdaC=0):
  183. nclass=xsetup['nclass'][0]
  184. code=config.getCode(r,xsetup)
  185. pat=config.getPattern('fitCompartment',code=code,nclass=nclass,ir=ir,qaName=name,iseg=iseg,qLambda=qLambda,qLambdaC=qLambdaC)
  186. f=getData.getLocalPath(r,xsetup,pat)
  187. print(f'Saving samples to {f}')
  188. numpy.savetxt(f,tac,delimiter=',')
  189. def readTAC(r,xsetup,name,iseg=0,ir=0,qLambda=0,qLambdaC=0):
  190. nclass=xsetup['nclass'][0]
  191. code=config.getCode(r,xsetup)
  192. pat=config.getPattern('fitCompartment',code=code,nclass=nclass,ir=ir,qaName=name,iseg=iseg,qLambda=qLambda,qLambdaC=qLambdaC)
  193. f=getData.getLocalPath(r,xsetup,pat)
  194. print(f'Reading from {f}')
  195. return numpy.loadtxt(f,delimiter=',')