assignOrthancStudy.ipynb 63 KB

import sys
import os
import SimpleITK
import numpy
import matplotlib.pyplot
import subprocess
import json
import chardet
import re
import getData

import segmentation
import importlib
import datetime

sys.path.append(os.path.join(os.path.expanduser('~'),'software','src','nixSuite','wrapper'))
import nixWrapper
nixWrapper.loadLibrary('labkeyInterface')
import labkeyInterface
import labkeyFileBrowser
import labkeyDatabaseBrowser

nixWrapper.loadLibrary('orthancInterface')
import orthancInterface
import orthancFileBrowser
import orthancDatabaseBrowser

def configFile(server):
    return os.path.join(os.path.expanduser('~'),'.labkey',"{}.json".format(server))
    

def connectDB(server):
    fconfig=configFile(server)
    net=labkeyInterface.labkeyInterface()
    net.init(fconfig)
    net.getCSRF()
    return labkeyDatabaseBrowser.labkeyDB(net)

def connectFB(server):
    fconfig=configFile(server)
    net=labkeyInterface.labkeyInterface()
    net.init(fconfig)
    net.getCSRF()
    return labkeyFileBrowser.labkeyFileBrowser(net)

def connectOrthanc(server):
    fconfig=configFile(server)
    net=orthancInterface.orthancInterface()
    net.init(fconfig)
    return orthancDatabaseBrowser.orthancDB(net)
    
#manipulate segmentations
#rewrite this
#nim=getPatientNIM(pId)

loadLibrary
remoteSourcesURL https://git0.fmf.uni-lj.si/studen/nixSuite/raw/master/remoteResources/resources.json
{'labkeyInterface': {'url': 'https://git0.fmf.uni-lj.si/studen/labkeyInterface/archive/master.zip', 'branch': 'master', 'modules': []}, 'irAEMM': {'url': 'https://git0.fmf.uni-lj.si/studen/iraemm/archive/master.zip', 'branch': 'master', 'modules': ['iraemmBrowser']}, 'SlicerLabkeyExtension': {'url': 'https://git0.fmf.uni-lj.si/studen/SlicerLabkeyExtension/archive/SlicerExtensionIndex.zip', 'branch': 'SlicerExtensionIndex', 'modules': ['labkeyBrowser']}, 'limfomiPET': {'url': 'https://git0.fmf.uni-lj.si/studen/limfomiPET/archive/master.zip', 'branch': 'master', 'modules': ['imageBrowser', 'segmentationBrowser']}, 'parseConfig': {'url': 'https://git0.fmf.uni-lj.si/studen/parseConfig/archive/master.zip', 'branch': 'master', 'modules': []}, 'orthancInterface': {'url': 'https://git0.fmf.uni-lj.si/studen/orthancInterface/archive/master.zip', 'branch': 'master', 'modules': []}, 'dynamicSPECT': {'url': 'https://git0.fmf.uni-lj.si/studen/dynamicSPECT/archive/master.zip', 'branch': 'master', 'modules': ['imageBrowser']}}
{'url': 'https://git0.fmf.uni-lj.si/studen/labkeyInterface/archive/master.zip', 'branch': 'master', 'modules': []}
File  /home/studen/temp/labkeyInterface.zip: True
loadLibrary
remoteSourcesURL https://git0.fmf.uni-lj.si/studen/nixSuite/raw/master/remoteResources/resources.json
{'labkeyInterface': {'url': 'https://git0.fmf.uni-lj.si/studen/labkeyInterface/archive/master.zip', 'branch': 'master', 'modules': []}, 'irAEMM': {'url': 'https://git0.fmf.uni-lj.si/studen/iraemm/archive/master.zip', 'branch': 'master', 'modules': ['iraemmBrowser']}, 'SlicerLabkeyExtension': {'url': 'https://git0.fmf.uni-lj.si/studen/SlicerLabkeyExtension/archive/SlicerExtensionIndex.zip', 'branch': 'SlicerExtensionIndex', 'modules': ['labkeyBrowser']}, 'limfomiPET': {'url': 'https://git0.fmf.uni-lj.si/studen/limfomiPET/archive/master.zip', 'branch': 'master', 'modules': ['imageBrowser', 'segmentationBrowser']}, 'parseConfig': {'url': 'https://git0.fmf.uni-lj.si/studen/parseConfig/archive/master.zip', 'branch': 'master', 'modules': []}, 'orthancInterface': {'url': 'https://git0.fmf.uni-lj.si/studen/orthancInterface/archive/master.zip', 'branch': 'master', 'modules': []}, 'dynamicSPECT': {'url': 'https://git0.fmf.uni-lj.si/studen/dynamicSPECT/archive/master.zip', 'branch': 'master', 'modules': ['imageBrowser']}}
{'url': 'https://git0.fmf.uni-lj.si/studen/orthancInterface/archive/master.zip', 'branch': 'master', 'modules': []}
File  /home/studen/temp/orthancInterface.zip: True
#figure out and set studyId from seriesId
#below - assingOrthancId from date
def assignFromSeriesId():
    db=connectDB('merlin')
    orthanc=connectOrthanc('merlin')
    project='/dinamic_spect/Patients'
    dataset='Imaging1'

    ds=db.selectRows(project,'study',dataset,'')
    for r in ds['rows']:
        se=orthanc.getSeriesData(r['nmCorrDataOrthancId'])
        r['studyOrthancId']=se['ParentStudy']
        db.modifyRows('update',project,'study',dataset,[r])


def sortStudies(orthanc,xs,f):
    xm={}
    for x in xs:
        sd=f(orthanc.getStudyData(x))
        try:
            xm[sd].append(x)
        except KeyError:
            xm[sd]=[x]
    return xm

#extractors as 3rd arguments to sortStudies;
#they operate on sdata as returned by orthancDatabaseBrowser

def getStudyDate(sdata):
    return sdata['MainDicomTags']['StudyDate']

def getBirthYear(sdata):
    return sdata['PatientMainDicomTags']['PatientBirthDate'][0:4]

#implementation of sortStudies by studyDate
def studyMap(orthanc):
    xs=orthanc.getList('studies')
    return sortStudies(orthanc,xs,getStudyDate)
    
    
        
        
def assignFromDate(modifyRows=False):
    db=connectDB('labkey-ukc')
    orthanc=connectOrthanc('labkey-ukc')
    project='dynamicSPECT/cardiacSPECT'
    dataset='Imaging1'
    oStudies=studyMap(orthanc)
    ds=db.selectRows(project,'study',dataset,'')
    print('Study date candidates: {}'.format(list(oStudies.keys())))
    for r in ds['rows']:
        sid=r['studyOrthancId']
        patientId=r['patientCode']
        visit=r['visitCode']
        if not patientId:
            patientId=r['PatientId']
        code=f'{patientId}/{visit}'
            
        if sid:
            print(f'SET  [{code}] ID:{sid}')
            continue
        sdate=r['imagingDate']
        try:
            studies=oStudies[sdate]
        except:
            print(f'FAIL [{code}] @ {sdate} study date not found'.format(patientId,sdate))
            continue
        if len(studies)==1:
            r['studyOrthancId']=studies[0]
            studyId=studies[0]
            print(f'OK   [{code}] @ {sdate} found {studyId}')
            if modifyRows:
                ds=db.modifyRows('update',project,'study',dataset,[r])
            continue
        print(f'\t [{code}] @ {sdate} multiple matches: {len(studies)}')
        xm=sortStudies(orthanc,studies,getBirthYear)
        #bdate=patientId[2:]
        #select only numeric glyphs
        bdate=re.sub(r'[^0-9]*','',patientId)
        #filter on bdate
        try:
            xmPrime=xm[bdate]
        except KeyError:
            print(f'FAIL [{code}] @ {sdate} no birth year {bdate}')
            continue
        #unique solution
        if len(xmPrime)==1:
            studyId=xmPrime[0]
            print(f'OK   [{code}] @ {sdate} match birth year {bdate}: {studyId}')
            r['studyOrthancId']=xmPrime[0]
            if modifyRows:
                ds=db.modifyRows('update',project,'study',dataset,[r])
            continue
        #print(xm)
        print(f'FAIL [{code}] @ {sdate} birth year {bdate} multiple: {xmPrime}')
        
            
        
assignFromDate(False)    
User: andrej studen CSRF: 07c44a2191bd67a30f42f1696b4b3fdf
Study date candidates: ['20190514', '20190513', '20220819', '20221129', '20221206', '20220512', '20230830', '20230515', '20190903', '20210202', '20210203', '20190902', '20210423', '20210421', '20220217', '20220215', '20210219', '20210216', '20220708', '20220706', '20200618', '20200619', '20210528', '20210526', '20210212', '20210209', '20190326', '20190327', '20200304', '20200305', '20190826', '20190827', '20210521', '20210519']
SET  [10KF/MIR] ID:992c0733-b219b554-7ffbb1eb-e29d0606-63a62c51
SET  [10KF/OBR] ID:8de576d0-e88601c2-5317457b-47705c87-60c15eee
FAIL [FJ1943/MIR1] @ 20190309 study date not found
FAIL [FJ1943/OBR1] @ 20190209 study date not found
SET  [FJ1943/MIR2] ID:79bcca93-9a5b01f7-516b7ea0-4e5ff2b1-7a1bdaac
SET  [FJ1943/OBR2] ID:4b1cde0a-72e63430-a9a00264-8861a4cb-a46377cd
SET  [JA1960/OBR1] ID:b6c889de-f8d38668-e7a15a74-c8530db3-08388687
FAIL [JA1960/MIR1] @ 20210424 study date not found
SET  [JA1960/OBR2] ID:adcd3506-691a5541-220c8aa1-b0f796fb-fa2db1cd
SET  [JA1960/MIR2] ID:84791e18-eefcd3cd-4c16e1ff-eaf2b9b4-ee8051a0
SET  [JD1971/MIR1] ID:6b4eacd2-2fbf8ef0-ee0ee52b-5dc1e26c-0ae36a23
SET  [JD1971/OBR1] ID:18a061b9-db13bed9-90bb43ea-c7f044c4-a86cfd3e
SET  [JD1971/MIR2] ID:8b017f66-1598a87d-1b8a3c3f-fe9f1ed5-0344686a
SET  [JD1971/OBR2] ID:72a6e5cd-0d1cac70-0f38027c-5c1c7d8a-f6eba43b
SET  [JD1973/MIR1] ID:670e9d2a-c1feec4b-99757eaf-997f73e8-8df2742a
SET  [JD1973/OBR1] ID:96c75aa9-0a16ea6e-d080cd60-29ffddf5-ef3c3f05
SET  [JD1973/MIR2] ID:9ae9acd5-5063fedb-0e0d7a72-29f3a951-1ff5fb6d
SET  [JD1973/OBR2] ID:36a0503d-220a1996-fec9b6ff-29de8388-a3cf3788
SET  [JI1943/MIR1] ID:345ed9ec-ec584712-87154bb0-1e6cb5a8-065443eb
SET  [JI1943/OBR1] ID:fb51a384-24bf561a-35bd3f4d-44079037-ab21e16b
SET  [JI1943/MIR2] ID:c52a79f1-da8abfa2-c47c8813-3cbdb1a5-50b6d490
SET  [JI1943/OBR2] ID:49191331-b4b07708-7e89c147-ce200efc-862d5240
SET  [JS1952/MIR1] ID:b473ba96-11f607ca-b79b5f59-230adb5a-f86c8976
SET  [JS1952/OBR1] ID:16e9c945-66d4c9ae-b796827f-4a598413-da10981b
	 [KA1940/MIR1] @ 20190514 multiple matches: 3
FAIL [KA1940/MIR1] @ 20190514 no birth year 1940
	 [KA1940/OBR1] @ 20190513 multiple matches: 3
FAIL [KA1940/OBR1] @ 20190513 no birth year 1940
	 [KA1940/MIR2] @ 20210212 multiple matches: 2
FAIL [KA1940/MIR2] @ 20210212 no birth year 1940
	 [KA1940/OBR2] @ 20210209 multiple matches: 2
FAIL [KA1940/OBR2] @ 20210209 no birth year 1940
SET  [MB1965/MIR] ID:b2bdb9c0-076fe14e-7d6481f1-14d4093f-7ca29b91
SET  [MB1965/MIR1] ID:3fe308e8-48fd71e2-0638aba2-dbfc9e6f-4f7d7718
SET  [MB1965/MIR2] ID:dc5d34f2-0fb785a6-d904ba2c-b765fbce-30161f8c
SET  [MI1943/MIR1] ID:36599b2d-35e85e38-5ccd4ce4-73b2fd77-a7dad7be
SET  [MI1943/OBR1] ID:00135c7f-9356e861-74c9704b-f133f38e-f42bf54a
	 [MI1943/MIR2] @ 20210212 multiple matches: 2
FAIL [MI1943/MIR2] @ 20210212 no birth year 1943
	 [MI1943/OBR2] @ 20210209 multiple matches: 2
FAIL [MI1943/OBR2] @ 20210209 no birth year 1943
SET  [MJ1963/MIR1] ID:7e643a55-34f441fc-de3d779a-9f6e29bf-6e354e21
SET  [MJ1963/OBR1] ID:e619b089-31190797-09b7fa68-3b7ebce5-cb0e342e
SET  [MM/MIR] ID:137d9e53-0e77d03e-55f56fbf-55358d85-f473d2c5
SET  [MM/MIR1] ID:3dd2760f-412cbfba-192c1d12-3832dc3c-321651a5
SET  [MM1936/MIR1] ID:c511a074-bfa73799-5df11a3e-c2ad96e1-a4a8e6de
SET  [MM1936/OBR1] ID:f99216d5-3d3ef44b-2cee1efa-526e0901-b68349dc
SET  [MM1936/MIR2] ID:42bd91bd-20dd2d19-64a6ff77-7bce6317-4bab8aaf
SET  [MM1936/OBR2] ID:8eb39455-6fa76e34-c04349a6-7f3ad1cd-61f0a307
SET  [MM/OBR] ID:07cb4e32-30da5d01-75d7067f-f393540f-432489e1
SET  [MNG1940/OBR1] ID:a9d91056-1388e280-bd6d58df-1ee96555-87441107
SET  [MNG1940/MIR1] ID:ad23f1a4-30388a48-9587d035-a5cfeb34-0e8d5d05
SET  [MNG1940/MIR2] ID:a6df647d-5474750c-67b017d7-e37b85ec-d7e86f39
SET  [MNG1940/OBR2] ID:842443a5-b97d0b03-dda3af69-16089e8b-70b6e87f
SET  [po1982022/MIR] ID:80bb7c25-6e4d4890-f6f3c46e-f0a7bdfd-2be580d2
SET  [pred15052022/MIR] ID:1a759996-7bdd0109-c5e8f833-c6857dfe-84eaed66
SET  [TT1998/MIR] ID:827fad2b-7a4b824f-c68d9e4a-7942961a-b9f1133f
SET  [VV1984/MIR] ID:484d95a5-fe38de02-d377e94b-74c1037d-201f8804
SET  [VV1984/MIR1] ID:1c21ea83-b3721080-f272ac26-f5d5ef73-aa56e160
#get series for data with study set

def isCT(orthanc,sedata):
    #base criteria - is CT and SeriesDescription contains AC
    mtags=sedata['MainDicomTags']
    if not mtags['Modality']=='CT':
        return False
    try:
        if not mtags['SeriesDescription'].find('AC')==0:
            return False
    except KeyError:
        pass
    #backup - more than a single instance
    n=len(sedata['Instances'])
    if n==1:
        return False
    return True

def isMasterNM(orthanc,sedata):
    mtags=sedata['MainDicomTags']
    if not mtags['Modality']=='NM':
        return False
    n=len(sedata['Instances'])
    if not n==1:
        return False
    idata=orthanc.getData('instances',sedata['Instances'][0])
    imtags=idata['MainDicomTags']
    iframes=int(imtags['NumberOfFrames'])
    if iframes<500:
        return False
    #print(idata)
    return True
    
def isCorrDataNM(orthanc,sedata):
    mtags=sedata['MainDicomTags']
    if not mtags['Modality']=='NM':
        return False
    n=len(sedata['Instances'])
    if n==1:
        return False
    #idata=orthanc.getData('instances',sedata['Instances'][0])
    #imtags=idata['MainDicomTags']
    itype=orthanc.getDicomField(sedata['Instances'][0],'0028-0051')
    if itype.find('SCAT')==-1:
        return False
    #print(itype)
    return True
            

def setSeries(modifyRows=False):
    db=connectDB('labkey-ukc')
    orthanc=connectOrthanc('labkey-ukc')
    project='dynamicSPECT/cardiacSPECT'
    dataset='Imaging1'
    ds=db.selectRows(project,'study',dataset,'')
    for r in ds['rows']:
        patientId=r['PatientId']
        visit=r['visitCode']
        sdate=r['imagingDate']
        code=f'[{patientId}/{visit} @ {sdate}]'
        
        if r['nmMasterOrthancId']:
            print(f'SET {code}')
            continue
        if not r['studyOrthancId']:
            print(f'FAIL {code}: no study id set, run assignFromDate()!')
            continue
        series=orthanc.getStudyData(r['studyOrthancId'])['Series']
        for s in series:
            sedata=orthanc.getSeriesData(s)
            mtags=sedata['MainDicomTags']
            #print('{} {}'.format(mtags['Modality'],mtags['SeriesDescription']))
            if isCT(orthanc,sedata):
                r['ctOrthancId']=s
                continue
            if isMasterNM(orthanc,sedata):
                r['nmMasterOrthancId']=s
                continue
            if isCorrDataNM(orthanc,sedata):
                r['nmCorrDataOrthancId']=s
                continue
            
            #print(sedata)
        #break
        print(f'{code}')
        if r['ctOrthancId']:
            x=r['ctOrthancId']
            print(f'\tCT: OK ID: {x}')
        else:
            print(f'\tCT: FAIL')
        if r['nmMasterOrthancId']:
            x=r['nmMasterOrthancId']
            print(f'\tNM(Raw) ID: {x}')
        else:
            print(f'\tNM(Raw) FAILED')
        if r['nmCorrDataOrthancId']:
            x=r['nmCorrDataOrthancId']
            print(f'\tNM(Img) ID: {x}')
        else:
            print(f'\tNM(Img) FAILED')
            
        if modifyRows:
            ds=db.modifyRows('update',project,'study',dataset,[r])
        #break
setSeries(True) 
    
User: andrej studen CSRF: a675486ae1b1befbc6ebd792df3a8c17
SET [10KF/MIR @ 20190514]
SET [10KF/OBR @ 20190513]
FAIL [FJ1943/MIR1 @ 20190309]: no study id set, run assignFromDate()!
FAIL [FJ1943/OBR1 @ 20190209]: no study id set, run assignFromDate()!
SET [FJ1943/MIR2 @ 20210202]
SET [FJ1943/OBR2 @ 20210203]
[JA1960/OBR1 @ 20210421]
	CT: OK ID: b79ee29f-dc4aaa68-78f4ad43-e678e11e-a520fcaf
	NM(Raw) ID: 17187242-e96a62d6-0c34ea12-3b80d992-e4a0db30
	NM(Img) ID: 4fe75631-dc32fbaf-c4f52623-faecfd73-f53ee029
User: andrej studen CSRF: d3796bb7537fd6b9462c460bcbd3a845
FAIL [JA1960/MIR1 @ 20210424]: no study id set, run assignFromDate()!
[JA1960/OBR2 @ 20220215]
	CT: OK ID: cba7385d-7aaef4ed-f21155f5-db0e55b6-ac29dea3
	NM(Raw) ID: 9e2e18d0-2799979f-d5794737-df61f83d-f0e8a8b4
	NM(Img) ID: 70538040-5c662ab7-b11e2052-19e04c62-72b68967
User: andrej studen CSRF: 79cbd15f916c74e6ea58631348b4d08c
[JA1960/MIR2 @ 20220217]
	CT: OK ID: 15ee88ea-35773b56-a6e864f7-c46f49a9-d1421f36
	NM(Raw) ID: 0db18702-1dd7c0c2-866eade8-74f5ee30-79a12dcf
	NM(Img) ID: 7edd0445-ae06d9c5-268a1182-3a814255-1882fab3
User: andrej studen CSRF: c81de448540579af2ac305cb0b33431d
[JD1971/MIR1 @ 20190903]
	CT: OK ID: 03d06718-724bfb17-3d181862-9d123117-e598f3ea
	NM(Raw) ID: 0de1d1d2-8710b71d-99cb9d3e-1c64c5db-5a2b495c
	NM(Img) ID: 690aa1c8-3db59555-b270e771-ba6c1992-e7c647c5
User: andrej studen CSRF: 0c096074f992403819bce555a2b22b65
[JD1971/OBR1 @ 20190902]
	CT: OK ID: afc725ba-c818c7b9-9843a39a-09905a44-e0b69f84
	NM(Raw) ID: 6e346b85-2d5b0b13-ceedd23e-abaa46a6-5b4f6ce1
	NM(Img) ID: 1a5192ca-23ebfcb5-3d2603c7-fade6633-7d427fb6
User: andrej studen CSRF: 85164cfa4c40f7f22f334cc37fd7242a
[JD1971/MIR2 @ 20210219]
	CT: OK ID: d8f06cb7-89f01c5d-46a69d6b-ba8c653a-d0060e1a
	NM(Raw) ID: 01ef80c4-7ae0ab2c-230cb908-b8ddaf68-5b864a2b
	NM(Img) ID: 41e870de-06479edc-d5a43f4b-0b5440cd-79c4b6bf
User: andrej studen CSRF: 8b992a30d78fd3c98a54e747251ccee7
[JD1971/OBR2 @ 20210216]
	CT: OK ID: 8acdda24-6d4cff97-eaaca89c-17c05b93-8be78bce
	NM(Raw) ID: 35b070a6-3f8b472c-cf186ca5-fcc35602-7ac7854c
	NM(Img) ID: eda3927f-eeced313-105b4088-7955765a-e0111caf
User: andrej studen CSRF: 41b65d29b560745614cb4a1bbc8bfd02
[JD1973/MIR1 @ 20210423]
	CT: OK ID: 9367d757-0a93c89b-f29c2c44-a81cd459-25562726
	NM(Raw) ID: 7d79ab8a-162aaad3-c85a0b83-213e4fcc-21d2815a
	NM(Img) ID: ecfd3162-665fa458-13889f24-4b10a77b-bbf6efa0
User: andrej studen CSRF: afb2b28b35aae2ae2b74b8a398fd4a62
[JD1973/OBR1 @ 20210421]
	CT: OK ID: 21f02bd0-7883466c-5cee4cf4-ac1762df-309fec00
	NM(Raw) ID: b4f36691-ff2b4acf-4ed9b04f-60bf102f-2dfcc532
	NM(Img) ID: 81b23560-456462a5-229f9508-3fbd7067-da170abd
User: andrej studen CSRF: d0532d3451546a886e74edbe3ee0eea9
[JD1973/MIR2 @ 20220708]
	CT: OK ID: b5db5dcd-73ffb6a2-30e388d4-a8703df5-390c6e40
	NM(Raw) ID: d2ad0b63-62409b0b-fd8a70b9-f71b805f-2f39f3fc
	NM(Img) ID: 3429be0f-f3824fd6-57426475-6bf47ed9-d75e4e0c
User: andrej studen CSRF: 1e581bef379eee356c6d71654d57276f
[JD1973/OBR2 @ 20220706]
	CT: OK ID: 7c79efa9-28523e0f-f897a8e9-63742b78-a26d0ff8
	NM(Raw) ID: fa97be07-7a806101-44f7079d-e1a3381e-89854f27
	NM(Img) ID: 39c7ae58-862bb23d-33c7e05e-d6587450-cabf15b2
User: andrej studen CSRF: 79875757c2656056293b51379e09b07d
[JI1943/MIR1 @ 20200618]
	CT: OK ID: 683e9555-b9b6e5fd-d06f5521-5adf12d5-ed85ced2
	NM(Raw) ID: f7b2bed3-c38a9600-e1bf5b01-cf2e4c70-4a4ab823
	NM(Img) ID: af15224b-2dc57712-f324695c-a50547e2-34e72e62
User: andrej studen CSRF: 71c60846321c8033056406a1eb4d3d9f
[JI1943/OBR1 @ 20200619]
	CT: OK ID: 9a78e8d8-df2fa3e7-02ba6d08-0fdbe51b-0e4246e9
	NM(Raw) ID: a9caf516-a38c8fe1-90ea7ee2-52ce3de8-77615243
	NM(Img) ID: 5bd63e93-651a5d1d-40076934-05cb0421-5c01d74d
User: andrej studen CSRF: c0eec3718396480bb81e2379fe9244dc
[JI1943/MIR2 @ 20210528]
	CT: OK ID: 773f9a42-dbdf8b4c-4ab0f808-b96be60d-a1084b63
	NM(Raw) ID: 933a27de-057d0e80-eb78afdb-739d3d16-31c125b9
	NM(Img) ID: 002ebf3c-3adb4ae0-728daeb5-7acce400-5362b1fa
User: andrej studen CSRF: f3c4798a3ed8106e0339e88434bf30c8
[JI1943/OBR2 @ 20210526]
	CT: OK ID: 03ff48ce-2bb5a42e-73d6b709-3ac1a875-b521e3c0
	NM(Raw) ID: 81a0661b-5e7c27d5-29c1288f-ca47451c-c83443ce
	NM(Img) ID: 056c3249-f132228b-68f39184-fd310fff-01cb4360
User: andrej studen CSRF: a2749828b4d77def4689100c17829549
[JS1952/MIR1 @ 20190514]
	CT: OK ID: 19f99b32-8d92b846-8865eeb2-7678b004-93bd4e76
	NM(Raw) ID: 87e86b89-ee314eb1-a95228f5-c3587c3b-b8016f52
	NM(Img) ID: 62bd627d-7e7b5824-b3b2bcb7-2493055f-1053d74e
User: andrej studen CSRF: 2ce0ddc27763a76e44fb8393e6ced1ad
[JS1952/OBR1 @ 20190513]
	CT: OK ID: b5b39140-58a11dbb-29f762ea-74eb5eee-babe1c29
	NM(Raw) ID: 9cefe25d-4c8ea4eb-33b38501-3386729f-11a434fd
	NM(Img) ID: ea75ac15-b48d4c11-7088a758-95f5a5e3-e5cec172
User: andrej studen CSRF: c000d67775020e76aa21d2de55ddea11
FAIL [KA1940/MIR1 @ 20190514]: no study id set, run assignFromDate()!
FAIL [KA1940/OBR1 @ 20190513]: no study id set, run assignFromDate()!
FAIL [KA1940/MIR2 @ 20210212]: no study id set, run assignFromDate()!
FAIL [KA1940/OBR2 @ 20210209]: no study id set, run assignFromDate()!
SET [MB1965/MIR @ 20220512]
SET [MB1965/MIR1 @ 20220819]
SET [MB1965/MIR2 @ 20221129]
[MI1943/MIR1 @ 20190326]
	CT: OK ID: 3cec3099-d6a5aa2c-80ceefa4-b2f24b5f-5914695d
	NM(Raw) ID: 1264c701-cf0be371-9c0639e0-9d3b1087-954bad3c
	NM(Img) ID: f4d20c35-856f0cbb-dd925c5b-869f392a-9cfd359e
User: andrej studen CSRF: 583cdc2d38f1a2f1c54624e9f48a1a4b
[MI1943/OBR1 @ 20190327]
	CT: OK ID: 3efeff50-bf7eb655-ee08824d-7b63792a-457fedd4
	NM(Raw) ID: 0e722805-ecf04f38-ca9d0ac2-01e1d87e-cbea14ea
	NM(Img) ID: b6322734-d5efec5a-300525ab-975bc0b1-5718c7eb
User: andrej studen CSRF: b8bd58a36daae5d165dd78e0d48f5f62
FAIL [MI1943/MIR2 @ 20210212]: no study id set, run assignFromDate()!
FAIL [MI1943/OBR2 @ 20210209]: no study id set, run assignFromDate()!
[MJ1963/MIR1 @ 20200304]
	CT: OK ID: 39aa62d1-dcbe7247-5cd23dac-6067bfc3-0e9e974e
	NM(Raw) ID: 17f28587-fcac56f2-a1747c7b-9e3e3a9d-b85ea454
	NM(Img) ID: dad69a7e-96ab9c71-c653230f-ac6ca06f-6ebbcf70
User: andrej studen CSRF: 02f342665ba2523c5df64be20dfbb17a
[MJ1963/OBR1 @ 20200305]
	CT: OK ID: 0047a1c3-6cdc3d79-8692a0cd-c3e23862-b0069561
	NM(Raw) ID: fe979a39-696e2e65-3c012807-8ba9818a-b26523a7
	NM(Img) ID: 133f8b65-8e1ca210-270c9259-b4244ad0-452fa07d
User: andrej studen CSRF: d93fe40483a9f916bfe0946d40706e71
SET [MM/MIR @ 20220819]
SET [MM/MIR1 @ 20221129]
[MM1936/MIR1 @ 20190827]
	CT: OK ID: 74b2a919-5fc51491-34f4276c-7daae0cc-269dd4ac
	NM(Raw) ID: 4746b129-56061f7b-e5ecbe6c-9cbac5ba-fd6ee400
	NM(Img) ID: c671017b-58898e0d-9aa6950e-7f31fbbb-9466a85a
User: andrej studen CSRF: ba46f35b592cc78b0a851ee032028060
[MM1936/OBR1 @ 20190826]
	CT: OK ID: ff84df5d-695eb992-b80ab669-e5329506-cfadf3dd
	NM(Raw) ID: 173fd06d-ffc44f86-c47084b9-5888612b-ab9c430a
	NM(Img) ID: f5f31de2-968e183c-f4e6ef8d-59b09f8b-f55e6d24
User: andrej studen CSRF: b177ccb2d217743ad3fe57cbd3c2f6c9
[MM1936/MIR2 @ 20210521]
	CT: OK ID: f94eda1b-adff3b63-2fc2a467-b88f79fa-15925c64
	NM(Raw) ID: 5a537e00-ca99bc11-6b0db820-fadfd1ab-76f3f712
	NM(Img) ID: 7706d5ae-9c0ca196-6bf786f0-1fccd37b-e9463de6
User: andrej studen CSRF: 73a0e916d395710fc82c3742860227bc
[MM1936/OBR2 @ 20210519]
	CT: OK ID: 61cb4866-fd57c584-9bffa6ad-30382fc8-7598b317
	NM(Raw) ID: a39cc437-bb66f647-0f820a25-e5110ff0-41414aba
	NM(Img) ID: e42d465b-86a6222e-29ce1948-a22a6757-ed346ab5
User: andrej studen CSRF: 460b41c11fd660124a7de2f2d9c9eca2
SET [MM/OBR @ 20221206]
[MNG1940/OBR1 @ 20210421]
	CT: OK ID: f32c172a-80b7f813-35ba3566-26d3acc2-82e016c8
	NM(Raw) ID: 8b9e1175-e2cff1a3-1314ac58-50e8ba3d-59171f28
	NM(Img) ID: 7be9bde7-6ee5f88f-3310c821-14733f77-346555b0
User: andrej studen CSRF: 5add02fab1cda2e6478b7037e1c76a6b
[MNG1940/MIR1 @ 20210423]
	CT: OK ID: beb26f2d-67e874f6-8d4c2d07-0ea23e21-b68c437e
	NM(Raw) ID: 286de30e-663ca5d9-2507026e-345d2b82-0cff87cf
	NM(Img) ID: 3d26bdf4-96f7ae44-dd977c3b-f7721f77-271093df
User: andrej studen CSRF: d3d8dc0fc56c658b20289e6b6aa50ec6
[MNG1940/MIR2 @ 20220217]
	CT: OK ID: 8edfbe5a-a4d171d2-9eae5b2b-bb3c92c7-e2fd3fc7
	NM(Raw) ID: 945da723-e1b2eeca-1ff0af60-cd733123-94a1c135
	NM(Img) ID: bf1c4f2d-72ce38bc-a77e0452-ca4b7079-a8dac61f
User: andrej studen CSRF: 813eae5a892bb0669baa1cde2f490754
[MNG1940/OBR2 @ 20220215]
	CT: OK ID: b836c90f-85cab249-d7c5fdb0-e3475e53-1d069753
	NM(Raw) ID: 0cc948ad-7856ba90-0c5f755b-8d58a5b8-62e32258
	NM(Img) ID: b7b7764e-5290b3bd-79b18d47-4320e153-e44b0932
User: andrej studen CSRF: 073bad98ab82533d8232c3138ea4bff1
SET [po1982022/MIR @ 20220819]
SET [pred15052022/MIR @ 20220512]
SET [TT1998/MIR @ 20230830]
SET [VV1984/MIR @ 20230515]
SET [VV1984/MIR1 @ 20230830]
#get imagingDate from studyOrthancId
def getImagingDate():
    db=connectDB('labkey-ukc')
    orthanc=connectOrthanc('labkey-ukc')
    project='/dynamicSPECT/cardiacSPECT'
    dataset='Imaging1'
    ds=db.selectRows(project,'study',dataset,'')
    rows=ds['rows']
    for r in rows:
        sid=r['studyOrthancId']
        patientId=r['PatientId']
        if not sid:
            print(f'No study id for {patientId}')
            continue
        sd=orthanc.getStudyData(r['studyOrthancId'])
        r['imagingDate']=sd['MainDicomTags']['StudyDate']
        db.modifyRows('update',project,'study',dataset,[r])
        
def setStudyDate():
    db=connectDB('labkey-ukc')
    orthanc=connectOrthanc('labkey-ukc')
    project='/dynamicSPECT/cardiacSPECT'
    dataset='Imaging1'
    ds=db.selectRows(project,'study',dataset,[])
    rows=ds['rows']
    for r in rows:
        dt=datetime.datetime.strptime(r['imagingDate'],'%Y%m%d')
        r['studyDate']=dt.strftime('%Y/%m/%d')
        db.modifyRows('update',project,'study',dataset,[r])
        
setStudyDate()
User: andrej studen CSRF: eda92fe6acfc645dcc20e64451de2bcc
User: andrej studen CSRF: ccdd6bfe993c84237648879c32922324
User: andrej studen CSRF: 1eefebcb86155da277327e320c6d855e
User: andrej studen CSRF: 97ac1e100819769b7852e9a7dd3290fd
User: andrej studen CSRF: ed40684a2b8537c23fc358ed4d900a47
User: andrej studen CSRF: 34ad147b1b7dd2dd3e61e67158a34afb
User: andrej studen CSRF: 5f51b6f277e43102b44c97658b8a11c8
User: andrej studen CSRF: 8b66c1e79af33886680486734ab0b10b
User: andrej studen CSRF: 0c4c51e3f4b05f46f5fe68b35a1d6e21
User: andrej studen CSRF: 73f023fe6494ee80f446212df52f6702
User: andrej studen CSRF: 479c20de89dc3d47e250677aab54db53
User: andrej studen CSRF: 375be6798203b87d56a61eafdcc2fdc4
User: andrej studen CSRF: 13553704c3885f2667711e1bb5bd8100
User: andrej studen CSRF: 84442ae1e529d6e74d730fe96342a64f
#set patientCode
db=connectDB('labkey-ukc')
project='/dynamicSPECT/cardiacSPECT'
dataset='Imaging1'
ds=db.selectRows(project,'study',dataset,'')
rows=ds['rows']
for r in rows:
    r['patientCode']=r['PatientId']
    db.modifyRows('update',project,'study',dataset,[r])
User: andrej studen CSRF: ef76bf934ffbf0af9fc0547fc7871983
User: andrej studen CSRF: 816ac23d327ba77af1abb18b9c0ba3e1
User: andrej studen CSRF: 1be64b3e1b0d3ed0b6853d56ac70e6a5
User: andrej studen CSRF: d5b958584db13089e2731feb37334487
User: andrej studen CSRF: 9ecdad5e798ef004b999fce6727c4e0f
User: andrej studen CSRF: 19850f8c5b0c4217d483bea59a6fe743
User: andrej studen CSRF: 3ecb54e610afb5605c92a7fa19fb3326
User: andrej studen CSRF: 602968a1373dac5c14d55af8dd1c475b
User: andrej studen CSRF: 16eb98eddbaa6b58f4a5d733a270c013
User: andrej studen CSRF: 207b55bf76fcd1a88fb316cd832d88a4
User: andrej studen CSRF: ecf8895ef0da5c1f092a6ec3a64f7d9c
User: andrej studen CSRF: 94735fb33035a678e5836a38f7cdcdb6
User: andrej studen CSRF: 9cbec531e64fed313135398a92341495
User: andrej studen CSRF: 2387d8b279dfa87b4a1d6cadf1db7d3f
#copy files from one orthanc instance to another
db=connectDB('merlin')
orthanc=connectOrthanc('merlin')
project='/dinamic_spect/Patients'
dataset='Imaging1'

ds=db.selectRows(project,'study',dataset,'')
src=configFile('merlin')
target=configFile('kclj')
path=['software','src','orthancInterface','scripts','moveDicom.sh']
path.insert(0,os.path.expanduser('~'))
script=os.path.join(*path)
for r in ds['rows']:
    subprocess.run([script,src,target,r['studyOrthancId']])
    
User: andrej studen CSRF: 4f341fbc6f8b6681df54039307becbd7
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  9.8M    0  9.8M    0     0  1017k      0 --:--:--  0:00:09 --:--:-- 2100k
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0Downloaded study 992c0733-b219b554-7ffbb1eb-e29d0606-63a62c51 to /home/studen/temp/Study.zip
100  9.9M  100 23131  100  9.8M   3353  1468k  0:00:06  0:00:06 --:--:-- 1524k
AlreadyStored AlreadyStored AlreadyStored AlreadyStored AlreadyStored AlreadyStored AlreadyStored AlreadyStored AlreadyStored AlreadyStored AlreadyStored AlreadyStored AlreadyStored AlreadyStored AlreadyStored AlreadyStored AlreadyStored AlreadyStored AlreadyStored AlreadyStored AlreadyStored AlreadyStored AlreadyStored AlreadyStored AlreadyStored AlreadyStored AlreadyStored AlreadyStored AlreadyStored AlreadyStored AlreadyStored AlreadyStored AlreadyStored AlreadyStored AlreadyStored AlreadyStored AlreadyStored AlreadyStored AlreadyStored AlreadyStored AlreadyStored AlreadyStored AlreadyStored AlreadyStored AlreadyStored AlreadyStored AlreadyStored AlreadyStored AlreadyStored AlreadyStored AlreadyStored AlreadyStored AlreadyStored AlreadyStored AlreadyStored AlreadyStored AlreadyStored AlreadyStored AlreadyStored
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 9262k    0 9262k    0     0   369k      0 --:--:--  0:00:25 --:--:-- 1015k
Downloaded study 8de576d0-e88601c2-5317457b-47705c87-60c15eee to /home/studen/temp/Study.zip
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 9283k  100 21233  100 9262k   3544  1546k  0:00:05  0:00:05 --:--:-- 1745k
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success
100 11.7M    0 11.7M    0     0   346k      0 --:--:--  0:00:34 --:--:-- 37959
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0Downloaded study 137d9e53-0e77d03e-55f56fbf-55358d85-f473d2c5 to /home/studen/temp/Study.zip
100 11.7M  100 33199  100 11.7M   4014  1455k  0:00:08  0:00:08 --:--:-- 1347k
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success
100 12.9M    0 12.9M    0     0   359k      0 --:--:--  0:00:36 --:--:-- 2426k
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0Downloaded study 3dd2760f-412cbfba-192c1d12-3832dc3c-321651a5 to /home/studen/temp/Study.zip
100 12.9M  100 35515  100 12.9M   3549  1326k  0:00:10  0:00:10 --:--:--  307k
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success
100 12.1M    0 12.1M    0     0   539k      0 --:--:--  0:00:22 --:--:--  123k
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0Downloaded study 07cb4e32-30da5d01-75d7067f-f393540f-432489e1 to /home/studen/temp/Study.zip
100 12.1M  100 34743  100 12.1M   4214  1503k  0:00:08  0:00:08 --:--:--  939k
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success
100 11.7M    0 11.7M    0     0   857k      0 --:--:--  0:00:14 --:--:--  964k
Downloaded study 80bb7c25-6e4d4890-f6f3c46e-f0a7bdfd-2be580d2 to /home/studen/temp/Study.zip
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 11.7M  100 33199  100 11.7M   4160  1508k  0:00:07  0:00:07 --:--:-- 1091k
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success
100 12.4M    0 12.4M    0     0   659k      0 --:--:--  0:00:19 --:--:-- 2216k
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0Downloaded study 1a759996-7bdd0109-c5e8f833-c6857dfe-84eaed66 to /home/studen/temp/Study.zip
100 12.4M    0     0  100 12.4M      0  1671k  0:00:07  0:00:07 --:--:-- 1762kSuccess Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success Success
100 12.5M  100 35515  100 12.4M   4102  1474k  0:00:08  0:00:08 --:--:--  910k
#copy dataset from one instance to another
src=connectDB('merlin')
target=connectDB('kclj')
srcProject='dinamic_spect/Patients'
targetProject='dynamicSPECT/cardiacSPECT'
schema='study'
dataset='Imaging1'

def copyDatasetDesign(src,srcProject,target,targetProject,schema,dataset):
    minProperties=['name','label','rangeURI','lookupSchema',
                       'lookupContainer','lookupQuery']
    dsgn=target.getQueryDesign(targetProject,'study',dataset)
    if 'exception' in dsgn:
        print('Missing {} {}'.format(schema,dataset))
        #impossible to create list copy them by hand
        if schema=='lists':
            print('create lists by list archive export')
            return
        design=src.getQueryDesign(srcProject,schema,dataset)

        fields=[]
        for f in design['fields']:
            #skip Key
            if f['name']=='Key':
                continue
            #use subselection
            q={p:f[p] for p in minProperties}
            fields.append(q)

        print(target.addQuery(targetProject,schema,dataset,fields))
        print('Created {}'.format(dataset))

def internalField(v):
    if v.find('_')==0:
        return True
    if v=='lsid':
        return True
    return False
        
def copyDatasetData(src,srcProject,target,targetProject,schema,dataset):
    ds=src.selectRows(srcProject,schema,dataset,[])
    fVar=['PatientId','SequenceNum']
    skipVar=['lsid']
    for r in ds['rows']:
        qfilter=[{'variable':x,'value':'{}'.format(r[x]),'oper':'eq'} for x in fVar]
        ds1=target.selectRows(targetProject,schema,dataset,qfilter)
        if len(ds1['rows'])>0:
            outRow=ds1['rows'][0]
            mode='update'
        else:
            mode='insert'
            outRow={}
        for x in r:
            if internalField(x):
                #print('{}/Skip'.format(x))
                continue
            #print('{}/Use'.format(x))
            outRow[x]=r[x]
        target.modifyRows(mode,targetProject,schema,dataset,[outRow])
        #break
#copyDatasetDesign(src,srcProject,target,targetProject,schema,dataset)
copyDatasetData(src,srcProject,target,targetProject,schema,dataset)
User: andrej studen CSRF: ad0e9a315e6fac8a19f892af1e550d39
User: andrej studen CSRF: e89f9c751f9ca44877fceac804e4909f
User: andrej studen CSRF: f7b3b5f0ddf5198e98a29b7ba31072bd
User: andrej studen CSRF: d34f232a12afc576f9d0477842f9d099
User: andrej studen CSRF: 16deee5f2eb2c59edb604416b8a71bab
User: andrej studen CSRF: fab98bb2b2fc0bb9c7c356ed7d468963
User: andrej studen CSRF: 20974f8994412e7c209edb0c100b59bc
User: andrej studen CSRF: 84cff63141f897248071e16692de5338
User: andrej studen CSRF: a80d3d28add7108dd4287c5fbf4b65b8
#check for converted NRRD files
def checkNRRD():
    db=connectDB('labkey-ukc')
    fb=connectFB('labkey-ukc')
    project='dynamicSPECT/cardiacSPECT'
    schema='study'
    dataset='Imaging1'
    ds=db.selectRows(project,schema,dataset,[])
    for r in ds['rows']:
        #print(r)
        fDir='processedImages'
        fDir=[fDir,r['PatientId'],r['visitCode']]
        fNameCT='{}_{}_CT.nrrd'.format(r['PatientId'],r['visitCode'])
        fNameSPECTCT='{}_{}_Volume19.nrrd'.format(r['PatientId'],r['visitCode'])
        
        fRemoteDir=fb.buildPathURL(project,fDir)
        fURL='/'.join([fRemoteDir,fName])
        if fb.entryExists(fURL):
            print(fName)
        #row={x:r[x] for x in ['PatientId','visitCode']}
        

checkNRRD()
User: andrej studen CSRF: e8d8f790b143dd4457ee6213d8ea11e6
User: andrej studen CSRF: 8af4603306dd5888f96e038b676b86dc
MB1965_MIR_CT.nrrd
MB1965_MIR1_CT.nrrd
MB1965_MIR2_CT.nrrd
MM_MIR1_CT.nrrd
TT1998_MIR_CT.nrrd
VV1984_MIR_CT.nrrd
VV1984_MIR1_CT.nrrd
#calculate k1 in units of ml/g*min
def convertToMinutes():
    db=connectDB('labkey-ukc')
    project='/dynamicSPECT/cardiacSPECT'
    dataset='Summary'
    ds=db.selectRows(project,'study',dataset,'')
    rows=ds['rows']
    for r in rows:
        k1=r['mean']
        k1p=60*r['mean']
        r['k1']=k1p
        db.modifyRows('update',project,'study',dataset,[r])
        
convertToMinutes()
User: andrej studen CSRF: 2b647191df95dff06e7a0c2fca6d8cfc
User: andrej studen CSRF: b9df37c5e367adc8640e4a3364df7273
User: andrej studen CSRF: c395eec2b1488cc7b67ff0f9a0eed82e
User: andrej studen CSRF: 7856f86e340ca8ea9cff217ce2ec45ea
User: andrej studen CSRF: f27049f4751cee7ae2d57cafbb903bc2
User: andrej studen CSRF: ac7532abb8da76c99052bb75c8eb01f7
User: andrej studen CSRF: 0f4d2fc6118e4a375b1448cb757cc448
User: andrej studen CSRF: e63ef87d0921b6688a9c36acc4d12033
User: andrej studen CSRF: 4777412ef946acc7496ae7bb12f9d843
User: andrej studen CSRF: 138efce81860aba8e2658ccd36f4f7bc
User: andrej studen CSRF: 3c54b3e94ffe618ec1733ecdb5b32baa
User: andrej studen CSRF: 0d9a9b94af06ff3dc2114845c7ce0fbb
User: andrej studen CSRF: 4519a0e635665a62ed494cd109c99d36
User: andrej studen CSRF: 07ad2d764675b85ad2eaa3ea03c19405
User: andrej studen CSRF: d04f0a0d00aec42f3ce4d5e96d3a3639
User: andrej studen CSRF: a50021923bce897e16f5bd1540ac36de
User: andrej studen CSRF: 0535c280d72a6aa7c35d9f0a6398a08a
User: andrej studen CSRF: d8a4d2a69ff4255ab4d0aaf9bf40de06
User: andrej studen CSRF: 02e76facca72414a6c28222e65ed75db
User: andrej studen CSRF: d65f663691b8f56bddb1e11dd0a6f1cf
User: andrej studen CSRF: 4574afaa21f7a3cf2b95736fd5a09521
User: andrej studen CSRF: 3b6bca3ca5d0e5ea4917b9ac71cc5313
User: andrej studen CSRF: 5fd4f12846e075e935f62bb421829d62
User: andrej studen CSRF: 737cf34db94a96870325218f639a64f7
User: andrej studen CSRF: 1cc23ba392ff498f2d5bf4d67ffca0a9
User: andrej studen CSRF: 975ab9ea5665016c0e0ce49dcd65780c
User: andrej studen CSRF: b6e8ec797131c9fe72726297a42fd2ea
User: andrej studen CSRF: 612e0d5eba1a9e940b320696cccb8304
User: andrej studen CSRF: ba12deac50bf69b82cf055e1ac302631
User: andrej studen CSRF: 88b7fdb4814f4442fed7ab3bf3e7f8ae
User: andrej studen CSRF: f95cc32b46243554e2e10812215cedb3
User: andrej studen CSRF: dd488484d5d7491dbdb657da60250edf
User: andrej studen CSRF: d818269c6dec47ddbbfddd7a3e17cc6c
User: andrej studen CSRF: 6b3a468a3d0e5d51ce0c005e369b787b
User: andrej studen CSRF: b48ba7a9ab7ea5e261aead00857a39be
User: andrej studen CSRF: 61b8cc1a60cc0618d2b4bf1267a0e02a
User: andrej studen CSRF: 0b7d3ebc8876a169ef5fc1f92e12412c
User: andrej studen CSRF: 8885784efb0b7730dd027c346ca8f6b3
User: andrej studen CSRF: a571c572ba07cf7cc94711b683da847a
User: andrej studen CSRF: fc4e4f3db722b9051ced9a134666c439
User: andrej studen CSRF: 90698920c95287d2a20f3898dbf92a75
User: andrej studen CSRF: 403d971e220822a88029f870440efb48
User: andrej studen CSRF: 04b0b7d180538b9939add86ddd02c334
User: andrej studen CSRF: b6ea921009be3be82c0865286b7cc83b
User: andrej studen CSRF: 66382f86201d2dbde8cfbea9198991c3
User: andrej studen CSRF: aa8ae1a1f9002224238cddf77b8e02ba
User: andrej studen CSRF: 3ddc81c982fa767587710491547c58d8
User: andrej studen CSRF: b78c2f9e29dd8117ef3012c7a7bc7397
User: andrej studen CSRF: 0be6b61aac56c78fec2bd265415e398d
#get fit results

def getPar(fb,project,patientCode,visitCode,ic,ir):
    rPath=['processedImages',patientCode,visitCode]
    opts={'global':'','IVF':'_IVF'}
    fs={x:f'{patientCode}_{visitCode}_{ic}_{ir}{opts[x]}_fitParFinal.txt' for x in opts}
    remotePaths={x:fb.formatPathURL(project,'/'.join([*rPath,fs[x]])) for x in opts}
    retVal={}
    for x in opts:
        if not fb.entryExists(remotePaths[x]):
            print(f'[{x}] Could not load for {patientCode}/{visitCode} {ic} {ir}')
            continue
        
        buffer=fb.readFileToBuffer(remotePaths[x])
        val=buffer.getvalue()
        xval=val.decode(chardet.detect(val)['encoding'])
        xval=re.sub('\n','',xval)
        retVal[x]=[float(y) for y in xval.split('\t')]
    return retVal

def clear(setup,dataset,qPar):
    qFilter=[{'variable':x,'value':'{}'.format(qPar[x]),'oper':'eq'} for x in qPar]
    ds=setup['db'].selectRows(setup['project'],'study',dataset,qFilter)
    if len(ds['rows'])>0:
        ds=setup['db'].modifyRows('delete',setup['project'],'study',dataset,ds['rows'])

def update(setup,dataset,qPar,row,val):
    #qFilter=[{'variable':x,'value':'{}'.format(qPar[x]),'oper':'eq'} for x in qPar]
    #ds=db.selectRows(project,'study',dataset,qFilter)
    
    try:
        debug=setup[dataset]['debug']
    except KeyError:
        debug=False
    if debug:
        print(f'qPar: {qPar}')
    outRow={x:qPar[x] for x in qPar}
    outRow['PatientId']=row['PatientId']
    seqNumOffset=setup[dataset]['count']*setup[dataset]['factor']
    outRow['SequenceNum']=row['SequenceNum']+seqNumOffset
    outRow.update(val)
    
    try:
        setup[dataset]['outRows'].append(outRow)
        if debug:
            print('Adding')
    except KeyError:
        setup[dataset]['outRows']=[outRow]
        if debug:
            print('Setting')
    
    setup[dataset]['count']=setup[dataset]['count']+1
    c=setup[dataset]['count']
    if debug:
        x=setup[dataset]['debug']
        s=outRow['SequenceNum']
        sz=len(setup[dataset]['outRows'])
        last=setup[dataset]['outRows'][0]
        s1=last['SequenceNum']
        print(f'{dataset} count {c} seqNum={s} sz={sz} seqNum(first)={s1}')

        
def upload(setup,dataset,last=False):
    mode='insert'
    rows=setup[dataset]['outRows']
    n=len(rows)
    print(f'Uploading {dataset} with {n} rows')
    try:
        x=setup[dataset]['debug']
        for r in setup[dataset]['outRows']:
            print('{} {}'.format(r['PatientId'],r['SequenceNum']))
    except KeyError:
        pass
    if n==setup['modifyBatch'] or last:
        x=setup['db'].modifyRows(mode,setup['project'],'study',dataset,rows)
        x1=x.decode(chardet.detect(x)['encoding'])
        xval=json.loads(x1)
        try:
            print(xval['exception'])
            print(xval)
        except KeyError:
            pass
        
        setup[dataset]['outRows']=[]

def setGlobalVal(par):
    val={}
    val['chi2']=par[0]
    val['A']=par[1]
    val['tau']=par[2]
    val['alpha']=par[3]
    val['dt']=par[4]
    rTau=max(val['tau'],1/val['alpha'])
    rAlpha=max(1/val['tau'],val['alpha'])
    val['rTau']=rTau
    val['rAlpha']=rAlpha
    return val

def setCenterVal(par,i):
    val={}
    val['k1']=par[4*i+5]
    val['BVF']=par[4*i+6]
    val['k2']=par[4*i+7]
    val['dt']=par[4*i+8]
    return val


def extractFitParameters():
    db=connectDB('labkey-ukc')
    fb=connectFB('labkey-ukc')
    project='/dynamicSPECT/cardiacSPECT'
    dataset='Imaging1'
    idFilter={'variable':'PatientId','value':'MB1965','oper':'eq'}
    ds=db.selectRows(project,'study',dataset,[idFilter])
    rows=ds['rows']
    dataset='fitResults'
    nc=[10,20,30]
    nr=20
    debug=True
    #expect no more than 1000 entries per visit/id pair
    setup={'db':db,'project':project,'modifyBatch':100}
    datasets=['globalFitParameters','centerFitParameters']
    setup['globalFitParameters']={'count':0,'factor':0.01}
    setup['centerFitParameters']={'count':0,'factor':0.0001}
    #setup['globalFitParameters']['debug']=True
    for r in rows:
        qVal=['patientCode','visitCode']
        qPar={x:r[x] for x in qVal}
        visitCode=r['visitCode']
        patientCode=r['patientCode']
        for d in datasets:
            clear(setup,d,qPar)
            setup[d]['count']=0
        for ic in nc:
            #print(f'[{ic}]')
            for ir in range(nr):
                #print(f'\t{ir}')
                qPar.update({'nc':ic,'realizationId':ir})
                
                dataset='globalFitParameters'
                
                qpar=getPar(fb,project,patientCode,visitCode,ic,ir+1)
                qval={x:setGlobalVal(qpar[x]) for x in qpar}
                val=qval['global']
                val['chi2IVF']=qval['IVF']['chi2']
                update(setup,dataset,qPar,r,val)
                for i in range(ic):
                    val=setCenterVal(qpar['IVF'],i)
                    val['file']=f'{patientCode}_{visitCode}_{ic}_{ir+1}_IVF_centers{i+1}.png'
                    dataset='centerFitParameters'
                    qPar1={x:qPar[x] for x in qPar}
                    qPar1['ic']=i
                    update(setup,dataset,qPar1,r,val)
#            if debug:
#                break
        val=setGlobalVal(qpar['IVF'])
        qPar.update({'nc':0,'realizationId':0})
        update(setup,'globalFitParameters',qPar,r,val)
        _tmp=[upload(setup,dataset,True) for dataset in datasets]
        if debug:
            break
        
extractFitParameters()
User: andrej studen CSRF: 2fcf1c21f2bc0fd02e727cc980d41512
User: andrej studen CSRF: ec0ddef0d985b0887827a9c934628186
User: andrej studen CSRF: dc72cad653ea65355b7d9048d3d6914c
User: andrej studen CSRF: b3061712c65aae314fa16540f3654af7
Uploading globalFitParameters with 61 rows
User: andrej studen CSRF: 156e6545790e1a4be8ff209ab04fad51
Uploading centerFitParameters with 1200 rows
User: andrej studen CSRF: 2b82e89d9f8ebfca7563d2473cb4f522