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