{ "cells": [ { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "import os\n", "import sys\n", "from functools import singledispatch\n", "import warnings\n", "\n", "import pandas as pd\n", "import numpy as np\n", "import math\n", "import pyproj\n", "\n", "# sys.path.insert(0, \"/home/tthatcher/Desktop/Projects/Plio/plio\")\n", "\n", "from plio.examples import get_path\n", "from plio.io.io_bae import read_gpf, read_ipf\n", "import plio.io.io_controlnetwork as cn\n", "import plio.io.isis_serial_number as sn" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "# Reads a .atf file and outputs all of the \n", "# .ipf, .gpf, .sup, .prj, and path to locate the \n", "# .apf file (should be the same as all others) \n", "def read_atf(atf_file):\n", " with open(atf_file) as f:\n", "\n", " files = []\n", " ipf = []\n", " sup = []\n", " files_dict = []\n", " \n", " # Grabs every PRJ, GPF, SUP, and IPF image from the ATF file\n", " for line in f:\n", " if line[-4:-1] == 'prj' or line[-4:-1] == 'gpf' or line[-4:-1] == 'sup' or line[-4:-1] == 'ipf' or line[-4:-1] == 'atf':\n", " files.append(line)\n", " \n", " files = np.array(files)\n", " \n", " # Creates appropriate arrays for certain files in the right format\n", " for file in files:\n", " file = file.strip()\n", " file = file.split(' ')\n", "\n", " # Grabs all the IPF files\n", " if file[1].endswith('.ipf'):\n", " ipf.append(file[1])\n", "\n", " # Grabs all the SUP files\n", " if file[1].endswith('.sup'):\n", " sup.append(file[1])\n", "\n", " files_dict.append(file)\n", "\n", " # Creates a dict out of file lists for GPF, PRJ, IPF, and ATF\n", " files_dict = (dict(files_dict))\n", " \n", " # Sets the value of IMAGE_IPF to all IPF images\n", " files_dict['IMAGE_IPF'] = ipf\n", " \n", " # Sets the value of IMAGE_SUP to all SUP images\n", " files_dict['IMAGE_SUP'] = sup\n", " \n", " # Sets the value of PATH to the path of the ATF file\n", " files_dict['PATH'] = os.path.dirname(os.path.abspath(atf_file))\n", " \n", " return files_dict\n", "\n", "# converts columns l. and s. to isis\n", "def line_sample_size(record, path):\n", " with open(os.path.join(path, record['ipf_file'] + '.sup')) as f:\n", " for i, line in enumerate(f):\n", " if i == 2:\n", " img_index = line.split('\\\\')\n", " img_index = img_index[-1].strip()\n", " img_index = img_index.split('.')[0]\n", " \n", " if i == 3:\n", " line_size = line.split(' ')\n", " line_size = line_size[-1].strip()\n", " assert int(line_size) > 0, \"Line number {} from {} is a negative number: Invalid Data\".format(line_size, record['ipf_file'])\n", " \n", " if i == 4:\n", " sample_size = line.split(' ')\n", " sample_size = sample_size[-1].strip()\n", " assert int(sample_size) > 0, \"Sample number {} from {} is a negative number: Invalid Data\".format(sample_size, record['ipf_file'])\n", " break\n", " \n", " \n", " line_size = int(line_size)/2.0 + record['l.'] + 1\n", " sample_size = int(sample_size)/2.0 + record['s.'] + 1\n", " return sample_size, line_size, img_index\n", " \n", "# converts known to ISIS keywords\n", "def known(record):\n", " if record['known'] == 0:\n", " return 'Free'\n", " \n", " elif record['known'] == 1 or record['known'] == 2 or record['known'] == 3:\n", " return 'Constrained'\n", " \n", "# converts +/- 180 system to 0 - 360 system\n", "def to_360(num):\n", " return num % 360\n", "\n", "# ocentric to ographic latitudes\n", "def oc2og(dlat, dMajorRadius, dMinorRadius):\n", " try: \n", " dlat = math.radians(dlat)\n", " dlat = math.atan(((dMajorRadius / dMinorRadius)**2) * (math.tan(dlat)))\n", " dlat = math.degrees(dlat)\n", " except:\n", " print (\"Error in oc2og conversion\")\n", " return dlat\n", "\n", "# ographic to ocentric latitudes\n", "def og2oc(dlat, dMajorRadius, dMinorRadius):\n", " try:\n", " dlat = math.radians(dlat)\n", " dlat = math.atan((math.tan(dlat) / ((dMajorRadius / dMinorRadius)**2)))\n", " dlat = math.degrees(dlat)\n", " except:\n", " print (\"Error in og2oc conversion\")\n", " return dlat\n", "\n", "# gets eRadius and pRadius from a .prj file\n", "def get_axis(file):\n", " with open(file) as f:\n", " from collections import defaultdict\n", "\n", " files = defaultdict(list)\n", " \n", " for line in f:\n", " \n", " ext = line.strip().split(' ')\n", " files[ext[0]].append(ext[-1])\n", " \n", " eRadius = float(files['A_EARTH'][0])\n", " pRadius = eRadius * (1 - float(files['E_EARTH'][0]))\n", " \n", " return eRadius, pRadius\n", " \n", "# function to convert lat_Y_North to ISIS_lat\n", "def lat_ISIS_coord(record, semi_major, semi_minor):\n", " ocentric_coord = og2oc(record['lat_Y_North'], semi_major, semi_minor)\n", " coord_360 = to_360(ocentric_coord)\n", " return coord_360\n", "\n", "# function to convert long_X_East to ISIS_lon\n", "def lon_ISIS_coord(record, semi_major, semi_minor):\n", " ocentric_coord = og2oc(record['long_X_East'], semi_major, semi_minor)\n", " coord_360 = to_360(ocentric_coord)\n", " return coord_360\n", "\n", "def body_fix(record, semi_major, semi_minor):\n", " ecef = pyproj.Proj(proj='geocent', a=semi_major, b=semi_minor)\n", " lla = pyproj.Proj(proj='latlon', a=semi_major, b=semi_minor)\n", " lon, lat, height = pyproj.transform(lla, ecef, record['long_X_East'], record['lat_Y_North'], record['ht'])\n", " return lon, lat, height\n", " \n", "\n", "# applys transformations to columns\n", "def apply_transformations(atf_dict, df):\n", " prj_file = os.path.join(atf_dict['PATH'], atf_dict['PROJECT'].split('\\\\')[-1])\n", " \n", " eRadius, pRadius = get_axis(prj_file)\n", " \n", " df['s.'], df['l.'], df['image_index'] = (zip(*df.apply(line_sample_size, path = atf_dict['PATH'], axis=1)))\n", " df['known'] = df.apply(known, axis=1)\n", " df['lat_Y_North'] = df.apply(lat_ISIS_coord, semi_major = eRadius, semi_minor = pRadius, axis=1)\n", " df['long_X_East'] = df.apply(lon_ISIS_coord, semi_major = eRadius, semi_minor = pRadius, axis=1)\n", " df['long_X_East'], df['lat_Y_North'], df['ht'] = zip(*df.apply(body_fix, semi_major = eRadius, semi_minor = pRadius, axis = 1))\n", " \n", "def socet2isis(prj_file):\n", " # Read in and setup the atf dict of information\n", " atf_dict = read_atf(prj_file)\n", " \n", " # Get the gpf and ipf files using atf dict\n", " gpf_file = os.path.join(atf_dict['PATH'], atf_dict['GP_FILE']);\n", " ipf_list = [os.path.join(atf_dict['PATH'], i) for i in atf_dict['IMAGE_IPF']]\n", " \n", " # Read in the gpf file and ipf file(s) into seperate dataframes\n", " gpf_df = read_gpf(gpf_file)\n", " ipf_df = read_ipf(ipf_list)\n", "\n", " # Check for differences between point ids using each dataframes\n", " # point ids as a reference\n", " gpf_pt_idx = pd.Index(pd.unique(gpf_df['point_id']))\n", " ipf_pt_idx = pd.Index(pd.unique(ipf_df['pt_id']))\n", "\n", " point_diff = ipf_pt_idx.difference(gpf_pt_idx)\n", "\n", " if len(point_diff) != 0:\n", " warnings.warn(\"The following points found in ipf files missing from gpf file: \\n\\n{}. \\\n", " \\n\\nContinuing, but these points will be missing from the control network\".format(list(point_diff)))\n", " \n", " # Merge the two dataframes on their point id columns\n", " socet_df = ipf_df.merge(gpf_df, left_on='pt_id', right_on='point_id')\n", " \n", " # Apply the transformations\n", " apply_transformations(atf_dict, socet_df)\n", " \n", " # Define column remap for socet dataframe\n", " column_remap = {'l.': 'y', 's.': 'x',\n", " 'res_l': 'LineResidual', 'res_s': 'SampleResidual', 'known': 'Type',\n", " 'lat_Y_North': 'AprioriY', 'long_X_East': 'AprioriX', 'ht': 'AprioriZ',\n", " 'sig0': 'AprioriLatitudeSigma', 'sig1': 'AprioriLongitudeSigma', 'sig2': 'AprioriRadiusSigma'}\n", " \n", " # Rename the columns using the column remap above\n", " socet_df.rename(columns = column_remap, inplace=True)\n", " \n", " # Return the socet dataframe to be converted to a control net\n", " return socet_df\n", "\n", "# creates a dict of serial numbers with the cub being the key\n", "def serial_numbers(images, path, extension):\n", " serial_dict = dict()\n", " \n", " for image in images:\n", " snum = sn.generate_serial_number(os.path.join(path, image + extension))\n", " snum = snum.replace('Mars_Reconnaissance_Orbiter', 'MRO')\n", " serial_dict[image] = snum\n", " return serial_dict" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "scrolled": false }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/Users/adampaquette/anaconda/envs/pysat/lib/python3.6/site-packages/ipykernel_launcher.py:173: UserWarning: The following points found in ipf files missing from gpf file: \n", "\n", "['P03_002226_1895_XI_09N203W_15', 'P03_002226_1895_XI_09N203W_16', 'P03_002226_1895_XI_09N203W_17', 'P03_002226_1895_XI_09N203W_18', 'P03_002226_1895_XI_09N203W_19', 'P03_002226_1895_XI_09N203W_20', 'P03_002226_1895_XI_09N203W_21', 'P03_002226_1895_XI_09N203W_22', 'P03_002226_1895_XI_09N203W_24', 'P03_002226_1895_XI_09N203W_26', 'P03_002226_1895_XI_09N203W_30', 'P03_002226_1895_XI_09N203W_31', 'P03_002226_1895_XI_09N203W_32', 'P03_002226_1895_XI_09N203W_34', 'P03_002226_1895_XI_09N203W_36', 'P03_002226_1895_XI_09N203W_37', 'P03_002226_1895_XI_09N203W_44', 'P03_002226_1895_XI_09N203W_48', 'P03_002226_1895_XI_09N203W_49', 'P03_002226_1895_XI_09N203W_56', 'P03_002226_1895_XI_09N203W_57', 'P03_002226_1895_XI_09N203W_61', 'P03_002226_1895_XI_09N203W_62', 'P03_002226_1895_XI_09N203W_63', 'P03_002226_1895_XI_09N203W_65', 'P19_008344_1894_XN_09N203W_4', 'P20_008845_1894_XN_09N203W_15']. \n", "\n", "Continuing, but these points will be missing from the control network\n" ] } ], "source": [ "# Setup stuffs for the cub information namely the path and extension\n", "path = '/Volumes/Blueman/'\n", "extension = '.lev1.cub'\n", "prj_file = get_path('CTX_Athabasca_Middle_step0.atf')\n", "\n", "socet_df = socet2isis(prj_file)\n", "\n", "images = pd.unique(socet_df['ipf_file'])\n", "\n", "serial_dict = serial_numbers(images, path, extension)\n", "\n", "# creates the control network\n", "cn.to_isis('/Volumes/Blueman/cn.net', socet_df, serial_dict)" ] }, { "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.6.3" } }, "nbformat": 4, "nbformat_minor": 2 }