Using the API

In this part, we will go back to the previous examples of this tutorial and see how to do the same with a python script. The data for the examples in this section are the same : ftp://ftp.cea.fr/pub/dsv/anatomist/data/demo_data.zip.

The following examples use the general API functions that are available in both direct and socket implementations.

To run the following examples, we will use an interactive python shell IPython. It is much more practical than the classic python shell because it offers useful features like automatic completion. This program is available in the BrainVISA package with all other executable programs in the bin directory of the BrainVISA package directory. IPython should be run with the option -q4thread, which runs a Qt event loop, needed for the graphical interface.

<brainvisa_installation_directory>/bin/ipython -q4thread
    

Run Anatomist

First of all, we need to import anatomist API module. Here, in a Python shell, the default implementation is the direct one (Python bindings).

Then we can create an instance of Anatomist class.

import anatomist.api as ana

a=ana.Anatomist()

Load an object

In this example, we will put the path to the data_for_anatomist directory in a variable named src. We will use this variable in all the next examples. We will also load a python module named os which has useful functions to handle files and paths.

import os
src="<path to data_for_anatomist directory>"
# Load an object
t1mri=a.loadObject( os.path.join(src, "data_for_anatomist", "subject01", "subject01.nii") )

See the corresponding actions in the graphical interface.

View an object

We open an axial window and add the volume loaded in the previous example in this window.

# view an object
axial=a.createWindow("Axial")
axial.addObjects(t1mri)

See the corresponding actions in the graphical interface.

When opening a new window, it is possible to change its initial position and size with the geometry parameter. This parameter is a list of 4 values (in pixels) : [x, y, width, height].

# customizing the position and size of a new window : the windows will be displayed at position (100, 150) with a size of (300, 300)
w=a.createWindow("Axial", geometry=[100,150, 300, 300 ])

Windows block

We create 4 views in the same windows block and add the image in each views.

# view an object in a 4 views block
block=a.createWindowsBlock(2) # 2 columns
w1=a.createWindow("Axial", block=block)
w2=a.createWindow("Sagittal", block=block)
w3=a.createWindow("Coronal", block=block)
w4=a.createWindow("3D", block=block)
t1mri.addInWindows( [w1, w2, w3, w4] )

Move the cursor

# show the cursor position
print "\nCursor at : ", a.linkCursorLastClickedPosition()
# move the linked cursor 
w1.moveLinkedCursor([150,100,60])
print "\nCursor at : ", a.linkCursorLastClickedPosition()

Camera

This method enables to change the camera parameters of a window. In this example, we change the zoom.

axial.camera(zoom=2) 
You can also change the rotation of the view by changing the view_quaternion parameters. The rotation is represented by a quaternion which is a vector with 4 parameters. As the interpretation of quaternions is not easy at first time, it is useful to look at the current value of the parameter in a window with the method getInfos().
axial.getInfos()
axial.camera(view_quaternion=[0.9, -0.2, -0.2, 0.3])
It is possible to change the orientation of the slice plan with the parameter slice_quaternion.
axial.camera(slice_quaternion=[0.3, 0.3, 0, 0.9])

See the corresponding actions in the graphical interface.

View header information

# view header
browser=a.createWindow("Browser")
browser.addObjects(t1mri)

See the corresponding actions in the graphical interface.

Change the color palette

# color palette
palette=a.getPalette("Blue-Green-Red-Yellow")
t1mri.setPalette(palette)

See the corresponding actions in the graphical interface.

Custom palette

You can create a new palette by giving the list of RGB parameters of the palette colors.

# custom palette
customPalette=a.createPalette("customPalette")
colors=[]
for x in xrange(255):
  colors.extend([0, 0, x])

customPalette.setColors(colors=colors)
t1mri.setPalette(customPalette)

View meshes

# view meshes
lwhite=a.loadObject( os.path.join(src, "data_for_anatomist", "subject01", "subject01_Lwhite.mesh") )
rwhite=a.loadObject( os.path.join(src, "data_for_anatomist", "subject01", "subject01_Rwhite.mesh") )
w3d=a.createWindow("3D")
w3d.addObjects([lwhite, rwhite])

See the corresponding actions in the graphical interface.

Superimposing

# superimposing
a.addObjects(t1mri, w3d)

See the corresponding actions in the graphical interface.

Change mesh material

# mesh material
head=a.loadObject(os.path.join(src, "data_for_anatomist", "subject01", "subject01_head.mesh"))
head.addInWindows(w3d)
material=a.Material(diffuse=[0.8, 0.6, 0.6, 0.5])
head.setMaterial(material)

See the corresponding actions in the graphical interface.

Fusion between 2 volumes

brain_mask=a.loadObject(os.path.join(src, "data_for_anatomist", "subject01", "brain_subject01.nii"))
brain_mask.setPalette(a.getPalette("GREEN-ufusion"))
t1mri.setPalette("B-W LINEAR")
# fusion 2D
fusion2d=a.fusionObjects([brain_mask, t1mri], "Fusion2DMethod")
axial=a.createWindow("Axial")
axial.addObjects(fusion2d)
# params of the fusion : linear on non null
a.execute("Fusion2DParams", object=fusion2d, mode="linear_on_defined", rate=0.4)

It is possible to do different types of fusion using the same method fusionObjects and changing the list of objects and the type of fusion.

See the corresponding actions in the graphical interface.

Load a transformation

t1mri_s2=a.loadObject( os.path.join(src, "data_for_anatomist", "subject02", "sujet02.ima") )
t1mri_s2.setPalette("Blue-White")
fusion2d=a.fusionObjects([t1mri, t1mri_s2], "Fusion2DMethod")
r1=a.createReferential()
r2=a.createReferential()
cr=a.centralRef
t1mri.assignReferential(r1)
t1mri_s2.assignReferential(r2)
# load a transformation
a.loadTransformation( os.path.join(src, "data_for_anatomist", "subject01", "RawT1-subject01_default_acquisition_TO_Talairach-ACPC.trm"), r1, cr)
a.loadTransformation( os.path.join(src, "data_for_anatomist", "subject02", "RawT1-sujet02_200810_TO_Talairach-ACPC.trm"), r2, cr)
axial=a.createWindow("Axial")
axial.addObjects(fusion2d)

See the corresponding actions in the graphical interface.

Load an existing referential

lwhite.assignReferential(r1)
axial.addObjects(lwhite)

See the corresponding actions in the graphical interface.

Load referential information from file header

map=a.loadObject( os.path.join(src, "data_for_anatomist", "subject01", "Audio-Video_T_map.nii" ) )
map.setPalette("tvalues100-200-100")
t1mri.loadReferentialFromHeader()
map.loadReferentialFromHeader()
fusion_map=a.fusionObjects([map, t1mri], "Fusion2DMethod")
axial=a.createWindow("Axial")
axial.addObjects(fusion_map)
a.execute("Fusion2DParams", object=fusion_map, mode="linear_on_defined", rate=0.5)

See the corresponding actions in the graphical interface.

Display a ROI graph

graph=a.loadObject( os.path.join(src, "data_for_anatomist", "roi", "basal_ganglia.arg") )
w = a.createWindow( '3D' )
w.addObjects( graph, add_graph_nodes=True )

See the corresponding actions in the graphical interface.

Sending a command to Anatomist

A lot of commands that can be processed by Anatomist are encapsulted in Anatomist class methods. But some commands, less commonly used are not available through specific methods. Nevertheless, they can be called through a generic method Anatomist.execute(< command name >, **parameters).

The list of available commands is listed in the following page : http://brainvisa.info/doc/anatomist/html/fr/programmation/commands.html.

In the previous examples, we use this method to call Fusion2DParams command which is not encapsulated in a specific method.

a.execute("Fusion2DParams", object=fusion_map, mode="linear_on_defined", rate=0.5)