scanOrthanc.py 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. #labkey/orthanc interface
  2. #scans the orthanc internal database and fills labkey table
  3. #"Orthanc" section expected in the configuration file, with
  4. #"queryName": query to be filled for each image
  5. #"demographicsQuery": query to be filled for every patient
  6. #"schemaName": the schema both queries are part of
  7. #"project": name of the project under labkey that collects Orthanc data,
  8. # typically named Orthanc or similar
  9. #"participantField": sorting participant field label in labkey study
  10. import os
  11. import json
  12. import re
  13. import sys
  14. def main(parameterFile):
  15. fhome=os.path.expanduser('~')
  16. fsetup=os.path.join(fhome,'.labkey','setup.json')
  17. with open(fsetup,'r') as f:
  18. setup=json.load(f)
  19. sys.path.insert(0,setup['paths']['nixWrapper'])
  20. import nixWrapper
  21. nixWrapper.loadLibrary("labkeyInterface")
  22. import labkeyInterface
  23. import labkeyDatabaseBrowser
  24. nixWrapper.loadLibrary('orthancInterface')
  25. import orthancInterface
  26. import orthancDatabaseBrowser
  27. fconfig=os.path.join(fhome,'.labkey','network.json')
  28. net=labkeyInterface.labkeyInterface()
  29. net.init(fconfig)
  30. db=labkeyDatabaseBrowser.labkeyDB(net)
  31. onet=orthancInterface.orthancInterface()
  32. onet.init(fconfig)
  33. odb=orthancDatabaseBrowser.orthancDB(onet)
  34. with open(parameterFile) as f:
  35. pars=json.load(f)
  36. i=0
  37. opars=pars['Orthanc']
  38. project=opars['project']
  39. participantField=opars['participantField']
  40. patients=odb.getPatients()
  41. n=len(patients)
  42. for p in patients:
  43. pdata=odb.getPatientData(p)
  44. dicom=pdata['MainDicomTags']
  45. patientId=dicom['PatientID']
  46. print("[{}/{}] Patient: {} ID: {}".format(i,n,p,patientId))
  47. qfilter={'variable':participantField,'value':patientId,'oper':'eq'}
  48. ds=db.selectRows(project,opars['schemaName'],\
  49. opars['demographicsQuery'],[qfilter])
  50. if len(ds['rows'])==0:
  51. row={}
  52. row[participantField]=patientId
  53. row['birthDate']=dicom['PatientBirthDate']
  54. row['PatientName']=dicom['PatientName']
  55. row['OrthancId']=p
  56. db.modifyRows('insert',project,opars['schemaName'],\
  57. opars['demographicsQuery'],[row])
  58. for s in pdata['Studies']:
  59. sdata=odb.getStudyData(s)
  60. sdicom=sdata['MainDicomTags']
  61. sid=sdicom['StudyInstanceUID']
  62. #print('Data: {}'.format(sdata))
  63. #this is try/except protetcted in previous version...
  64. sdate="19700101"
  65. try:
  66. sdate=sdicom['StudyDate']
  67. except KeyError:
  68. pass
  69. #continue
  70. print('\tStudy[{}]: {}/{}'.format(sdate,s,sid))
  71. for se in sdata['Series']:
  72. sedata=odb.getSeriesData(se)
  73. sedicom=sedata['MainDicomTags']
  74. seid=sedicom['SeriesInstanceUID']
  75. #print('Data: {}'.format(sedata))
  76. seDesc="NONE"
  77. try:
  78. seDesc=sedicom['SeriesDescription']
  79. except KeyError:
  80. pass
  81. #replace letters that might trip the database
  82. spanishOAcute=''.join([chr(3619),chr(3603)])
  83. spanishAAcute=''.join([chr(3619),chr(3585)])
  84. seDesc=re.sub(spanishOAcute,'o',seDesc)
  85. seDesc=re.sub(spanishAAcute,'a',seDesc)
  86. print('\t\tSeries[{}]: {}/{}'.format(seDesc,se,seid))
  87. qfilter={'variable':'orthancSeries','value':se,'oper':'eq'}
  88. ds=db.selectRows(project,opars['schemaName'],\
  89. opars['queryName'],[qfilter])
  90. mode='insert'
  91. if len(ds['rows'])>0:
  92. mode='update'
  93. #use existing row data
  94. row=ds['rows'][0]
  95. else:
  96. #count existing entries for patient
  97. qfilter={'variable':participantField,'value':patientId,'oper':'eq'}
  98. ds=db.selectRows(project,opars['schemaName'],\
  99. opars['queryName'],[qfilter])
  100. seqNum=len(ds['rows'])
  101. #create new row
  102. row={}
  103. row[participantField]=patientId
  104. row['sequenceNum']=seqNum
  105. row['orthancSeries']=se
  106. row['dicomStudy']=sid
  107. row['orthancStudy']=s
  108. row['dicomSeries']=seid
  109. row['studyDate']=sdate
  110. row['seriesDescription']=seDesc
  111. db.modifyRows(mode,project,opars['schemaName'],\
  112. opars['queryName'],[row])
  113. i+=1
  114. print("Done")
  115. if __name__=="__main__":
  116. main(sys.argv[1])