Commit 2cafb715 authored by Christoph Sommer's avatar Christoph Sommer
Browse files

added imaris swc impex

parent bbb05a03
# Imaris XT for Import/Export SWC
This is Python XTensions for importing/exporting SWC files into/from Imaris
by Sarun Gulyanon, 28 July 2018, adapted by Christoph Sommer 31 January 2022.
## Installation ##
- Install [Python Anaconda](https://www.anaconda.com/download/) (tested on Anaconda 5.2)
- Open "Anaconda prompt" from windows Start menu
- Create new python environment by typing and execute command: "conda create -n imaris_XT_py27 python=2.7 numpy -y" (without ")
- Activate that environment by: "conda activate imaris_XT_py27" (without ")
- Retrieve full path of environment's python executable: "where python" and copy displayed path to clip-board (used later)
- Put `importswc.py` and `exportswc.py` in Python XTensions folder, e.g., `C:\Program Files\Bitplane\Imaris x64 9.2.0\XT\python`
- Link Python to Imaris by select Files > Preferences.. > CustomTools, and browse the Python 2.7 Application, e.g., `<folder>/Anaconda2/python.exe` <-- (copy from clip-board)
- Link the Python XTensions folder by select Files > Preferences.. > CustomTools, and add the XTensions Folders, e.g., `C:\Program Files\Bitplane\Imaris x64 9.2.0\XT\python\`
## How to Use ##
To import SWC,
1. First, open the image volume.
2. Go to Image Processing > Import SWC as Filament
3. Select the SWC file using the dialog.
To export SWC,
1. First, open the image volume with Filament.
2. Second, select the Filament you want to export.
3. Go to Image Processing > Export Filament as SWC
4. Select the save location using the dialog.
#### Requirements ####
- Numpy
- ImarisLib (given in Python XTensions folder)
#### Note ####
- [Tutorial for making Imaris XT](http://www.scs2.net/next/files/courses/iic/ImarisXTCourse.pdf)
- [pIceImarisConnector](http://www.scs2.net/next/index.php?id=110) for testing the code.
\ No newline at end of file
# Export Filament
# By Sarun Gulyanon 28 July 2018
#
# <CustomTools>
# <Menu>
# <Item name="Export Filament as SWC" icon="Python">
# <Command>PythonXT::ExportSWC(#i)</Command>
# </Item>
# </Menu>
# </CustomTools>
import ImarisLib
import Tkinter
import tkFileDialog
import numpy as np
import time
def ExportSWC(aImarisId):
# Create an ImarisLib object
vImarisLib = ImarisLib.ImarisLib()
# Get an imaris object with id aImarisId
vImaris = vImarisLib.GetApplication(aImarisId)
# Check if the object is valid
if vImaris is None:
print 'Could not connect to Imaris!'
time.sleep(2)
return
vFactory = vImaris.GetFactory()
vFilaments = vFactory.ToFilaments(vImaris.GetSurpassSelection())
if vFilaments is None:
print('Pick a filament first')
time.sleep(2)
return
# get pixel scale in XYZ resolution (pixel/um)
V = vImaris.GetDataSet()
pixel_scale = np.array([V.GetSizeX() / (V.GetExtendMaxX() - V.GetExtendMinX()), \
V.GetSizeY() / (V.GetExtendMaxY() - V.GetExtendMinY()), \
V.GetSizeZ() / (V.GetExtendMaxZ() - V.GetExtendMinZ())])
pixel_offset = np.array([V.GetExtendMinX(), V.GetExtendMinY(), V.GetExtendMinZ()])
# ad-hoc fix Z-flip when |maxZ| < |minZ|
if abs(V.GetExtendMinZ()) > abs(V.GetExtendMaxZ()):
pixel_offset = np.array([V.GetExtendMinX(), V.GetExtendMinY(), V.GetExtendMaxZ()])
pixel_scale[2] = -pixel_scale[2]
# get filename
root = Tkinter.Tk()
root.withdraw()
savename = tkFileDialog.asksaveasfilename(defaultextension=".swc")
root.destroy()
if not savename: # asksaveasfilename return '' if dialog closed with "cancel".
print('No files selected')
time.sleep(2)
return
print(savename)
# go through Filaments and convert to SWC format
head = 0;
swcs = np.zeros((0,7))
vCount = vFilaments.GetNumberOfFilaments()
for vFilamentIndex in range(vCount):
vFilamentsXYZ = vFilaments.GetPositionsXYZ(vFilamentIndex)
vFilamentsEdges = vFilaments.GetEdges(vFilamentIndex)
vFilamentsRadius = vFilaments.GetRadii(vFilamentIndex)
vFilamentsTypes = vFilaments.GetTypes(vFilamentIndex)
#vFilamentsTime = vFilaments.GetTimeIndex(vFilamentIndex)
N = len(vFilamentsXYZ)
G = np.zeros((N,N),np.bool)
visited = np.zeros(N, np.bool)
for p1, p2 in vFilamentsEdges:
G[p1,p2] = True
G[p2,p1] = True
# traverse through the Filament using BFS
swc = np.zeros((N,7))
visited[0] = True
queue = [0]
prevs = [-1]
while queue:
cur = queue.pop()
prev = prevs.pop()
swc[head] = [head+1, vFilamentsTypes[cur], 0, 0, 0, vFilamentsRadius[cur], prev]
pos = vFilamentsXYZ[cur] - pixel_offset
swc[head,2:5] = pos*pixel_scale
for idx in np.where(G[cur])[0]:
if not visited[idx]:
visited[idx] = True
queue.append(idx)
prevs.append(head+1)
head = head + 1
swcs = np.concatenate((swcs,swc),axis=0)
# write to file
np.savetxt(savename, swcs, '%d %d %f %f %f %f %d')
print('Export to ' + savename + ' completed')
# Import Filament
# By Sarun Gulyanon 28 July 2018
# Adapted by Christoph Sommer 31 Jannuary 2022
#
# <CustomTools>
# <Menu>
# <Item name="Import SWC as Filament" icon="Python">
# <Command>PythonXT::ImportSWC(#i)</Command>
# </Item>
# </Menu>
# </CustomTools>
import ImarisLib
import Tkinter
import tkFileDialog
import numpy as np
import time
import traceback
def ImportSWC(aImarisId):
try:
# Create an ImarisLib object
vImarisLib = ImarisLib.ImarisLib()
# Get an imaris object with id aImarisId
vImaris = vImarisLib.GetApplication(aImarisId)
# Check if the object is valid
if vImaris is None:
print 'Could not connect to Imaris!'
time.sleep(2)
return
vFactory = vImaris.GetFactory()
vFilaments = vFactory.ToFilaments(vImaris.GetSurpassSelection())
# get swc file to load
root = Tkinter.Tk()
root.withdraw()
swcnames = tkFileDialog.askopenfilenames(title = "Select SWC file", filetypes = (("SWC files","*.swc"),("all files","*.*")))
root.destroy()
for swcname in swcnames:
if not swcname: # asksaveasfilename return '' if dialog closed with "cancel".
print 'No file was selected.'
time.sleep(2)
return
swc = np.loadtxt(swcname)
# get pixel scale in XYZ resolution (pixel/um)
V = vImaris.GetDataSet()
pixel_scale = np.array([V.GetSizeX() / (V.GetExtendMaxX() - V.GetExtendMinX()), \
V.GetSizeY() / (V.GetExtendMaxY() - V.GetExtendMinY()), \
V.GetSizeZ() / (V.GetExtendMaxZ() - V.GetExtendMinZ())])
pixel_offset = np.array([V.GetExtendMinX(), V.GetExtendMinY(), V.GetExtendMinZ()])
# ad-hoc fix Z-flip when |maxZ| < |minZ|
if abs(V.GetExtendMinZ()) > abs(V.GetExtendMaxZ()):
pixel_offset = np.array([V.GetExtendMinX(), V.GetExtendMinY(), V.GetExtendMaxZ()])
pixel_scale[2] = -pixel_scale[2]
# draw Filament
N = swc.shape[0]
vFilaments = vImaris.GetFactory().CreateFilaments();
vPositions = swc[:,2:5].astype(np.float) / pixel_scale
vPositions = vPositions + pixel_offset
vRadii = swc[:,5].astype(np.float)
vTypes = swc[:,1] #(0: Dendrite; 1: Spine)
vEdges = swc[:,[6, 0]]
idx = np.all(vEdges > 0, axis=1)
vEdges = vEdges[idx,:] - 1
vTimeIndex = 0;
vFilaments.AddFilament(vPositions.tolist(), vRadii.tolist(), vTypes.tolist(), vEdges.tolist(), vTimeIndex)
vFilamentIndex = 0;
vVertexIndex = 1;
vFilaments.SetBeginningVertexIndex(vFilamentIndex, vVertexIndex)
# Add the filament object to the scene
vScene = vImaris.GetSurpassScene();
vScene.AddChild(vFilaments, -1)
print('Import ' + swcname + ' completed')
except:
print traceback.format_exc()
time.sleep(3)
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment