scanOrthancLocal.py 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  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. sys.path.insert(0,setup['paths']['labkeyInterface'])
  21. sys.path.insert(0,setup['paths']['orthancInterface'])
  22. import nixWrapper
  23. #nixWrapper.loadLibrary("labkeyInterface")
  24. import labkeyInterface
  25. import labkeyDatabaseBrowser
  26. #nixWrapper.loadLibrary('orthancInterface')
  27. import orthancInterface
  28. import orthancDatabaseBrowser
  29. fconfig=os.path.join(fhome,'.labkey','network.json')
  30. net=labkeyInterface.labkeyInterface()
  31. net.init(fconfig)
  32. db=labkeyDatabaseBrowser.labkeyDB(net)
  33. onet=orthancInterface.orthancInterface()
  34. onet.init(fconfig)
  35. odb=orthancDatabaseBrowser.orthancDB(onet)
  36. with open(parameterFile) as f:
  37. pars=json.load(f)
  38. i=0
  39. opars=pars['Orthanc']
  40. project=opars['project']
  41. demoQuery=opars['demographicsQuery']
  42. schema=opars['schemaName']
  43. query=opars['queryName']
  44. participantField=opars['participantField']
  45. patients=odb.getPatients()
  46. n=len(patients)
  47. print('Npatients: {}'.format(n))
  48. for p in patients:
  49. pdata=odb.getPatientData(p)
  50. dicom=pdata['MainDicomTags']
  51. patientId=dicom['PatientID']
  52. print("[{}/{}] Patient: {} ID: {}".format(i,n,p,patientId))
  53. qfilter={'variable':participantField,'value':patientId,'oper':'eq'}
  54. print('selectRows({},{},{})'.format(project,schema,demoQuery))
  55. ds=db.selectRows(project,schema,demoQuery,[qfilter])
  56. if len(ds['rows'])==0:
  57. row={}
  58. row[participantField]=patientId
  59. try:
  60. row['birthDate']=dicom['PatientBirthDate']
  61. except KeyError:
  62. pass
  63. row['PatientName']=dicom['PatientName']
  64. row['OrthancId']=p
  65. db.modifyRows('insert',project,schema,demoQuery,[row])
  66. for s in pdata['Studies']:
  67. sdata=odb.getStudyData(s)
  68. sdicom=sdata['MainDicomTags']
  69. sid=sdicom['StudyInstanceUID']
  70. #print('Data: {}'.format(sdata))
  71. #this is try/except protetcted in previous version...
  72. sdate="19700101"
  73. try:
  74. sdate=sdicom['StudyDate']
  75. except KeyError:
  76. pass
  77. #continue
  78. print('\tStudy[{}]: {}/{}'.format(sdate,s,sid))
  79. for se in sdata['Series']:
  80. sedata=odb.getSeriesData(se)
  81. sedicom=sedata['MainDicomTags']
  82. seid=sedicom['SeriesInstanceUID']
  83. #print('Data: {}'.format(sedata))
  84. seDesc="NONE"
  85. try:
  86. seDesc=sedicom['SeriesDescription']
  87. except KeyError:
  88. pass
  89. #replace letters that might trip the database
  90. spanishOAcute=''.join([chr(3619),chr(3603)])
  91. spanishAAcute=''.join([chr(3619),chr(3585)])
  92. seDesc=re.sub(spanishOAcute,'o',seDesc)
  93. seDesc=re.sub(spanishAAcute,'a',seDesc)
  94. print('\t\tSeries[{}]: {}/{}'.format(seDesc,se,seid))
  95. qfilter={'variable':'orthancSeries','value':se,'oper':'eq'}
  96. ds=db.selectRows(project,schema,query,[qfilter])
  97. mode='insert'
  98. if len(ds['rows'])>0:
  99. mode='update'
  100. #use existing row data
  101. row=ds['rows'][0]
  102. else:
  103. #count existing entries for patient
  104. qfilter={'variable':participantField,'value':patientId,'oper':'eq'}
  105. ds=db.selectRows(project,schema,query,[qfilter])
  106. seqNum=len(ds['rows'])
  107. #create new row
  108. row={}
  109. row[participantField]=patientId
  110. row['sequenceNum']=seqNum
  111. row['orthancSeries']=se
  112. row['dicomStudy']=sid
  113. row['orthancStudy']=s
  114. row['dicomSeries']=seid
  115. row['studyDate']=sdate
  116. row['seriesDescription']=seDesc
  117. db.modifyRows(mode,project,schema,query,[row])
  118. i+=1
  119. print("Done")
  120. if __name__=="__main__":
  121. main(sys.argv[1])