copyAnonymizedImagesToOrthanc.py 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. import os
  2. import json
  3. import re
  4. import subprocess
  5. import shutil
  6. import sys
  7. import numpy
  8. import pydicom
  9. import copy
  10. shome=os.path.expanduser('~nixUser')
  11. sys.path.insert(1,shome+'/software/src/labkeyInterface')
  12. import labkeyInterface
  13. import labkeyDatabaseBrowser
  14. sys.path.insert(1,shome+'/software/src/orthancInterface')
  15. import orthancInterface
  16. import orthancDatabaseBrowser
  17. sys.path.insert(1,shome+'/software/src/IPNUMM/dicomUtils')
  18. import loadDicom
  19. fhome=os.path.expanduser('~')
  20. fconfig=os.path.join(fhome,'.labkey','network.json')
  21. net=labkeyInterface.labkeyInterface()
  22. net.init(fconfig)
  23. db=labkeyDatabaseBrowser.labkeyDB(net)
  24. #also need merlin credentials
  25. fconfigMerlin=os.path.join(fhome,'.labkey','merlin.json')
  26. netMerlin=labkeyInterface.labkeyInterface()
  27. netMerlin.init(fconfigMerlin)
  28. dbMerlin=labkeyDatabaseBrowser.labkeyDB(netMerlin)
  29. onetMerlin=orthancInterface.orthancInterface()
  30. onetMerlin.init(fconfigMerlin)
  31. odbMerlin=orthancDatabaseBrowser.orthancDB(onetMerlin)
  32. project='iPNUMMretro/Study'
  33. merlinProject=project
  34. #project='Orthanc/Database'
  35. labkeyBase='/data/labkey'
  36. tempBase=os.path.join(fhome,'temp')
  37. #anonymousClinicalDataset='AnonymousClinicalData'
  38. anonymousImagingDataset='AnonymousImaging'
  39. merlinImagingDataset='Imaging'
  40. #getNixID
  41. studyData=db.selectRows(project,'study','Study',[])
  42. nixID=studyData['rows'][0]['nixID']
  43. ds=db.selectRows(project,'study',anonymousImagingDataset,[])
  44. #get UID generator
  45. uid=loadDicom.uuid()
  46. #paths
  47. projectAnonymousBase=os.path.join(labkeyBase,'files',project,'@files/anonymous')
  48. i=0
  49. status="OK"
  50. for row in ds['rows']:
  51. outRow=copy.deepcopy(row)
  52. outRow['PatientId']='{}-{}'.format(nixID,row['PatientId'])
  53. studyUID=uid.generateStudyUUID('volume')
  54. for iMod in ['CT','PETWB']:
  55. anonSeriesId=row[iMod+'_UUID']
  56. dicomZipFile=os.path.join(projectAnonymousBase,anonSeriesId+'.zip')
  57. tempDir=os.path.join(tempBase,anonSeriesId)
  58. try:
  59. os.mkdir(tempDir)
  60. except FileExistsError:
  61. shutil.rmtree(tempDir)
  62. os.mkdir(tempDir)
  63. subprocess.run(['unzip','-d',tempDir,'-xj',dicomZipFile])
  64. seriesUID=uid.generateSeriesUUID('volume')
  65. for f in os.listdir(tempDir):
  66. dicomFile=os.path.join(tempDir,f)
  67. #modify patientId field?
  68. dcm=pydicom.dcmread(dicomFile)
  69. dcm['PatientID'].value='{}-{}'.format(nixID,row['PatientId'])
  70. #make sure series and study UID are set:
  71. try:
  72. outRow['studyUUID']=dcm['StudyInstanceUID']
  73. except KeyError:
  74. dcm.StudyInstanceUID=studyUID
  75. outRow['studyUUID']=studyUID
  76. try:
  77. outRow[iMod+'_UUID']=dcm['SeriesInstanceUID']
  78. except KeyError:
  79. dcm.SeriesInstanceUID=seriesUID
  80. outRow[iMod+'_UUID']=seriesUID
  81. dcm.save_as(dicomFile)
  82. print('Modified: {}'.format(dicomFile))
  83. #send instance to orthanc
  84. resp=odbMerlin.upload(dicomFile)
  85. try:
  86. if resp['status']=="FAIL":
  87. sys.exit()
  88. except KeyError:
  89. pass
  90. outRow[iMod+'_orthancId']=resp['ParentSeries']
  91. outRow['orthancId']=resp['ParentStudy']
  92. outRow['patientOrthancId']=resp['ParentPatient']
  93. #keep track of the ID to change instance
  94. print(resp)
  95. if i==-1:
  96. break
  97. shutil.rmtree(tempDir)
  98. if i==-1:
  99. break
  100. #check on studyUID for duplicates
  101. studyFilter={'variable':'studyUUID','value':outRow['studyUUID'],'oper':'eq'}
  102. dsMerlin=dbMerlin.selectRows(merlinProject,'study',\
  103. merlinImagingDataset,[studyFilter])
  104. mode='insert'
  105. if len(dsMerlin['rows'])>0:
  106. mode='update'
  107. dbMerlin.modifyRows(mode,merlinProject,'study',\
  108. merlinImagingDataset,[outRow])
  109. if i==-1:
  110. break
  111. i=i+1
  112. print('Done')