123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 |
- import os
- import sys
- import numpy
- import random
- import SimpleITK
- import datetime
- def initDB(site,returnFB=False):
- home=os.path.expanduser('~'),
- nixSuite=os.path.join(home,'software','src','nixSuite')
- sys.path.append(os.path.join(nixSuite,'wrapper'))
- import nixWrapper
- nixWrapper.loadLibrary('labkeyInterface')
- import labkeyInterface
- import labkeyDatabaseBrowser
- import labkeyFileBrowser
- net=labkeyInterface.labkeyInterface()
- fconfig=os.path.join(home,'.labkey','{}.json'.format(site))
- net.init(fconfig)
- net.getCSRF()
- if not returnFB:
- return labkeyDatabaseBrowser.labkeyDB(net)
- return labkeyDatabaseBrowser.labkeyDB(net),
- labkeyFileBrowser.labkeyFileBrowser(net)
- def initOrthanc(site,returnFB=False):
- home=os.path.expanduser('~'),
- nixSuite=os.path.join(home,'software','src','nixSuite')
- sys.path.append(os.path.join(nixSuite,'wrapper'))
- import nixWrapper
- nixWrapper.loadLibrary('orthancInterface')
- import orthancInterface
- import orthancDatabaseBrowser
- import orthancFileBrowser
- net=orthancInterface.orthancInterface()
- fconfig=os.path.join(home,'.labkey','{}.json'.format(site))
- net.init(fconfig)
- if not returnFB:
- return orthancDatabaseBrowser.orthancDB(net)
- return orthancDatabaseBrowser.orthancDB(net),
- orthancFileBrowser.orthancFileBrowser(net)
- def parsePos(x):
- return [float(y) for y in x.split('\\')]
- def parseOrientation(x):
- z=[float(y) for y in x.split('\\')]
- O=[z[0:3],z[3:6]]
- O.append(list(numpy.cross(numpy.array(O[0]),numpy.array(O[1]))))
- return O
- def getGeometry(code,odb,seriesId):
-
-
-
-
-
-
- sd=odb.getData('series',seriesId)
- firstId=sd['Instances'][0]
-
- ior=parseOrientation(odb.getDicomField(firstId,'0020-0037'))
-
- ips=parsePos(odb.getDicomField(firstId,'0028-0030'))
- ist=parsePos(odb.getDicomField(firstId,'0018-0050'))
-
-
-
- ipos=[parsePos(odb.getDicomField(y,'0020-0032')) for y in sd['Instances']]
-
- m=[numpy.dot(numpy.array(ior[2]),numpy.array(x)) for x in ipos]
-
- m1=numpy.sort(m)
- dm=m1[1:]-m1[:-1]
- zSpc=numpy.average(dm)
- zDev=numpy.std(dm)
- print(f'sliceThickness={zSpc} +- {zDev}')
- ips.append(zSpc)
-
-
-
- xdir=[y for y in ior]
- for i in range(3):
- xdir[i]=[ips[i]*w for w in xdir[i]]
-
-
- im=numpy.argmin(numpy.array(m))
- print(im)
- org=ipos[im]
- print(org)
- print(xdir)
- return {f'{code}origin':org,f'{code}orientation':xdir}
-
-
-
- def getFile(db,odb,project,outdir,n1=0,n2=1):
- schema='study'
- query='Imaging1'
-
- ds=db.selectRows(project,schema,query,[])
- rows=ds['rows']
- if n2>0:
- rows=rows[n1:n2]
- imgs={'CT':'CT_orthancId','PET':'PETWB_orthancId'}
- files=[]
- for r in rows:
- code=r['pseudoCode']
- doUpdate=False
- if not code:
- code='{:16x}'.format(random.randrange(16**16))
- r['pseudoCode']=code
- doUpdate=True
- codes.append(code)
- fname=os.path.join(outdir,f'{code}.npz')
- arr={}
-
- iSUV={x:getSUVfactor(odb,r[imgs[x]]) for x in imgs}
- arr.update({x:iSUV[x]*numpy.load(odb.getNumpy('series',r[imgs[x]])) for x in imgs})
-
- igeo={x:getGeometry(x,odb,r[imgs[x]]) for x in imgs}
-
-
- _={arr.update(igeo[x]) for x in igeo}
-
-
-
- numpy.savez_compressed(fname,**arr)
- files.append(fname)
- if doUpdate:
- db.modifyRows('update',project,schema,query,[r])
- return files
-
- def mergeDateAndTime(date,time):
- time=time.replace(' ','')
- dateTimeStr=' '.join([date,time])
-
- dt=datetime.datetime.strptime(dateTimeStr,'%Y%m%d %H%M%S.%f')
-
- return dt
-
- def getSUVfactor(odb,seriesId):
- sd=odb.getData('series',seriesId)
- orthancId=sd['Instances'][0]
-
- MODALITY='0008-0060'
- PATIENT_WEIGHT='0010-1030'
- RADIOPHARMACEUTICAL_STARTTIME='0054-0016/0/0018-1072'
- RADIONUCLIDE_TOTALDOSE='0054-0016/0/0018-1074'
- RADIONUCLIDE_HALFLIFE='0054-0016/0/0018-1075'
- RADIOPHARMACEUTICAL_STARTDATETIME='0054-0016/0/0018-1078'
- SERIES_TIME='0008-0031'
- SERIES_DATE='0008-0021'
- modality=odb.getDicomField(orthancId,MODALITY)
- if modality!='PT':
- print('Returning 1')
- return 1
- weight = float(odb.getDicomField(orthancId,PATIENT_WEIGHT))
-
- halfLife = float(odb.getDicomField(orthancId,RADIONUCLIDE_HALFLIFE))
-
- injDose = float(odb.getDicomField(orthancId,RADIONUCLIDE_TOTALDOSE))
-
-
-
-
- injDateTime = mergeDateAndTime(odb.getDicomField(orthancId,SERIES_DATE),
- odb.getDicomField(orthancId,RADIOPHARMACEUTICAL_STARTTIME))
- scanDateTime=mergeDateAndTime(odb.getDicomField(orthancId,SERIES_DATE),
- odb.getDicomField(orthancId,SERIES_TIME))
- t=(scanDateTime-injDateTime).total_seconds()
- scanDose = injDose*numpy.exp(-(numpy.log(2)*t)/halfLife);
- SUV_factor = 1/((scanDose/weight)*0.001);
- print(SUV_factor)
- return SUV_factor
|