def __init__(self, fig=None, filename=None, dirsave=None, fileformat='avi', frameRate=None): """ fig or axes can be given. gif swf or avi possible framerate to save depends on graphics card pc. default is 10fps, if faster than real world, use 5-7fps """ # import os # import imageio # import visvis as vv # import datetime # from stentseg.utils.datahandling import select_dir # self.os = os # self.imageio = imageio # self.vv = vv # self.datetime = datetime self.r = None self.frameRate = frameRate if fig is None: self.fig = vv.gcf() else: self.fig = fig self.filename = filename self.fileformat = fileformat if dirsave is None: self.dirsave = select_dir(r'C:\Users\Maaike\Desktop', r'D:\Profiles\koenradesma\Desktop') else: self.dirsave = dirsave print( '"recordMovie" active, use r (rec), t (stop), y (continue), m (save), q (clear)' ) # Bind eventhandler record self.fig.eventKeyUp.Bind(self.record)
""" Load static CT data and save to ssdf format """ import os import sys import imageio from stentseg.utils.datahandling import select_dir, loadvol from stentseg.utils.datahandling import savecropvols, saveaveraged # Select base directory for LOADING DICOM data # The stentseg datahandling module is agnostic about where the DICOM data is dicom_basedir = select_dir(r'G:\LSPEAS_data', r'D:\LSPEAS\LSPEAS_data_BACKUP') # Select base directory to SAVE SSDF ssdf_basedir = select_dir(r'D:\LSPEAS\LSPEAS_ssdf', r'F:\LSPEAS_ssdf_toPC', r'G:\LSPEAS_ssdf_toPC') ptcode = 'LSPEAS_022_CTA_20160126' # ctcode = 'S40' # 'CTA_pre', 'static..' stenttype = 'anaconda' # Set which crops to save cropnames = ['ring'] # ['prox'] or ['ring','stent'] or .. # Step A: read single volume if ctcode == 'CTA_pre': vol = imageio.volread(os.path.join(dicom_basedir, ctcode, ptcode), 'dicom')
return abs_errors_profiles def read_ampl_errorcam123(exceldir, workbook, profile): wb = openpyxl.load_workbook(os.path.join(exceldir, workbook), data_only=True) sheet = wb.get_sheet_by_name(profile) phaserow = 58 - 1 # 58 for 58; 60 for 60 errors = sheet.rows[phaserow][1:] # skip first col with notes errors = [obj.value for obj in errors if obj.value is not None] return errors exceldir = select_dir( r'C:\Users\Maaike\Dropbox\UTdrive\LSPEAS\Analysis\Validation robot', r'D:\Profiles\koenradesma\Dropbox\UTdrive\LSPEAS\Analysis\Validation robot' ) workbook = 'Errors cam123ref_vs_alg Toshiba.xlsx' workbookF = 'Errors cam123ref_vs_alg Siemens.xlsx' ## test over all 10 positions prof = 'ZA1' abs_errors_T_x = read_error_cam123(exceldir, workbook, [prof]) abs_errors_F_x = read_error_cam123(exceldir, workbookF, [prof]) t2, p2 = paired_samples_ttest(abs_errors_T_x, abs_errors_F_x, prof) prof = 'ZA2' abs_errors_T_x = read_error_cam123(exceldir, workbook, [prof]) abs_errors_F_x = read_error_cam123(exceldir, workbookF, [prof])
from stentseg.utils import _utils_GUI, PointSet from stentseg.utils.picker import pick3d from stentseg.utils.centerline import find_centerline, points_from_mesh, smooth_centerline, dist_over_centerline from lspeas.analysis.utils_analysis import ExcelAnalysis from stentseg.utils.utils_graphs_pointsets import point_in_pointcloud_closest_to_p #sys.path.insert(0, os.path.abspath('..')) # parent, 2 folders further in pythonPath #import utils_analysis #from utils_analysis import ExcelAnalysis #import get_anaconda_ringparts from lspeas.utils.get_anaconda_ringparts import _get_model_hooks, get_midpoints_peaksvalleys, identify_peaks_valleys #todo: from outline to script: ## Initialize # select the ssdf basedir basedir = select_dir(r'F/LSPEAS\LSPEAS_ssdf', r'F/LSPEAS_ssdf_backup') basedirstl = select_dir( r'D:\Profiles\koenradesma\Dropbox\UTdrive\MedDataMimics\LSPEAS_Mimics\Tests' ) # select dataset ptcode = 'LSPEAS_003' ctcodes = ctcode1, ctcode2 = 'discharge', '12months' # ctcode2 = None if no second code cropname = 'ring' modelname = 'modelavgreg' vesselname1 = 'LSPEAS_003_D_MK Smoothed_Wrapped1.0_edit-smart 4_copy_001.stl' # LSPEAS_003_D_MK Smoothed_Wrapped1.0_edit-smart 4_copy_noRenals 7_001 vesselname2 = 'LSPEAS_003_12M_MK Smoothed_Wrapped1.0_smart 3_copy_001.stl' sheet_renals_obs = 'renal locations obs1'
import numpy as np from stentseg.utils import PointSet, _utils_GUI, visualization from stentseg.stentdirect import stentgraph from visvis import ssdf from stentseg.utils.picker import pick3d, label2worldcoordinates from stentseg.stentdirect import StentDirect, getDefaultParams from stentseg.utils.visualization import DrawModelAxes from lspeas.landmarks.landmarkselection import (saveLandmarkModel, LandmarkSelector, makeLandmarkModelDynamic) # Select the ssdf basedir basedir = select_dir( r'D:\LSPEAS\LSPEAS_ssdf', r'F:\LSPEAS_ssdf_BACKUP', r'G:\LSPEAS_ssdf_BACKUP', r'E:\Maaike-Freija\LSPEAS_ssdf_backup', r'D:\Maaike-Freija\LSPEAS_ssdf_backup', ) # Select location storeOutputTemplate EXCEL file exceldir = select_dir( r'C:\Users\Maaike\Desktop', r'D:\Profiles\koenradesma\Desktop', ) dirsave = select_dir( r'G:\LSPEAS_ssdf_toPC\landmarks', r'D:\Profiles\koenradesma\SURFdrive\UTdrive\LSPEAS\Analysis\Landmark Validation\phantom_article\ssdf', r'C:\Users\Maaike\SURFdrive\UTdrive\LSPEAS\Analysis\Landmark Validation\phantom_article\ssdf' )
import time import numpy as np import networkx import visvis as vv from visvis import ssdf import os from stentseg.stentdirect import StentDirect, StentDirect_old, getDefaultParams, stentgraph from stentseg.stentdirect.stentgraph import create_mesh from stentseg.utils.datahandling import select_dir, loadvol # Automatically select basedir for ssdf data basedir = select_dir( os.getenv('LSPEAS_BASEDIR', ''), r'C:\Users\Maaike\Documents\UT MA3\LSPEAS_ssdf', ) # Set params to load the data ptcode = 'LSPEAS_003' ctcode = 'discharge' cropname = 'ring' what = 'avg3090' # Load volume data s = loadvol(basedir, ptcode, ctcode, cropname, what) vol = s.vol ##
""" Show deform grid and checkerboard of 2d registration Nellix data """ import os, time import numpy as np import visvis as vv import pirt.reg # Python Image Registration Toolkit from stentseg.utils.datahandling import select_dir, loadvol import scipy from scipy import ndimage from lspeas.utils.vis_grid_deform import imagePooper # Select the ssdf basedir basedir = select_dir(r'E:\Nellix_chevas\CT_SSDF\SSDF_automated', r'D:\Nellix_chevas_BACKUP\CT_SSDF\SSDF_automated') # Select dataset to register ptcode = 'chevas_10' ctcode, nr = '12months', 1 cropname = 'prox' # Select dataset to register what = 'phases' phase1 = 3 # 30% phase2 = 9 # 90% slice = None #70 slicey = 107 # Load volumes
elif j == 10: # write 1D array distances worksheet.write_column(rowstart, 3, variable) elif j == 11: # write comment for max pulsatility worksheet.write_string(rowoffset, 1, variable) rowoffset += 2 # add rowspace for next analysis Output # Store screenshot of stent #vv.screenshot(r'C:\Users\Maaike\Desktop\storeScreenshot.png', vv.gcf(), sf=2) workbook.close() if __name__ == '__main__': # Select the ssdf basedir basedir = select_dir(os.getenv('LSPEAS_BASEDIR', ''), r'D:\LSPEAS\LSPEAS_ssdf', r'F:\LSPEAS_ssdf_backup',r'G:\LSPEAS_ssdf_backup') # Select location storeOutputTemplate EXCEL file exceldir = select_dir(r'C:\Users\Maaike\Desktop', r'D:\Profiles\koenradesma\Desktop') # Select dataset to register ptcode = 'LSPEAS_023' ctcode = '24months' cropname = 'ring' modelname = 'modelavgreg' # Load static CT image to add as reference s = loadvol(basedir, ptcode, ctcode, cropname, 'avgreg') vol = s.vol
from stentseg.utils import PointSet, _utils_GUI, visualization from stentseg.utils.datahandling import select_dir, loadvol, loadmodel from stentseg.stentdirect import stentgraph, getDefaultParams, initStentDirect from stentseg.utils.picker import pick3d, get_picked_seed from stentseg.utils.visualization import DrawModelAxes from stentseg.utils.visualization import show_ctvolume from stentseg.stentdirect.stentgraph import create_mesh from stentseg.utils.utils_graphs_pointsets import points_from_edges_in_graph from stentseg.utils.centerline import points_from_nodes_in_graph from stentseg.utils.datahandling import select_dir, loadvol, loadmodel # Select the ssdf basedir basedir = select_dir(os.getenv('LSPEAS_BASEDIR', ''), r'D:\LSPEAS\LSPEAS_ssdf', r'E:\LSPEAS_ssdf_backup',r'G:\LSPEAS_ssdf_backup') targetdir = select_dir(r'C:\Users\Gebruiker\Google Drive\Afstuderen\Rings') targetdir1 = select_dir(r'C:\Users\Gebruiker\Dropbox\M3 Vaatchirurgie Enschede\Py_analysis', r'C:\Users\Gebruiker\Dropbox\LSPEAS Stages-gedeelde map\M3_20180106_Jaimy\Distances rings 30072018') basedir1 = select_dir(r'C:\Users\Gebruiker\Google Drive\Afstuderen\Rings',r'C:\Users\Gebruiker\Dropbox\LSPEAS Stages-gedeelde map\M3_20180106_Jaimy\Distances rings 30072018') basedir2 = select_dir(r'E:\LSPEAS_ssdf_backup') # Select dataset to register ptcode = 'LSPEAS_008' ctcode = 'discharge' cropname = 'stent' n = 26 # number of rings what = 'avgreg' # avgreg normalize = True
origin = [0, 34.087, 71.238] #s.origin # sampling2 = (1,1,1) # ground truth sampling from Matlab (width_pixel=1) #todo: in matlab set pixel_width DataDressed/DataDressedInterpolated with dicom sampling for realistic registration?! origin2 = (0, 0, 0) # ====================================================== savemat = True visualize = True reg2d = False # Load the mat files with original and deformed volumes matpath = select_dir( #r'F:\LSPEAS_insilico_mat', (r'D:\Profiles\koenradesma\SURFdrive\UTdrive\LSPEAS\In silico validation' r'\translation_Geurts_2019-02-08\translation\LSPEAS_insilico_mat'), (r'C:\Users\Maaike\SURFdrive\UTdrive\LSPEAS\In silico validation' r'\translation_Geurts_2019-02-08\translation\LSPEAS_insilico_mat'), #r'/Users/geurtsbj/ownCloud/research/articles/maaike/registration_sensitivity/registration_assessment/LSPEAS_insilico_mat', r'/Users/geurtsbj/ownCloud/research/articles/maaike/registration_sensitivity_cases/translation/LSPEAS_insilico_mat' ) #savelocation regpath = select_dir( #r'F:\LSPEAS_insilico_ssdf', (r'D:\Profiles\koenradesma\SURFdrive\UTdrive\LSPEAS\In silico validation' r'\translation_Geurts_2019-02-08\translation\LSPEAS_insilico_ssdf'), (r'C:\Users\Maaike\SURFdrive\UTdrive\LSPEAS\In silico validation' r'\translation_Geurts_2019-02-08\translation\LSPEAS_insilico_ssdf'), #r'/Users/geurtsbj/ownCloud/research/articles/maaike/registration_sensitivity/registration_assessment/LSPEAS_insilico_ssdf/reg1', r'/Users/geurtsbj/ownCloud/research/articles/maaike/registration_sensitivity_cases/translation/LSPEAS_insilico_ssdf' )
## TESTING if __name__ == "__main__": import os import numpy as np import visvis as vv from visvis import ssdf from stentseg.utils.datahandling import select_dir, loadvol, loadmodel from stentseg.utils.picker import pick3d cropname = 'prox' what = 'avgreg' ptcode = 'chevas_01' ctcode = '12months' basedir = select_dir(r'F:\Nellix_chevas\CT_SSDF\SSDF_automated') # Load volumes s = loadvol(basedir, ptcode, ctcode, cropname, what) # sampling was not properly stored after registration for all cases: reset sampling vol_org = copy.deepcopy(s.vol) s.vol.sampling = [ vol_org.sampling[1], vol_org.sampling[1], vol_org.sampling[2] ] # z,y,x s.sampling = s.vol.sampling vol = s.vol ## Get isosurface verts, faces, pp_vertices, mesh = get_isosurface3d(vol, threshold=300,
def on_key(event): """KEY commands for user interaction 'UP/DOWN = show/hide nodes' 'DELETE = remove edge [select 2 nodes] or pop node [select 1 node] ' 'or remove seed in nodes1 closest to [picked point]' 'PageDown = remove graph posterior (y-axis) to [picked point] (use for spine seeds)' 'ALT = clean graph: remove residual clusters, pop, corner' 'CTRL+SHIFT = add [picked point] (SHIFT+R-click) as seed' """ global label global node_points global sd if event.key == vv.KEY_DOWN: # hide nodes t1.visible = False t2.visible = False t3.visible = False for node_point in node_points: node_point.visible = False if event.key == vv.KEY_UP: # show nodes for node_point in node_points: node_point.visible = True if event.key == vv.KEY_DELETE: if len(selected_nodes) == 0: # remove node closest to picked point node = _utils_GUI.snap_picked_point_to_graph(sd._nodes1, vol, label, nodesOnly=True) sd._nodes1.remove_node(node) view = a1.GetView() a1.Clear() label = DrawModelAxes(vol, sd._nodes1, a1, clim=clim, showVol=showVol, removeStent=False) a1.SetView(view) if len(selected_nodes) == 2: # remove edge select1 = selected_nodes[0].node select2 = selected_nodes[1].node c = sd._nodes3.edge[select1][select2]['cost'] ct = sd._nodes3.edge[select1][select2]['ctvalue'] path = sd._nodes3.edge[select1][select2]['path'] l = stentgraph._edge_length(sd._nodes3, select1, select2) sd._nodes3.remove_edge(select1, select2) stentgraph.pop_nodes(sd._nodes3) # pop residual nodes # Visualize removed edge, show keys and deselect nodes selected_nodes[1].faceColor = 'b' selected_nodes[0].faceColor = 'b' selected_nodes.clear() t1.text = 'Edge ctvalue: \b{%1.2f HU}' % ct t2.text = 'Edge cost: \b{%1.7f }' % c t3.text = 'Edge length: \b{%1.2f mm}' % l t1.visible = True t2.visible = True t3.visible = True view = a3.GetView() pp = Pointset(path) line = vv.solidLine(pp, radius=0.2) line.faceColor = 'r' # a3.SetView(view) if len(selected_nodes) == 1: # pop node select1 = selected_nodes[0].node stentgraph._pop_node(sd._nodes3, select1) # asserts degree == 2 selected_nodes[0].faceColor = 'w' selected_nodes.clear() if event.key == vv.KEY_ALT: # ALT will FINISH model stentgraph.prune_clusters(sd._nodes3, 3) #remove residual nodes/clusters stentgraph.pop_nodes(sd._nodes3) stentgraph.add_corner_nodes(sd._nodes3, th=sd._params.graph_angleVector, angTh=sd._params.graph_angleTh) # Create mesh and visualize view = a3.GetView() a3.Clear() DrawModelAxes(vol, sd._nodes3, a3, meshColor=meshColor, clim=clim, showVol=showVol, lc='b', mw=8, lw=0.2) _utils_GUI.vis_spared_edges(sd._nodes3) a3.SetView(view) print( '----DO NOT FORGET TO SAVE THE MODEL TO DISK; RUN _SAVE_SEGMENTATION----' ) if event.text == 'n': # add picked seed to nodes_1 coord2 = get_picked_seed(vol, label) sd._nodes1.add_node(tuple(coord2)) view = a1.GetView() point = vv.plot(coord2[0], coord2[1], coord2[2], mc='b', ms='o', mw=8, alpha=0.5, axes=a1) a1.SetView(view) if event.text == 'p': # protect node from pop pickedNode = _utils_GUI.snap_picked_point_to_graph(sd._nodes1, vol, label, nodesOnly=True) sd._nodes1.add_node(pickedNode, nopop=True) sd._nodes2.add_node(pickedNode, nopop=True) view = a1.GetView() point = vv.plot(pickedNode[0], pickedNode[1], pickedNode[2], mc='y', ms='o', mw=8, alpha=0.5, axes=a1) a1.SetView(view) # now rerun step 3 if event.key == vv.KEY_PAGEDOWN: # remove false seeds posterior to picked point, e.g. for spine try: _utils_GUI.remove_nodes_by_selected_point(sd._nodes3, vol, a3, label, clim, showVol=showVol) except ValueError: # false nodes already cleaned by Step3 pass _utils_GUI.remove_nodes_by_selected_point(sd._nodes2, vol, a2, label, clim, showVol=showVol) label = _utils_GUI.remove_nodes_by_selected_point(sd._nodes1, vol, a1, label, clim, showVol=showVol) if event.text == '1': # redo step1 view = a1.GetView() a1.Clear() a2.Clear() a3.Clear() sd._params = p sd.Step1() label = DrawModelAxes(vol, sd._nodes1, a1, clim=clim, showVol=showVol, removeStent=False) # lc, mc a1.SetView(view) if event.text == '2': # redo step2 and 3 view = a2.GetView() a2.Clear() a3.Clear() sd._params = p sd.Step2() sd.Step3(cleanNodes=cleanNodes) DrawModelAxes(vol, sd._nodes2, a2, clim=clim, showVol=showVol, removeStent=False) DrawModelAxes(vol, sd._nodes3, a3, meshColor=meshColor, clim=clim, showVol=showVol, removeStent=False) a2.SetView(view) if event.text == '3': view = a3.GetView() a3.Clear() sd._params = p sd.Step3(cleanNodes=cleanNodes) DrawModelAxes(vol, sd._nodes3, a3, meshColor=meshColor, clim=clim, showVol=showVol, removeStent=False) node_points = _utils_GUI.interactive_node_points(sd._nodes3, scale=0.6) _utils_GUI.node_points_callbacks(node_points, selected_nodes, pick=False) a3.SetView(view) if event.text == 's': # SAVE SEGMENTATION # make centerline points of segmentation paths_as_pp = points_from_edges_in_graph(sd._nodes3, type='order') ringpoints = paths_as_pp[0].T # Get graph model model = sd._nodes3 seeds = sd._nodes1 Draw = sd.Draw # Build struct s2 = vv.ssdf.new() # We do not need croprange, but keep for reference s2.sampling = s.sampling s2.origin = s.origin s2.stenttype = s.stenttype s2.croprange = s.croprange for key in dir(s): if key.startswith('meta'): suffix = key[4:] s2['meta' + suffix] = s['meta' + suffix] s2.what = what s2.params = p s2.stentType = stentType # Store model s2.model = model.pack() s2.seeds = seeds.pack() s2.Draw = Draw s2.ringpoints = ringpoints #s2.mesh = ssdf.new() # Save savedir = select_dir( r'C:\Users\Gebruiker\Google Drive\Afstuderen\Rings') filename = '%s_%s_%s_%s_%s.ssdf' % (ptcode, ctcode, cropname, 'model' + what, ring) ssdf.save(os.path.join(savedir, filename), s2) print('saved to disk in {} as {}.'.format(savedir, filename))
import numpy as np import visvis as vv from visvis import ssdf from visvis import Pointset import scipy.io from stentseg.utils import PointSet, _utils_GUI, visualization from stentseg.utils.datahandling import select_dir, loadvol, loadmodel from stentseg.stentdirect import stentgraph, getDefaultParams, initStentDirect from stentseg.utils.picker import pick3d, get_picked_seed from stentseg.utils.visualization import DrawModelAxes from stentseg.utils.utils_graphs_pointsets import points_from_edges_in_graph from stentseg.utils.centerline import points_from_nodes_in_graph # Select the ssdf basedir basedir = select_dir(os.getenv('LSPEAS_BASEDIR', ''), r'D:\LSPEAS\LSPEAS_ssdf', r'E:\LSPEAS_ssdf_backup', r'G:\LSPEAS_ssdf_backup') targetdir = select_dir(r'C:\Users\Gebruiker\Google Drive\Afstuderen\Rings') # Select dataset to register ptcode = 'LSPEAS_008' ctcode = 'discharge' ring = 'ringR26' # side and number of ring segmented (from proximal) cropname = 'stent' what = 'avgreg' # avgreg normalize = True # Load volumes s = loadvol(basedir, ptcode, ctcode, cropname, what) vol = s.vol # h = vv.hist(vol, bins = 1000)
""" import os import visvis as vv from stentseg.utils.datahandling import select_dir, loadvol, loadmodel from stentseg.utils.visualization import show_ctvolume, DrawModelAxes from stentseg.stentdirect.stentgraph import create_mesh from stentseg.motion.vis import create_mesh_with_abs_displacement from lspeas.utils.get_anaconda_ringparts import get_model_struts, get_model_rings from stentseg.utils.utils_graphs_pointsets import get_graph_in_phase from stentseg.utils import _utils_GUI from stentseg.utils.picker import pick3d # Select the ssdf basedir basedir = select_dir(r'D:\LSPEAS\LSPEAS_ssdf', r'F:\LSPEAS_ssdf_backup', r'G:\LSPEAS_ssdf_backup') # Select dataset to register ptcode = 'LSPEAS_020' # codes = ctcode1, ctcode2, ctcode3 = 'discharge', '1month', '6months' # codes = ctcode1, ctcode2 = 'discharge', '1month' codes = ctcode1 = 'discharge' cropname = 'ring' modelname = 'modelavgreg' ringnames = ['modelR1'] # ['modelR1', 'modelR2'] or ['model'] showVol = 'ISO' # MIP or ISO or 2D or None phases = range(10) # range(10) for all 10 phases; [3,9] for 30% and 90% showmodelavgreg = True # show also model in avgreg at mid cycle? showvol = True removeStent = True
import os import numpy as np import visvis as vv from visvis import ssdf from visvis import Pointset from stentseg.utils import PointSet, _utils_GUI, visualization from stentseg.utils.datahandling import select_dir, loadvol, loadmodel from stentseg.stentdirect import stentgraph, getDefaultParams, initStentDirect from stentseg.utils.picker import pick3d, get_picked_seed, label2worldcoordinates from stentseg.utils.visualization import DrawModelAxes from stentseg.utils.visualization import show_ctvolume # Select the ssdf basedir basedir = select_dir(os.getenv('LSPEAS_BASEDIR', ''), r'D:\LSPEAS\LSPEAS_ssdf', r'F:\LSPEAS_ssdf_backup', r'G:\LSPEAS_ssdf_backup') dirsave = select_dir( r'D:\Profiles\koenradesma\SURFdrive\UTdrive\LSPEAS\Analysis\Leg angulation', r'C:\Users\Maaike\SURFdrive\UTdrive\LSPEAS\Analysis\Leg angulation') # Select dataset to register ptcode = 'LSPEAS_021' ctcode = '6months' cropname = 'stent' what = 'avgreg' # avgreg normalize = True # Load volumes s = loadvol(basedir, ptcode, ctcode, cropname, what) vol = s.vol
""" Show the vessel in motion, based on segmentated 3D mesh model. Input: stl of vessel, avgreg and deforms """ import os import imageio import visvis as vv from stentseg.utils.datahandling import select_dir, loadvol import pirt from pirt.utils.deformvis import DeformableTexture3D, DeformableMesh import numpy as np # Select the ssdf basedir basedir = select_dir(os.getenv('LSPEAS_BASEDIR', ''), r'D:\LSPEAS\LSPEAS_ssdf', r'F:\LSPEAS_ssdf_backup') # Select dataset to register ptcode = 'LSPEAS_002' # ctcode, nr = 'discharge', 1 ctcode, nr = 'pre', 2 cropname = 'stent' meshfile = 'LSPEAS_002_Smoothed5x0.8_Wrapped5mm_plus r renalis2 9_001.stl' # Load ssdf s = loadvol(basedir, ptcode, ctcode, cropname, 'avgreg') volavg = s.vol origin = volavg.origin # z y x # Load deformations (apply forward for mesh) s = loadvol(basedir, ptcode, ctcode, cropname, 'deforms') deforms = [s['deform%i' % (i * 10)] for i in range(10)]
""" Make centerline dynamic with deformation fields from registration and store Input: ssdf and mat of centerline Output: ssdf and mat of centerline stored as _dynamic; deforms are added as var """ import pirt from stentseg.motion.dynamic import incorporate_motion_nodes, incorporate_motion_edges from visvis import ssdf import os import scipy.io from stentseg.utils.datahandling import select_dir, loadvol, loadmodel # Select the ssdf basedir basedir = select_dir(r'D:\LSPEAS\LSPEAS_ssdf', r'F:\LSPEAS_ssdf_backup', r'G:\LSPEAS_ssdf_backup') basedirstl = select_dir( r'D:\Profiles\koenradesma\SURFdrive\UTdrive\LSPEAS\Analysis\Leg angulation', r'C:\Users\Maaike\SURFdrive\UTdrive\LSPEAS\Analysis\Leg angulation') # Select dataset ptcode = 'LSPEAS_008' ctcode = 'discharge' cropname = 'stent' what = 'centerline' # Load deforms s = loadvol(basedir, ptcode, ctcode, cropname, 'deforms') deformkeys = [] for key in dir(s): if key.startswith('deform'): deformkeys.append(key)
centerlineZ = np.asarray(coordz, dtype=np.float32) centerlineZ = np.flip(centerlineZ, axis=0) # z of volume is also flipped # convert centerline coordinates to world coordinates (mm) origin = vol1.origin # z,y,x sampling = vol1.sampling # z,y,x centerlineX = centerlineX * sampling[2] + origin[2] centerlineY = centerlineY * sampling[1] + origin[1] centerlineZ = (centerlineZ - 0.5 * vol1.shape[0]) * sampling[0] + origin[0] return centerlineX, centerlineY, centerlineZ # Select the ssdf basedir basedir = select_dir(os.getenv('LSPEAS_BASEDIR', ''), r'D:\LSPEAS\LSPEAS_ssdf', r'F:\LSPEAS_ssdf_backup', r'F:\LSPEAS_ssdf_BACKUP') basedirMesh = select_dir( r'D:\Profiles\koenradesma\SURFdrive\UTdrive\MedDataMimics\LSPEAS_Mimics', r'C:\Users\Maaike\SURFdrive\UTdrive\MedDataMimics\LSPEAS_Mimics', r"C:\stack\data\lspeas\vaatwand") basedirCenterline = select_dir( r"C:\stack\data\lspeas\vaatwand", r'D:\Profiles\koenradesma\SURFdrive\UTdrive\LSPEAS_centerlines_terarecon', r'C:\Users\Maaike\SURFdrive\UTdrive\LSPEAS_centerlines_terarecon', r"C:\stack\data\lspeas\vaatwand") # Select dataset ptcode = 'LSPEAS_003' ctcode1 = 'discharge'
# Load the stent model and mesh s = loadmodel(basedir, ptcode, ctcode, cropname, modelname) model = s.model mesh = create_mesh(model, 0.4) # Param is thickness (with 0.4 -> ~0.75mm diam) mesh._vertices[:,-1] *= -1 # flip z, negative in original dicom mesh._normals[:,-1] *= -1 # flip also normals to change front face and back face along vv.meshWrite(os.path.join(savedir, filename),mesh) if __name__ == '__main__': import os import visvis as vv from stentseg.utils.datahandling import select_dir, loadvol, loadmodel # Select the ssdf basedir basedir = select_dir(r'D:\LSPEAS\LSPEAS_ssdf', r'F:\LSPEAS_ssdf_backup',r'G:\LSPEAS_ssdf_backup') # Dir to save mesh savedir = select_dir(r'D:\LSPEAS\LSPEAS_mesh_ring', r'C:\Users\Maaike\Desktop\tempmeshring') # Select dataset to register # ptcodes = ['LSPEAS_001','LSPEAS_002','LSPEAS_003','LSPEAS_005','LSPEAS_008', # 'LSPEAS_009','LSPEAS_011','LSPEAS_015','LSPEAS_017','LSPEAS_018', # 'LSPEAS_019','LSPEAS_020','LSPEAS_021','LSPEAS_022','LSPEAS_025', # 'LSPEAS_023', 'LSPEAS_004'] # ptcodes = ['LSPEAS_001','LSPEAS_002','LSPEAS_003','LSPEAS_005','LSPEAS_008', # 'LSPEAS_009','LSPEAS_011','LSPEAS_017', # 'LSPEAS_019','LSPEAS_020','LSPEAS_021' # ] ptcodes = ['LSPEAS_003'] ctcode = '1month'
class PlotRingDynamics(): """ Read the stored mat files """ filedir = select_dir( r'C:\Users\Maaike\SURFdrive\UTdrive\LSPEAS\Analysis\Ring motion\matfiles_from_readsheets_python', r'D:\Profiles\koenradesma\SURFdrive\UTdrive\LSPEAS\Analysis\Ring motion\matfiles_from_readsheets_python' ) dirsaveIm = select_dir(r'C:\Users\Maaike\Desktop', 'D:\Profiles\koenradesma\Desktop') def __init__(self): self.filedir = PlotRingDynamics.filedir self.dirsaveIm = PlotRingDynamics.dirsaveIm self.folderringdynamics = '_get_ring_dynamics' self.folderringmotion = '_plot_ring_motion' self.fontsize1 = 17 # self.fontsize2 = 16 # self.fontsize3 = 13 # legend title self.fontsize4 = 10 # legend contents self.fontsize5 = 14 # xticks self.fontsize6 = 15 # ylabel self.colorsdirections = [ # from phantom paper in vivo plots 'k', '#d73027', # 1 red '#fc8d59', # orange '#91bfdb', # blue '#4575b4' # 5 ] def plot_displacement_mean_over_time(self, ylim=[0, 2], saveFig=False, showlegend=True): """ Plot mean displacement rings for full ring and all 4 directions using the mean of the patients """ # init figure f1 = plt.figure(figsize=(10, 9)) # from 11.6 to 10 to place legend xlabels = ['D', '1M', '6M', '12M', '24M'] xrange = range( 1, 1 + len(xlabels)) # not start from x=0 to play with margin xlim # init axis ax1 = f1.add_subplot(3, 2, 1) plt.xticks(xrange, xlabels, fontsize=self.fontsize5) ax2 = f1.add_subplot(3, 2, 2) plt.xticks(xrange, xlabels, fontsize=self.fontsize5) ax3 = f1.add_subplot(3, 2, 3) plt.xticks(xrange, xlabels, fontsize=self.fontsize5) ax4 = f1.add_subplot(3, 2, 4) plt.xticks(xrange, xlabels, fontsize=self.fontsize5) ax5 = f1.add_subplot(3, 2, 5) plt.xticks(xrange, xlabels, fontsize=self.fontsize5) ax6 = f1.add_subplot(3, 2, 6) plt.xticks(xrange, xlabels, fontsize=self.fontsize5) # ax7 = f1.add_subplot(4,2,7) # plt.xticks(xrange, xlabels, fontsize = self.fontsize5) # ax8 = f1.add_subplot(4,2,8) # plt.xticks(xrange, xlabels, fontsize = self.fontsize5) axes = [ax1, ax2, ax3, ax4, ax5, ax6] #, ax7, ax8] yname2 = 'mm' yname = 'Displacement' for ax in axes: ax.set_ylabel('{} ({})'.format(yname, yname2), fontsize=self.fontsize6) ax.set_ylim(ylim) ax.set_xlim([0.8, len(xlabels) + 0.2]) # xlim margins 0.2 # set markers markers = ['p', 'D', '^', 'o', 's'] colorsdirections = self.colorsdirections # capsize = 8 lss = ['--', '-', '-', '-', '-'] # lw = 1 # lw2 = 1.1 # alpha = 0.7 Qnames = ['Full ring', 'QP', 'QA', 'QL', 'QR'] Qs = ['', 'Q1', 'Q3', 'Q2', 'Q4'] Rs = ['R1', 'R2'] filedir = os.path.join(self.filedir, self.folderringdynamics, 'Displacement') def plot_displacement_line_errorbar(filedir, name, ax, Q, R, xrange, labelname, ls, marker, color, alpha=0.7, capsize=8, lw=1, lw2=1.1): """ """ filename = 'Displacement{}{}_{}_pts'.format(Q, R, name) matdict = scipy.io.loadmat(os.path.join(filedir, filename + '.mat')) var = matdict[filename] # plot ax.plot(xrange, np.nanmean(var, axis=0), ls=ls, lw=lw, marker=marker, color=color, label=labelname, alpha=alpha) ax.errorbar(xrange, np.nanmean(var, axis=0), yerr=np.nanstd(var, axis=0), fmt=None, ecolor=color, capsize=capsize, elinewidth=lw2, capthick=lw2) # read mat files for i, labelname in enumerate(Qnames): R = Rs[0] plot_displacement_line_errorbar(filedir, 'x', ax1, Qs[i], R, xrange, labelname, lss[i], markers[i], colorsdirections[i]) plot_displacement_line_errorbar(filedir, 'y', ax3, Qs[i], R, xrange, labelname, lss[i], markers[i], colorsdirections[i]) plot_displacement_line_errorbar(filedir, 'z', ax5, Qs[i], R, xrange, labelname, lss[i], markers[i], colorsdirections[i]) R = Rs[1] plot_displacement_line_errorbar(filedir, 'x', ax2, Qs[i], R, xrange, labelname, lss[i], markers[i], colorsdirections[i]) plot_displacement_line_errorbar(filedir, 'y', ax4, Qs[i], R, xrange, labelname, lss[i], markers[i], colorsdirections[i]) plot_displacement_line_errorbar(filedir, 'z', ax6, Qs[i], R, xrange, labelname, lss[i], markers[i], colorsdirections[i]) if showlegend: ax2.legend(loc='upper right', fontsize=self.fontsize3, numpoints=1, title='Legend') _initaxis(axes, axsize=self.fontsize5) if saveFig: plt.savefig(os.path.join(self.dirsaveIm, 'plot_ring_quadrants_displacement.png'), papertype='a0', dpi=600) def plot_meancurvaturechange(self, ylim=[0, 0.1], saveFig=False, showlegend=True): """ """ # init figure f1 = plt.figure(figsize=(10, 4.6)) # from 11.6 to 10 to place legend xlabels = ['D', '1M', '6M', '12M', '24M'] xrange = range( 1, 1 + len(xlabels)) # not start from x=0 to play with margin xlim # init axis ax1 = f1.add_subplot(1, 2, 1) plt.xticks(xrange, xlabels, fontsize=self.fontsize5) ax2 = f1.add_subplot(1, 2, 2) plt.xticks(xrange, xlabels, fontsize=self.fontsize5) axes = [ax1, ax2] yname2 = 'cm$^{-1}$' yname = 'Curvature change' for ax in axes: ax.set_ylabel('{} ({})'.format(yname, yname2), fontsize=self.fontsize6) ax.set_ylim(ylim) ax.set_xlim([0.8, len(xlabels) + 0.2]) # xlim margins 0.2 # set markers markers = ['p', 'D', '^', 'o', 's'] colorsdirections = self.colorsdirections lss = ['--', '-', '-', '-', '-'] Qnames = ['Full ring', 'QP', 'QA', 'QL', 'QR'] Qs = ['', 'Q1', 'Q3', 'Q2', 'Q4'] Rs = ['R1', 'R2'] filedir = os.path.join(self.filedir, self.folderringdynamics, 'Curvature') def plot_curvaturechange_line_errorbar(filedir, name, ax, Q, R, xrange, labelname, ls, marker, color, alpha=0.7, capsize=8, lw=1, lw2=1.1): """ """ filename = 'Curvature{}{}_{}_pts'.format(Q, R, name) matdict = scipy.io.loadmat(os.path.join(filedir, filename + '.mat')) var = matdict[filename] # plot ax.plot(xrange, np.nanmean(var, axis=0), ls=ls, lw=lw, marker=marker, color=color, label=labelname, alpha=alpha) ax.errorbar(xrange, np.nanmean(var, axis=0), yerr=np.nanstd(var, axis=0), fmt=None, ecolor=color, capsize=capsize, elinewidth=lw2, capthick=lw2) # read mat files for i, labelname in enumerate(Qnames): R = Rs[0] plot_curvaturechange_line_errorbar(filedir, 'meanchange', ax1, Qs[i], R, xrange, labelname, lss[i], markers[i], colorsdirections[i]) R = Rs[1] plot_curvaturechange_line_errorbar(filedir, 'meanchange', ax2, Qs[i], R, xrange, labelname, lss[i], markers[i], colorsdirections[i]) if showlegend: ax2.legend(loc='upper right', fontsize=self.fontsize3, numpoints=1, title='Legend') _initaxis(axes, axsize=self.fontsize5) if saveFig: plt.savefig(os.path.join( self.dirsaveIm, 'plot_ring_quadrants_meanchangecurvature.png'), papertype='a0', dpi=600)
* displacement centerlines (e.g. branches, aorta) * angulation branches/end-stent angle * distance change between branch proximally and aorta * """ import os from stentseg.utils.datahandling import select_dir, loadmodel, loadvol ptcode = 'LSPEASF_C_01' ctcode = 'pre' # pre, dis, 6w, 12m # Set basedir for saving and loading ssdf basedir = select_dir(r'D:\LSPEAS_F\LSPEASF_ssdf', r'F:\LSPEASF_backup\LSPEASF_ssdf') ## LOAD CT if True: from lspeasf.utils.dicom2ssdf import dicom2ssdf dicom_basedir = r'F:\LSPEASF_backup\LSPEASF_CT_dicom_backup\LSPEASF_C_01\LSPEASF_C_01_pre' print(dicom_basedir) vols = dicom2ssdf(dicom_basedir, ptcode, ctcode, basedir) print('load, crop and convert to ssdf: done') # show vols dynamic from lspeas.utils.vis import showVolPhases showVol = 'mip' t = showVolPhases(basedir,
vv.ylabel('position (mm)') vv.legend('B1 (A=0.6, T=0.8)') # B5 (A=2.0, T=0.8, N=20, top=0.35, extra=(0.7, 0.8, 0.05)) ax5 = vv.subplot(122) #; vv.title('profile5') plot_pattern(*(tt5, aa5)) ax5.axis.showGrid = False ax5.SetLimits(rangeX=(-0.01, 2), rangeY=(-0.02, 2.5)) ax5.axis.showBox = False vv.xlabel('time (s)') vv.ylabel('position (mm)') vv.legend('B5 (A=2.0, T=0.8, extra=0.7, 0.8, 0.05)') f.relativeFontSize = 1.2 if False: exceldir = select_dir(r'C:\Users\Maaike\Desktop', r'D:\Profiles\koenradesma\Desktop') vv.screenshot(os.path.join(exceldir, 'screenshot.png'), f, sf=3, bg=(1, 1, 1)) ## Plot for paper proceedings, patternexample import matplotlib.pyplot as plt from lspeas.analysis.utils_analysis import _initaxis from stentseg.utils.aortamotionpattern import plot_pattern_plt import numpy as np dirsave = select_dir(r'C:\Users\Maaike\Desktop', 'D:\Profiles\koenradesma\Desktop') xlim = (-0.01, 2)
calculates 10 deformation fields from it, which are then stored to disk. We can also create an average image from all volumes by first registering the volumes toward each-other. """ ## Perform image registration import os, time import numpy as np import visvis as vv import pirt.reg # Python Image Registration Toolkit from stentseg.utils.datahandling import select_dir, loadvol, loadmodel # Select the ssdf basedir basedir = select_dir(os.getenv('LSPEAS_BASEDIR', ''), r'D:\LSPEAS\LSPEAS_ssdf', r'G:\LSPEAS_ssdf_backup') # basedir = select_dir(r'D:\LSPEAS_F\LSPEASF_ssdf') # Select dataset to register # ptcode = 'QRM_FANTOOM_20160121' # ctcode = '12months' cropnames = ['stent'] ptcodes = ['LSPEAS_018', 'LSPEAS_025', 'LSPEAS_023', 'LSPEAS_024'] ctcodes = ['24months'] for ptcode in ptcodes: for ctcode in ctcodes: for cropname in cropnames: # Load volumes try:
| \ | """ from lspeas.analysis.utils_analysis import readRingExcel, _initaxis, cols2num from stentseg.utils import PointSet import openpyxl from stentseg.utils.datahandling import select_dir import sys, os import math import numpy as np import matplotlib.pyplot as plt import itertools from matplotlib import gridspec from lspeas.utils import normality_statistics exceldir = select_dir(r'C:\Users\Maaike\SURFdrive\UTdrive\LSPEAS\Analysis', r'D:\Profiles\koenradesma\SURFdrive\UTdrive\LSPEAS\Analysis') workbook_stent = 'LSPEAS_pulsatility_expansion_avgreg_subp_v2.1.xlsx' workbook_renal_cll = 'Peak valley displacement\\dist_peaks_valleys_cll.xlsx' # data with distances over CLL # workbook_renal_cll = 'Peak valley displacement\\dist_peaks_valleys_cll_interobserver_JS_fillnans.xlsx' dirsaveIm = select_dir(r'C:\Users\Maaike\Desktop','D:\Profiles\koenradesma\Desktop') def read_dist_to_renal(exceldir, workbook_renal_cll, ctcode, obs='obsMK'): """Read distance from peaks and valleys of R1 to lowest renal (along CLL by Terarecon) for all patients return lists """ wb = openpyxl.load_workbook(os.path.join(exceldir, workbook_renal_cll), data_only=True) sheet = wb.get_sheet_by_name(obs) # patient order as neck dilation sheet! ...21,25,15,22 colsStart = ['D','I','N','S','X'] # timepoints D tot 24M
import numpy as np if __name__ == "__main__": print("---------------------------- ") print("Write ssdf to dicom") print("----------------------------") print("Based on PyDicom demo code") print("See http://pydicom.googlecode.com") print("and https://code.google.com/p/pydicom/wiki/GettingStarted") print("NOTE: module reuses own official UIDs") print("----------------------------") ## Select directory to save dicom # basedir_save = select_dir(r'D:\LSPEAS\DICOMavgreg', # r'F:\DICOMavgreg_toPC') basedir_save = select_dir(r'D:\LSPEAS_F\DICOMavgreg') ## Select directory to load dicom # dicom_basedir = select_dir(r'F:\LSPEAS_data\ECGgatedCT', # r'D:\LSPEAS\LSPEAS_data_BACKUP\ECGgatedCT') dicom_basedir = select_dir(r'D:\LSPEAS_F\CT_dicom_backup') # *** or set a slice location manual *** manualdicomslice = True dicomfolderRead = r'D:\LSPEAS_F\CT_dicom_backup\LSPEASF_C_01\LSPEASF_C_01_pre' dicomfileRead = 'LSPEAS_FEVAR001_PO_1.CT.0004.0001.2017.02.08.10.07.57.428321.447272392.ima' # use to get ds and write on dicomfolderWrite = r'D:\LSPEAS\LSPEAS_data_BACKUP\ECGgatedCT\LSPEAS_001\LSPEAS_001_discharge\1.2.392.200036.9116.2.6.1.48.1214833767.1399597166.677650\1.2.392.200036.9116.2.6.1.48.1214833767.1399597810.119489' dicomfileWrite = '1.2.392.200036.9116.2.6.1.48.1214833767.1399597831.761589.dcm'
class ExcelAnalysisRingDynamics(): """ Create graphs from excel file per patient created by ring_dynamics.py """ exceldir = select_dir( r'C:\Users\Maaike\SURFdrive\UTdrive\LSPEAS\Analysis\Ring motion\ringdynamics', r'D:\Profiles\koenradesma\SURFdrive\UTdrive\LSPEAS\Analysis\Ring motion\ringdynamics' ) dirsaveIm = select_dir(r'C:\Users\Maaike\Desktop', 'D:\Profiles\koenradesma\Desktop') def __init__(self): self.exceldir = ExcelAnalysisRingDynamics.exceldir self.dirsaveIm = ExcelAnalysisRingDynamics.dirsaveIm self.patients = [ 'LSPEAS_001', 'LSPEAS_002', 'LSPEAS_003', 'LSPEAS_005', 'LSPEAS_008', 'LSPEAS_009', 'LSPEAS_011', 'LSPEAS_015', 'LSPEAS_017', 'LSPEAS_018', 'LSPEAS_019', 'LSPEAS_020', 'LSPEAS_021', 'LSPEAS_022', 'LSPEAS_025', ] self.fontsize1 = 16 self.fontsize2 = 16 # ylabel self.fontsize4 = 10 # legend contents def get_curvature_change(self, patients=None, analysis=['R1', 'Q1R1', 'Q2R1', 'Q3R1', 'Q4R1'], curvetype='pointchange', storemat=False): """ Read curvature change for the ring and/or ring quadrant analysis: R1 and/or Q1R1 etc for ring or part of ring curvetype: 'pointchange' --> curvature change per point 'peakcurvature' --> max diff between peak angle over phases 'meancurvature' --> max diff between mean curvature over phases """ if patients == None: patients = self.patients ctcodes = ['discharge', '1month', '6months', '12months', '24months'] # read workbooks per patient (this might take a while) for a in analysis: # init to collect over time all pts curvechangeOverTime_pts = [] # cm-1; 5 values for each patient curvechangePOverTime_pts = [] # % curvechangeRelLocOverTime_pts = [] # % avgcurvechangeOverTime_pts = [] # cm-1 avgcurvechangePOverTime_pts = [] # % avgcurveMinOverTime_pts = [] avgcurveMaxOverTime_pts = [] for patient in patients: # init to collect parameter for all timepoints for this patient curvechangeOverTime = [] # cm-1 curvechangePOverTime = [] # % curvechangeRelLocOverTime = [] # % avgcurvechangeOverTime = [] avgcurvechangePOverTime = [] avgcurveMinOverTime = [] avgcurveMaxOverTime = [] for i in range(len(ctcodes)): filename = '{}_ringdynamics_{}.xlsx'.format( patient, ctcodes[i]) workbook_stent = os.path.join(self.exceldir, filename) # read workbook try: wb = openpyxl.load_workbook(workbook_stent, data_only=True) except FileNotFoundError: # handle missing scans if curvetype == 'pointchange': # collect curvechangeOverTime.append(np.nan) curvechangePOverTime.append(np.nan) curvechangeRelLocOverTime.append(np.nan) avgcurvechangeOverTime.append(np.nan) avgcurvechangePOverTime.append(np.nan) avgcurveMinOverTime.append(np.nan) avgcurveMaxOverTime.append(np.nan) continue # no scan, next # get sheet sheetname = 'Curvature{}'.format(a) sheet = wb.get_sheet_by_name(sheetname) # set row for type of curvature analysis if curvetype == 'pointchange': rowstart = 5 # as in excel; max change of a point rowstart2 = 9 # as in excel; rel location rowstart3 = 13 # as in excel; mean curvature change all points rowstart4 = 26 # as in excel; mean curvature min and max value colstart = 1 # 1 = B # read change curvechange = sheet.rows[rowstart - 1][colstart].value curvechangeP = sheet.rows[rowstart - 1][colstart + 1].value curvechangeRelLoc = sheet.rows[rowstart2 - 1][colstart].value avgcurvechange = sheet.rows[rowstart3 - 1][colstart].value avgcurvechangeP = sheet.rows[rowstart3 - 1][colstart + 1].value avgcurvemin = sheet.rows[rowstart4 - 1][colstart].value avgcurvemax = sheet.rows[rowstart4 - 1][colstart + 1].value # collect curvechangeOverTime.append(curvechange) curvechangePOverTime.append(curvechangeP) curvechangeRelLocOverTime.append(curvechangeRelLoc) avgcurvechangeOverTime.append(avgcurvechange) avgcurvechangePOverTime.append(avgcurvechangeP) avgcurveMinOverTime.append(avgcurvemin) avgcurveMaxOverTime.append(avgcurvemax) # collect for pts curvechangeOverTime_pts.append(np.asarray(curvechangeOverTime)) curvechangePOverTime_pts.append( np.asarray(curvechangePOverTime)) curvechangeRelLocOverTime_pts.append( np.asarray(curvechangeRelLocOverTime)) avgcurvechangeOverTime_pts.append( np.asarray(avgcurvechangeOverTime)) avgcurvechangePOverTime_pts.append( np.asarray(avgcurvechangePOverTime)) avgcurveMinOverTime_pts.append(np.asarray(avgcurveMinOverTime)) avgcurveMaxOverTime_pts.append(np.asarray(avgcurveMaxOverTime)) # store in self self.curvechangeOverTime_pts = np.asarray(curvechangeOverTime_pts) self.curvechangePOverTime_pts = np.asarray( curvechangePOverTime_pts) self.curvechangeRelLocOverTime_pts = np.asarray( curvechangeRelLocOverTime_pts) self.avgcurvechangeOverTime_pts = np.asarray( avgcurvechangeOverTime_pts) self.avgcurvechangePOverTime_pts = np.asarray( avgcurvechangePOverTime_pts) self.avgcurveMinOverTime_pts = np.asarray(avgcurveMinOverTime_pts) self.avgcurveMaxOverTime_pts = np.asarray(avgcurveMaxOverTime_pts) print_stats_var_over_time_( self.curvechangeOverTime_pts, varname='Curvature{}_maxchange_pts'.format(a), dec=3) print_stats_var_over_time_( self.curvechangePOverTime_pts, varname='Curvature{}_maxchangeP_pts'.format(a)) print_stats_var_over_time_( self.curvechangeRelLocOverTime_pts, varname='Curvature{}_maxchangeRelLoc_pts'.format(a)) print_stats_var_over_time_( self.avgcurvechangeOverTime_pts, varname='Curvature{}_meanchange_pts'.format(a), dec=3) print_stats_var_over_time_( self.avgcurvechangePOverTime_pts, varname='Curvature{}_meanchangeP_pts'.format(a)) print_stats_var_over_time_( self.avgcurveMinOverTime_pts, varname='Curvature{}_meanMin_pts'.format(a), dec=3) print_stats_var_over_time_( self.avgcurveMaxOverTime_pts, varname='Curvature{}_meanMax_pts'.format(a), dec=3) # Store to .mat per analysis if storemat: if curvetype == 'pointchange': self.store_var_to_mat( np.asarray(curvechangeOverTime_pts), varname='Curvature{}_maxchange_pts'.format(a)) self.store_var_to_mat( np.asarray(curvechangePOverTime_pts), varname='Curvature{}_maxchangeP_pts'.format(a)) self.store_var_to_mat( np.asarray(curvechangeRelLocOverTime_pts), varname='Curvature{}_maxchangeRelLoc_pts'.format(a)) self.store_var_to_mat( np.asarray(avgcurvechangeOverTime_pts), varname='Curvature{}_meanchange_pts'.format(a)) self.store_var_to_mat( np.asarray(avgcurvechangePOverTime_pts), varname='Curvature{}_meanchangeP_pts'.format(a)) self.store_var_to_mat( np.asarray(avgcurveMinOverTime_pts), varname='Curvature{}_meanMin_pts'.format(a)) self.store_var_to_mat( np.asarray(avgcurveMaxOverTime_pts), varname='Curvature{}_meanMax_pts'.format(a)) def get_displacement_cycle(self, patients=None, analysis=['R1', 'Q1R1', 'Q2R1', 'Q3R1', 'Q4R1'], storemat=False): """ Read displacement during the cycle for the ring and/or ring quadrant analysis: R1 and/or Q1R1 etc for ring or part of ring Obtain mean displacement in 3d and x,y,z directions """ if patients == None: patients = self.patients ctcodes = ['discharge', '1month', '6months', '12months', '24months'] # read workbooks per patient (this might take a while) for a in analysis: # init to collect over time all pts displxyzOverTime_pts = [] # xyz mm; 5 values for each patient curvechangePOverTime_pts = [] # x mm curvechangeRelLocOverTime_pts = [] # y mm avgcurvechangeOverTime_pts = [] # z mm for patient in patients: # init to collect parameter for all timepoints for this patient displxyzOverTime = [] displxOverTime = [] displyOverTime = [] displzOverTime = [] for i in range(len(ctcodes)): filename = '{}_ringdynamics_{}.xlsx'.format( patient, ctcodes[i]) workbook_stent = os.path.join(self.exceldir, filename) # read workbook try: wb = openpyxl.load_workbook(workbook_stent, data_only=True) except FileNotFoundError: # handle missing scans # collect displxyzOverTime.append(np.nan) displxOverTime.append(np.nan) displyOverTime.append(np.nan) displzOverTime.append(np.nan) continue # no scan, next # get sheet sheetname = 'Motion{}'.format(a) sheet = wb.get_sheet_by_name(sheetname) # set row for 3d,x,y,z rowstart = 6 # as in excel; xyz/3d rowstart2 = 7 # as in excel; x rowstart3 = 8 # as in excel; y rowstart4 = 9 # as in excel; z colstart = 1 # 1 = B # read change displxyz = sheet.rows[rowstart - 1][colstart].value displx = sheet.rows[rowstart2 - 1][colstart].value disply = sheet.rows[rowstart3 - 1][colstart].value displz = sheet.rows[rowstart4 - 1][colstart].value # collect displxyzOverTime.append(displxyz) displxOverTime.append(displx) displyOverTime.append(disply) displzOverTime.append(displz) # collect for pts displxyzOverTime_pts.append(np.asarray(displxyzOverTime)) curvechangePOverTime_pts.append(np.asarray(displxOverTime)) curvechangeRelLocOverTime_pts.append( np.asarray(displyOverTime)) avgcurvechangeOverTime_pts.append(np.asarray(displzOverTime)) self.displxyzOverTime_pts = np.asarray(displxyzOverTime_pts) self.displxOverTime_pts = np.asarray(curvechangePOverTime_pts) self.displyOverTime_pts = np.asarray(curvechangeRelLocOverTime_pts) self.displzOverTime_pts = np.asarray(avgcurvechangeOverTime_pts) print_stats_var_over_time_( self.displxOverTime_pts, varname='Displacement{}_x_pts'.format(a)) print_stats_var_over_time_( self.displyOverTime_pts, varname='Displacement{}_y_pts'.format(a)) print_stats_var_over_time_( self.displzOverTime_pts, varname='Displacement{}_z_pts'.format(a)) print_stats_var_over_time_( self.displxyzOverTime_pts, varname='Displacement{}_3d_pts'.format(a)) # Store to .mat per analysis if storemat: self.store_var_to_mat( np.asarray(displxyzOverTime_pts), varname='Displacement{}_3d_pts'.format(a)) self.store_var_to_mat(np.asarray(curvechangePOverTime_pts), varname='Displacement{}_x_pts'.format(a)) self.store_var_to_mat( np.asarray(curvechangeRelLocOverTime_pts), varname='Displacement{}_y_pts'.format(a)) self.store_var_to_mat(np.asarray(avgcurvechangeOverTime_pts), varname='Displacement{}_z_pts'.format(a)) def get_distance_change_between_rings( self, patients=None, analysis=['R1R2', 'Q1R1R2', 'Q2R1R2', 'Q3R1R2', 'Q4R1R2'], storemat=False): """ Read distance change during the cycle for the ring and/or ring quadrant analysis: R1 and/or Q1R1 etc for ring or part of ring Obtain mean and max distance change """ if patients == None: patients = self.patients ctcodes = ['discharge', '1month', '6months', '12months', '24months'] # read workbooks per patient (this might take a while) for a in analysis: # init to collect over time all pts meanOverTime_pts = [] # mm; 5 values for each patient maxOverTime_pts = [] # mm for patient in patients: # init to collect parameter for all timepoints for this patient meanOverTime = [] maxOverTime = [] for i in range(len(ctcodes)): filename = '{}_ringdynamics_{}.xlsx'.format( patient, ctcodes[i]) workbook_stent = os.path.join(self.exceldir, filename) # read workbook try: wb = openpyxl.load_workbook(workbook_stent, data_only=True) except FileNotFoundError: # handle missing scans # collect meanOverTime.append(np.nan) maxOverTime.append(np.nan) continue # no scan, next # get sheet sheetname = 'Distances{}'.format(a) sheet = wb.get_sheet_by_name(sheetname) # set row for 3d,x,y,z rowstart = 16 # as in excel; mean rowstart2 = 6 # as in excel; max colstart = 1 # 1 = B # read change distmean = sheet.rows[rowstart - 1][colstart].value distmax = sheet.rows[rowstart2 - 1][colstart].value # collect meanOverTime.append(distmean) maxOverTime.append(distmax) # collect for pts meanOverTime_pts.append(np.asarray(meanOverTime)) maxOverTime_pts.append(np.asarray(maxOverTime)) self.meanOverTime_pts = np.asarray(meanOverTime_pts) self.maxOverTime_pts = np.asarray(maxOverTime_pts) print_stats_var_over_time_( self.meanOverTime_pts, varname='Distances{}_mean_pts'.format(a)) print_stats_var_over_time_(self.maxOverTime_pts, varname='Distances{}_max_pts'.format(a)) # Store to .mat per analysis if storemat: self.store_var_to_mat(np.asarray(meanOverTime_pts), varname='Distances{}_mean_pts'.format(a)) self.store_var_to_mat(np.asarray(maxOverTime_pts), varname='Distances{}_max_pts'.format(a)) def store_var_to_mat(self, variable, varname=None, storematdir=None): """ Save as .mat to easy copy to spss """ if storematdir is None: storematdir = os.path.join(self.dirsaveIm, 'python_to_mat_output_ringdynamics') if varname is None: varname = 'variable_from_python' storemat = os.path.join(storematdir, varname + '.mat') storevar = dict() # check if variable has multiple vars in list if isinstance(variable, list): for i, var in enumerate(variable): name = varname + '{}'.format(i) storevar[name] = var else: storevar[varname] = variable storevar['workbooks_ringdynamics'] = '_ringdynamics_' storevar['patients'] = self.patients io.savemat(storemat, storevar) print('') print('variable {} was stored as.mat to {}'.format(varname, storemat)) def plot_curvature_during_cycle(self, patients=['LSPEAS_001'], analysis=[''], ctcode='discharge', ring='R1', ylim=[0, 2], ylimRel=[-0.1, 0.1], saveFig=False): """ plot change in curvature during the cardiac cycle for point with max curvature change at ring or ring quadrants at a certain time point (CT scan) * ctcode = discharge, 1month, 6 months, ... 24months * analysis = '' for ring or Q1, Q2, Q3, Q4 """ self.curveAll = {} self.curveRelAll = {} # init figure self.f1 = plt.figure(figsize=(11.5, 4.2)) xlabels = ['0', '10', '20', '30', '40', '50', '60', '70', '80', '90'] xrange = range( 1, 1 + len(xlabels)) # not start from x=0 to play with margin xlim fontsize1 = self.fontsize1 fontsize2 = self.fontsize2 # init axis factor = 1.33 # 1.36 gs = gridspec.GridSpec(1, 2, width_ratios=[1, factor]) # plot right wider ax1 = plt.subplot(gs[0]) plt.xticks(xrange, xlabels, fontsize=fontsize1) ax2 = plt.subplot(gs[1]) plt.xticks(xrange, xlabels, fontsize=fontsize1) ax1.set_ylabel('Curvature (cm$^{-1}$)', fontsize=fontsize2) # absolute curvature values ax1.set_ylim(ylim) ax1.set_xlim([0.8, len(xlabels) + 0.2]) # xlim margins 0.2 ax1.set_xlabel('Phase in cardiac cycle', fontsize=fontsize2) ax2.set_ylabel('Relative curvature change (cm$^{-1}$)', fontsize=fontsize2) # relative dist from avgreg ax2.set_ylim(ylimRel) ax2.set_xlim([0.8, len(xlabels) * factor + 0.2 ]) # xlim margins 0.2; # longer for legend ax2.set_xlabel('Phase in cardiac cycle', fontsize=fontsize2) # plot init lw = 1 alpha = 0.9 ls = '-' markers = ['o', 'D', '^', 'o', 's'] colorsdirections = [ # from phantom paper in vivo plots 'k', '#d73027', # 1 red '#fc8d59', # orange '#91bfdb', # blue '#4575b4' # 5 ] Qnames = ['Full ring', 'QP', 'QA', 'QL', 'QR'] Qs = ['', 'Q1', 'Q3', 'Q2', 'Q4'] for patient in patients: for a in analysis: # read workbook filename = '{}_ringdynamics_{}.xlsx'.format(patient, ctcode) workbook_stent = os.path.join(self.exceldir, filename) wb = openpyxl.load_workbook(workbook_stent, data_only=True) sheetname = 'Curvature{}{}'.format(a, ring) sheet = wb.get_sheet_by_name(sheetname) # read cuvrature of point with max change rowstart = 12 # as in excel; during cycle colstart = 1 # 1 = B # read change curvatures = sheet.rows[rowstart - 1][colstart:colstart + 10] curvatures = [obj.value for obj in curvatures] # convert to array curvatures = np.asarray(curvatures) # get curvature at mid heart cycle avgcurvature = np.nanmean(curvatures) # relative curvatures from avgreg curveRel = curvatures - avgcurvature self.curveAll['{}_{}'.format(patient, a)] = curvatures self.curveRelAll['{}_{}'.format(patient, a)] = curveRel # plotting # color1 = color_per_patient(patient) color1 = colorsdirections[Qs.index(a)] marker = markers[Qs.index(a)] label = Qnames[Qs.index(a)] ax1.plot(xrange, curvatures, ls=ls, lw=lw, marker=marker, color=color1, label=label, alpha=alpha) ax2.plot(xrange, curveRel, ls=ls, lw=lw, marker=marker, color=color1, label=label, alpha=alpha) ax2.legend(loc='upper right', fontsize=self.fontsize4, numpoints=1, title='Legend:') _initaxis([ax1, ax2], axsize=fontsize1) if saveFig: plt.savefig(os.path.join( self.dirsaveIm, 'plot_curvature_over_cycle_{}.png'.format(analysis)), papertype='a0', dpi=600)
return abs_errors_profiles import os import openpyxl import matplotlib.pyplot as plt from stentseg.utils.datahandling import select_dir import numpy as np from lspeas.analysis.utils_analysis import _initaxis # import seaborn as sns #sns.tsplot # https://www.wakari.io/sharing/bundle/ijstokes/pyvis-1h?has_login=False # http://spartanideas.msu.edu/2014/06/28/how-to-make-beautiful-data-visualizations-in-python-with-matplotlib/ exceldir = select_dir( r'C:\Users\Maaike\surfdrive\UTdrive\LSPEAS\Analysis\Validation robot', r'D:\Profiles\koenradesma\surfdrive\UTdrive\LSPEAS\Analysis\Validation robot' ) workbook = 'Errors cam123ref_vs_alg Toshiba.xlsx' workbookF = 'Errors cam123ref_vs_alg Siemens.xlsx' dirsave = select_dir(r'C:\Users\Maaike\Desktop', 'D:\Profiles\koenradesma\Desktop') savefig = True # plot frequency profiles # profiles, mean_abs_error, SD, MIN, Q1, Q3, MAX = read_error_ouput(exceldir, workbookErrors) profilesB = ['ZA6', 'ZB1', 'ZB2', 'ZB3', 'ZB6', 'ZB5', 'ZB4'] boxlabelsB = ['B0', 'B1', 'B2', 'B3', 'B6', 'B5', 'B4'] profilesA = ['ZA1', 'ZA2', 'ZA3'] #, 'ZA3 STENT2'] # A1, boxlabelsA = ['A1', 'A2', 'A3'] profilesBxaxis = [0.02, 0.23, 0.37, 0.70, 1.22, 1.26, 1.36] # zb6=1.24 profilesAxaxis = [49.0, 96.3, 73.3]
2019, Maaike A. Koenrades A CT scanned helix-shaped phantom with a known theoretically calculated curvature was used: Schuurmann RCL, Kuster L, Slump CH, Vahl A, Van Den Heuvel DAF, Ouriel K, et al. Aortic curvature instead of angulation allows improved estimation of the true aorto-iliac trajectory. Eur J Vasc Endovasc Surg 2016;51(2):216–24. Doi: 10.1016/j.ejvs.2015.09.008. """ from stentseg.utils.datahandling import select_dir import sys, os import scipy.io from lspeas.utils.curvature import get_curvatures import numpy as np import visvis as vv from stentseg.utils.centerline import smooth_centerline filedir = select_dir(r'C:\Users\Maaike\SURFdrive\UTdrive\LSPEAS\Analysis\Ring motion\curvature check helix fantoom', r'D:\Profiles\koenradesma\SURFdrive\UTdrive\LSPEAS\Analysis\Ring motion\curvature check helix fantoom') filename = 'helix' matdict = scipy.io.loadmat(os.path.join(filedir, filename+'.mat')) var = matdict['HELIX'] # show phantom vv.plot(var) pp = np.asarray(var[99:1399]) # 100:1400 was used in Matlab implementation to exclude ends (Jaimy) vv.plot(pp, lc='r', lw=3) # smooth pp (as in implementation) smooth_pp = smooth_centerline(pp, 15) # smooth the 'interpolated polygon' to helix shape vv.figure() vv.plot(smooth_pp, lc='r', lw=1) # calc curvature
import os import visvis as vv from stentseg.utils.datahandling import select_dir, loadvol, loadmodel from pirt.utils.deformvis import DeformableTexture3D, DeformableMesh from stentseg.utils.visualization import show_ctvolume from stentseg.stentdirect.stentgraph import create_mesh from stentseg.motion.vis import create_mesh_with_abs_displacement import pirt import numpy as np from stentseg.motion.displacement import _calculateAmplitude, _calculateSumMotion from stentseg.motion.displacement import calculateMeanAmplitude # Select the ssdf basedir basedir = select_dir(os.getenv('LSPEAS_BASEDIR', ''), r'D:\LSPEAS\LSPEAS_ssdf', r'F:\LSPEAS_ssdf_BACKUP', r'G:\LSPEAS_ssdf_BACKUP') # Select dataset to register ptcode = 'LSPEAS_002' ctcode, nr = '12months', 1 # ptcode = 'QRM_FANTOOM_20160121' # ctcode, nr = 'ZA3-75-1.2', 1 cropname = 'ring' modelname = 'modelavgreg' motion = 'amplitude' # amplitude or sum dimension = 'xyz' showVol = 'ISO' # MIP or ISO or 2D or None clim0 = (-10, 2500) clim2 = (0, 3) isoTh = 250 motionPlay = 9, 1 # each x ms, a step of perc of T
calculates N deformation fields from it, which are then stored to disk. We can also create an average image from all volumes by first registering the volumes toward each-other. """ ## Perform image registration import os, time import numpy as np import visvis as vv import pirt.reg # Python Image Registration Toolkit from stentseg.utils.datahandling import select_dir, loadvol, loadmodel # Select the ssdf basedir basedir = select_dir(r'D:\LSPEAS\Nellix_chevas\CHEVAS_SSDF', r'G:\Nellix_chevas\CHEVAS_SSDF_BACKUP') # Select dataset to register cropname = 'prox' ptcode = 'chevas_01' ctcode = '12months' what = '10phases' # Load volumes s = loadvol(basedir, ptcode, ctcode, cropname, what) vols = [] phases = [] for key in dir(s): if key.startswith('vol'): print(key)