瀏覽代碼

Minor corrections to OrthancLocal, adding QuickLocal

NIX User 2 年之前
父節點
當前提交
856c29dbd1
共有 2 個文件被更改,包括 326 次插入121 次删除
  1. 124 121
      pythonScripts/scanOrthancLocal.py
  2. 202 0
      pythonScripts/scanOrthancQuickLocal.py

+ 124 - 121
pythonScripts/scanOrthancLocal.py

@@ -18,142 +18,145 @@ import sys
 
 def main(parameterFile):
 
-    fhome=os.path.expanduser('~')
-    fsetup=os.path.join(fhome,'.labkey','setup.json')
+   fhome=os.path.expanduser('~')
+   fsetup=os.path.join(fhome,'.labkey','setup.json')
 
-    with open(fsetup,'r') as f:
-        setup=json.load(f)
+   with open(fsetup,'r') as f:
+     setup=json.load(f)
 
-    sys.path.insert(0,setup['paths']['nixWrapper'])
-    sys.path.insert(0,setup['paths']['labkeyInterface'])
-    sys.path.insert(0,setup['paths']['orthancInterface'])
-    import nixWrapper
+   sys.path.insert(0,setup['paths']['nixWrapper'])
+   sys.path.insert(0,setup['paths']['labkeyInterface'])
+   sys.path.insert(0,setup['paths']['orthancInterface'])
+   import nixWrapper
 
-    #nixWrapper.loadLibrary("labkeyInterface")
-    import labkeyInterface
-    import labkeyDatabaseBrowser
+#nixWrapper.loadLibrary("labkeyInterface")
+   import labkeyInterface
+   import labkeyDatabaseBrowser
 
-    #nixWrapper.loadLibrary('orthancInterface')
-    import orthancInterface
-    import orthancDatabaseBrowser
+#nixWrapper.loadLibrary('orthancInterface')
+   import orthancInterface
+   import orthancDatabaseBrowser
 
-    fconfig=os.path.join(fhome,'.labkey','network.json')
+   fconfig=os.path.join(fhome,'.labkey','network.json')
 
-    net=labkeyInterface.labkeyInterface()
-    net.init(fconfig)
-    db=labkeyDatabaseBrowser.labkeyDB(net)
+   net=labkeyInterface.labkeyInterface()
+   net.init(fconfig)
+   db=labkeyDatabaseBrowser.labkeyDB(net)
 
 
-    onet=orthancInterface.orthancInterface()
-    onet.init(fconfig)
-    odb=orthancDatabaseBrowser.orthancDB(onet)
+   onet=orthancInterface.orthancInterface()
+   onet.init(fconfig)
+   odb=orthancDatabaseBrowser.orthancDB(onet)
 
 
-    with open(parameterFile) as f:
-        pars=json.load(f)
+   with open(parameterFile) as f:
+     pars=json.load(f)
 
-    i=0
-    opars=pars['Orthanc']
-    project=opars['project']
-    
-    participantField=opars['participantField']
+   i=0
+   opars=pars['Orthanc']
+   project=opars['project']
+   demoQuery=opars['demographicsQuery']
+   schema=opars['schemaName']
+   query=opars['queryName']
 
-    patients=odb.getPatients()
-    n=len(patients)
+   participantField=opars['participantField']
 
-    for p in patients:
-        pdata=odb.getPatientData(p)
-        dicom=pdata['MainDicomTags']
-        patientId=dicom['PatientID']
-    
-        print("[{}/{}] Patient: {} ID: {}".format(i,n,p,patientId))
+   patients=odb.getPatients()
+   n=len(patients)
+   print('Npatients: {}'.format(n))
 
-        qfilter={'variable':participantField,'value':patientId,'oper':'eq'}
-        ds=db.selectRows(project,opars['schemaName'],\
-                opars['demographicsQuery'],[qfilter])
-        if len(ds['rows'])==0:
-            row={}
-            row[participantField]=patientId
+   for p in patients:
+      pdata=odb.getPatientData(p)
+      dicom=pdata['MainDicomTags']
+      patientId=dicom['PatientID']
+
+      print("[{}/{}] Patient: {} ID: {}".format(i,n,p,patientId))
+
+      qfilter={'variable':participantField,'value':patientId,'oper':'eq'}
+      print('selectRows({},{},{})'.format(project,schema,demoQuery))
+      ds=db.selectRows(project,schema,demoQuery,[qfilter])
+      if len(ds['rows'])==0:
+         row={}
+         row[participantField]=patientId
+         try:
             row['birthDate']=dicom['PatientBirthDate']
-            row['PatientName']=dicom['PatientName']
-            row['OrthancId']=p
-            db.modifyRows('insert',project,opars['schemaName'],\
-                    opars['demographicsQuery'],[row])
-
-        for s in pdata['Studies']:
-            sdata=odb.getStudyData(s)
-            sdicom=sdata['MainDicomTags']
-            sid=sdicom['StudyInstanceUID']
-            #print('Data: {}'.format(sdata))
-            #this is try/except protetcted in previous version...
-            sdate="19700101"
-            try:
-                sdate=sdicom['StudyDate']
-            except KeyError:
-                pass
-            #continue
-        
-            print('\tStudy[{}]: {}/{}'.format(sdate,s,sid))
-        
-            for se in sdata['Series']:
-
-                sedata=odb.getSeriesData(se)
-                sedicom=sedata['MainDicomTags']
-                    
-                seid=sedicom['SeriesInstanceUID']
-                #print('Data: {}'.format(sedata))
-                seDesc="NONE"
-                try:
-                    seDesc=sedicom['SeriesDescription']
-                except KeyError:
-                    pass
-
-                #replace letters that might trip the database
-                spanishOAcute=''.join([chr(3619),chr(3603)])
-                spanishAAcute=''.join([chr(3619),chr(3585)])
-                seDesc=re.sub(spanishOAcute,'o',seDesc)
-                seDesc=re.sub(spanishAAcute,'a',seDesc)
-
-
-                print('\t\tSeries[{}]: {}/{}'.format(seDesc,se,seid))
-
-                qfilter={'variable':'orthancSeries','value':se,'oper':'eq'}
-                ds=db.selectRows(project,opars['schemaName'],\
-                        opars['queryName'],[qfilter])
-                
-                mode='insert'
-
-                if len(ds['rows'])>0:
-                    mode='update'
-                    #use existing row data
-                    row=ds['rows'][0]
-
-                else:
-
-                    #count existing entries for patient
-                    qfilter={'variable':participantField,'value':patientId,'oper':'eq'}
-                    ds=db.selectRows(project,opars['schemaName'],\
-                        opars['queryName'],[qfilter])
-                    seqNum=len(ds['rows'])
-                    
-                    #create new row
-                    row={}
-                    row[participantField]=patientId
-                    row['sequenceNum']=seqNum
-                    row['orthancSeries']=se
-                
-                
-                row['dicomStudy']=sid
-                row['orthancStudy']=s
-                row['dicomSeries']=seid
-                row['studyDate']=sdate
-                row['seriesDescription']=seDesc
-                db.modifyRows(mode,project,opars['schemaName'],\
-                        opars['queryName'],[row])
-
-
-        i+=1
-    print("Done")
+         except KeyError:
+            pass
+         row['PatientName']=dicom['PatientName']
+         row['OrthancId']=p
+         db.modifyRows('insert',project,schema,demoQuery,[row])
+
+      for s in pdata['Studies']:
+         sdata=odb.getStudyData(s)
+         sdicom=sdata['MainDicomTags']
+         sid=sdicom['StudyInstanceUID']
+         #print('Data: {}'.format(sdata))
+         #this is try/except protetcted in previous version...
+         sdate="19700101"
+         try:
+             sdate=sdicom['StudyDate']
+         except KeyError:
+             pass
+         #continue
+
+         print('\tStudy[{}]: {}/{}'.format(sdate,s,sid))
+
+         for se in sdata['Series']:
+
+             sedata=odb.getSeriesData(se)
+             sedicom=sedata['MainDicomTags']
+                 
+             seid=sedicom['SeriesInstanceUID']
+             #print('Data: {}'.format(sedata))
+             seDesc="NONE"
+             try:
+                 seDesc=sedicom['SeriesDescription']
+             except KeyError:
+                 pass
+
+             #replace letters that might trip the database
+             spanishOAcute=''.join([chr(3619),chr(3603)])
+             spanishAAcute=''.join([chr(3619),chr(3585)])
+             seDesc=re.sub(spanishOAcute,'o',seDesc)
+             seDesc=re.sub(spanishAAcute,'a',seDesc)
+
+
+             print('\t\tSeries[{}]: {}/{}'.format(seDesc,se,seid))
+
+             qfilter={'variable':'orthancSeries','value':se,'oper':'eq'}
+             ds=db.selectRows(project,schema,query,[qfilter])
+             
+             mode='insert'
+
+             if len(ds['rows'])>0:
+                 mode='update'
+                 #use existing row data
+                 row=ds['rows'][0]
+
+             else:
+
+                 #count existing entries for patient
+                 qfilter={'variable':participantField,'value':patientId,'oper':'eq'}
+                 ds=db.selectRows(project,schema,query,[qfilter])
+                 seqNum=len(ds['rows'])
+                 
+                 #create new row
+                 row={}
+                 row[participantField]=patientId
+                 row['sequenceNum']=seqNum
+                 row['orthancSeries']=se
+             
+             
+             row['dicomStudy']=sid
+             row['orthancStudy']=s
+             row['dicomSeries']=seid
+             row['studyDate']=sdate
+             row['seriesDescription']=seDesc
+             db.modifyRows(mode,project,schema,query,[row])
+
+
+      i+=1
+   print("Done")
 
 if __name__=="__main__":
     main(sys.argv[1])

+ 202 - 0
pythonScripts/scanOrthancQuickLocal.py

@@ -0,0 +1,202 @@
+#labkey/orthanc interface
+
+#scans the orthanc internal database and fills labkey table
+
+#"Orthanc" section expected in the configuration file, with
+#"queryName": query to be filled for each image 
+#"demographicsQuery": query to be filled for every patient
+#"schemaName": the schema both queries are part of
+#"project": name of the project under labkey that collects Orthanc data,
+#           typically named Orthanc or similar
+#"participantField": sorting participant field label in labkey study
+
+
+import os
+import json
+import re
+import sys
+import datetime
+
+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'])
+   sys.path.insert(0,setup['paths']['orthancInterface'])
+   sys.path.insert(0,setup['paths']['labkeyInterface'])
+   import nixWrapper
+
+#nixWrapper.loadLibrary("labkeyInterface")
+   import labkeyInterface
+   import labkeyDatabaseBrowser
+
+#nixWrapper.loadLibrary('orthancInterface')
+   import orthancInterface
+   import orthancDatabaseBrowser
+
+   fconfig=os.path.join(fhome,'.labkey','network.json')
+
+   net=labkeyInterface.labkeyInterface()
+   net.init(fconfig)
+   db=labkeyDatabaseBrowser.labkeyDB(net)
+
+
+   onet=orthancInterface.orthancInterface()
+   onet.init(fconfig)
+   odb=orthancDatabaseBrowser.orthancDB(onet)
+
+
+   with open(parameterFile) as f:
+      pars=json.load(f)
+
+   opars=pars['Orthanc']
+   project=opars['project']
+
+   participantField=opars['participantField']
+
+   patients=odb.getPatients()
+
+
+#equivalent for labkey side?
+   dsDemo=db.selectRows(project,opars['schemaName'],\
+         opars['demographicsQuery'],[])
+   dsPatients=[row['OrthancId'] for row in dsDemo['rows']]
+   pMissing=[p for p in patients if p not in dsPatients]
+   print('Missing : {}'.format(len(pMissing)))
+
+#we need details for all patients (some might have just a study uploaded
+   pdata={p:odb.getPatientData(p) for p in patients}
+
+#update patient data for missing patients
+   prows=[]
+   for p in pMissing:
+      dicom=pdata[p]['MainDicomTags']
+      row={}
+      pid=dicom['PatientID']
+      if len(pid)>32:
+         pid=pid[:32]
+      row[participantField]=pid
+      
+      try:
+         row['birthDate']=datetime.datetime.strptime(dicom['PatientBirthDate'],'%Y-%m-%d %H:%M')
+      except (KeyError,ValueError):
+         pass
+      
+      row['PatientName']=dicom['PatientName']
+      row['OrthancId']=p
+      prows.append(row)
+
+   if len(prows)>0:
+
+      resp=db.modifyRows('insert',project,opars['schemaName'],\
+         opars['demographicsQuery'],prows)
+      print(resp)
+
+   n=len(patients)
+   i=0
+#download the full images dataset (~1000 rows)
+   ds=db.selectRows(project,opars['schemaName'],opars['queryName'],[])
+   for p in patients:
+      dicom=pdata[p]['MainDicomTags']
+      patientId=dicom['PatientID']
+      if len(patientId)>32:
+         patientId=patientId[:32]
+
+#get all studies for pateint
+#qfilter={'variable':participantField,'value':patientId,'oper':'eq'}
+      dsStudies=[row['orthancStudy'] for row in ds['rows'] if row[participantField]==patientId]
+#number of entries for patient (if new must be inserted)
+      seqNum=len(dsStudies)
+
+#unique
+      dsStudies=list(set(dsStudies))
+      studies=pdata[p]['Studies']
+      pHex=p.split('-')
+
+      print("[{:>3d}/{:>3d}] ID: {:>10s} [{}] Studies: {:>2}/{:>2} Entries in DB: {:>4d}".format(i,n,patientId,pHex[-1],len(dsStudies),len(studies),seqNum))
+      missingStudies=[s for s in studies if s not in dsStudies]
+#print('Missing studies: {}'.format(len(missingStudies)))
+
+      srows=[]
+      for s in missingStudies:
+
+         sdata=odb.getStudyData(s)
+         sdicom=sdata['MainDicomTags']
+         sid=sdicom['StudyInstanceUID']
+         #print('Data: {}'.format(sdata))
+         #this is try/except protetcted in previous version...
+         sdate="19700101"
+         try:
+             sdate=datetime.datetime.strptime(sdicom['StudyDate'],'%Y-%m-%d %H:%M')
+         except (KeyError,ValueError):
+             pass
+         #continue
+
+         print('\tStudy[{}]: {}/{}'.format(sdate,s,sid))
+
+         for se in sdata['Series']:
+
+            sedata=odb.getSeriesData(se)
+            sedicom=sedata['MainDicomTags']
+              
+            seid=sedicom['SeriesInstanceUID']
+#print('Data: {}'.format(sedata))
+            seDesc="NONE"
+            try:
+              seDesc=sedicom['SeriesDescription']
+            except KeyError:
+              pass
+
+#replace letters that might trip the database
+            spanishOAcute=''.join([chr(3619),chr(3603)])
+            spanishAAcute=''.join([chr(3619),chr(3585)])
+            seDesc=re.sub(spanishOAcute,'o',seDesc)
+            seDesc=re.sub(spanishAAcute,'a',seDesc)
+            #this is a weird O that appears sometimes
+            seDesc=seDesc.replace(chr(212),'O')
+
+
+            print('\t\tSeries[{}]: {}/{}'.format(seDesc,se,seid))
+
+            
+
+#qfilter={'variable':'orthancSeries','value':se,'oper':'eq'}
+#ds=db.selectRows(project,opars['schemaName'],\
+#        opars['queryName'],[qfilter])
+
+#count existing entries for patient
+#qfilter={'variable':participantField,'value':patientId,'oper':'eq'}
+#ds=db.selectRows(project,opars['schemaName'],\
+#opars['queryName'],[qfilter])
+#    seqNum=len(ds['rows'])
+              
+#create new row
+            row={}
+            row[participantField]=patientId
+            row['sequenceNum']=seqNum
+            row['orthancSeries']=se
+
+
+            row['dicomStudy']=sid
+            row['orthancStudy']=s
+            row['dicomSeries']=seid
+            row['studyDate']=sdate
+            row['seriesDescription']=seDesc
+            srows.append(row)
+            seqNum+=1
+
+#upload updates
+      if len(srows)>0:
+         db.modifyRows('insert',project,opars['schemaName'],\
+             opars['queryName'],srows)
+
+
+      i+=1
+   print("Done")
+
+if __name__=="__main__":
+   main(sys.argv[1])