{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "Use cases of Axon python API\n",
    "============================\n",
    "\n",
    "Load Brainvisa\n",
    "--------------\n",
    "\n",
    "The following lines enable to load Brainvisa without the graphical user interface through a python script:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "('Qt backend:', 'PyQt5')\n",
      "Loading toolbox baby\n",
      "Loading toolbox bioprocessing\n",
      "Loading toolbox brainrat\n",
      "Loading toolbox connectomist\n",
      "Loading toolbox constellation\n",
      "Loading toolbox cortical_surface\n",
      "Loading toolbox data management\n",
      "Loading toolbox datamind\n",
      "Loading toolbox disco\n",
      "Loading toolbox freesurfer\n",
      "Loading toolbox morphologist\n",
      "Loading toolbox nuclearimaging\n",
      "Loading toolbox preclinical_imaging\n",
      "Loading toolbox structural_analysis\n",
      "Loading toolbox tms\n",
      "Loading toolbox tools\n",
      "Loading toolbox viewers\n",
      "Loading toolbox My processes\n",
      "The log file for this session is '/home/dr144257/.brainvisa/brainvisa2.log'\n",
      "Database /volatile/riviere/brainvisa/build-stable-qt5/share/brainvisa-share-4.5\n",
      "must be updated because the database file is too old.\n",
      "Database /volatile/riviere/basetests-3.1.0 must be updated because the database\n",
      "file is too old.\n",
      "Database /neurospin/hbp/Users/riviere/archi-sulci must be updated because the\n",
      "database file is too old.\n",
      "Database /neurospin/archi-private/Users/Analysis/2-Morphologist/DataBaseArchi\n",
      "must be updated because the database file is too old.\n",
      "/usr/lib/nvidia-340/libGL.so.340.101\n",
      "OpenGL lib already loaded. Using Xvfb will not be possible.\n",
      "The current Xvfb does not have a GLX extension. Aborting it.\n",
      "Headless Anatomist running in normal (non-headless) mode\n",
      "global modules: /volatile/riviere/brainvisa/build-stable-qt5/share/anatomist-4.5/python_plugins\n",
      "home   modules: /home/dr144257/.anatomist/python_plugins\n",
      "loading module selection\n",
      "loading module profilewindow\n",
      "loading module gradientpalette\n",
      "loading module bundles_split_by_cortical_regions\n",
      "loading module volumepalettes\n",
      "loading module histogram\n",
      "loading module foldsplit\n",
      "loading module bundles_small_brains\n",
      "loading module modelGraphs\n",
      "loading module bsa_proba\n",
      "loading module meshsplit\n",
      "loading module palettecontrols\n",
      "loading module paletteViewer\n",
      "loading module anacontrolmenu\n",
      "all python modules loaded\n",
      "Anatomist started.\n",
      "launchFreesurferCommand\n",
      "freesurfer_home_path: /i2bm/local/freesurfer\n",
      "running command: /volatile/riviere/brainvisa/build-stable-qt5/scripts/runFreesurferCommand.sh /i2bm/local/freesurfer/FreeSurferEnv.sh mri_convert -h\n",
      "launchFreesurferCommand OK\n",
      "exec: /volatile/riviere/brainvisa/build-stable-qt5/brainvisa/toolboxes/morphologist/startup.py\n",
      "/i2bm/local/fsl/data: parse directories and insert items\n",
      "/i2bm/local/fsl/data: 4 files are stored as 4 DiskItems in 0 seconds\n",
      "/i2bm/local/spm12-standalone/spm12_mcr/spm12: parse directories and insert items\n",
      "/i2bm/local/spm12-standalone/spm12_mcr/spm12: 8 files are stored as 8 DiskItems\n",
      "in 0 seconds\n"
     ]
    }
   ],
   "source": [
    "import brainvisa.axon\n",
    "brainvisa.axon.initializeProcesses()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "deletable": true,
    "editable": true
   },
   "source": [
    "Call a process\n",
    "--------------\n",
    "\n",
    "The module [brainvisa.processes](python_bv_processing.html#module-brainvisa.processes) manages the processes, pipelines and their execution.\n",
    "\n",
    "The object [brainvisa.processes.ExecutionContext](python_bv_processing.html#brainvisa.processes.ExecutionContext) enables to start a Brainvisa process using the method [brainvisa.processes.ExecutionContext.runProcess](python_bv_processing.html#brainvisa.processes.ExecutionContext.runProcess).\n",
    "When Brainvisa is loaded, a default execution context exists and is returned by the function [brainvisa.processes.defaultContext](python_bv_processing.html#brainvisa.processes.defaultContext)\n",
    "\n",
    "The following example will run the process Threshold on an image:\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": false,
    "deletable": true,
    "editable": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Traitement Seuillage démarré sur 2017/07/06 14:44\n",
      "Traitement Seuillage terminé sur 2017/07/06 14:44 (1 seconds)\n"
     ]
    }
   ],
   "source": [
    "import brainvisa.processes\n",
    "context = brainvisa.processes.defaultContext()\n",
    "\n",
    "# Just to get an example data for running the process\n",
    "from brainvisa.configuration.neuroConfig import getSharePath, bvShareDirectory\n",
    "import os\n",
    "example_data = os.path.join(getSharePath(), bvShareDirectory, \"anatomical_templates\", \"MNI152_T1_1mm_brain_mask.nii\")\n",
    "# creating a temporary file for the output\n",
    "output_data = context.temporary(\"NIFTI-1 image\")\n",
    "\n",
    "context.runProcess(\"threshold\", image_input=example_data, image_output=output_data, threshold1=100)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Select a step in a pipeline\n",
    "---------------------------\n",
    "\n",
    "In a pipeline, some steps may be optional and can be selected or unselected for execution. \n",
    "It is possible to select or unselect a step of a pipeline before running it through a python script. \n",
    "A pipeline is a process that have execution nodes. The method [brainvisa.processes.Process.executionNode](python_bv_processing.html#brainvisa.processes.Process.executionNode) returns an [brainvisa.processes.ExecutionNode](python_bv_processing.html#brainvisa.processes.ExecutionNode).\n",
    "The execution node of the pipeline contains child nodes, the name of these nodes can be obtained with the method [brainvisa.processes.ExecutionNode.childrenNames](python_bv_processing.html#brainvisa.processes.ExecutionNode.childrenNames).\n",
    "To get a specific child node, the method [brainvisa.processes.ExecutionNode.child](python_bv_processing.html#brainvisa.processes.ExecutionNode.child) can be used.\n",
    "\n",
    "The following examples gets an instance of the *convertOldDatabase* pipeline and unselects all its steps:\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "pipeline=brainvisa.processes.getProcessInstance(\"convertOldDatabase\")\n",
    "nodes=pipeline.executionNode()\n",
    "\n",
    "nodes.childrenNames()\n",
    "assert(nodes.childrenNames() == ['ConvertDatabase', 'CheckDatabase', 'CleanDatabase'])\n",
    "nodes.child(\"ConvertDatabase\").setSelected(0)\n",
    "assert(not nodes.child(\"ConvertDatabase\").isSelected())\n",
    "nodes.child(\"CheckDatabase\").setSelected(0)\n",
    "nodes.child(\"CleanDatabase\").setSelected(0)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The process instance can be given as a parameter for the [brainvisa.processes.ExecutionContext.runProcess](python_bv_processing.html#brainvisa.processes.ExecutionContext.runProcess) method instead of the process id.\n",
    "\n",
    "\n",
    "Query a database\n",
    "----------------\n",
    "\n",
    "At Brainvisa startup, an internal database and the database selected in the user's preferences are loaded. \n",
    "The list of databases ([brainvisa.data.sqlFSODatabase.SQLDatabases](python_bv_data.html#brainvisa.data.sqlFSODatabase.SQLDatabases)) is stored in the global variable [brainvisa.data.neuroHierarchy.databases](python_bv_data.html#brainvisa.data.neuroHierarchy.databases).\n",
    "Each database is an instance of the class [brainvisa.data.sqlFSODatabase.SQLDatabase](python_bv_data.html#brainvisa.data.sqlFSODatabase.SQLDatabases).\n",
    "Several methods enable to query a database or a list of databases. The results of queries are generally [brainvisa.data.neuroDiskItems.DiskItem](python_bv_data.html#brainvisa.data.neuroDiskItems.DiskItem) objects. A DiskItem represents data stored in files and indexed in a database with additionnal information.\n",
    "\n",
    "In the following example, a DiskItem is searched in the databases by filename:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "from brainvisa.data.neuroHierarchy import databases\n",
    "from brainvisa.data.neuroDiskItems import DiskItem\n",
    "\n",
    "item = databases.getDiskItemFromFileName(example_data)\n",
    "assert(isinstance(item, DiskItem))\n",
    "assert(str(item.type) == 'anatomical Mask Template')\n",
    "assert(str(item.format) == 'NIFTI-1 image')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Here is a request for all DiskItems of type \"anatomical Template\" with the value of *Size* attribute being \"1 mm\":"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "items = databases.findDiskItems({\"_type\" : \"anatomical Template\", \"Size\": \"1 mm\"})\n",
    "assert(str(items).startswith('<generator object findDiskItems'))\n",
    "model_filename = items.next().fileName()\n",
    "assert(model_filename.startswith(os.path.join(getSharePath(), bvShareDirectory, \"anatomical_templates\")))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The object [brainvisa.data.readdiskitem.ReadDiskItem](python_bv_data.html#brainvisa.data.readdiskitem.ReadDiskItem) enables to search for an existing DiskItem in the databases using the method [ReadDiskItem.findValue](python_bv_data.html#brainvisa.data.readdiskitem.ReadDiskItem.findValue). If the request is not precise enought and several DiskItems match, the method returns *None*."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "from brainvisa.data.readdiskitem import ReadDiskItem\n",
    "from brainvisa.configuration import neuroConfig\n",
    "rd = ReadDiskItem(\"anatomical Template\", \"Aims readable volume formats\")\n",
    "template = rd.findValue({\"Size\" : \"2 mm\"})\n",
    "assert(template is None)\n",
    "template = rd.findValue({\"Size\" : \"2 mm\", \"skull_stripped\": \"no\", \n",
    "                         \"_database\": neuroConfig.dataPath[0].directory})\n",
    "assert(template is not None)\n",
    "assert(template.fileName().startswith(os.path.join(getSharePath(), bvShareDirectory, \"anatomical_templates\")))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The object [brainvisa.data.writediskitem.WriteDiskItem](python_bv_data.html#brainvisa.data.writediskitem.WriteDiskItem) enables to create new DiskItems to write output data according to Brainvisa hierarchy of directories."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "from brainvisa.data.writediskitem import WriteDiskItem\n",
    "wd = WriteDiskItem(\"Raw T1 MRI\", \"NIFTI-1 image\")\n",
    "item = wd.findValue({\"protocol\" : 'test', \"subject\" : \"mysubject\"})\n",
    "# nothe that item is not None only if one (and only one) user database has been setup."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Quit Brainvisa\n",
    "--------------\n",
    "\n",
    "The function [brainvisa.axon.processes.cleanup](python_bv_processing.html#brainvisa.axon.processes.cleanup) should be called at the end of the script to quit properly Brainvisa."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 40,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "brainvisa.axon.cleanup()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 2",
   "language": "python",
   "name": "python2"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
