{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Add Continuous Borders Around Labelled Regions"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "from freesurfer_surface import Surface\n",
    "\n",
    "SUBJECTS_DIR = '../tests/subjects'\n",
    "surface = Surface.read_triangular(SUBJECTS_DIR + '/fabian/surf/lh.pial')\n",
    "surface.load_annotation_file(SUBJECTS_DIR + '/fabian/label/lh.aparc.annot')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "import numpy\n",
    "from freesurfer_surface import PolygonalChain, Vertex\n",
    "\n",
    "def unit_vector(vector: numpy.array) -> numpy.array:\n",
    "    return vector / numpy.linalg.norm(vector)\n",
    "\n",
    "def add_blocks_along(border_chain: PolygonalChain, length_add_mm: float,\n",
    "                     height_mm: float, width_mm: float):\n",
    "    for vertex_triplet_indices in border_chain.adjacent_vertex_indices(3):\n",
    "        vertex_triplet = surface.select_vertices(vertex_triplet_indices)\n",
    "        backward_vector = vertex_triplet[0] - vertex_triplet[1]\n",
    "        forward_vector = vertex_triplet[2] - vertex_triplet[1]\n",
    "        forward_vector = unit_vector(forward_vector) \\\n",
    "                         * (numpy.linalg.norm(forward_vector) + length_add_mm)\n",
    "        upward_vector = unit_vector(numpy.cross(backward_vector, forward_vector)) * height_mm / 2\n",
    "        sideward_vector = unit_vector(numpy.cross(upward_vector, forward_vector)) * width_mm / 2\n",
    "        base_corners = [vertex_triplet[1] + v for v in [-upward_vector -sideward_vector,\n",
    "                                                        -upward_vector +sideward_vector,\n",
    "                                                        +upward_vector +sideward_vector,\n",
    "                                                        +upward_vector -sideward_vector]]\n",
    "        top_corners = [v + forward_vector for v in base_corners]\n",
    "        base_indices = [surface.add_vertex(Vertex(*coords)) for coords in base_corners]\n",
    "        top_indices = [surface.add_vertex(Vertex(*coords)) for coords in top_corners]\n",
    "        for surface_indices in [base_indices, top_indices]:\n",
    "            surface.add_rectangle(surface_indices)\n",
    "        for i in range(4):\n",
    "            j = (i + 1) % 4\n",
    "            surface.add_rectangle((base_indices[i], base_indices[j],\n",
    "                                   top_indices[j], top_indices[i]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "#8: inferiorparietal (borders: 1)\n",
      "#17: paracentral (borders: 1)\n",
      "#22: postcentral (borders: 1)\n",
      "#24: precentral (borders: 1)\n",
      "#29: superiorparietal (borders: 1)\n"
     ]
    }
   ],
   "source": [
    "for label in filter(lambda l: 'central' in l.name or 'parietal' in l.name,\n",
    "                    surface.annotation.labels.values()):\n",
    "    borders = list(surface.find_label_border_polygonal_chains(label))\n",
    "    print('#{}: {} (borders: {})'.format(label.index, label.name, len(borders)))\n",
    "    for border in borders:\n",
    "        add_blocks_along(border, length_add_mm=0.2,\n",
    "                         height_mm=1.5, width_mm=1.0)\n",
    "            \n",
    "surface.write_triangular('border.lh.pial')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "```sh\n",
    "freeview --surface examples/border.lh.pial:annot=tests/subjects/fabian/label/lh.aparc.annot\n",
    "```"
   ]
  }
 ],
 "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.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}