findCandidatesForSchedule.py 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. #date sorts studies from orthanc dataset into target study dataset
  2. #takes transferQuery as the list of images that should be available on orthanc
  3. import os
  4. import json
  5. import re
  6. import sys
  7. import datetime
  8. import re
  9. def main(parameterFile):
  10. fhome=os.path.expanduser('~')
  11. fsetup=os.path.join(fhome,'.labkey','setup.json')
  12. with open(fsetup,'r') as f:
  13. setup=json.load(f)
  14. sys.path.insert(0,setup['paths']['nixWrapper'])
  15. import nixWrapper
  16. nixWrapper.loadLibrary("labkeyInterface")
  17. import labkeyInterface
  18. import labkeyDatabaseBrowser
  19. import labkeyFileBrowser
  20. fconfig=os.path.join(fhome,'.labkey','network.json')
  21. net=labkeyInterface.labkeyInterface()
  22. net.init(fconfig)
  23. db=labkeyDatabaseBrowser.labkeyDB(net)
  24. fb=labkeyFileBrowser.labkeyFileBrowser(net)
  25. with open(parameterFile,'r') as f:
  26. pars=json.load(f)
  27. i=0
  28. #from orthancDatabase/Imaging dataset
  29. projectOrthanc=pars['Orthanc']['project']
  30. inputQuery=pars['Orthanc']['queryName']
  31. inputSchema=pars['Orthanc']['schemaName']
  32. inputParticipantField=pars['Orthanc']['participantField']
  33. #to target project dataset
  34. projectStudy=pars['Database']['project']
  35. #'iPNUMMretro/Study'
  36. #for prospective, set
  37. #projectStudy='IPNUMMprospektiva/Study'
  38. outputQuery=pars['Database']['queryName']
  39. outputSchema=pars['Database']['schemaName']
  40. #test for schedule entries which are scheduled
  41. scheduleCutOffDate=pars['Database']['scheduleCutOffDate']#format YYYY-MM-DD
  42. scheduleQuery=pars['Database']['scheduleQuery']
  43. scheduleToleranceDays=int(pars['Database']['scheduleToleranceDays'])
  44. dbParticipantField=pars['Database']['participantField']
  45. missingSchema=pars['Database']['missingImagesSchema']
  46. missingQuery=pars['Database']['missingImagesQuery']
  47. #make a list of images from transferQuery
  48. cutOffFilter={'variable':'actionDate','value':scheduleCutOffDate,'oper':'datelt'}
  49. #status of 1 is scheduled
  50. statusFilter={'variable':'actionStatus','value':'1','oper':'eq'}
  51. dsImage=db.selectRows(projectStudy,outputSchema,scheduleQuery,[cutOffFilter,statusFilter])
  52. #clear entries from missing list
  53. failureFilter={'variable':'failureDescription','value':'MISSING FORM','oper':'eq'}
  54. dsDelete=db.selectRows(projectStudy,missingSchema,missingQuery,[failureFilter])
  55. db.modifyRows('delete',projectStudy,missingSchema,missingQuery,dsDelete['rows'])
  56. for im in dsImage['rows']:
  57. print('{}: {} {}'.format(im[dbParticipantField],im['actionDate'],im['actionStatus']))
  58. im['imagingVisitId']=im['visitId']
  59. actionDate=datetime.datetime.strptime(im['actionDate'],'%Y/%m/%d %H:%M:%S')
  60. actionDateYMD=actionDate.strftime('%Y%m%d')
  61. im['imageDate']=actionDateYMD
  62. #this is still to be configured
  63. inputIdFilter={'variable':inputParticipantField,\
  64. 'value':im[dbParticipantField],\
  65. 'oper':'eq'}
  66. idFilter={'variable':dbParticipantField,\
  67. 'value':im[dbParticipantField],\
  68. 'oper':'eq'}
  69. #filter on series descripton - for PET, we should have 'PET WB'
  70. sdFilter={'variable':'seriesDescription','value':'PET WB','oper':'eq'}
  71. #have to convert from datetime to %Y%m%d format
  72. #dateFilter={'variable':'imageDate','value':im['imageDate'],'oper':'eq'}
  73. dsOrthanc=db.selectRows(projectOrthanc,inputSchema,inputQuery,[inputIdFilter,sdFilter])
  74. #what if dsOrthanc['rows'] is empty?
  75. #this is part of QA and is reported in missingImages Schema/Query
  76. uploadStatus="FAILED"
  77. imageDateMismatch=[]
  78. for im1 in dsOrthanc['rows']:
  79. date=datetime.datetime.strptime(im1['studyDate'],'%Y/%m/%d %H:%M:%S')
  80. dt=date-actionDate
  81. if (abs(dt.days)>scheduleToleranceDays):
  82. continue
  83. #convert date to %Y%m%d notation
  84. dateYMD=date.strftime('%Y%m%d')
  85. #enter this time difference to a list
  86. imFilter={'variable':'imagingVisitId',
  87. 'value':'{}'.format(im['imagingVisitId']),
  88. 'oper':'eq'}
  89. dsMissing=db.selectRows(projectStudy,missingSchema,\
  90. missingQuery,[idFilter,imFilter])
  91. #already recorded
  92. vals=[dbParticipantField,'imagingVisitId','imageDate']
  93. mode='insert'
  94. if len(dsMissing['rows'])>0:
  95. mode='update'
  96. orow=dsMissing['rows'][0]
  97. else:
  98. orow={v:im[v] for v in vals}
  99. orow['imageDateMismatch']=dateYMD
  100. orow['failureDescription']='MISSING FORM'
  101. db.modifyRows(mode,projectStudy,missingSchema,\
  102. missingQuery,[orow])
  103. print("Done: {}".format(len(dsImage['rows'])))
  104. if __name__=='__main__':
  105. main(sys.argv[1])