Skip to content
Snippets Groups Projects
Commit b4b37c37 authored by Adam Paquette's avatar Adam Paquette
Browse files

Fixed system to cooperate with isis programs.

parent f55cbbfd
Branches
Tags
No related merge requests found
#!/usr/bin/env python
import argparse
import os
def parse_args():
parser = argparse.ArgumentParser()
# Add args here
return parser.parse_args()
def main(args):
print('Do some stuff')
if __name__ == '__main__':
main(parse_args())
......@@ -20,6 +20,7 @@ def parse_args():
parser.add_argument('at_file', help='Path to the .atf file for a project.')
parser.add_argument('cub_file_path', help='Path to cube files related to ipf files.')
parser.add_argument('cub_ipf_map', help='Path to map file for all ipfs and cubes.')
parser.add_argument('target_name', help='Name of the target body used in the control net')
parser.add_argument('--outpath', help='Directory for the control network to be output to.',
required = False)
......@@ -86,7 +87,7 @@ def main(args):
serial_dict = serial_numbers(image_dict, cub_path)
# creates the control network
cn.to_isis(os.path.join(outpath, cnet_out + '.net'), socet_df, serial_dict)
cn.to_isis(os.path.join(outpath, cnet_out + '.net'), socet_df, serial_dict, targetname = args.target_name)
if __name__ == '__main__':
main(parse_args())
%% Cell type:code id: tags:
``` python
import os
import sys
from functools import singledispatch
import warnings
import pandas as pd
import numpy as np
import math
import pyproj
from plio.examples import get_path
from plio.io.io_bae import read_gpf, read_ipf
from collections import defaultdict
import plio.io.io_controlnetwork as cn
import plio.io.isis_serial_number as sn
```
%% Cell type:code id: tags:
``` python
# Reads a .atf file and outputs all of the
# .ipf, .gpf, .sup, .prj, and path to locate the
# .apf file (should be the same as all others)
def read_atf(atf_file):
with open(atf_file) as f:
# Extensions of files we want
files_ext = ['.prj', '.sup', '.ipf', '.gpf']
files_dict = []
files = defaultdict(list)
for line in f:
ext = os.path.splitext(line)[-1].strip()
# Check is needed for split as all do not have a space
if ext in files_ext:
# If it is the .prj file, it strips the directory away and grabs file name
if ext == '.prj':
files[ext].append(line.strip().split(' ')[1].split('\\')[-1])
# If the ext is in the list of files we care about, it addes to the dict
files[ext].append(line.strip().split(' ')[-1])
else:
# Adds to the dict even if not in files we care about
files[ext.strip()].append(line)
# Gets the base filepath
files['basepath'] = os.path.dirname(os.path.abspath(atf_file))
# Creates a dict out of file lists for GPF, PRJ, IPF, and ATF
files_dict = (dict(files_dict))
# Sets the value of IMAGE_IPF to all IPF images
files_dict['IMAGE_IPF'] = files['.ipf']
# Sets the value of IMAGE_SUP to all SUP images
files_dict['IMAGE_SUP'] = files['.sup']
# Sets value for GPF file
files_dict['GP_FILE'] = files['.gpf'][0]
# Sets value for PRJ file
files_dict['PROJECT'] = files['.prj'][0]
# Sets the value of PATH to the path of the ATF file
files_dict['PATH'] = files['basepath']
return files_dict
# converts columns l. and s. to isis
# no transform applied
def line_sample_size(record, path):
with open(os.path.join(path, record['ipf_file'] + '.sup')) as f:
for i, line in enumerate(f):
if i == 2:
img_index = line.split('\\')
img_index = img_index[-1].strip()
img_index = img_index.split('.')[0]
if i == 3:
line_size = line.split(' ')
line_size = line_size[-1].strip()
assert int(line_size) > 0, "Line number {} from {} is a negative number: Invalid Data".format(line_size, record['ipf_file'])
if i == 4:
sample_size = line.split(' ')
sample_size = sample_size[-1].strip()
assert int(sample_size) > 0, "Sample number {} from {} is a negative number: Invalid Data".format(sample_size, record['ipf_file'])
break
line_size = int(line_size)/2.0 + record['l.'] + 1
sample_size = int(sample_size)/2.0 + record['s.'] + 1
return sample_size, line_size, img_index
# converts known to ISIS keywords
# transform
def known(record):
if record['known'] == 0:
return 'Free'
elif record['known'] == 1 or record['known'] == 2 or record['known'] == 3:
return 'Constrained'
# converts +/- 180 system to 0 - 360 system
def to_360(num):
return num % 360
# ocentric to ographic latitudes
# transform but unsure how to handle
def oc2og(dlat, dMajorRadius, dMinorRadius):
try:
dlat = math.radians(dlat)
dlat = math.atan(((dMajorRadius / dMinorRadius)**2) * (math.tan(dlat)))
dlat = math.degrees(dlat)
except:
print ("Error in oc2og conversion")
return dlat
# ographic to ocentric latitudes
# transform but unsure how to handle
def og2oc(dlat, dMajorRadius, dMinorRadius):
try:
dlat = math.radians(dlat)
dlat = math.atan((math.tan(dlat) / ((dMajorRadius / dMinorRadius)**2)))
dlat = math.degrees(dlat)
except:
print ("Error in og2oc conversion")
return dlat
# gets eRadius and pRadius from a .prj file
def get_axis(file):
with open(file) as f:
from collections import defaultdict
files = defaultdict(list)
for line in f:
ext = line.strip().split(' ')
files[ext[0]].append(ext[-1])
eRadius = float(files['A_EARTH'][0])
pRadius = eRadius * (1 - float(files['E_EARTH'][0]))
return eRadius, pRadius
# function to convert lat_Y_North to ISIS_lat
def lat_ISIS_coord(record, semi_major, semi_minor):
ocentric_coord = og2oc(record['lat_Y_North'], semi_major, semi_minor)
coord_360 = to_360(ocentric_coord)
return coord_360
# function to convert long_X_East to ISIS_lon
def lon_ISIS_coord(record, semi_major, semi_minor):
ocentric_coord = og2oc(record['long_X_East'], semi_major, semi_minor)
coord_360 = to_360(ocentric_coord)
return coord_360
def body_fix(record, semi_major, semi_minor, inverse=False):
"""
Parameters
----------
record : ndarray
(n,3) where columns are x, y, height or lon, lat, alt
"""
ecef = pyproj.Proj(proj='geocent', a=semi_major, b=semi_minor)
lla = pyproj.Proj(proj='latlon', a=semi_major, b=semi_minor)
if inverse:
lon, lat, height = pyproj.transform(ecef, lla, record[0], record[1], record[2])
return lon, lat, height
else:
y, x, z = pyproj.transform(lla, ecef, record[0], record[1], record[2])
return y, x, z
def ignore_toggle(record):
if record['stat'] == 0:
return True
else:
return False
# TODO: Does isis cnet need a convariance matrix for sigmas? Even with a static matrix of 1,1,1,1
def compute_sigma_covariance_matrix(lat, lon, rad, latsigma, lonsigma, radsigma, semimajor_axis):
"""
Given geospatial coordinates, desired accuracy sigmas, and an equitorial radius, compute a 2x3
sigma covariange matrix.
Parameters
----------
lat : float
A point's latitude in degrees
lon : float
A point's longitude in degrees
rad : float
The radius (z-value) of the point in meters
latsigma : float
The desired latitude accuracy in meters (Default 10.0)
lonsigma : float
The desired longitude accuracy in meters (Default 10.0)
radsigma : float
The desired radius accuracy in meters (Defualt: 15.0)
semimajor_axis : float
The semi-major or equitorial radius in meters (Default: 1737400.0 - Moon)
Returns
-------
rectcov : ndarray
(2,3) covariance matrix
"""
lat = math.radians(lat)
lon = math.radians(lon)
# SetSphericalSigmasDistance
scaled_lat_sigma = latsigma / semimajor_axis
# This is specific to each lon.
scaled_lon_sigma = lonsigma * math.cos(lat) / semimajor_axis
# SetSphericalSigmas
cov = np.eye(3,3)
cov[0,0] = scaled_lat_sigma ** 2
cov[1,1] = scaled_lon_sigma ** 2
cov[2,2] = radsigma ** 2
# Approximate the Jacobian
j = np.zeros((3,3))
cosphi = math.cos(lat)
sinphi = math.sin(lat)
coslambda = math.cos(lon)
sinlambda = math.sin(lon)
rcosphi = rad * cosphi
rsinphi = rad * sinphi
j[0,0] = -rsinphi * coslambda
j[0,1] = -rcosphi * sinlambda
j[0,2] = cosphi * coslambda
j[1,0] = -rsinphi * sinlambda
j[1,1] = rcosphi * coslambda
j[1,2] = cosphi * sinlambda
j[2,0] = rcosphi
j[2,1] = 0.
j[2,2] = sinphi
mat = j.dot(cov)
mat = mat.dot(j.T)
rectcov = np.zeros((2,3))
rectcov[0,0] = mat[0,0]
rectcov[0,1] = mat[0,1]
rectcov[0,2] = mat[0,2]
rectcov[1,0] = mat[1,1]
rectcov[1,1] = mat[1,2]
rectcov[1,2] = mat[2,2]
return rectcov
return np.array(rectcov)
# return np.array([[1.0, 1.0, 1.0], [1.0, 1.0, 1.0]])
def compute_cov_matrix(record, semimajor_axis):
cov_matrix = compute_sigma_covariance_matrix(record['lat_Y_North'], record['long_X_East'], record['ht'], record['sig0'], record['sig1'], record['sig2'], semimajor_axis)
return cov_matrix.ravel().tolist()
# applys transformations to columns
def apply_transformations(atf_dict, df):
def apply_two_isis_transformations(atf_dict, df):
prj_file = os.path.join(atf_dict['PATH'], atf_dict['PROJECT'])
eRadius, pRadius = get_axis(prj_file)
lla = np.array([[df['long_X_East']], [df['lat_Y_North']], [df['ht']]])
ecef = body_fix(lla, semi_major = eRadius, semi_minor = pRadius, inverse=False)
df['s.'], df['l.'], df['image_index'] = (zip(*df.apply(line_sample_size, path = atf_dict['PATH'], axis=1)))
df['known'] = df.apply(known, axis=1)
df['long_X_East'] = ecef[0][0]
df['lat_Y_North'] = ecef[1][0]
df['ht'] = ecef[2][0]
df['aprioriCovar'] = df.apply(compute_cov_matrix, semimajor_axis = eRadius, axis=1)
df['ignore'] = df.apply(ignore_toggle, axis=1)
# df['ignore'] = df.apply(ignore_toggle, axis=1)
def socet2isis(prj_file):
# Read in and setup the atf dict of information
atf_dict = read_atf(prj_file)
# Get the gpf and ipf files using atf dict
gpf_file = os.path.join(atf_dict['PATH'], atf_dict['GP_FILE']);
ipf_list = [os.path.join(atf_dict['PATH'], i) for i in atf_dict['IMAGE_IPF']]
# Read in the gpf file and ipf file(s) into seperate dataframes
gpf_df = read_gpf(gpf_file)
ipf_df = read_ipf(ipf_list)
# Check for differences between point ids using each dataframes
# point ids as a reference
gpf_pt_idx = pd.Index(pd.unique(gpf_df['point_id']))
ipf_pt_idx = pd.Index(pd.unique(ipf_df['pt_id']))
point_diff = ipf_pt_idx.difference(gpf_pt_idx)
if len(point_diff) != 0:
warnings.warn("The following points found in ipf files missing from gpf file: \n\n{}. \
\n\nContinuing, but these points will be missing from the control network".format(list(point_diff)))
# Merge the two dataframes on their point id columns
socet_df = ipf_df.merge(gpf_df, left_on='pt_id', right_on='point_id')
# Apply the transformations
apply_transformations(atf_dict, socet_df)
# apply_two_isis_transformations(atf_dict, socet_df)
# Define column remap for socet dataframe
column_remap = {'l.': 'y', 's.': 'x',
'res_l': 'lineResidual', 'res_s': 'sampleResidual', 'known': 'Type',
'lat_Y_North': 'AprioriY', 'long_X_East': 'AprioriX', 'ht': 'AprioriZ',
'sig0': 'AprioriLatitudeSigma', 'sig1': 'AprioriLongitudeSigma', 'sig2': 'AprioriRadiusSigma',
'sig_l': 'linesigma', 'sig_s': 'samplesigma'}
# column_map = {'pt_id': 'id', 'l.': 'y', 's.': 'x',
# 'res_l': 'lineResidual', 'res_s': 'sampleResidual', 'known': 'Type',
# 'lat_Y_North': 'aprioriY', 'long_X_East': 'aprioriX', 'ht': 'aprioriZ',
# 'sig0': 'aprioriLatitudeSigma', 'sig1': 'aprioriLongitudeSigma', 'sig2': 'aprioriRadiusSigma',
# 'sig_l': 'linesigma', 'sig_s': 'samplesigma'}
# Rename the columns using the column remap above
socet_df.rename(columns = column_remap, inplace=True)
# socet_df.rename(columns = column_map, inplace=True)
# Return the socet dataframe to be converted to a control net
return socet_df
# creates a dict of serial numbers with the cub being the key
def serial_numbers(images, path, extension):
serial_dict = dict()
for image in images:
snum = sn.generate_serial_number(os.path.join(path, image + extension))
snum = snum.replace('Mars_Reconnaissance_Orbiter', 'MRO')
serial_dict[image] = snum
return serial_dict
```
%% Cell type:code id: tags:
``` python
# Setup stuffs for the cub information namely the path and extension
path = '/path/where/cub/files/are/'
path = '/home/acpaquette/repos/plio/test_cubes'
targetname = 'Mars'
# Extension of your cub files
extension = '.something.cub'
extension = '.8bit.cub'
# Path to atf file
atf_file = ('/path/to/atf/file')
atf_file = ('/home/acpaquette/repos/plio/plio/examples/SocetSet/Relative.atf')
socet_df = socet2isis(atf_file)
images = pd.unique(socet_df['ipf_file'])
# images = pd.unique(socet_df['ipf_file'])
serial_dict = serial_numbers(images, path, extension)
# serial_dict = serial_numbers(images, path, extension)
# creates the control network
cn.to_isis('/path/you/want/the/cnet/to/be/in/cn.net', socet_df, serial_dict)
# cn.to_isis('/home/acpaquette/repos/plio/plio/examples/SocetSet/cn.net', socet_df, serial_dict, targetname = targetname)
```
%% Cell type:code id: tags:
``` python
return_df = cn.from_isis("/home/acpaquette/repos/plio/plio/examples/SocetSet/cn.net")
columns = []
column_index = []
for i, column in enumerate(list(return_df.columns)):
if column not in columns:
column_index.append(i)
columns.append(column)
return_df = return_df.iloc[:, column_index]
```
%% Cell type:code id: tags:
``` python
column_map = {'pt_id': 'id', 'l.': 'y', 's.': 'x',
'res_l': 'lineResidual', 'res_s': 'sampleResidual', 'known': 'Type',
'lat_Y_North': 'aprioriY', 'long_X_East': 'aprioriX', 'ht': 'aprioriZ',
'sig0': 'aprioriLatitudeSigma', 'sig1': 'aprioriLongitudeSigma', 'sig2': 'aprioriRadiusSigma',
'sig_l': 'linesigma', 'sig_s': 'samplesigma'}
column_map = {k: v for v, k in column_map.items()}
return_df.rename(columns = column_map, inplace=True)
return_df.drop(['chooserName', 'datetime', 'referenceIndex', 'jigsawRejected', 'editLock', 'aprioriSurfPointSource', 'aprioriSurfPointSourceFile','aprioriRadiusSource', 'aprioriRadiusSourceFile'] , axis = 1, inplace=True)
```
%% Cell type:code id: tags:
``` python
return_df[['lat_Y_North', 'long_X_East', 'ht']]
```
%% Output
lat_Y_North long_X_East ht
0 139525.230749 3.390974e+06 4506.496945
1 139525.230749 3.390974e+06 4506.496945
2 139489.278045 3.390969e+06 4516.454802
3 139489.278045 3.390969e+06 4516.454802
4 139823.489797 3.390990e+06 4536.274914
5 139823.489797 3.390990e+06 4536.274914
6 139772.738004 3.390936e+06 4518.050219
7 139772.738004 3.390936e+06 4518.050219
8 139575.914815 3.390952e+06 3816.666542
9 139575.914815 3.390952e+06 3816.666542
10 139614.756296 3.390953e+06 3791.232717
11 139614.756296 3.390953e+06 3791.232717
12 139912.041374 3.390914e+06 3875.608660
13 139912.041374 3.390914e+06 3875.608660
14 139909.452033 3.390930e+06 3845.361327
15 139909.452033 3.390930e+06 3845.361327
16 139669.826849 3.391120e+06 3270.672620
17 139669.826849 3.391120e+06 3270.672620
18 139694.517017 3.391205e+06 3289.744506
19 139694.517017 3.391205e+06 3289.744506
20 139968.793338 3.391126e+06 3274.711397
21 139968.793338 3.391126e+06 3274.711397
22 139979.200780 3.391138e+06 3298.297228
23 139979.200780 3.391138e+06 3298.297228
24 139688.031217 3.391041e+06 4253.956077
25 139688.031217 3.391041e+06 4253.956077
26 139686.910823 3.391089e+06 4216.743792
27 139686.910823 3.391089e+06 4216.743792
28 139786.205284 3.390979e+06 3579.127600
29 139786.205284 3.390979e+06 3579.127600
30 139785.010997 3.391002e+06 3546.549796
31 139785.010997 3.391002e+06 3546.549796
%% Cell type:code id: tags:
``` python
socet_df[['lat_Y_North', 'long_X_East', 'ht']]
```
%% Output
lat_Y_North long_X_East ht
0 0.095708 2.356167 -2342.889214
1 0.095708 2.356167 -2342.889214
2 0.095920 2.355564 -2349.638414
3 0.095920 2.355564 -2349.638414
4 0.096339 2.361186 -2314.316425
5 0.096339 2.361186 -2314.316425
6 0.095954 2.360368 -2370.502882
7 0.095954 2.360368 -2370.502882
8 0.081058 2.357037 -2363.989968
9 0.081058 2.357037 -2363.989968
10 0.080518 2.357691 -2360.922571
11 0.080518 2.357691 -2360.922571
12 0.082311 2.362733 -2388.123298
13 0.082311 2.362733 -2388.123298
14 0.081668 2.362678 -2371.973499
15 0.081668 2.362678 -2371.973499
16 0.069458 2.358505 -2193.309629
17 0.069458 2.358505 -2193.309629
18 0.069861 2.358862 -2106.769773
19 0.069861 2.358862 -2106.769773
20 0.069543 2.363543 -2174.971745
21 0.069543 2.363543 -2174.971745
22 0.070044 2.363710 -2162.103231
23 0.070044 2.363710 -2162.103231
24 0.090342 2.358866 -2269.610862
25 0.090342 2.358866 -2269.610862
26 0.089550 2.358814 -2222.328983
27 0.089550 2.358814 -2222.328983
28 0.076012 2.360565 -2328.281125
29 0.076012 2.360565 -2328.281125
30 0.075320 2.360529 -2305.362047
31 0.075320 2.360529 -2305.362047
%% Cell type:code id: tags:
``` python
```
......
......@@ -187,6 +187,7 @@ class IsisStore(object):
header_bytes = find_in_dict(pvl_header, 'HeaderBytes')
point_start_byte = find_in_dict(pvl_header, 'PointsStartByte')
version = find_in_dict(pvl_header, 'Version')
if version == 2:
point_attrs = [i for i in cnf._CONTROLPOINTFILEENTRYV0002.fields_by_name if i != 'measures']
measure_attrs = [i for i in cnf._CONTROLPOINTFILEENTRYV0002_MEASURE.fields_by_name]
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment