{ "cells": [ { "cell_type": "markdown", "id": "4d23bace", "metadata": {}, "source": [ "# Anatomist notebook extension demo\n", "\n", "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](https://github.com/brainvisa/casa-distro), and a recent build in python3 (jupyter extensions have been added only in python3 in this container)." ] }, { "cell_type": "code", "execution_count": null, "id": "166a1539", "metadata": {}, "outputs": [], "source": [ "import os\n", "from soma import aims\n", "doc = aims.carto.Paths.findResourceFile('doc/pyanatomist-5.1/sphinx/pyanatomist_notebook.html')\n", "casa = os.environ.get('CASA_HOST_DIR')\n", "if casa: # we are in a virtual container, replace with host path\n", " doc = os.sep.join(doc.split(os.sep)[-4:])\n", " doc = os.path.join(casa, doc)\n", "print('Doc is available at the following address:')\n", "print('file://' + doc)\n", "print('You can copy it and paste it in your web browser.')" ] }, { "cell_type": "markdown", "id": "3c8cbb18", "metadata": {}, "source": [ "First download and install a small dataset, if needed:" ] }, { "cell_type": "code", "execution_count": null, "id": "b0fbc3b4", "metadata": {}, "outputs": [], "source": [ "dl_url = 'https://brainvisa.info/download/data/morpho_demo.tar.bz2'\n", "from soma import aims\n", "install_dir = os.path.join(aims.carto.Paths.globalShared(), 'morpho_demo')\n", "temp_dirs = []\n", "if os.path.exists(install_dir):\n", " print('the data directory already exists. Assuming it is OK.')\n", "else:\n", " try:\n", " os.makedirs(install_dir)\n", " except:\n", " # maybe we don't have write permission in the directory\n", " # try again in a temp directory\n", " install_dir = tempfile.mkdtemp(prefix='ana_notebook_demo')\n", " temp_dirs.append(install_dir)\n", " \n", " # download demo data\n", " from six.moves.urllib.request import urlopen\n", " import tempfile\n", " import tarfile\n", " \n", " tmp_dl = tempfile.mkstemp(suffix='.tar.bz2')\n", " os.close(tmp_dl[0])\n", " with urlopen(dl_url) as f:\n", " with open(tmp_dl[1], 'wb') as g:\n", " g.write(f.read())\n", " # extract the archive\n", " with tarfile.open(tmp_dl[1], 'r') as tf:\n", " tf.extractall(install_dir)\n", "print('using data in:', install_dir)\n", "os.chdir(install_dir)" ] }, { "cell_type": "markdown", "id": "b58f26c2", "metadata": {}, "source": [ "The API is exactly the same as the \"regular\" Anatomist:" ] }, { "cell_type": "code", "execution_count": null, "id": "4a3ac04c", "metadata": {}, "outputs": [], "source": [ "import anatomist.notebook as ana\n", "a = ana.Anatomist()\n", "print(a.headless_info.__dict__)" ] }, { "cell_type": "code", "execution_count": null, "id": "50eabf78", "metadata": {}, "outputs": [], "source": [ "mri = a.loadObject('demo/morphee/t1mri/default_acquisition/morphee.nii.gz')\n", "seg = a.loadObject('demo/morphee/t1mri/default_acquisition/default_analysis/segmentation/Lgrey_white_morphee.nii.gz')\n", "w1 = a.createWindow('Axial')\n", "w2 = a.createWindow('Coronal')\n", "mri.addInWindows([w1, w2])\n", "seg.setPalette('Blue-Red-fusion')\n", "w2.addObjects(seg)\n", "w1.moveLinkedCursor([70., 120., 75.])" ] }, { "cell_type": "markdown", "id": "bb9a4367", "metadata": {}, "source": [ "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.\n", "\n", "\"expensive\" renderings such as Volume Rendering can be done without more overhead:" ] }, { "cell_type": "code", "execution_count": null, "id": "7174cbca", "metadata": {}, "outputs": [], "source": [ "fus2 = a.fusionObjects([mri, seg], method='Fusion2DMethod')\n", "a.execute('TexturingParams', objects=[fus2], texture_index=1, mode='linear_A_if_B_white')\n", "vol_render = a.fusionObjects([fus2], method='VolumeRenderingFusionMethod')\n", "vol_render.setPalette(minVal=0.25, maxVal=1.3)\n", "cut_vr = a.fusionObjects([vol_render], method='FusionClipMethod')\n", "w3 = a.createWindow('3D')\n", "w3.addObjects(cut_vr)\n", "w3.setControl('CutControl')" ] }, { "cell_type": "markdown", "id": "69b5b536", "metadata": {}, "source": [ "The view above is also interactive (use middle button to rotate, shift+middle to orient the cut plane, ctrl+middle to shift it)" ] }, { "cell_type": "markdown", "id": "34dc697c", "metadata": {}, "source": [ "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):" ] }, { "cell_type": "code", "execution_count": null, "id": "9649701f", "metadata": {}, "outputs": [], "source": [ "browser = a.createWindow('Browser')\n", "hist = a.createWindow('Matplotlib-histogram')\n", "mri.addInWindows([browser, hist])" ] }, { "cell_type": "markdown", "id": "5d66196c", "metadata": {}, "source": [ "Of course, meshes can also be displayed (as well as all objects supported by Anatomist):" ] }, { "cell_type": "code", "execution_count": null, "id": "396cda81", "metadata": {}, "outputs": [], "source": [ "mesh_l = a.loadObject('demo/morphee/t1mri/default_acquisition/default_analysis/segmentation/mesh/morphee_Lhemi.gii')\n", "mesh_r = a.loadObject('demo/morphee/t1mri/default_acquisition/default_analysis/segmentation/mesh/morphee_Rwhite.gii')\n", "nomenclature = a.loadObject(aims.carto.Paths.findResourceFile('nomenclature/hierarchy/sulcal_root_colors.hie'))\n", "sulci_r = a.loadObject('demo/morphee/t1mri/default_acquisition/default_analysis/folds/3.1/default_session_auto/Rmorphee_default_session_auto.arg')\n", "mesh_r.setMaterial(diffuse=[0.7, 1., 0.7, 1.])\n", "mesh_cut = a.fusionObjects([mesh_l, mri], method='FusionCutMeshMethod')\n", "w4 = a.createWindow('3D')\n", "w4.addObjects([mesh_cut, mesh_r, sulci_r])" ] }, { "cell_type": "markdown", "id": "11bc9677", "metadata": {}, "source": [ "It is also possible to embed 3D views only (without sliders and buttons):" ] }, { "cell_type": "code", "execution_count": null, "id": "f7fa0e3d", "metadata": {}, "outputs": [], "source": [ "view = a.createWindow('3D', only_3d=True)\n", "view.addObjects([mesh_cut, mri])\n", "view.camera(view_quaternion=[0.445286393165588, 0.11355659365654, 0.125850886106491, 0.879196524620056])" ] }, { "cell_type": "markdown", "id": "3c7d75e1", "metadata": {}, "source": [ "or with sliders but without buttons (as in the regular anatomist):" ] }, { "cell_type": "code", "execution_count": null, "id": "0ded812e", "metadata": {}, "outputs": [], "source": [ "w5 = a.createWindow('3D', no_decoration=True)\n", "w5.addObjects([mesh_cut, mri])\n", "w5.camera(view_quaternion=[0.445286393165588, 0.11355659365654, 0.125850886106491, 0.879196524620056])" ] }, { "cell_type": "markdown", "id": "51a3c7c6", "metadata": {}, "source": [ "If needed, we may cleanup the data installed temporarily..." ] }, { "cell_type": "code", "execution_count": null, "id": "5c739ad9", "metadata": {}, "outputs": [], "source": [ "import shutil\n", "for d in temp_dirs:\n", " shutil.rmtree(d)" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.9" } }, "nbformat": 4, "nbformat_minor": 5 }