segmentation.py 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  1. import numpy
  2. import config
  3. import SimpleITK
  4. import os
  5. import getData
  6. import matplotlib.pyplot
  7. def guessPixelPosition15(sx=-1,sy=-1,sz=-1):
  8. #guess position of segments
  9. if sx<0:
  10. sx=12
  11. if sy<0:
  12. sy=28
  13. if sz<0:
  14. sz=32
  15. rz=4
  16. oz=0
  17. slc=[sx,sy,sz]
  18. p1=[sx,sy,sz]
  19. pts={
  20. '0':[sx-5,sy,sz],\
  21. '1':[sx-2,sy,sz-rz],\
  22. '2':[sx-2,sy,sz+rz-1],\
  23. '3':[sx-1,sy-rz,sz],\
  24. '4':[sx-1,sy+rz-1,sz],\
  25. '5':[sx,sy-rz+oz,sz],\
  26. '6':[sx,sy-0.3*rz+oz,sz-rz],\
  27. '7':[sx,sy-0.3*rz+oz,sz+rz],\
  28. '8':[sx,sy,sz],\
  29. '9':[sx,sy+0.3*rz+oz,sz-rz],\
  30. '10':[sx,sy+0.3*rz+oz,sz+rz],\
  31. '11':[sx,sy+rz+oz,sz],\
  32. '12':[sx+3,sy-rz,sz],\
  33. '13':[sx+3,sy,sz-rz],\
  34. '14':[sx+3,sy,sz+rz],\
  35. '15':[sx+3,sy+rz,sz]}
  36. slices={'0':['8','0','1','13','2','14'],\
  37. '1':['8','0','3','4','12','15'],\
  38. '2':['8','11','9','6','5','7','10']}
  39. print(slices['0'])
  40. fp={x:[pts[q] for q in slices[x]] for x in slices}
  41. sliceIds={x:[] for x in pts}
  42. for p in pts:
  43. for s in slices:
  44. if p in slices[s]:
  45. sliceIds[p].append(s)
  46. sliceCode={x:';'.join(sliceIds[x]) for x in sliceIds}
  47. print(fp)
  48. print(sliceCode)
  49. return fp
  50. #tip
  51. fp={'0':[\
  52. [sx,sy,sz],
  53. [sx-5,sy,sz],\
  54. [sx-2,sy,sz-rz],\
  55. [sx+3,sy,sz-rz],\
  56. [sx-2,sy,sz+rz-1],\
  57. [sx+3,sy,sz+rz]],\
  58. '1':[\
  59. [sx,sy,sz],
  60. [sx-5,sy,sz],\
  61. [sx-1,sy-rz,sz],\
  62. [sx-1,sy+rz-1,sz],\
  63. [sx+3,sy-rz,sz],\
  64. [sx+3,sy+rz,sz]],\
  65. '2':[\
  66. [sx,sy,sz],
  67. [sx,sy+rz+oz,sz],\
  68. [sx,sy+0.3*rz+oz,sz-rz],\
  69. [sx,sy-0.3*rz+oz,sz-rz],\
  70. [sx,sy-rz+oz,sz],\
  71. [sx,sy-0.3*rz+oz,sz+rz],\
  72. [sx,sy+0.3*rz+oz,sz+rz]]}
  73. return fp
  74. def guessPixelPosition4(sx=-1,sy=-1,sz=-1):
  75. #guess position of segments
  76. if sx<0:
  77. sx=32
  78. if sy<0:
  79. sy=31
  80. if sz<0:
  81. sz=31
  82. rz=4
  83. pts={
  84. '0':[sx,sy,sz],\
  85. '1':[sx,sy,sz-rz],\
  86. '2':[sx,sy,sz+rz],\
  87. '3':[sx,sy-rz,sz],\
  88. '4':[sx,sy+rz,sz]}
  89. slices={
  90. '0':['0','1','2'],\
  91. '1':['0','3','4'],\
  92. '2':['0','1','2','3','4']}
  93. print(slices['0'])
  94. fp={x:[pts[q] for q in slices[x]] for x in slices}
  95. sliceIds={x:[] for x in pts}
  96. for p in pts:
  97. for s in slices:
  98. if p in slices[s]:
  99. sliceIds[p].append(s)
  100. sliceCode={x:';'.join(sliceIds[x]) for x in sliceIds}
  101. print(fp)
  102. print(sliceCode)
  103. return [{'regionId':x,'x':pts[x][0],'y':pts[x][1],'z':pts[x][2],'sliceId':sliceCode[x]} for x in pts]
  104. def updateSegmentation(db,setup,r,pixels):
  105. copyFields=['PatientId','visitCode']
  106. for x in pixels:
  107. for c in copyFields:
  108. x[c]=r[c]
  109. x['SequenceNum']=r['SequenceNum']+0.01*int(x['regionId'])
  110. filterVar=['PatientId','SequenceNum']
  111. qFilter=[{'variable':y,'value':'{}'.format(x[y]),'oper':'eq'} for y in filterVar]
  112. ds=db.selectRows(setup['project'],'study','Segmentation',qFilter)
  113. entry={}
  114. mode='insert'
  115. if len(ds['rows'])>0:
  116. entry=ds['rows'][0]
  117. mode='update'
  118. for q in x:
  119. entry[q]=x[q]
  120. db.modifyRows(mode,setup['project'],'study','Segmentation',[entry])
  121. print('Done')
  122. def getSegmentationFileName(r,setup,db=None):
  123. if not db:
  124. db,fb=getData.connectDB(setup['network'])
  125. if setup['segmentationMode']=='TXT':
  126. return '{}_Segmentation.txt'.format(config.getCode(r,setup))
  127. if setup['segmentationMode']=='NRRD':
  128. copyFields=['PatientId','visitCode']
  129. qFilter=[{'variable':x,'value':r[x],'oper':'eq'} for x in copyFields]
  130. qFilter.append({'variable':'User','value':setup['targetUser'],'oper':'eq'})
  131. rows=getData.getSegmentation(db,setup,qFilter)
  132. r=rows[0]
  133. return r['latestFile']
  134. def getURL(fb,r,setup,name):
  135. remoteDir=fb.buildPathURL(setup['project'],config.getPathList(r,setup))
  136. return '/'.join([remoteDir,'Segmentations',name])
  137. def copyFromServer(fb,r,setup,names):
  138. try:
  139. forceReload=setup['forceReload']
  140. except KeyError:
  141. forceReload=False
  142. getData.getLocalDir(r,setup,createIfMissing=True)
  143. remoteDir=fb.buildPathURL(setup['project'],config.getPathList(r,setup))
  144. for n in names:
  145. localPath=getData.getLocalPath(r,setup,n)
  146. if os.path.isfile(localPath) and not forceReload:
  147. continue
  148. remotePath='/'.join([remoteDir,'Segmentations',n])
  149. fb.readFileToFile(remotePath,localPath)
  150. def copyToServer(fb,r,setup,names):
  151. remoteDir=fb.buildPathURL(setup['project'],config.getPathList(r,setup))
  152. for n in names:
  153. localPath=getLocalPath(r,setup,n)
  154. remotePath='/'.join([remoteDir,'Segmentations',n])
  155. fb.writeFileToFile(localPath,remotePath)
  156. def writeSegmentation(db,fb,r,setup):
  157. if setup['segmentationMode']=='NRRD':
  158. print('Failed to load segmentation')
  159. return
  160. fileName=getSegmentationFileName(db,r,setup)
  161. idFilter={'variable':'PatientId','value':config.getPatientId(r,setup),'oper':'eq'}
  162. visitFilter={'variable':'visitCode','value':config.getVisitId(r,setup),'oper':'eq'}
  163. rows=getData.getSegmentation(db,setup,[idFilter,visitFilter])
  164. v=numpy.zeros((len(rows),3))
  165. for qr in rows:
  166. region=int(qr['regionId'])
  167. v[region,2]=float(qr['x'])
  168. v[region,1]=float(qr['y'])
  169. v[region,0]=float(qr['z'])
  170. #for i in range(len(rows)):
  171. # print(v[i,:])
  172. numpy.savetxt(getData.getLocalPath(r,setup,fileName),v)
  173. getData.copyToServer(fb,r,setup,[fileName])
  174. def getNC(r,xsetup):
  175. if xsetup['segmentationMode']=='TXT':
  176. getNCTxt(r,xsetup)
  177. if xsetup['segmentationMode']=='NRRD':
  178. return xsetup['NC']
  179. def getNCTxt(r,xsetup):
  180. sName=getSegmentationFileName(db=None,r=r,setup=xsetup)
  181. fName=getData.getLocalPath(r,xsetup,sName)
  182. x=numpy.loadtxt(fName)
  183. nc=x.shape[0]
  184. return nc
  185. def loadSegmentation(db,fb,r,setup):
  186. sName=getSegmentationFileName(db,r,setup)
  187. print(f'Looking for {sName}')
  188. fName=getData.getLocalPath(r,setup,sName)
  189. print(f'Local {fName}')
  190. if not os.path.isfile(fName):
  191. fURL=getData.getURL(fb,r,setup,sName)
  192. if fb.entryExists(fURL):
  193. getData.copyFromServer(fb,r,setup,[sName])
  194. if os.path.isfile(fName):
  195. print(f'Copied {fURL} to {fName}')
  196. else:
  197. print(f'Failed to load {fName} from {fURL}')
  198. else:
  199. #this creates local and global file
  200. writeSegmentation(db,fb,r,setup)
  201. if setup['segmentationMode']=='TXT':
  202. return numpy.loadtxt(fName)
  203. def plotSegmentation(db,fb,r,setup,vmax=1000):
  204. copyFields=['PatientId','visitCode']
  205. qFilter=[{'variable':x,'value':r[x],'oper':'eq'} for x in copyFields]
  206. nim=getData.getPatientNIM(fb,r,setup)
  207. rows=getData.getSegmentation(db,setup,qFilter)
  208. if len(rows)==0:
  209. pId=r['PatientId']
  210. visitCode=r['visitCode']
  211. print(f'Not found for id={pId}/{visitCode}')
  212. return
  213. fp={}
  214. for q in rows:
  215. if q['regionId']==0:
  216. slc=[q['x'],q['y'],q['z']]
  217. slc=[int(x) for x in slc]
  218. slices=q['sliceId'].split(';')
  219. for s in slices:
  220. try:
  221. fp[s].append([float(x) for x in [q['x'],q['y'],q['z']]])
  222. except KeyError:
  223. fp[s]=[]
  224. fp[s].append([float(x) for x in [q['x'],q['y'],q['z']]])
  225. cut0=20
  226. w0=20
  227. cut1=20
  228. w1=20
  229. cut2=20
  230. w2=20
  231. vmin=0
  232. nd=3
  233. fig,ax=matplotlib.pyplot.subplots(3,2*nd+1,figsize=(20,12))
  234. for i in numpy.arange(0,2*nd+1):
  235. ax[0,i].set_xlabel('z')
  236. ax[0,i].set_ylabel('x')
  237. ax[0,i].imshow(nim[cut2:cut2+w2,slc[1]-nd+i,cut0:cut0+w0],cmap='gray_r',vmax=vmax,vmin=vmin)
  238. ax[1,i].set_xlabel('x')
  239. ax[1,i].set_ylabel('y')
  240. ax[1,i].imshow(nim[cut2:cut2+w2,cut0:cut0+w0,slc[2]-nd+i].T,cmap='gray_r',vmax=vmax,vmin=vmin)
  241. ax[2,i].set_xlabel('z')
  242. ax[2,i].set_ylabel('y')
  243. ax[2,i].imshow(nim[slc[0]-nd+i,cut1:cut1+w1,cut1:cut1+w1],cmap='gray_r',vmax=vmax,vmin=vmin)
  244. if i==nd:
  245. pt=fp['0']
  246. ax[0,i].scatter([x[2]-cut0 for x in pt],[x[0]-cut2 for x in pt])
  247. pt=fp['1']
  248. ax[1,i].scatter([x[0]-cut2 for x in pt],[x[1]-cut0 for x in pt])
  249. pt=fp['2']
  250. ax[2,i].scatter([x[2]-cut1 for x in pt],[x[1]-cut1 for x in pt])
  251. if i==0:
  252. ax[0,i].text(2,2,pId,fontsize='large')
  253. name='{}_segmentation.png'.format(config.getCode(r,setup))
  254. fPath=getData.getLocalPath(r,setup,name)
  255. fig.savefig(fPath)
  256. getData.copyToServer(fb,r,setup,[name])
  257. def getNRRDImage(r,setup,names=None):
  258. if names:
  259. localFile=getData.getLocalPath(r,setup,names['segmentation'][0])
  260. else:
  261. localFile=getData.getLocalPath(r,setup,getSegmentationFileName(r,setup))
  262. segImg=SimpleITK.ReadImage(localFile)
  263. seg=SimpleITK.GetArrayFromImage(segImg)
  264. return seg