{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os, pvl, shapely, itertools\n",
    "from plio.io import io_controlnetwork\n",
    "import networkx as nx\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "from pysis import isis\n",
    "from pysis.exceptions import ProcessError"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Network and cube list to check"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "data_dir = 'europa/'\n",
    "good_net = '11ESMORPHY01_Island9_Add.net'\n",
    "bad_net = '11ESMORPHY01_Island9.net'\n",
    "cube_list = '11ESMORPHY01_Island9.lis'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Get the image serial numbers and footprints"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "cube_files = {}\n",
    "labels = {}\n",
    "for line in open(os.path.join(data_dir, cube_list)):\n",
    "    cube_file = os.path.join(data_dir, line.strip())\n",
    "    try:\n",
    "        sn = isis.getsn(from_=cube_file).strip().decode('utf-8')\n",
    "    except ProcessError as e:\n",
    "        print(e.stderr)\n",
    "        raise\n",
    "    cube_files[sn] = cube_file\n",
    "    labels[sn] = pvl.load(cube_file)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "from shapely.wkt import dumps, loads\n",
    "footprints = {}\n",
    "for sn, file in cube_files.items():\n",
    "    footprint_label = labels[sn]['Polygon']\n",
    "    footprint_start_bytes = footprint_label['StartByte']\n",
    "    footprint_bytes = footprint_label['Bytes']\n",
    "    with open(file, 'rb') as fh:\n",
    "        fh.seek(footprint_start_bytes - 1)\n",
    "        footprint_binary = fh.read(footprint_bytes)\n",
    "    footprints[sn] = loads(footprint_binary.decode('utf-8'))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Create the overlap graph"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "footprint_graph = nx.Graph()\n",
    "for sn in footprints.keys():\n",
    "    footprint_graph.add_node(sn)\n",
    "for sn1, sn2 in itertools.combinations(footprints.keys(), 2):\n",
    "    if (footprints[sn1].intersects(footprints[sn2])):\n",
    "        footprint_graph.add_edge(sn1, sn2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Create the network graph"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "cnet_df = io_controlnetwork.from_isis(os.path.join(data_dir, bad_net))\n",
    "#cnet_df = io_controlnetwork.from_isis(os.path.join(data_dir, good_net))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "network_graph = nx.Graph()\n",
    "for point_id, group in cnet_df.groupby('id'):\n",
    "    for sn1, sn2 in itertools.combinations(group['serialnumber'].unique(), 2):\n",
    "        network_graph.add_edge(sn1, sn2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Find the overlaps without control points"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Image Galileo/SSI/04206267.13 and Galileo/SSI/04206267.26 overlap but are not directly connected!\n",
      "  Image Galileo/SSI/04206267.13 overlap ratio: 0.04741618092597161\n",
      "  Image Galileo/SSI/04206267.26 overlap ratio: 0.04802103744420974\n",
      "Image Galileo/SSI/04206267.65 and Galileo/SSI/04206268.00 overlap but are not directly connected!\n",
      "  Image Galileo/SSI/04206267.65 overlap ratio: 0.08328826088823132\n",
      "  Image Galileo/SSI/04206268.00 overlap ratio: 0.08298887506906216\n"
     ]
    }
   ],
   "source": [
    "bad_overlaps = []\n",
    "for source, dest in footprint_graph.edges:\n",
    "    if not network_graph.has_edge(source, dest):\n",
    "        print(f\"Image {source} and {dest} overlap but are not directly connected!\")\n",
    "        intersection = footprints[source].intersection(footprints[dest])\n",
    "        print(f\"  Image {source} overlap ratio: {intersection.area / footprints[source].area}\")\n",
    "        print(f\"  Image {dest} overlap ratio: {intersection.area / footprints[dest].area}\")\n",
    "        bad_overlaps.append(intersection)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Plot the overlaps without control points"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 21412 characters]\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig = plt.figure()\n",
    "for _, footprint in footprints.items():\n",
    "    for poly in footprint:\n",
    "        plt.plot(*poly.exterior.xy, c='g')\n",
    "for poly in bad_overlaps:\n",
    "    plt.fill(*poly.exterior.xy, c='r')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "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.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
