{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Writing out a USGSCSM ISD from a PDS3 Messenger MDIS image"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import ale\n",
    "from ale.drivers.messenger_drivers import MessengerMdisPds3NaifSpiceDriver\n",
    "from ale.formatters.usgscsm_formatter import to_usgscsm\n",
    "import json\n",
    "import os"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Instantiating an ALE driver\n",
    "\n",
    "ALE drivers are objects that define how to acquire common ISD keys from an input image format, in this case we are reading in a PDS3 image using NAIF SPICE kernels for exterior orientation data. If the driver utilizes NAIF SPICE kernels, it is implemented as a [context manager](https://docs.python.org/3/reference/datamodel.html#context-managers) and will furnish metakernels when entering the context (i.e. when entering the `with` block) and free the metakernels on exit. This maintains the integrity of spicelib's internal data structures. These driver objects are short-lived and are input to a formatter function that consumes the API to create a serializable file format. `ale.formatters` contains available formatter functions. \n",
    "\n",
    "The default config file is located at `ale/config.yml` and is copied into your home directory at `.ale/config.yml` on first use of the library. The config file can be modified using a text editor. `ale.config` is loaded into memory as a dictionary. It is used to find metakernels for different missions. For example, there is an entry for MDIS that points to `/scratch/jlaura/spice/mess-e_v_h-spice-6-v1.0/messsp_1000/extras/mk` by default. If you want to use your own metakernels, you will need to update this path. For example, if the metakernels are located in `/data/mdis/mk/` the MDIS entry should be updated with this path. If you are using the default metakernels, then you do not need to update the path.\n",
    "\n",
    "ALE has a two step process for writing out an ISD: 1. Instantiate your driver (in this case `MessengerMdisPds3NaifSpiceDriver`) within a context and 2. pass the driver object into a formatter (in this case, `to_usgscsm`).  \n",
    "\n",
    "Requirements:\n",
    " * A PDS3 Messenger MDIS image\n",
    " * NAIF metakernels installed\n",
    " * Config file path for MDIS (ale.config.mdis) pointing to MDIS NAIF metakernel directory \n",
    " * A conda environment with ALE installed into it usisng the `conda install` command or created using the environment.yml file at the base of ALE."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "cassini: /usgs/cpkgs/isis3/data/cassini/kernels/mk/\n",
      "dawn: /data/spice/dawn-m_a-spice-6-v1.0/dawnsp_1000/extras/mk\n",
      "kaguya: /data/spice/SELENE/kernels/mk/\n",
      "lro: /scratch/jlaura/spice/lro-l-spice-6-v1.0/lrosp_1000/extras/mk/\n",
      "mdis: /scratch/jlaura/spice/mess-e_v_h-spice-6-v1.0/messsp_1000/extras/mk\n",
      "mro: /data/spice/mro-m-spice-6-v1.0/mrosp_1000/extras/mk\n",
      "spice_root: /data/spice/\n",
      "\n",
      "MDIS spice directory: /scratch/jlaura/spice/mess-e_v_h-spice-6-v1.0/messsp_1000/extras/mk\n"
     ]
    }
   ],
   "source": [
    "# printing config displays the yaml formatted string\n",
    "print(ale.config)\n",
    "\n",
    "# config object is a dictionary so it has the same access patterns \n",
    "print('MDIS spice directory:', ale.config['mdis'])\n",
    "\n",
    "# updating config for new MDIS path in this notebook \n",
    "# Note: this will not change the path in `.ale/config.yml`. This change only lives in the notebook.\n",
    "# ale.config['mdis'] = '/data/mdis/mk/'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "# change to desired PDS3 image path \n",
    "fileName = 'EN1072174528M.IMG'\n",
    "\n",
    "# metakernels are furnished when entering the context (with block) with a driver instance\n",
    "# most driver constructors simply accept an image path \n",
    "with MessengerMdisPds3NaifSpiceDriver(fileName) as driver:\n",
    "    # pass driver instance into formatter function\n",
    "    usgscsmString = to_usgscsm(driver)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Write ISD to disk \n",
    "\n",
    "ALE formatter functions generally return bytes or a string that can be written out to disk. ALE's USGSCSM formatter function returns a JSON encoded string that can be written out using any JSON library. \n",
    "\n",
    "USGSCSM requires the ISD to be colocated with the image file with a `.json` extension in place of the image extension."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "# load the json encoded string ISD\n",
    "usgscsm_dict = json.loads(usgscsmString)\n",
    "\n",
    "# strip the image file extension and append .json \n",
    "jsonFile = os.path.splitext(fileName)[0] + '.json'\n",
    "\n",
    "# write to disk \n",
    "with open(jsonFile, 'w') as fp:\n",
    "    json.dump(usgscsm_dict, fp)"
   ]
  }
 ],
 "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.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
