Anatomist notebook extension demo¶
This notebook demonstrates the notebook variant of Anatomist. It runs inside Jupyter notebook. Paths in the demo assume that the notebook is run inside a casa-distro container, and a recent build in python3 (jupyter extensions have been added only in python3 in this container).
[1]:
import os
from soma import aims
ver = '.'.join(aims.__version__.split('.')[:2])
doc = aims.carto.Paths.findResourceFile(f'doc/pyanatomist-{ver}/sphinx/pyanatomist_notebook.html')
casa = os.environ.get('CASA_HOST_DIR')
if casa: # we are in a virtual container, replace with host path
doc = os.sep.join(doc.split(os.sep)[-4:])
doc = os.path.join(casa, doc)
print('Doc is available at the following address:')
print('file://' + doc)
print('You can copy it and paste it in your web browser.')
Doc is available at the following address:
file:///home_local/a-sac-ns-brainvisa/bbi-daily/brainvisa-web/build/share/doc/pyanatomist-6.0/sphinx/pyanatomist_notebook.html
You can copy it and paste it in your web browser.
First download and install a small dataset, if needed:
[2]:
dl_url = 'https://brainvisa.info/download/data/morpho_demo.tar.bz2'
from soma import aims
from soma.aims import demotools
install_dir = os.path.join(aims.carto.Paths.globalShared(), 'morpho_demo')
temp_dirs = []
try:
# download demo data
demotools.install_demo_data('morpho_demo.tar.bz2', install_dir=install_dir)
except Exception:
# maybe we don't have write permission in the directory
# try again in a temp directory
install_dir = tempfile.mkdtemp(prefix='ana_notebook_demo')
temp_dirs.append(install_dir)
# download demo data
demotools.install_demo_data('morpho_demo.tar.bz2', download_dir_dir=install_dir)
print('using data in:', install_dir)
os.chdir(install_dir)
download dir: /home_local/a-sac-ns-brainvisa/bbi-daily/brainvisa-web/build/share/brainvisa_demo
install dir: /home_local/a-sac-ns-brainvisa/bbi-daily/brainvisa-web/build/share/morpho_demo
already downloaded, skipping download.
installing morpho_demo.tar.bz2 ...
using data in: /home_local/a-sac-ns-brainvisa/bbi-daily/brainvisa-web/build/share/morpho_demo
The API is exactly the same as the “regular” Anatomist:
[3]:
import anatomist.notebook as ana
a = ana.Anatomist()
print(a.headless_info.__dict__)
Qt offscreen works.
starting QApplication offscreen.
Starting Anatomist.....
global modules: /home_local/a-sac-ns-brainvisa/bbi-daily/brainvisa-web/build/share/anatomist-6.0/python_plugins
home modules: /home/a-sac-ns-brainvisa/.anatomist/python_plugins
config file : /home/a-sac-ns-brainvisa/.anatomist/config/settings.cfg
loading module statsplotwindow
This plugin does not support propagateSizeHints()
loading module gltf_io
Anatomist started.
loading module valuesplotwindow
loading module anacontrolmenu
loading module ana_image_math
loading module histogram
loading module modelGraphs
loading module infowindow
loading module volumepalettes
loading module profilewindow
loading module simple_controls
loading module gradientpalette
loading module bundles_small_brains
loading module bsa_proba
loading module paletteViewer
loading module selection
loading module foldsplit
loading module bundles_split_by_cortical_regions
loading module meshsplit
loading module measure
loading module save_resampled
loading module palettecontrols
all python modules loaded
Anatomist started.
{'virtual_display_proc': None, 'original_display': None, 'display': None, 'glx': 2, 'virtualgl': None, 'headless': True, 'mesa': False, 'qtapp': None, 'qt_offscreen': True, 'qapp': <PyQt5.QtWidgets.QApplication object at 0x7c2c28084c10>}
[4]:
mri = a.loadObject('demo/morphee/t1mri/default_acquisition/morphee.nii.gz')
seg = a.loadObject('demo/morphee/t1mri/default_acquisition/default_analysis/segmentation/Lgrey_white_morphee.nii.gz')
w1 = a.createWindow('Axial')
w2 = a.createWindow('Coronal')
mri.addInWindows([w1, w2])
seg.setPalette('Blue-Red-fusion')
w2.addObjects(seg)
w1.moveLinkedCursor([70., 120., 75.])
This plugin does not support propagateSizeHints()
Multitexturing present
function glActiveTexture found.
function glClientActiveTexture found.
function glBlendEquation found.
function glTexImage3D found.
function glMultiTexCoord3f found.
function glBindFramebuffer found.
function glBindRenderbuffer found.
function glFramebufferTexture2D found.
function glGenFramebuffers found.
function glGenRenderbuffers found.
function glFramebufferRenderbuffer found.
function glRenderbufferStorage found.
function glCheckFramebufferStatus found.
function glDeleteRenderbuffers found.
function glDeleteFramebuffers found.
Number of texture units: 8
function glUniform1f found.
function glUniform1i found.
function glUniform4fv found.
function glGetUniformLocation found.
function glMultTransposeMatrixf found.
function glAttachShader found.
function glDetachShader found.
function glCompileShader found.
function glCreateProgram found.
function glCreateShader found.
function glDeleteProgram found.
function glDeleteShader found.
function glGetProgramiv found.
function glGetShaderiv found.
function glLinkProgram found.
function glShaderSource found.
function glUseProgram found.
GL_ARB_shadow present
GL_SGIX_shadow extension not available
GL_SGIX_depth_texture extension not available
GL_ARB_depth_texture extension present
GL_ARB_texture_cube_map extension present
GL_EXT_texture_cube_map extension present
Number of texture units: 8
This plugin does not support raise()
This plugin does not support propagateSizeHints()
This plugin does not support propagateSizeHints()
This plugin does not support raise()
This plugin does not support propagateSizeHints()
As you will note, views here are interactive and are displaying standard Anatomist views. 3D hardware is used when possible as in the headless variant of Anatomist. Displaying is a blit slower (thus less smooth) however because rendering is performed on server side, then compressed in JPEG, and transfered to the web browser.
“expensive” renderings such as Volume Rendering can be done without more overhead:
[5]:
fus2 = a.fusionObjects([mri, seg], method='Fusion2DMethod')
a.execute('TexturingParams', objects=[fus2], texture_index=1, mode='linear_A_if_B_white')
vol_render = a.fusionObjects([fus2], method='VolumeRenderingFusionMethod')
vol_render.setPalette(minVal=0.25, maxVal=1.3)
cut_vr = a.fusionObjects([vol_render], method='FusionClipMethod')
w3 = a.createWindow('3D')
w3.addObjects(cut_vr)
w3.setControl('CutControl')
This plugin does not support propagateSizeHints()
This plugin does not support raise()
This plugin does not support propagateSizeHints()
This plugin does not support propagateSizeHints()
This plugin does not support propagateSizeHints()
This plugin does not support propagateSizeHints()
This plugin does not support propagateSizeHints()
The view above is also interactive (use middle button to rotate, shift+middle to orient the cut plane, ctrl+middle to shift it)
Other kind of windows can be displayed also, but are not refreshed as often as needed. Only user input triggers updates (but moving the mouse focus in/out is enough):
[6]:
browser = a.createWindow('Browser')
hist = a.createWindow('Matplotlib-histogram')
mri.addInWindows([browser, hist])
This plugin does not support propagateSizeHints()
This plugin does not support raise()
This plugin does not support raise()
This plugin does not support propagateSizeHints()
This plugin does not support raise()
Of course, meshes can also be displayed (as well as all objects supported by Anatomist):
[7]:
mesh_l = a.loadObject('demo/morphee/t1mri/default_acquisition/default_analysis/segmentation/mesh/morphee_Lhemi.gii')
mesh_r = a.loadObject('demo/morphee/t1mri/default_acquisition/default_analysis/segmentation/mesh/morphee_Rwhite.gii')
nomenclature = a.loadObject(aims.carto.Paths.findResourceFile('nomenclature/hierarchy/sulcal_root_colors.hie'))
sulci_r = a.loadObject('demo/morphee/t1mri/default_acquisition/default_analysis/folds/3.1/default_session_auto/Rmorphee_default_session_auto.arg')
mesh_r.setMaterial(diffuse=[0.7, 1., 0.7, 1.])
mesh_cut = a.fusionObjects([mesh_l, mri], method='FusionCutMeshMethod')
w4 = a.createWindow('3D')
w4.addObjects([mesh_cut, mesh_r, sulci_r])
memory limit: 292459049779
Reading FGraph version 5.1
Warning: wrong filename_base in graph, trying to fix it
bounding box found : 49, 51, 2
127, 236, 85
This plugin does not support propagateSizeHints()
This plugin does not support raise()
This plugin does not support propagateSizeHints()
It is also possible to embed 3D views only (without sliders and buttons):
[8]:
view = a.createWindow('3D', only_3d=True)
view.addObjects([mesh_cut, mri])
view.camera(view_quaternion=[0.445286393165588, 0.11355659365654, 0.125850886106491, 0.879196524620056])
This plugin does not support propagateSizeHints()
This plugin does not support raise()
or with sliders but without buttons (as in the regular anatomist):
[9]:
w5 = a.createWindow('3D', no_decoration=True)
w5.addObjects([mesh_cut, mri])
w5.camera(view_quaternion=[0.445286393165588, 0.11355659365654, 0.125850886106491, 0.879196524620056])
This plugin does not support propagateSizeHints()
This plugin does not support raise()
This plugin does not support propagateSizeHints()
snap 1 : OpenGL error: invalid operation
If needed, we may cleanup the data installed temporarily…
[10]:
import shutil
for d in temp_dirs:
shutil.rmtree(d)
[ ]: