Note
Click here to download the full example code
Anatomist api testsΒΆ
This example uses data of i2bm platform.
from __future__ import print_function
from __future__ import absolute_import
import os
import sys
import soma.config
import numpy as np
import tempfile
data_directory = os.path.join(
os.environ.get("BRAINVISA_TEST_RUN_DATA_DIR", ""),
"tmp_tests_brainvisa/data_for_anatomist")
failures = []
mode = 'direct mode'
def testDirectImpl(interactive=True):
import anatomist.direct.api as pyanatomist
global mode
mode = 'direct mode'
a = pyanatomist.Anatomist()
return testAnatomist(a, interactive)
def testSocketImpl(interactive=True):
# test socket impl, not threaded
import anatomist.socket.api as pyanatomist
global mode
mode = 'socket mode'
a = pyanatomist.Anatomist()
return testAnatomist(a, interactive)
def test_assert(condition, message):
try:
assert(condition)
except AssertionError:
global failures
failures.append('%s: %s' % (mode, message))
print('** error: %s: %s **' % (mode, message))
def testAnatomist(a, interactive=True):
print("\n--- CreateWindowsBlock ---")
block = a.createWindowsBlock(3) # a block of windows with 3 columns
# in direct api the block object is really created only when the first
# window is added to it
print("block.internalRep = ", block.internalRep, ", block.nbCols = ",
block.nbCols)
test_assert(block.internalRep not in (None, 0), "block is invalid")
print("\n--- CreateWindow ---")
w1 = a.createWindow(wintype='Axial', block=block)
print("w1 : Axial window, added to the block. w1 = ", w1,
", block.internalRep = ", block.internalRep)
test_assert(w1 is not None, 'window w1 is None')
test_assert(w1.block == block, 'block in w1 is wrong')
w2 = a.createWindow(wintype='Sagittal', geometry=[10, 20, 200, 500],
block=block)
test_assert(w2 is not None, 'window w2 is None')
print(
"w2 : Sagittal window, added to the block. The geometry attribute is not taken into account because of the block, the window is resized to fit into the block.")
w3 = a.createWindow(wintype='Coronal', block=block, no_decoration=True)
print(
"w3 : Coronal window, added to the block (3rd column), thanks to the attribute no decoration, the window has no menus, buttons and so on...")
test_assert(w3 is not None, 'window w3 is None')
w4 = a.createWindow(wintype='3D', geometry=[10, 20, 200, 500])
print("w4 : 3D window, not in the block, with geometry attribute.")
test_assert(w4 is not None, 'window w4 is None')
w5 = a.createWindow(wintype='3D', no_decoration=True)
print("w5 : 3D window, not in the block, with no decoration.")
test_assert(w5 is not None, 'window w5 is None')
print("\n--- LoadObject ---")
o = a.loadObject(os.path.join(data_directory,
"subject01/subject01_Lwhite.mesh"), "objetO")
test_assert(o is not None, 'object o is None')
print("o : mesh Lhemi.mesh, renamed objecO, internalRep = ", o,
", o.__class__ = ", o.__class__)
o2 = a.loadObject(os.path.join(data_directory,
"subject01/subject01_Lwhite_curv.tex"),
"objetO2")
test_assert(o2 is not None, 'object o2 is None')
print("o2 : texture Lwhite_curv.tex, renamed objetO2, internalRep = ", o2)
o4 = a.loadObject(os.path.join(data_directory,
"roi/basal_ganglia.hie"))
test_assert(o4 is not None, 'object o4 is None')
print("o4 : nomenclature basal_ganglia.hie, internalRep = ", o4)
o3 = a.loadObject(os.path.join(data_directory,
"roi/basal_ganglia.arg"))
test_assert(o3 is not None, 'object o3 is None')
print("o3 : graph basal_ganglia.arg, internalRep = ", o3)
# this should fail
print(
'o5 : trying to load an object with wrong type (field restrict_object_type doesn\'t match the type of the object): it should fail.')
o5 = a.loadObject(filename=os.path.join(data_directory,
"subject01/subject01.nii"),
restrict_object_types={'Volume': ['FLOAT']})
# test_assert(o5 is None, 'object o5 is not None')
print('The error message is normal, o5 = ', o5)
o6 = a.loadObject(filename=os.path.join(data_directory,
"subject01/subject01.nii"),
restrict_object_types={'Volume': ['S16', 'FLOAT']})
test_assert(o6 is not None, 'object o6 is None')
print(
"o6 : volume subject01.ima, restrict_object_type match the object type. internalRep = ", o6)
o7 = a.loadObject(
filename=os.path.join(data_directory, "subject01/subject01.nii"))
test_assert(o7 is not None, 'object o7 is None')
print("o7 : same object")
cur = a.loadCursor(os.path.join(data_directory,
"subject01/subject01_Lhemi.mesh"))
test_assert(cur is not None, 'object cur is None')
print(
"cur : load Lhemi.mesh as a cursor. The object is not in the list of objects in Anatomist main window but can be selected as cursor in preferences. ")
test_assert(cur not in a.getObjects(),
'object cur is in Anatomist global list')
print("\n--- FusionObjects ---")
fus = a.fusionObjects([o, o2], "FusionTexSurfMethod", interactive)
test_assert(fus is not None, 'fusion fus is None')
print(
"fus : fusion of o and o2, method is FusionTexSurfMethod and askOrder is True, so a window opens to let the user choose the order of the objects in the fusion. internalRep = ", fus)
print("\n--- CreateReferential ---")
r = a.createReferential(os.path.join(
soma.config.BRAINVISA_SHARE,
"registration/Talairach-MNI_template-SPM.referential"))
test_assert(r is not None, 'referential r is None')
print(
"r : Referential loaded from the Talairach-MNI_template-SPM.referential. r.__class__ = ", r.__class__, ", internalRep = ", r, ", r.refUuid = ",
r.refUuid, ". This should not create a new referential because Talairach-MNI_template-SPM referential is already loaded in Anatomist. ")
test_assert(r == a.mniTemplateRef,
'referenrial r is not the MNI referential')
r2 = a.createReferential()
test_assert(r2 is not None, 'referential r2 is None')
print("r2 : new referential. internalRep = ", r2, ", refUuid = ",
r2.refUuid)
cr = a.centralRef
test_assert(cr is not None, 'central ref is None')
print("cr : central referential, ", cr, ", refUuid = ", cr.refUuid,
". This referential is already loaded in Anatomist.")
print("\n--- LoadTransformation ---")
t = a.loadTransformation(os.path.join(
data_directory,
"subject01/RawT1-subject01_default_acquisition_TO_Talairach-ACPC.trm"),
r2, cr)
test_assert(t is not None, 'transformation t is None')
print(
"t : loaded from the file chaos_TO_talairach.trm, as a transformation between r2 and cr. t.__class__ = ",
t.__class__, ", internalRep = ", t)
print("\n--- CreatePalette ---")
p = a.createPalette("maPalette")
test_assert(p is not None, 'palette p is None')
print(
"p : new palette named maPalette, added Anatomist list of palettes. p.__class__ = ",
p.__class__, ", internalRep = ", p)
print("\n--- GroupObjects ---")
g = a.groupObjects([o, o2])
test_assert(g is not None, 'group g is None')
print("g : new group of objects containing o and o2. g.__class__ = ",
g.__class__, ", internalRep = ", g)
test_assert(o in g.children and o2 in g.children,
'objects o or o2 are not children of group g')
print("\n--- linkWindows ---")
wg = a.linkWindows([w1, w2])
test_assert(wg is not None, 'window group wg is None')
print("wg : new group of windows containing w1 and w2. wg.__class__ = ",
wg.__class__, ", internalRep = ", wg)
print("\n--- GetInfos ---")
lo = a.getObjects()
test_assert(lo is not None, 'objects list lo is None')
print("\nObjects refererenced in current context : ", lo)
print("Total : ", len(lo))
nio = 79
if mode == "direct mode":
no = 79
nt = 6
nr = 3
else:
no = 9
nt = 1
# in socket mode r has a different ID as mniTemplateRef, but the same
# UUID, and it points to the same object in Anatomist. But we now
# see 4 refs from the client.
nr = 4
test_assert(len(lo) == no, 'wrong number of objects')
lio = a.importObjects(False) # top_level_only = False -> all objects
test_assert(lio is not None, 'objects list lio is None')
print(
"All objects (importing those that were not referenced in current context) : ", lio)
print("Total : ", len(lio))
print("-> Should be the same in direct implementation.")
test_assert(len(lio) == 79, 'wrong total number of objects')
lw = a.getWindows()
test_assert(lw is not None, 'windows list lw is None')
liw = a.importWindows()
test_assert(liw is not None, 'windows list liw is None')
print("\nGetWindows : ", len(lw), ", ImportWindows : ", len(liw))
print(liw)
test_assert(len(liw) == 5, 'wrong number of windows')
print("\nPalettes : ", a.getPalettes())
test_assert(len(a.getPalettes()) > 50, 'too few palettes')
lr = a.getReferentials()
test_assert(lr is not None, 'referentials list lr is None')
lir = a.importReferentials()
test_assert(lir is not None, 'referentials list lir is None')
print("\ngetReferentials : ", len(lr), ", importReferentials : ",
len(lir))
print(lir)
test_assert(len(lr) == nr, 'wrong referentials number: %d instead of %d'
% (len(lr), nr))
test_assert(len(lir) == nr,
'wrong imported referentials number: %d instead of %d'
% (len(lir), nr))
lt = a.getTransformations()
test_assert(lt is not None, 'transformations list lt is None')
lit = a.importTransformations()
test_assert(lit is not None, 'transformations list lit is None')
print("\ngetTransformations : ", len(lt), ", importTransformations : ",
len(lit))
test_assert(len(lt) == nt,
'wrong number of transformations: %d instead od %d'
% (len(lt), nt))
test_assert(len(lit) == 6,
'wrong number of imported transformations: %d instead of 6'
% len(lt))
sel = a.getSelection()
test_assert(sel is not None, 'selection sel is None')
print("\nSelections in default group", sel)
test_assert(len(sel) == 0, 'some objects are already selected')
print("\nCursor last pos", a.linkCursorLastClickedPosition())
print("Cursor last pos dans ref r2", a.linkCursorLastClickedPosition(r2))
print("\n--- AddObjects ---")
a.addObjects([fus], [w1, w2, w3])
print("Object fus added in windows w1, w2, and w3.")
test_assert(w1.objects == [fus], 'wrong objects in window w1')
print("\n--- RemoveObjects ---")
a.removeObjects([fus], [w2, w1])
print("Object fus removed from window w1 and w2.")
test_assert(len(w1.objects) == 0,
'objects still in window w1')
print("\n--- DeleteObjects ---")
# delete the list of objects to avoid keeping a reference on object that
# prevent from deleting it
del lo
del lio
a.deleteObjects([o7])
print("Delete object o7.")
test_assert(len(a.getObjects()) == nio - 1,
'wrong objects number after deletion of o7: %d instead of %d'
% (len(a.getObjects()), nio - 1))
print("\n--- AssignReferential ---")
a.assignReferential(r, [o2, w2])
print("Referential r assigned to object o2 and window w2.")
test_assert(w2.getReferential() == r, 'wrong referential in window w2')
test_assert(o2.referential is not None, 'No referential in object o6')
test_assert(o2.referential is not None and o2.referential == r,
'wrong referential in object o2: %s' % repr(o6.referential))
o6.assignReferential(r)
print(
"Referential r assigned to object o6. Should not have worked because o6 already has a transform to the MNI ref.")
test_assert(o6.referential is None or o6.referential != r,
'o6 referential has actually changed to r (wrong)')
print("\n--- camera ---")
a.camera([w3], zoom=1.5)
print("Set zoom to 1.5 in window w3.")
print("\n--- closeWindows ---")
# delete lists of windows to avoid keeping a reference that prevent from
# closing the window.
del lw
del liw
a.closeWindows([w4])
print("Close window w4.")
test_assert(len(a.getWindows()) == 4,
'wrong number of windows after deletion of w4: %d'
% len(a.getWindows()))
print("\n--- setMaterial ---")
o.addInWindows([w1])
mat = a.Material(diffuse=[0.5, 0.1, 0.1, 1], smooth_shading=1)
a.setMaterial([o], mat)
print("Add object o to the window w1 and change its material : ",
o.material)
test_assert(w1.objects == [o], 'wrong objects in w1')
test_assert(np.sum((np.array(o.getInfos()['material']['diffuse']) -
[0.5, 0.1, 0.1, 1]) ** 2) <= 1e-10,
'Material on o has not been updated correctly: %s'
% repr(o.getInfos()['material']['diffuse']))
print("\n--- setObjectPalette ---")
pal = a.getPalette("Blue-Red")
w6 = a.createWindow('Axial')
o6.addInWindows([w6])
a.setObjectPalette([o6], pal, minVal=0, maxVal=0.2)
print(
"Put object o6 in a new Axial window w6 and change its palette to Blue-Red with min and max values to 0 and 0.2")
test_assert(o6.getInfos()['palette']['palette'] == 'Blue-Red',
'Palette on o6 has not been set to "Blue-Red"')
print("\n--- setGraphParams ---")
a.setGraphParams(display_mode="mesh")
print("Set display mode (paint mode of objects in graph nodes) to mesh.")
print("\n--- AObject Methods---")
w7 = a.createWindow('3D')
o3.addInWindows([w7])
print("Put object o3 in new 3D window (w7). o3 attributes : filename : ",
o3.filename, ", material : ", o3.material, "objectType : ",
o3.objectType, ", children : ", o3.children)
o.addInWindows([w6])
o.removeFromWindows([w6])
print("\nAdd and remove object o from window w6.")
print(
"Try to delete o2. Should fail because the object is used in a fusion:")
o2.delete()
# Some methods are available in Anatomist class and Objects classes
# Anatomist.assignReferential -> AObject.assignReferential
# Anatomist.setMaterial -> AObject.setMaterial
# Anatomist.setObjectPalette -> AObject.setPalette
o4.assignReferential(r)
fus.setMaterial(mat)
o.setPalette(pal)
tex = fus.extractTexture()
test_assert(tex is not None, 'extracted texture is None')
print("\nExtract texture from object fus :", tex)
tex = fus.generateTexture()
test_assert(tex is not None, 'generated texture is None')
print("Generate a texture: tex =", tex)
fus2 = a.fusionObjects([o, tex], method="FusionTexSurfMethod")
fus2.addInWindows([w5])
print("Fusion the generated texture with object o : fus2 = ", fus2)
tmp_file = tempfile.mkstemp(suffix='.gii')
os.close(tmp_file[0])
fus.exportTexture(tmp_file[1])
a.sync() # wait for save operation to complete
test_assert(os.path.getsize(tmp_file[1]) != 0,
'saved texture file is empty')
print("fus texture is saved in file %s." % tmp_file[1])
tex = a.loadObject(tmp_file[1])
test_assert(tex is not None, 'could not re-read saved texture')
test_assert(tex.objectType == 'TEXTURE',
'loaded texture is not a texture...')
os.unlink(tmp_file[1])
os.unlink(tmp_file[1] + '.minf')
tmp_file = tempfile.mkstemp(suffix='.gii')
os.close(tmp_file[0])
o.save(tmp_file[1])
print("The object o is saved in the file %s." % tmp_file[1])
a.sync() # wait for save operation to complete
test_assert(os.path.getsize(tmp_file[1]) != 0, 'saved mesh file is empty')
mesh = a.loadObject(tmp_file[1])
test_assert(mesh is not None, 'could not re-read saved mesh')
test_assert(mesh.objectType == 'SURFACE', 'loaded mesh is not a mesh...')
os.unlink(tmp_file[1])
os.unlink(tmp_file[1] + '.minf')
print("\n--- AWindow Methods---")
print(
"Window attributes: w2.windowType = ", w2.windowType, ", w2.group = ",
w2.group)
test_assert(w2.windowType == 'Sagittal', 'w2 type is not Sagittal')
test_assert(w2.group == wg, 'w2 group is not wg')
# Some methods available in Anatomist class are also available directly in
# AWindows class.
w2.addObjects([o])
w2.removeObjects([o])
w2.camera(2)
w2.assignReferential(cr)
w2.addObjects([fus])
w2.moveLinkedCursor([150, 100, 60])
w6.showToolbox()
# opens the toolbox window. This toolbox will be empty if
# the window is empty. If there is an object on which it is
# possible to draw a roi, the roi toolbox will be shown.
print("\n--- AWindowsGroup Methods---")
wg.setSelection([fus])
print("Set fus object as selected in the group of windows wg : ")
print("-> selection in default group has not changed :", a.getSelection())
print("-> selection in the group of window wg :", a.getSelection(wg))
wg.unSelect([fus])
print("After unselect, selection in wg :", a.getSelection(wg))
g0 = a.getDefaultWindowsGroup() # the default group has the id 0
g0.setSelectionByNomenclature(o4, ['Caude_droit'])
print("Selection by nomenclature in default group - add 'Caude_droit':",
g0.getSelection())
g0.addToSelectionByNomenclature(o4, ['Caude_gauche'])
print("Selection by nomenclature default group - add 'Caude_gauche' :",
g0.getSelection())
g0.toggleSelectionByNomenclature(o4, ['Caude_gauche'])
print(
"Toggle selection by nomenclature in default group - toggle 'Caude_gauche' : ",
g0.getSelection())
print("\n--- APalette Methods---")
# set colors take as parameter a list of RGB components for colors :
# [r1,g1,b1,r2,g2,b2...]
p.setColors(colors=[100, 0, 0] * 20 + [0, 100, 0] * 20 + [0, 0, 100] * 20)
print("The colors of palette 'maPalette' has changed.")
print("\n--- ATransformation Methods---")
tmp_file = tempfile.mkstemp(suffix='.trm')
os.close(tmp_file[0])
t.save(tmp_file[1])
a.sync() # wait for save operation to complete
print("Save the transformation t in file %s." % tmp_file[1])
test_assert(os.path.getsize(tmp_file[1]) != 0,
'saved transformation file is empty')
os.unlink(tmp_file[1])
os.unlink(tmp_file[1] + '.minf')
# return objects and windows to keep a reference on them and avoid their
# destroying.
objects = a.getObjects()
windows = a.getWindows()
return (objects, windows)
def testBase():
# base module : simple interface, methods are not implemented
import anatomist.base as pyanatomist
a = pyanatomist.Anatomist()
w = a.createWindow('Axial')
print(w)
interactive = True
if len(sys.argv) >= 2 and "-b" in sys.argv[1:] or "--batch" in sys.argv[1:] \
or 'sphinx_gallery' in sys.modules:
interactive = False
print("\n**** TEST ANATOMIST API DIRECT IMPLEMENTATION ****\n")
res1 = testDirectImpl(interactive)
if not interactive:
del res1
print("\n**** TEST ANATOMIST API SOCKET IMPLEMENTATION ****\n")
res2 = testSocketImpl(interactive)
if not interactive:
del res2
if len(failures) != 0:
print('\n\n** tests have failed: **')
print('\n'.join(failures))
print()
raise RuntimeError('tests have failed:')
else:
print('\nTests OK.')
Total running time of the script: ( 0 minutes 0.000 seconds)