From 3035ac9d5dfa7c8e5c7cfd904fb2347a5f7ee8f7 Mon Sep 17 00:00:00 2001 From: AustinSanders Date: Mon, 2 Nov 2020 09:54:01 -0700 Subject: [PATCH] Initial cropping utilities (#4094) * Initial cropping utilities * Moved notebooks from scripts to notebooks directory --- isis/notebooks/crop_chandrayaan.ipynb | 457 ++++++++++++++++++++++++++ isis/notebooks/crop_kaguya.ipynb | 350 ++++++++++++++++++++ isis/notebooks/crop_leisa.ipynb | 173 ++++++++++ isis/notebooks/crop_marci.ipynb | 236 +++++++++++++ 4 files changed, 1216 insertions(+) create mode 100644 isis/notebooks/crop_chandrayaan.ipynb create mode 100644 isis/notebooks/crop_kaguya.ipynb create mode 100644 isis/notebooks/crop_leisa.ipynb create mode 100644 isis/notebooks/crop_marci.ipynb diff --git a/isis/notebooks/crop_chandrayaan.ipynb b/isis/notebooks/crop_chandrayaan.ipynb new file mode 100644 index 0000000000..a8e2643bd5 --- /dev/null +++ b/isis/notebooks/crop_chandrayaan.ipynb @@ -0,0 +1,457 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import pvl\n", + "import struct\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import datetime\n", + "import os.path\n", + "import binascii" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "class RealIsisCubeLabelEncoder(pvl.encoder.IsisCubeLabelEncoder): \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.encode('utf-8')" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "chan_file = '/home/arsanders/testData/chandrayaan/forwardDescending/input/M3G20081129T171431_V03_L1B.LBL'\n", + "image_file = chan_file" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "header = pvl.load(chan_file)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [], + "source": [ + "rdn_file = os.path.dirname(chan_file) + \"/\"+ header['RDN_FILE']['^RDN_IMAGE']\n", + "obs_file = os.path.dirname(chan_file) + \"/\"+ header['OBS_FILE']['^OBS_IMAGE']\n", + "loc_file = os.path.dirname(chan_file) + \"/\"+ header['LOC_FILE']['^LOC_IMAGE']\n", + "tab_file = os.path.dirname(chan_file) + \"/\"+ header['UTC_FILE']['^UTC_TIME_TABLE']" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "with open(rdn_file, 'rb') as f:\n", + " # From the end, seek n_records * record_size backwards\n", + " f.seek(-header['RDN_FILE']['RECORD_BYTES'] * header['RDN_FILE']['FILE_RECORDS'], 2)\n", + " b_image_data = f.read()" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [], + "source": [ + "n_lines = 5\n", + "line_length = header['RDN_FILE']['RDN_IMAGE']['LINE_SAMPLES'] * (header['RDN_FILE']['RDN_IMAGE']['SAMPLE_BITS']//8)" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "def read_chandrayaan(b_image_data, line_length, n_lines, n_bands):\n", + " image_data = []\n", + " for j in range(n_lines*n_bands):\n", + " image_sample = np.frombuffer(b_image_data[j*line_length:(j+1)*line_length],\n", + " dtype=np.float32, count=int(line_length/4))\n", + " image_data.append(image_sample)\n", + " return np.array(image_data)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [], + "source": [ + "n_bands = header['RDN_FILE']['RDN_IMAGE']['BANDS']\n", + "n_output_bands = 3\n", + "image_data = read_chandrayaan(b_image_data, line_length, n_lines, n_bands)\n", + "cropped_image_data = image_data[np.where(np.arange(image_data.shape[0]) % n_bands < n_output_bands)]\n", + "#cropped_image_data = image_data" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(15, 304)" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cropped_image_data.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "plt.imshow(cropped_image_data[0::n_output_bands])" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "with open(obs_file, 'rb') as f:\n", + " # From the end, seek n_records * record_size backwards\n", + " f.seek(-header['OBS_FILE']['RECORD_BYTES'] * header['OBS_FILE']['FILE_RECORDS'], 2)\n", + " b_image_data = f.read()" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [], + "source": [ + "n_bands = header['OBS_FILE']['OBS_IMAGE']['BANDS']\n", + "obs_image_data = read_chandrayaan(b_image_data, line_length, n_lines, n_bands)" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(50, 304)" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "obs_image_data.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "plt.imshow(obs_image_data[1::10])" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": {}, + "outputs": [], + "source": [ + "with open(loc_file, 'rb') as f:\n", + " # From the end, seek n_records * record_size backwards\n", + " f.seek(-header['LOC_FILE']['RECORD_BYTES'] * header['LOC_FILE']['FILE_RECORDS'], 2)\n", + " b_image_data = f.read()" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [], + "source": [ + "line_length = header['LOC_FILE']['LOC_IMAGE']['LINE_SAMPLES'] * (header['LOC_FILE']['LOC_IMAGE']['SAMPLE_BITS']//8)\n", + "n_bands = header['LOC_FILE']['LOC_IMAGE']['BANDS']\n", + "image_data = []\n", + "for j in range(n_lines*n_bands):\n", + " image_sample = np.frombuffer(b_image_data[j*line_length:(j+1)*line_length],\n", + " dtype=np.float64, count=int(line_length/8))\n", + " image_data.append(image_sample)\n", + "loc_image_data = np.array(image_data)" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 19, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "plt.imshow(loc_image_data[0::n_bands])" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": {}, + "outputs": [], + "source": [ + "rdn_fn, rdn_ext = os.path.splitext(rdn_file)\n", + "obs_fn, obs_ext = os.path.splitext(obs_file)\n", + "loc_fn, loc_ext = os.path.splitext(loc_file)\n", + "tab_fn, tab_ext = os.path.splitext(tab_file)\n", + "\n", + "mini_rdn_fn = rdn_fn + '_cropped' + rdn_ext\n", + "mini_rdn_bn = os.path.basename(mini_rdn_fn)\n", + "\n", + "mini_obs_fn = obs_fn + '_cropped' + obs_ext\n", + "mini_obs_bn = os.path.basename(mini_obs_fn)\n", + "\n", + "mini_loc_fn = loc_fn + '_cropped' + loc_ext\n", + "mini_loc_bn = os.path.basename(mini_loc_fn)\n", + "\n", + "mini_tab_fn = tab_fn + '_cropped' + tab_ext\n", + "mini_tab_bn = os.path.basename(mini_tab_fn)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": {}, + "outputs": [], + "source": [ + "header['RDN_FILE']['^RDN_IMAGE'] = mini_rdn_bn\n", + "header['OBS_FILE']['^OBS_IMAGE'] = mini_obs_bn\n", + "header['LOC_FILE']['^LOC_IMAGE'] = mini_loc_bn\n", + "header['UTC_FILE']['^UTC_TIME_TABLE'] = mini_tab_bn\n", + "\n", + "header['RDN_FILE']['FILE_RECORDS'] = n_lines\n", + "header['RDN_FILE']['RDN_IMAGE']['LINES'] = n_lines\n", + "header['RDN_FILE']['RDN_IMAGE']['BANDS'] = n_output_bands\n", + "header['RDN_FILE']['RECORD_BYTES'] = int(n_output_bands * (header['RDN_FILE']['RDN_IMAGE']['SAMPLE_BITS']/8) *header['RDN_FILE']['RDN_IMAGE']['LINE_SAMPLES'])\n", + "\n", + "header['LOC_FILE']['FILE_RECORDS'] = n_lines\n", + "header['LOC_FILE']['LOC_IMAGE']['LINES'] = n_lines\n", + "\n", + "header['OBS_FILE']['FILE_RECORDS'] = n_lines\n", + "header['OBS_FILE']['OBS_IMAGE']['LINES'] = n_lines\n", + "\n", + "header['UTC_FILE']['FILE_RECORDS'] = n_lines\n", + "header['UTC_FILE']['UTC_TIME_TABLE']['ROWS'] = n_lines" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "metadata": {}, + "outputs": [], + "source": [ + "label_fn, label_ext = os.path.splitext(chan_file)\n", + "out_label = label_fn + '_cropped' + label_ext\n", + "pvl.dump(header, out_label, cls=RealIsisCubeLabelEncoder)" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "with open(mini_rdn_fn, 'wb+') as f:\n", + " b_reduced_image_data = cropped_image_data.tobytes()\n", + " f.seek(0, 2)\n", + " f.write(b_reduced_image_data)" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [], + "source": [ + "with open(mini_loc_fn, 'wb+') as f:\n", + " b_reduced_image_data = loc_image_data.tobytes()\n", + " f.seek(0, 2)\n", + " f.write(b_reduced_image_data)" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "with open(mini_obs_fn, 'wb+') as f:\n", + " b_reduced_image_data = obs_image_data.tobytes()\n", + " f.seek(0, 2)\n", + " f.write(b_reduced_image_data)" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [], + "source": [ + "with open(tab_file) as f:\n", + " head = [next(f) for x in range(n_lines)]\n", + " head = \"\".join(head)\n", + "with open(mini_tab_fn, 'w+') as f:\n", + " f.write(head)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python autocnet", + "language": "python", + "name": "autocnet" + }, + "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": 2 +} diff --git a/isis/notebooks/crop_kaguya.ipynb b/isis/notebooks/crop_kaguya.ipynb new file mode 100644 index 0000000000..9dec7ac3eb --- /dev/null +++ b/isis/notebooks/crop_kaguya.ipynb @@ -0,0 +1,350 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 80, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import pvl\n", + "import struct\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import datetime\n", + "import os.path\n", + "import binascii" + ] + }, + { + "cell_type": "code", + "execution_count": 120, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "#kaguya_file = '/scratch/arsanders/kaguyatc/TC2S2B0_01_03043N107E3384.img'\n", + "#kaguya_file = '/home/arsanders/testData/apollo/AS15-M-1450.lbl'\n", + "kaguya_file = '/home/arsanders/testData/marci/MOI_000009_0294_MU_00N044W.IMG'\n", + "image_file = kaguya_file" + ] + }, + { + "cell_type": "code", + "execution_count": 121, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "header = pvl.load(kaguya_file)" + ] + }, + { + "cell_type": "code", + "execution_count": 122, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "PVLModule([\n", + " ('PDS_VERSION_ID', 'PDS3')\n", + " ('FILE_NAME', 'MOI_000009_0294_MU_00N044W.IMG')\n", + " ('RECORD_TYPE', 'FIXED_LENGTH')\n", + " ('RECORD_BYTES', 128)\n", + " ('FILE_RECORDS', 2259)\n", + " ('LABEL_RECORDS', 11)\n", + " ('^IMAGE', 12)\n", + " ('SPACECRAFT_NAME', 'MARS_RECONNAISSANCE_ORBITER')\n", + " ('INSTRUMENT_NAME', 'MARS COLOR IMAGER')\n", + " ('INSTRUMENT_HOST_NAME', 'MARS RECONNAISSANCE ORBITER')\n", + " ('MISSION_PHASE_NAME', 'POSTMOI')\n", + " ('TARGET_NAME', 'MARS')\n", + " ('INSTRUMENT_ID', 'MARCI')\n", + " ('PRODUCER_ID', 'MRO_MARCI_TEAM')\n", + " ('DATA_SET_ID', 'MRO-M-MARCI-2-EDR-L0-V1.0')\n", + " ('PRODUCT_CREATION_TIME', datetime.datetime(2007, 5, 17, 18, 31, 28))\n", + " ('SOFTWARE_NAME', 'makepds05 $Revision: 1.7 $')\n", + " ('UPLOAD_ID', 'UNK')\n", + " ('ORIGINAL_PRODUCT_ID', '4A_05_0001000200')\n", + " ('PRODUCT_ID', 'MOI_000009_0294_MU_00N044W')\n", + " ('START_TIME', datetime.datetime(2006, 3, 24, 4, 25, 53, 96000))\n", + " ('STOP_TIME', datetime.datetime(2006, 3, 24, 4, 55, 48, 296000))\n", + " ('SPACECRAFT_CLOCK_START_COUNT', '827641567:30')\n", + " ('SPACECRAFT_CLOCK_STOP_COUNT', 'N/A')\n", + " ('INTERFRAME_DELAY', Units(value=3.2, units='SECONDS'))\n", + " ('FOCAL_PLANE_TEMPERATURE', Units(value=240.9, units='K'))\n", + " ('SAMPLE_BIT_MODE_ID', 'SQROOT')\n", + " ('LINE_EXPOSURE_DURATION', Units(value=3112.237, units='MSEC'))\n", + " ('SAMPLING_FACTOR', 8)\n", + " ('SAMPLE_FIRST_PIXEL', 0)\n", + " ('FILTER_NAME', {'LONG_UV', 'SHORT_UV'})\n", + " ('RATIONALE_DESC', 'Post-MOI image of Argyre and Mare Erythraeum region')\n", + " ('DATA_QUALITY_DESC', 'OK')\n", + " ('ORBIT_NUMBER', 9)\n", + " ('IMAGE',\n", + " {'CHECKSUM': 12820826,\n", + " 'LINES': 2248,\n", + " 'LINE_PREFIX_BYTES': 0,\n", + " 'LINE_SAMPLES': 128,\n", + " 'LINE_SUFFIX_BYTES': 0,\n", + " 'SAMPLE_BITS': 8,\n", + " 'SAMPLE_BIT_MASK': 255,\n", + " 'SAMPLE_TYPE': 'UNSIGNED_INTEGER'})\n", + "])" + ] + }, + "execution_count": 122, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "header" + ] + }, + { + "cell_type": "code", + "execution_count": 123, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "12" + ] + }, + "execution_count": 123, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "header[\"^IMAGE\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 132, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "with open(kaguya_file, 'rb') as f:\n", + " try:\n", + " image_offset = header[\"^IMAGE\"].value-(header['IMAGE']['SAMPLE_BITS']//8)\n", + " f.seek(image_offset)\n", + " b_image_data = f.read()\n", + " except AttributeError:\n", + " # If detached label, \"^IMAGE\" will be a list.\n", + " image_file = os.path.dirname(kaguya_file) + \"/\" + header[\"^IMAGE\"][0]\n", + " image_offset = header[\"^IMAGE\"][1].value\n", + " with open(image_file, 'rb') as im_f:\n", + " b_image_data = im_f.read()" + ] + }, + { + "cell_type": "code", + "execution_count": 133, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "n_lines = 40\n", + "line_length = header['IMAGE']['LINE_SAMPLES'] * (header['IMAGE']['SAMPLE_BITS']//8)" + ] + }, + { + "cell_type": "code", + "execution_count": 137, + "metadata": {}, + "outputs": [ + { + "ename": "ValueError", + "evalue": "buffer is smaller than requested size", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", + "\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0mimage_data\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mj\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mn_lines\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0mimage_sample\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfrombuffer\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mb_image_data\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mj\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0mline_length\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mj\u001b[0m\u001b[0;34m+\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0mline_length\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdtype\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mint16\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mcount\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mline_length\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 4\u001b[0m \u001b[0mimage_data\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mimage_sample\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0mimage_data\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0marray\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mimage_data\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mValueError\u001b[0m: buffer is smaller than requested size" + ] + } + ], + "source": [ + "image_data = []\n", + "for j in range(n_lines):\n", + " image_sample = np.frombuffer(b_image_data[j*line_length:(j+1)*line_length], dtype=np.int16, count=int(line_length/2))\n", + " image_data.append(image_sample)\n", + "image_data = np.array(image_data)" + ] + }, + { + "cell_type": "code", + "execution_count": 136, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(40, 64)" + ] + }, + "execution_count": 136, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "image_data.shape" + ] + }, + { + "cell_type": "code", + "execution_count": 135, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 135, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "plt.imshow(image_data)" + ] + }, + { + "cell_type": "code", + "execution_count": 112, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "class RealIsisCubeLabelEncoder(pvl.encoder.IsisCubeLabelEncoder): \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.encode('utf-8')" + ] + }, + { + "cell_type": "code", + "execution_count": 113, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "image_fn, image_ext = os.path.splitext(image_file)\n", + "mini_image_fn = image_fn + '_cropped' + image_ext\n", + "mini_image_bn = os.path.basename(mini_image_fn)\n", + "\n", + "# Overwrite the number of lines in the label\n", + "header['IMAGE']['LINES'] = n_lines\n", + "\n", + "if kaguya_file != image_file:\n", + " # If detached label, point the mini label to the mini image\n", + " header['^IMAGE'] = [mini_image_bn, pvl._collections.Units(1, 'BYTES')]\n", + " header['FILE_NAME'] = mini_image_bn\n", + "else:\n", + " # If attached label, calculate the new offset\n", + " header['^IMAGE'] = pvl._collections.Units(len(pvl.dumps(header, cls=RealIsisCubeLabelEncoder)), 'BYTES')" + ] + }, + { + "cell_type": "code", + "execution_count": 114, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "label_fn, label_ext = os.path.splitext(kaguya_file)\n", + "out_label = label_fn + '_cropped' + label_ext\n", + "\n", + "pvl.dump(header, out_label, cls=RealIsisCubeLabelEncoder)" + ] + }, + { + "cell_type": "code", + "execution_count": 115, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "with open(mini_image_fn, 'ab+') as f:\n", + " b_reduced_image_data = image_data.tobytes()\n", + " f.seek(0, 2)\n", + " f.write(b_reduced_image_data)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python autocnet", + "language": "python", + "name": "autocnet" + }, + "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": 2 +} diff --git a/isis/notebooks/crop_leisa.ipynb b/isis/notebooks/crop_leisa.ipynb new file mode 100644 index 0000000000..47b9b21426 --- /dev/null +++ b/isis/notebooks/crop_leisa.ipynb @@ -0,0 +1,173 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "from astropy.io import fits" + ] + }, + { + "cell_type": "code", + "execution_count": 41, + "metadata": {}, + "outputs": [], + "source": [ + "#test_data_filename = './tsts/badfiles/input/lsb_0034933739_0x53c_sci_1.fit'\n", + "#test_data_filename = './tsts/calib/input/lsb_0034933739_0x53c_sci_1.fit'\n", + "#test_data_filename = './tsts/qualityReplacement/input/lsb_0034931099_0x53c_sci_1.fit'\n", + "test_data_filename = './tsts/raw/input/lsb_0030594839_0x53d_eng_1.fit'\n", + "original_fits = fits.open(test_data_filename, mode='readonly')" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[, ]" + ] + }, + "execution_count": 42, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "original_fits" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Filename: ./tsts/raw/input/lsb_0030594839_0x53d_eng_1.fit\n", + "No. Name Ver Type Cards Dimensions Format\n", + " 0 PRIMARY 1 PrimaryHDU 283 (256, 256, 319) int16 \n", + " 1 HOUSEKEEPING 1 BinTableHDU 183 46R x 75C [J, B, B, B, B, B, B, I, I, I, I, I, I, I, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, I, I, I, B, B, B, B, B, B, B, B, B, B, B, B, I, I, I, I, I, I, I, I, I, J, J, B, I, I, I, I, I, I, I, I, I, J] \n" + ] + } + ], + "source": [ + "fits.info(test_data_filename)" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "## This fuction creates and populates the HDU (Header Data Unit) for each FITS extension\n", + "## I fully expect that this function would need to be modified for other special-case FITS data.\n", + "def to_extension(header, data):\n", + " hdu = fits.ImageHDU()\n", + " hdu.data = data\n", + " \n", + " # Special case:\n", + " # These FITS files do not meet the FITS standard, so two keywords needed to be added to the header of \n", + " # most extensions so that astropy would write out a FITS file without error. \n", + " \n", + " # Don't add 'PCOUNT' or 'GCOUNT' to the primary image or the first extension\n", + " # These keywords aren't needed for the primary image and the first extenison already has them \n", + " if not('SIMPLE' in header.keys() or 'WCSNAME' in header.keys()):\n", + " header['PCOUNT'] = 0\n", + " header['GCOUNT'] = 1\n", + " hdu.header = header\n", + " return hdu" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "new_fits = fits.HDUList() \n", + "\n", + "# Copy cropped data from original FITS file into new FITS file.\n", + "for hdu in original_fits:\n", + " try:\n", + " new_fits.append(to_extension(hdu.header, hdu.data[0:3, 0:25]))\n", + " except:\n", + " pass" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "new_fits.writeto(\"./cropped/raw.fit\", overwrite='True')" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Filename: ./cropped/raw.fit\n", + "No. Name Ver Type Cards Dimensions Format\n", + " 0 PRIMARY 1 PrimaryHDU 280 (256, 25, 3) int16 \n" + ] + } + ], + "source": [ + "fits.info(\"./cropped/raw.fit\")\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "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.5.3" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/isis/notebooks/crop_marci.ipynb b/isis/notebooks/crop_marci.ipynb new file mode 100644 index 0000000000..41fffec6be --- /dev/null +++ b/isis/notebooks/crop_marci.ipynb @@ -0,0 +1,236 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 48, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "import pvl\n", + "import struct\n", + "import matplotlib.pyplot as plt\n", + "import numpy as np\n", + "import datetime\n", + "import os.path\n", + "import binascii" + ] + }, + { + "cell_type": "code", + "execution_count": 70, + "metadata": {}, + "outputs": [], + "source": [ + "#kaguya_file = '/scratch/arsanders/kaguyatc/TC2S2B0_01_03043N107E3384.img'\n", + "#kaguya_file = '/home/arsanders/testData/apollo/AS15-M-1450.lbl'\n", + "marci_file = '/home/arsanders/testData/marci/T02_001251_1292_MU_00N237W.IMG'\n", + "image_file = marci_file" + ] + }, + { + "cell_type": "code", + "execution_count": 71, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "header = pvl.load(marci_file)" + ] + }, + { + "cell_type": "code", + "execution_count": 72, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "with open(marci_file, 'rb') as f:\n", + " try:\n", + " image_offset = ((header[\"^IMAGE\"]-1) * header[\"RECORD_BYTES\"]) - (header['IMAGE']['SAMPLE_BITS']//8)\n", + " f.seek(image_offset)\n", + " b_image_data = f.read()\n", + " except AttributeError:\n", + " # If detached label, \"^IMAGE\" will be a list.\n", + " image_file = os.path.dirname(marci_file) + \"/\" + header[\"^IMAGE\"][0]\n", + " image_offset = header[\"^IMAGE\"][1].value\n", + " with open(image_file, 'rb') as im_f:\n", + " b_image_data = im_f.read()" + ] + }, + { + "cell_type": "code", + "execution_count": 73, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "n_lines = 100\n", + "line_length = header['IMAGE']['LINE_SAMPLES'] * (header['IMAGE']['SAMPLE_BITS']//8)" + ] + }, + { + "cell_type": "code", + "execution_count": 74, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "image_data = []\n", + "for j in range(n_lines):\n", + " image_sample = np.frombuffer(b_image_data[j*line_length:(j+1)*line_length], dtype=np.uint8, count=int(line_length))\n", + " image_data.append(image_sample)\n", + "image_data = np.array(image_data)" + ] + }, + { + "cell_type": "code", + "execution_count": 75, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 75, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "plt.imshow(image_data)" + ] + }, + { + "cell_type": "code", + "execution_count": 76, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "class RealIsisCubeLabelEncoder(pvl.encoder.IsisCubeLabelEncoder): \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.encode('utf-8')" + ] + }, + { + "cell_type": "code", + "execution_count": 77, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "image_fn, image_ext = os.path.splitext(image_file)\n", + "mini_image_fn = image_fn + '_cropped' + image_ext\n", + "mini_image_bn = os.path.basename(mini_image_fn)\n", + "\n", + "# Overwrite the number of lines in the label\n", + "header['IMAGE']['LINES'] = n_lines\n", + "\n", + "if marci_file != image_file:\n", + " # If detached label, point the mini label to the mini image\n", + " #header['^IMAGE'] = [mini_image_bn, pvl._collections.Units(1, 'BYTES')]\n", + " header['FILE_NAME'] = mini_image_bn\n", + "else:\n", + " # If attached label, calculate the new offset\n", + " header['^IMAGE'] = pvl._collections.Units(len(pvl.dumps(header, cls=RealIsisCubeLabelEncoder)), 'BYTES')" + ] + }, + { + "cell_type": "code", + "execution_count": 78, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "label_fn, label_ext = os.path.splitext(marci_file)\n", + "out_label = label_fn + '_cropped' + label_ext\n", + "\n", + "pvl.dump(header, out_label, cls=RealIsisCubeLabelEncoder)" + ] + }, + { + "cell_type": "code", + "execution_count": 79, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "with open(mini_image_fn, 'ab+') as f:\n", + " b_reduced_image_data = image_data.tobytes()\n", + " #f.seek(0, 2)\n", + " f.write(b_reduced_image_data)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python autocnet", + "language": "python", + "name": "autocnet" + }, + "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": 2 +}