|
@@ -4,13 +4,9 @@ import unittest
|
|
|
import vtk, qt, ctk, slicer
|
|
|
from slicer.ScriptedLoadableModule import *
|
|
|
import logging
|
|
|
-import parseDicom
|
|
|
import vtkInterface as vi
|
|
|
-import fileIO
|
|
|
import slicer
|
|
|
import numpy as np
|
|
|
-import slicerNetwork
|
|
|
-import resample
|
|
|
import json
|
|
|
import re
|
|
|
#
|
|
@@ -51,17 +47,12 @@ class cardiacSPECTWidget(ScriptedLoadableModuleWidget):
|
|
|
ScriptedLoadableModuleWidget.setup(self)
|
|
|
|
|
|
|
|
|
- self.selectRemote=fileIO.remoteFileSelector()
|
|
|
- try:
|
|
|
- self.network=slicer.modules.labkeySlicerPythonExtensionWidget.network
|
|
|
- except:
|
|
|
- self.network=slicerNetwork.labkeyURIHandler()
|
|
|
-
|
|
|
- configFile=os.path.join(os.path.expanduser('~'),'.cardiacSPECT','cardiacSPECT.json')
|
|
|
- self.logic=cardiacSPECTLogic(configFile)
|
|
|
- self.logic.setURIHandler(self.network)
|
|
|
- self.selectRemote.setMaster(self)
|
|
|
-
|
|
|
+ #load config
|
|
|
+ configFile=os.path.join(os.path.expanduser('~'),\
|
|
|
+ '.cardiacSPECT','cardiacSPECT.json')
|
|
|
+ with open(configFile) as f:
|
|
|
+ self.cfg=json.load(f)
|
|
|
+
|
|
|
# Instantiate and connect widgets ...
|
|
|
dataButton = ctk.ctkCollapsibleButton()
|
|
|
dataButton.text = "Data"
|
|
@@ -241,6 +232,9 @@ class cardiacSPECTWidget(ScriptedLoadableModuleWidget):
|
|
|
|
|
|
self.resetPosition=1
|
|
|
|
|
|
+ #add logic aware of all GUI elements on page
|
|
|
+ self.logic=cardiacSPECTLogic(self.cfg)
|
|
|
+
|
|
|
def cleanup(self):
|
|
|
pass
|
|
|
|
|
@@ -404,32 +398,46 @@ class cardiacSPECTLogic(ScriptedLoadableModuleLogic):
|
|
|
"""
|
|
|
def __init__(self,config):
|
|
|
ScriptedLoadableModuleLogic.__init__(self)
|
|
|
+ sconfig=os.path.join(os.path.expanduser('~'),'.labkey','setup.json')
|
|
|
+ with open(sconfig) as f:
|
|
|
+ setup=json.load(f)
|
|
|
+ sys.path.append(setup['paths']['labkeyInterface'])
|
|
|
+ import labkeyInterface
|
|
|
+ import labkeyDatabaseBrowser
|
|
|
+ import labkeyFileBrowser
|
|
|
+
|
|
|
+ self.net=labkeyInterface.labkeyInterface()
|
|
|
+ fconfig=os.path.join(os.path.expanduser('~'),'.labkey','network.json')
|
|
|
+ self.net.init(fconfig)
|
|
|
+ self.db=labkeyDatabaseBrowser.labkeyDB(self.net)
|
|
|
+ self.fb=labkeyFileBrowser.labkeyFileBrowser(self.net)
|
|
|
+
|
|
|
+ sys.path.append(setup['paths']['parseDicom'])
|
|
|
+ import parseDicom
|
|
|
+
|
|
|
self.pd=parseDicom.parseDicomLogic(self)
|
|
|
+ self.pd.setFileBrowser(self.fb)
|
|
|
+
|
|
|
+ sys.path.append(setup['paths']['resample'])
|
|
|
+ import resample
|
|
|
self.resampler=resample.resampleLogic(None)
|
|
|
-
|
|
|
- fname=config
|
|
|
- try:
|
|
|
-
|
|
|
- f=open(fname)
|
|
|
- except OSError as e:
|
|
|
- print "Confgiuration error: OS error({0}): {1}".format(e.errno, e.strerror)
|
|
|
- return
|
|
|
-
|
|
|
- self.cfg=json.load(f)
|
|
|
- self.coreRelativePath=self.cfg["project"]+'/'+self.cfg['atFiles']
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- def setURIHandler(self,net):
|
|
|
- self.net=net
|
|
|
- self.pd.setURIHandler(net)
|
|
|
-
|
|
|
+
|
|
|
+
|
|
|
+ self.tempPath=os.path.join(os.path.expanduser('~'),\
|
|
|
+ 'temp','cardiacSPECT')
|
|
|
+ if not os.path.isdir(self.tempPath):
|
|
|
+ os.makedirs(self.tempPath)
|
|
|
+
|
|
|
+ self.cfg=config
|
|
|
+
|
|
|
def loadData(self,widget):
|
|
|
|
|
|
+ #calculate inputDir from data on form
|
|
|
inputDir=str(widget.dataPath.text)
|
|
|
self.pd.readMasterDirectory(inputDir)
|
|
|
self.frame_data, self.frame_time, self.frame_duration, self.frame_origin, \
|
|
|
- self.frame_pixel_size, self.frame_orientation=self.pd.readNMDirectory(inputDir)
|
|
|
+ self.frame_pixel_size, \
|
|
|
+ self.frame_orientation=self.pd.readNMDirectory(inputDir)
|
|
|
|
|
|
self.ct_data,self.ct_origin,self.ct_pixel_size, \
|
|
|
self.ct_orientation=self.pd.readCTDirectory(inputDir)
|
|
@@ -450,25 +458,26 @@ class cardiacSPECTLogic(ScriptedLoadableModuleLogic):
|
|
|
|
|
|
def getFilespecPath(self,r):
|
|
|
if self.cfg["remote"]==True:
|
|
|
- path=r['_labkeyurl_Series']
|
|
|
- path=path[:path.rfind('/')]
|
|
|
- return "labkey://"+path
|
|
|
+ return self.fb.formatPathURL(self.cfg['project'],\
|
|
|
+ '/'.join(self.cfg['imageDir'],r['Study'],r['Series']))
|
|
|
else:
|
|
|
path=os.path.join(self.cfg["dicomPath"],r["Study"],r["Series"])
|
|
|
- return "file://"+path
|
|
|
+ return path
|
|
|
|
|
|
def loadPatient(self,patientId):
|
|
|
print("Loading {}").format(patientId)
|
|
|
- ds=self.net.loadDataset("dinamic_spect/Patients","Imaging")
|
|
|
- for r in ds['rows']:
|
|
|
- if r['aliasID']==patientId:
|
|
|
- visit=r
|
|
|
+ ds=self.db.selectRows(self.cfg['project'],self.cfg['schemaName'],
|
|
|
+ self.cfg['queryName'])
|
|
|
+ visit=[r for r in ds['rows'] if r['aliasID']==patientId][0]
|
|
|
|
|
|
print visit
|
|
|
- dicoms=self.net.loadDataset("Test/Transfer","Imaging")
|
|
|
+ idFilter={'variable':'PatientId','value':visit['aliasID'],'oper':'eq'}
|
|
|
+ dicoms=self.db.selectRows(self.cfg['transfer']['project'],
|
|
|
+ self.cfg['transfer']['schemaName'],
|
|
|
+ self.cfg['transfer']['queryName'],
|
|
|
+ [idFilter])
|
|
|
+
|
|
|
for r in dicoms['rows']:
|
|
|
- if not r['PatientId']==visit['aliasID']:
|
|
|
- continue
|
|
|
if abs(r['SequenceNum']-float(visit['nmMaster']))<0.1:
|
|
|
masterPath=self.getFilespecPath(r)
|
|
|
#masterPath="labkey://"+path
|
|
@@ -533,13 +542,19 @@ class cardiacSPECTLogic(ScriptedLoadableModuleLogic):
|
|
|
self.loadNode(patientId,'Heart','SegmentationFile')
|
|
|
|
|
|
def loadNode(self,patientId,fName,type,suffix='.nrrd'):
|
|
|
- relativePath=self.coreRelativePath+'/'+patientId
|
|
|
- labkeyFile=relativePath+'/'+fName+suffix
|
|
|
+ remotePath=self.fb.formatPathURL(self.cfg['project'],
|
|
|
+ '/'.join([patientId]))
|
|
|
+ labkeyFile=remotePath+'/'+fName+suffix
|
|
|
+ localFile=os.path.join(self.tempPath+fName+suffix)
|
|
|
+ self.fb.readFileToFile(labkeyFile,localFile)
|
|
|
print ("Remote: {}").format(labkeyFile)
|
|
|
- return self.net.loadNode(labkeyFile,type,returnNode=True)
|
|
|
+ node=slicer.util.loadNodeFromFile(localFile,type)
|
|
|
+ os.remove(localFile)
|
|
|
+ return node
|
|
|
|
|
|
|
|
|
- def addNode(self,nodeName,v, lpsOrigin, pixel_size, lpsOrientation, dataType):
|
|
|
+ def addNode(self,nodeName,v, lpsOrigin, pixel_size, \
|
|
|
+ lpsOrientation, dataType):
|
|
|
|
|
|
# if dataType=0 it is CT data, which gets propagated to background an is
|
|
|
#used to fit the view field dimensions
|
|
@@ -729,7 +744,7 @@ class cardiacSPECTLogic(ScriptedLoadableModuleLogic):
|
|
|
return "NONE"
|
|
|
return segNode.GetSegmentation().GetSegment(segNode.GetSegmentation().GetNthSegmentID(i)).GetName()
|
|
|
|
|
|
- def storeNodeRemote(self,relativePath,nodeName):
|
|
|
+ def storeNodeRemote(self,pathList,nodeName):
|
|
|
|
|
|
node=slicer.mrmlScene.GetFirstNodeByName(nodeName)
|
|
|
if node==None:
|
|
@@ -745,47 +760,33 @@ class cardiacSPECTLogic(ScriptedLoadableModuleLogic):
|
|
|
|
|
|
fileName=nodeName+suffix
|
|
|
|
|
|
- localPath=self.getLocalPath(relativePath)
|
|
|
- if not os.path.isdir(localPath):
|
|
|
- os.mkdir(localPath)
|
|
|
+ localPath=os.path.join(self.tempPath,fileName)
|
|
|
|
|
|
file=os.path.join(localPath,fileName)
|
|
|
slicer.util.saveNode(node,file)
|
|
|
print("Stored to: {}").format(file)
|
|
|
if self.cfg["remote"]:
|
|
|
- labkeyPath=self.pd.net.GetLabkeyPathFromRelativePath(relativePath)
|
|
|
+ labkeyPath=self.fb.buildPathURL(self.cfg['project'],pathList)
|
|
|
print ("Remote: {}").format(labkeyPath)
|
|
|
#checks if exists
|
|
|
- self.pd.net.mkdir(labkeyPath)
|
|
|
remoteFile=labkeyPath+'/'+fileName
|
|
|
- f=open(file,"rb")
|
|
|
- self.pd.net.put(remoteFile,f.read())
|
|
|
-
|
|
|
- def getLocalPath(self,relativePath):
|
|
|
- if self.cfg["remote"]:
|
|
|
- localPath=self.pd.net.GetLocalPathFromRelativePath(relativePath)
|
|
|
- localPath.replace('/',os.path.sep)
|
|
|
- return localPath
|
|
|
-
|
|
|
- localPath=os.path.join(self.cfg["labkeyBase"],relativePath)
|
|
|
- return localPath
|
|
|
-
|
|
|
+ self.fb.writeFileToFile(localPath,remoteFile)
|
|
|
|
|
|
def storeVolumeNodes(self,patientId,n1,n2):
|
|
|
#n1=self.time_frame.minimum;
|
|
|
#n2=self.time_frame.maximum
|
|
|
- relativePath=self.coreRelativePath+'/'+patientId
|
|
|
+ pathList=[patientId]
|
|
|
|
|
|
print("Store CT")
|
|
|
nodeName=patientId+'CT'
|
|
|
|
|
|
- self.storeNodeRemote(relativePath,nodeName)
|
|
|
+ self.storeNodeRemote(pathList,nodeName)
|
|
|
|
|
|
#prefer resampled
|
|
|
testNode=slicer.util.getFirstNodeByName(nodeName+"_RS")
|
|
|
if testNode:
|
|
|
nodeName=nodeName+"_RS"
|
|
|
- self.storeNodeRemote(relativePath,nodeName)
|
|
|
+ self.storeNodeRemote(pathList,nodeName)
|
|
|
|
|
|
print("Storing NM from {} to {}").format(n1,n2)
|
|
|
n=n2-n1+1
|
|
@@ -793,35 +794,35 @@ class cardiacSPECTLogic(ScriptedLoadableModuleLogic):
|
|
|
it=i+n1
|
|
|
nodeName=patientId+'Volume'+str(it)
|
|
|
|
|
|
- self.storeNodeRemote(relativePath,nodeName)
|
|
|
+ self.storeNodeRemote(pathList,nodeName)
|
|
|
|
|
|
#add resampled
|
|
|
testNode=slicer.util.getFirstNodeByName(nodeName+"_RS")
|
|
|
if testNode:
|
|
|
nodeName=nodeName+"_RS"
|
|
|
- self.storeNodeRemote(relativePath,nodeName)
|
|
|
+ self.storeNodeRemote(pathList,nodeName)
|
|
|
|
|
|
self.storeDummyInputFunction(patientId)
|
|
|
|
|
|
def storeSegmentation(self,patientId):
|
|
|
- relativePath=self.coreRelativePath+'/'+patientId
|
|
|
+ pathList=[patientId]
|
|
|
segNodeName="Heart"
|
|
|
- self.storeNodeRemote(relativePath,segNodeName)
|
|
|
+ self.storeNodeRemote(pathList,segNodeName)
|
|
|
|
|
|
def storeInputFunction(self,patientId):
|
|
|
self.calculateInputFunction(patientId)
|
|
|
- relativePath=self.coreRelativePath+'/'+patientId
|
|
|
+ relativePath=[patientId]
|
|
|
doubleArrayNodeName=patientId+'_Ventricle'
|
|
|
self.storeNodeRemote(relativePath,doubleArrayNodeName)
|
|
|
|
|
|
def storeDummyInputFunction(self,patientId):
|
|
|
self.calculateDummyInputFunction(patientId)
|
|
|
- relativePath=self.coreRelativePath+'/'+patientId
|
|
|
+ relativePath=[patientId]
|
|
|
doubleArrayNodeName=patientId+'_Dummy'
|
|
|
self.storeNodeRemote(relativePath,doubleArrayNodeName)
|
|
|
|
|
|
def storeTransformation(self,patientId):
|
|
|
- relativePath=self.coreRelativePath+'/'+patientId
|
|
|
+ relativePath=[patientId]
|
|
|
transformNodeName=patientId+"_DF"
|
|
|
self.storeNodeRemote(relativePath,transformNodeName)
|
|
|
|