diff --git a/ale/__init__.py b/ale/__init__.py index 2c88f6c020ec3a78618819fbe38134c26052cef0..ee4529a99559a06144ee8b5fa8e5c414d95b1916 100644 --- a/ale/__init__.py +++ b/ale/__init__.py @@ -1,11 +1,29 @@ -from . import drivers -from . import formatters -from .drivers import load, loads - import os - +import pathlib +from shutil import copyfile +import yaml from pkg_resources import get_distribution, DistributionNotFound +class DotDict(dict): + """dot.notation access to dictionary attributes""""" + __getattr__ = dict.get + __setattr__ = dict.__setitem__ + __delattr__ = dict.__delitem__ + + def __str__(self): + return yaml.dump(dict(self)) + +home_path = os.path.expanduser('~') +config_dir = pathlib.Path(os.path.join(home_path, '.ale')) +config_file_path = pathlib.Path(os.path.join(home_path, '.ale', 'config.yml')) + +config_dir.mkdir(parents=True, exist_ok=True) + +if not config_file_path.is_file(): + copyfile(os.path.join(os.path.dirname(__file__), 'config.yml'), config_file_path) + +config = DotDict(yaml.load(open(config_file_path), Loader=yaml.FullLoader)) + try: _dist = get_distribution('ale') # Normalize case for Windows systems @@ -19,3 +37,7 @@ except DistributionNotFound: else: __version__ = _dist.version +# bring ale stuff into main ale module +from . import drivers +from . import formatters +from . drivers import load, loads diff --git a/ale/config.py b/ale/config.py deleted file mode 100644 index 0dd30a03ed96028aaa8b33f7849a9fc5ce50bb0b..0000000000000000000000000000000000000000 --- a/ale/config.py +++ /dev/null @@ -1,12 +0,0 @@ -""" -Config File -""" - -# Directory with metakernals -spice_root = "/data/spice/" -cassini = '/usgs/cpkgs/isis3/data/cassini/kernels/mk/' # Cassini ISS -mdis = '/data/spice/mess-e_v_h-spice-6-v1.0/messsp_1000/extras/mk' # Messenger -mro = '/data/spice/mro-m-spice-6-v1.0/mrosp_1000/extras/mk' # Mars Reconnaissance Orbiter -kaguya = '/data/spice/SELENE/kernels/mk/' -dawn = '/data/spice/dawn-m_a-spice-6-v1.0/dawnsp_1000/extras/mk' -lro = '/usgs/cpkgs/isis3/data/lro/kernels/mk/' # LRO diff --git a/ale/config.yml b/ale/config.yml new file mode 100644 index 0000000000000000000000000000000000000000..363647696790c943b5b82fdea6ca3b2a3ca0686b --- /dev/null +++ b/ale/config.yml @@ -0,0 +1,7 @@ +spice_root: "/data/spice/" +cassini: '/usgs/cpkgs/isis3/data/cassini/kernels/mk/' # Cassini ISS +mdis: '/data/spice/mess-e_v_h-spice-6-v1.0/messsp_1000/extras/mk' # Messenger +mro: '/data/spice/mro-m-spice-6-v1.0/mrosp_1000/extras/mk' # Mars Reconnaissance Orbiter +kaguya: '/data/spice/SELENE/kernels/mk/' +dawn: '/data/spice/dawn-m_a-spice-6-v1.0/dawnsp_1000/extras/mk' +lro: '/scratch/jlaura/spice/lro-l-spice-6-v1.0/lrosp_1000/extras/mk/' # LRO diff --git a/notebooks/write_LroLrocPds3LabelNaifSpiceDriver.ipynb b/notebooks/write_LroLrocPds3LabelNaifSpiceDriver.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..db4dd0d573114603a9ec0cb2a08e37d34dc89a7c --- /dev/null +++ b/notebooks/write_LroLrocPds3LabelNaifSpiceDriver.ipynb @@ -0,0 +1,141 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Writing out a USGSCSM ISD from a PDS3 LRO LROC NAC image" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import ale\n", + "from ale.drivers.lro_drivers import LroLrocPds3LabelNaifSpiceDriver\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 LRO that points to `/usgs/cpkgs/isis3/data/lro/kernels/mk/` by default. If you want to use your own metakernels, you will need to udpate this path. For example, if the metakernels are located in `/data/lrolrocnac/mk/` the LRO 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 `LroLrocPds3LabelNaifSpiceDriver`) within a context and 2. pass the driver object into a formatter (in this case, `to_usgscsm`). \n", + "\n", + "Requirements:\n", + " * A PDS3 LRO LROC NAC image\n", + " * NAIF metakernels installed\n", + " * Config file path for LRO (ale.config.lro) pointing to LRO 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: /data/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", + "LRO spice directory: /scratch/jlaura/spice/lro-l-spice-6-v1.0/lrosp_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('LRO spice directory:', ale.config['lro'])\n", + "\n", + "# updating config for new LRO 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['lro'] = '/data/lrolrocnac/mk/'" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "# change to desired PDS3 image path \n", + "fileName = 'M1142142198RE.IMG'\n", + "\n", + "# metakernels are furnsh-ed when entering the context (with block) with a driver instance\n", + "# most driver constructors simply accept an image path \n", + "with LroLrocPds3LabelNaifSpiceDriver(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.\n" + ] + }, + { + "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.3" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +}