diff --git a/isis/notebooks/crop_themis.ipynb b/isis/notebooks/crop_themis.ipynb new file mode 100644 index 0000000000000000000000000000000000000000..f2e139173d0a9620ce90570d4a8d3f6f379ae330 --- /dev/null +++ b/isis/notebooks/crop_themis.ipynb @@ -0,0 +1,221 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "import os.path\n", + "import datetime\n", + "\n", + "import pvl\n", + "import numpy as np\n", + "\n", + "import matplotlib.pyplot as plt" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "themis_file = '/Path/to/themis/raw_data.QUB'\n", + "image_file = themis_file" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "header = pvl.load(image_file)\n", + "header" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "with open(image_file, 'rb') as f:\n", + " # -1 offset obtained from ISIS, record offset likely one based \n", + " # so subtract one as we need it to be zero based\n", + " image_offset = int((header['^SPECTRAL_QUBE'] - 1) * header['RECORD_BYTES'])\n", + "\n", + " f.seek(image_offset)\n", + " b_image_data = f.read()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "n_bands = header['SPECTRAL_QUBE']['CORE_ITEMS'][header['SPECTRAL_QUBE']['AXIS_NAME'].index('BAND')]\n", + "# n_bands = 5\n", + "n_lines = header['SPECTRAL_QUBE']['CORE_ITEMS'][header['SPECTRAL_QUBE']['AXIS_NAME'].index('LINE')]\n", + "n_lines = 10\n", + "\n", + "if 'LINE_SUFFIX_ITEM_BYTES' in header['SPECTRAL_QUBE'].keys():\n", + " n_lines += 2\n", + " \n", + "line_length = header['RECORD_BYTES']\n", + "# Add line suffix offset to handle reading two extra lines from each band\n", + "if 'LINE_SUFFIX_ITEM_BYTES' in header['SPECTRAL_QUBE'].keys():\n", + " bytes_per_band = ((header['SPECTRAL_QUBE']['CORE_ITEMS'][header['SPECTRAL_QUBE']['AXIS_NAME'].index('LINE')]) + header['SPECTRAL_QUBE']['LINE_SUFFIX_ITEM_BYTES']) * line_length\n", + "else:\n", + " bytes_per_band = (header['SPECTRAL_QUBE']['CORE_ITEMS'][1]) * line_length\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "image_data = []\n", + "# Custom numpy data type to handle appropriate DN conversion\n", + "# Not necessary but was done for debugging purposes\n", + "dt = np.dtype(np.int16)\n", + "dt = dt.newbyteorder('>')\n", + "\n", + "for i in range(n_bands):\n", + "# image_data.append([])\n", + " for j in range(n_lines):\n", + " start = (j*line_length) + (bytes_per_band * i)\n", + " stop = ((j+1)*line_length) + (bytes_per_band * i)\n", + " image_sample = np.frombuffer(b_image_data[start:stop], dtype=dt, count=line_length//2)\n", + " image_data.append(image_sample)\n", + "image_data = np.array(image_data, dtype=dt)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "plt.figure(0, figsize=(20, 20))\n", + "plt.imshow(image_data)\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "class RealIsisCubeLabelEncoder(pvl.encoder.ISISEncoder): \n", + " def encode_time(self, value):\n", + " if value.microsecond:\n", + " second = u'%02d.%06d' % (value.second, value.microsecond)\n", + " else:\n", + " second = u'%02d' % value.second\n", + "\n", + " time = u'%02d:%02d:%s' % (value.hour, value.minute, second)\n", + " return time" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "image_fn, image_ext = os.path.splitext(image_file)\n", + "crop = '_cropped'\n", + "themis_image_fn = image_fn + crop + image_ext\n", + "themis_image_bn = os.path.basename(themis_image_fn)\n", + "\n", + "grammar = pvl.grammar.ISISGrammar()\n", + "grammar.comments+=((\"#\", \"\\n\"), )\n", + "encoder = RealIsisCubeLabelEncoder()\n", + "\n", + "if header['SPECTRAL_QUBE']['DESCRIPTION'] == '':\n", + " header['SPECTRAL_QUBE']['DESCRIPTION'] = \" \"\n", + "\n", + "# Overwrite the number of lines in the label\n", + "if 'LINE_SUFFIX_ITEM_BYTES' in header['SPECTRAL_QUBE'].keys():\n", + " n_lines -= 2\n", + "header['SPECTRAL_QUBE']['CORE_ITEMS'][header['SPECTRAL_QUBE']['AXIS_NAME'].index('LINE')] = n_lines\n", + "\n", + "# Calculate the new offset\n", + "# Run this twice as the change to the header will change the headers length.\n", + "# Then add two to handle an extra new line character later on\n", + "header['^SPECTRAL_QUBE'] = pvl.collections.Units(len(pvl.dumps(header, encoder=encoder, grammar=grammar)), 'BYTES')\n", + "header['^SPECTRAL_QUBE'] = pvl.collections.Units(len(pvl.dumps(header, encoder=encoder, grammar=grammar)) + 2, 'BYTES')\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "label_fn, label_ext = os.path.splitext(themis_file)\n", + "out_label = label_fn + crop + label_ext\n", + "\n", + "pvl.dump(header, out_label, encoder=encoder, grammar=grammar)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "with open(themis_image_fn, 'ab+') as f:\n", + " b_reduced_image_data = image_data.tobytes()\n", + " f.seek(0, 2)\n", + " f.write(b'\\n')\n", + " f.write(b_reduced_image_data)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "new_header = pvl.load(out_label)\n", + "new_header" + ] + }, + { + "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.1" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +}