{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# PROMISE12 prostate segmentation demo"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Preparation:\n",
    "1) Make sure you have set up the PROMISE12 data set. If not, download it from https://promise12.grand-challenge.org/ (registration required) and run data/PROMISE12/setup.py\n",
    "\n",
    "2) Make sure you are in NiftyNet root, setting niftynet_path correctly to the path with the niftynet folder in it"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import os,sys \n",
    "niftynet_path=r'path/to/NiftyNet'\n",
    "os.chdir(niftynet_path)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "3) Make sure you have all the dependencies installed (replacing gpu with cpu for cpu-only mode):"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import pip\n",
    "#pip.main(['install','-r','requirements-gpu.txt'])\n",
    "pip.main(['install','-r','requirements-cpu.txt'])\n",
    "pip.main(['install', 'SimpleITK>=1.0.0'])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Training a network from the command line\n",
    "The simplest way to use NiftyNet is via the commandline net_segment.py script. Normally, this is done on the command line with a command like this from the NiftyNet root directory:\n",
    "\n",
    "```python net_segment.py train --conf demos/PROMISE12/promise12_demo_train_config.ini --max_iter 10```\n",
    "\n",
    "Notice that we use configuration file that is specific to this experiment. This file contains default settings. Also note that we can override these settings on the command line.\n",
    "\n",
    "To execute NiftyNet from within the notebook, you can run the following python code:  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import os\n",
    "import sys\n",
    "import niftynet\n",
    "sys.argv=['','train','-a','net_segment','--conf',os.path.join('demos','PROMISE12','promise12_demo_train_config.ini'),'--max_iter','10']\n",
    "niftynet.main()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now you have trained (a few iterations of) a deep learning network for medical image segmentation. If you have some time on your hands, you can finish training the network (by leaving off the max_iter argument) and try it out, by running the following command\n",
    "\n",
    "```python net_segment.py inference --conf demos/PROMISE12/promise12_demo_inference_config.ini```\n",
    "\n",
    "or the following python code in the Notebook"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import os\n",
    "import sys\n",
    "import niftynet\n",
    "sys.argv=['', 'inference','-a','net_segment','--conf',os.path.join('demos','PROMISE12','promise12_demo_inference_config.ini')]\n",
    "niftynet.main()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Otherwise, you can load up some pre-trained weights for the network:\n",
    "\n",
    "```python net_segment.py inference --conf demo/PROMISE12/promise12_demo_config.ini --model_dir demo/PROMISE12/pretrained```\n",
    "or the following python code in the Notebook"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true,
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "import os\n",
    "import sys\n",
    "import niftynet\n",
    "sys.argv=['', 'inference','-a','net_segment','--conf',os.path.join('demos','PROMISE12','promise12_demo_inference_config.ini'), '--model_dir', os.path.join('demos','PROMISE12','pretrained')]\n",
    "niftynet.main()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can find your segmented images in output/promise12_demo\n",
    "\n",
    "NiftyNet has taken care of a lot of details behind the scenes:\n",
    "1. Organizing data into a dataset of images and segmentation labels\n",
    "2. Building a deep leaning network (in this case, it is based on VNet by Milletari et al.)\n",
    "3. Added deep learning infrastruture, such as a loss function for segmentation, the ADAM optimizer.\n",
    "4. Added augmentation, where the images are zoomed and rotated a little bit for every training step so that you do not over-fit the data\n",
    "5. Run the training algorithm\n",
    "\n",
    "All of this was controlled by the configuration file.\n",
    "\n",
    "## The configuration file\n",
    "\n",
    " Let's take a closer look at the configuration file. Further details about the configuration settings are available in ```config/readme.md```"
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "[promise12]\n",
    "path_to_search = data/PROMISE12/TrainingData_Part1,data/PROMISE12/TrainingData_Part2,data/PROMISE12/TrainingData_Part3\n",
    "filename_contains = Case,mhd\n",
    "filename_not_contains = Case2,segmentation\n",
    "spatial_window_size = (64, 64, 64)\n",
    "interp_order = 3\n",
    "axcodes=(A, R, S)\n",
    "\n",
    "[label]\n",
    "path_to_search = data/PROMISE12/TrainingData_Part1,data/PROMISE12/TrainingData_Part2,data/PROMISE12/TrainingData_Part3\n",
    "filename_contains = Case,_segmentation,mhd\n",
    "filename_not_contains = Case2\n",
    "spatial_window_size = (64, 64, 64)\n",
    "interp_order = 3\n",
    "axcodes=(A, R, S)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "These lines define how NiftyNet organizes your data. In this case, in the ./data/PROMISE12 folder there is one T2-weighted MR image named 'Case??_T2.nii.gz' and one reference segmentation named 'Case??_segmentation.nii.gz' per patient. The images for each patient are automatically grouped because they share the same prefix 'Case??'. For training, we exclude patients Case20-Case26, and for inference, we only include patients Case20-Case26, so that our training and inference data are mutually exclusive."
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "[SYSTEM]\n",
    "cuda_devices = \"\"\n",
    "num_threads = 2\n",
    "num_gpus = 1\n",
    "model_dir = ./promise12_model"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "These lines are setting up some system parameters: which GPUs to use (in this case whatever is available), where to save the trained network parameters, and how many threads to use for queuing them up.\n",
    "\n",
    "The following lines specify network properties."
   ]
  },
  {
   "cell_type": "raw",
   "metadata": {},
   "source": [
    "[NETWORK]\n",
    "name = dense_vnet\n",
    "activation_function = prelu\n",
    "batch_size = 1\n",
    "\n",
    "# volume level preprocessing\n",
    "volume_padding_size = 0\n",
    "# histogram normalisation\n",
    "histogram_ref_file = standardisation_models.txt\n",
    "norm_type = percentile\n",
    "cutoff = (0.01, 0.99)\n",
    "normalisation = True\n",
    "whitening = True\n",
    "normalise_foreground_only=True\n",
    "foreground_type = otsu_plus\n",
    "multimod_foreground_type = and\n",
    "window_sampling = resize\n",
    "\n",
    "#how many images to queue up in advance so that the GPU isn't waiting for data\n",
    "queue_length = 8\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Summary\n",
    "\n",
    "In this demo \n",
    "1. you learned to run training and testing for a deep-learning-based segmentation pipeline from the command-line and from python code directly; \n",
    "2. you also learned about the NiftyNet configuration files, and how they control the learning and inference process; and \n",
    "3. you learned multiple ways to tell NiftyNet which data to use."
   ]
  }
 ],
 "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.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
