|
@@ -0,0 +1,137 @@
|
|
|
+#date sorts studies from orthanc dataset into target study dataset
|
|
|
+
|
|
|
+#takes transferQuery as the list of images that should be available on orthanc
|
|
|
+
|
|
|
+
|
|
|
+import os
|
|
|
+import json
|
|
|
+import re
|
|
|
+import sys
|
|
|
+import datetime
|
|
|
+import re
|
|
|
+
|
|
|
+def main(parameterFile):
|
|
|
+ fhome=os.path.expanduser('~')
|
|
|
+ fsetup=os.path.join(fhome,'.labkey','setup.json')
|
|
|
+ with open(fsetup,'r') as f:
|
|
|
+ setup=json.load(f)
|
|
|
+
|
|
|
+ sys.path.insert(0,setup['paths']['nixWrapper'])
|
|
|
+
|
|
|
+ import nixWrapper
|
|
|
+
|
|
|
+ nixWrapper.loadLibrary("labkeyInterface")
|
|
|
+
|
|
|
+ import labkeyInterface
|
|
|
+ import labkeyDatabaseBrowser
|
|
|
+ import labkeyFileBrowser
|
|
|
+
|
|
|
+ fconfig=os.path.join(fhome,'.labkey','network.json')
|
|
|
+
|
|
|
+ net=labkeyInterface.labkeyInterface()
|
|
|
+ net.init(fconfig)
|
|
|
+ db=labkeyDatabaseBrowser.labkeyDB(net)
|
|
|
+ fb=labkeyFileBrowser.labkeyFileBrowser(net)
|
|
|
+
|
|
|
+ with open(parameterFile,'r') as f:
|
|
|
+ pars=json.load(f)
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ i=0
|
|
|
+ #from orthancDatabase/Imaging dataset
|
|
|
+ projectOrthanc=pars['Orthanc']['project']
|
|
|
+ inputQuery=pars['Orthanc']['queryName']
|
|
|
+ inputSchema=pars['Orthanc']['schemaName']
|
|
|
+ inputParticipantField=pars['Orthanc']['participantField']
|
|
|
+
|
|
|
+ #to target project dataset
|
|
|
+ projectStudy=pars['Database']['project']
|
|
|
+ #'iPNUMMretro/Study'
|
|
|
+ #for prospective, set
|
|
|
+ #projectStudy='IPNUMMprospektiva/Study'
|
|
|
+ outputQuery=pars['Database']['queryName']
|
|
|
+ outputSchema=pars['Database']['schemaName']
|
|
|
+ #test for schedule entries which are scheduled
|
|
|
+ scheduleCutOffDate=pars['Database']['scheduleCutOffDate']#format YYYY-MM-DD
|
|
|
+ scheduleQuery=pars['Database']['scheduleQuery']
|
|
|
+ scheduleToleranceDays=int(pars['Database']['scheduleToleranceDays'])
|
|
|
+ dbParticipantField=pars['Database']['participantField']
|
|
|
+
|
|
|
+ missingSchema=pars['Database']['missingImagesSchema']
|
|
|
+ missingQuery=pars['Database']['missingImagesQuery']
|
|
|
+
|
|
|
+ #make a list of images from transferQuery
|
|
|
+ cutOffFilter={'variable':'actionDate','value':scheduleCutOffDate,'oper':'datelt'}
|
|
|
+ #status of 1 is scheduled
|
|
|
+ statusFilter={'variable':'actionStatus','value':'1','oper':'eq'}
|
|
|
+ dsImage=db.selectRows(projectStudy,outputSchema,scheduleQuery,[cutOffFilter,statusFilter])
|
|
|
+
|
|
|
+ #clear entries from missing list
|
|
|
+ failureFilter={'variable':'failureDescription','value':'MISSING FORM','oper':'eq'}
|
|
|
+ dsDelete=db.selectRows(projectStudy,missingSchema,missingQuery,[failureFilter])
|
|
|
+ db.modifyRows('delete',projectStudy,missingSchema,missingQuery,dsDelete['rows'])
|
|
|
+
|
|
|
+
|
|
|
+ for im in dsImage['rows']:
|
|
|
+
|
|
|
+ print('{}: {} {}'.format(im[dbParticipantField],im['actionDate'],im['actionStatus']))
|
|
|
+ im['imagingVisitId']=im['visitId']
|
|
|
+ actionDate=datetime.datetime.strptime(im['actionDate'],'%Y/%m/%d %H:%M:%S')
|
|
|
+ actionDateYMD=actionDate.strftime('%Y%m%d')
|
|
|
+ im['imageDate']=actionDateYMD
|
|
|
+ #this is still to be configured
|
|
|
+ inputIdFilter={'variable':inputParticipantField,\
|
|
|
+ 'value':im[dbParticipantField],\
|
|
|
+ 'oper':'eq'}
|
|
|
+
|
|
|
+ idFilter={'variable':dbParticipantField,\
|
|
|
+ 'value':im[dbParticipantField],\
|
|
|
+ 'oper':'eq'}
|
|
|
+ #filter on series descripton - for PET, we should have 'PET WB'
|
|
|
+ sdFilter={'variable':'seriesDescription','value':'PET WB','oper':'eq'}
|
|
|
+
|
|
|
+
|
|
|
+ #have to convert from datetime to %Y%m%d format
|
|
|
+ #dateFilter={'variable':'imageDate','value':im['imageDate'],'oper':'eq'}
|
|
|
+
|
|
|
+ dsOrthanc=db.selectRows(projectOrthanc,inputSchema,inputQuery,[inputIdFilter,sdFilter])
|
|
|
+ #what if dsOrthanc['rows'] is empty?
|
|
|
+ #this is part of QA and is reported in missingImages Schema/Query
|
|
|
+
|
|
|
+ uploadStatus="FAILED"
|
|
|
+ imageDateMismatch=[]
|
|
|
+ for im1 in dsOrthanc['rows']:
|
|
|
+
|
|
|
+ date=datetime.datetime.strptime(im1['studyDate'],'%Y/%m/%d %H:%M:%S')
|
|
|
+ dt=date-actionDate
|
|
|
+ if (abs(dt.days)>scheduleToleranceDays):
|
|
|
+ continue
|
|
|
+
|
|
|
+ #convert date to %Y%m%d notation
|
|
|
+ dateYMD=date.strftime('%Y%m%d')
|
|
|
+
|
|
|
+ #enter this time difference to a list
|
|
|
+ imFilter={'variable':'imagingVisitId',
|
|
|
+ 'value':'{}'.format(im['imagingVisitId']),
|
|
|
+ 'oper':'eq'}
|
|
|
+ dsMissing=db.selectRows(projectStudy,missingSchema,\
|
|
|
+ missingQuery,[idFilter,imFilter])
|
|
|
+
|
|
|
+ #already recorded
|
|
|
+ vals=[dbParticipantField,'imagingVisitId','imageDate']
|
|
|
+ mode='insert'
|
|
|
+ if len(dsMissing['rows'])>0:
|
|
|
+ mode='update'
|
|
|
+ orow=dsMissing['rows'][0]
|
|
|
+ else:
|
|
|
+ orow={v:im[v] for v in vals}
|
|
|
+ orow['imageDateMismatch']=dateYMD
|
|
|
+ orow['failureDescription']='MISSING FORM'
|
|
|
+ db.modifyRows(mode,projectStudy,missingSchema,\
|
|
|
+ missingQuery,[orow])
|
|
|
+
|
|
|
+ print("Done: {}".format(len(dsImage['rows'])))
|
|
|
+
|
|
|
+if __name__=='__main__':
|
|
|
+ main(sys.argv[1])
|