From 160c1ae05ed650de443a6ec5fb0f52fa95643997 Mon Sep 17 00:00:00 2001 From: acpaquette <acp263@nau.edu> Date: Fri, 12 Oct 2018 11:45:01 -0700 Subject: [PATCH] Small changes (#81) * Small updates to get the scripts working. * Fixed pradius calculations, and made some small changes. * Removed coord transforms and made body_fix func more generic. * Updated reproj doc string. * General refactor to socet scripts and clean up. Simplfied input for both scripts. * Updated conf to use conda prefix * Fixed up __getattr__ func * Corrected attribute error text * Uploaded notebooks for remote access * Updated notebooks with complete footprint function * More or less final notebook * Forgot to tab this in under the first except block * Updated version. * Removed unnecessary notebooks * Removed previously removed module * Removed old import * Updates travis to use environment.yml * Fixes issue indexing on the hcube --- docs/conf.py | 3 +- plio/io/hcube.py | 21 ++++++++------ plio/io/io_crism.py | 33 ++++++++++++++++++++-- plio/io/io_gdal.py | 41 ++++++++++++++++------------ plio/io/io_moon_minerology_mapper.py | 14 ++++++---- recipe/meta.yaml | 1 + 6 files changed, 77 insertions(+), 36 deletions(-) diff --git a/docs/conf.py b/docs/conf.py index 7ed992f..af2d4db 100755 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!$CONDA_PREFIX/bin/python # -*- coding: utf-8 -*- # # autocnet documentation build configuration file, created by @@ -17,7 +17,6 @@ import sys import os from unittest.mock import MagicMock - autodoc_mock_imports = ['proj4', 'gdal', 'osr','ogr', 'osgeo', 'osgeo.gdal', 'osgeo.gdalconst'] diff --git a/plio/io/hcube.py b/plio/io/hcube.py index 0d1ed9f..5c50699 100644 --- a/plio/io/hcube.py +++ b/plio/io/hcube.py @@ -8,7 +8,7 @@ class HCube(object): """ A Mixin class for use with the io_gdal.GeoDataset class to optionally add support for spectral labels, label - based indexing, and lazy loading for reads. + based indexing, and lazy loading for reads. """ @property @@ -23,11 +23,11 @@ class HCube(object): except: self._wavelengths = [] return self._wavelengths - + @property def tolerance(self): return getattr(self, '_tolerance', 2) - + @tolerance.setter def tolerance(self, val): if isinstance(val, int): @@ -43,15 +43,15 @@ class HCube(object): def __getitem__(self, key): i = _iLocIndexer(self) return i[key] - + @property def loc(self): return _LocIndexer(self) - + @property def iloc(self): return _iLocIndexer(self) - + def _read(self, key): ifnone = lambda a, b: b if a is None else a @@ -69,12 +69,17 @@ class HCube(object): ystep = ystop - ystart else: raise TypeError("Loc style access elements must be slices, e.g., [:] or [10:100]") - + pixels = (xstart, ystart, xstep, ystep) if isinstance(key[0], (int, np.integer)): return self.read_array(band=int(key[0]+1), pixels=pixels) + + elif isinstance(key[0], slice): + # Given some slice iterate over the bands and get the bands and pixel space requested + return [self.read_array(i, pixels = pixels) for i in list(range(1, self.nbands + 1))[key[0]]] + else: arrs = [] for b in key[0]: arrs.append(self.read_array(band=int(b+1), pixels=pixels)) - return np.stack(arrs) \ No newline at end of file + return np.stack(arrs) diff --git a/plio/io/io_crism.py b/plio/io/io_crism.py index 415ec47..a65657f 100644 --- a/plio/io/io_crism.py +++ b/plio/io/io_crism.py @@ -2,13 +2,42 @@ import os import numpy as np from .io_gdal import GeoDataset from .hcube import HCube + +try: + from libpysat.derived import crism + from libpysat.derived.utils import get_derived_funcs + libpysat_enabled = True +except: + print('No libpysat module. Unable to attach derived product functions') + libpysat_enabled = False + import gdal class Crism(GeoDataset, HCube): """ - An M3 specific reader with the spectral mixin. + An Crism specific reader with the spectral mixin. """ + def __init__(self, file_name): + + GeoDataset.__init__(self, file_name) + HCube.__init__(self) + + self.derived_funcs = {} + + if libpysat_enabled: + self.derived_funcs = get_derived_funcs(crism) + + def __getattr__(self, name): + try: + func = self.derived_funcs[name] + + setattr(self, name, func.__get__(self)) + return getattr(self, name) + + except KeyError as keyerr: + raise AttributeError("'Crism' object has no attribute '{}'".format(name)) from None + @property def wavelengths(self): if not hasattr(self, '_wavelengths'): @@ -29,4 +58,4 @@ def open(input_data): input_data = os.path.splitext(input_data)[:-1] + '.img' ds = Crism(input_data) - return ds \ No newline at end of file + return ds diff --git a/plio/io/io_gdal.py b/plio/io/io_gdal.py index a890015..49f1210 100644 --- a/plio/io/io_gdal.py +++ b/plio/io/io_gdal.py @@ -269,6 +269,7 @@ class GeoDataset(object): @property def footprint(self): if not hasattr(self, '_footprint'): + # Try to get the footprint from the image try: polygon_pvl = find_in_dict(self.metadata, 'Polygon') start_polygon_byte = find_in_dict(polygon_pvl, 'StartByte') @@ -280,28 +281,32 @@ class GeoDataset(object): # Sloppy unicode to string because GDAL pukes on unicode stream = str(f.read(num_polygon_bytes)) self._footprint = ogr.CreateGeometryFromWkt(stream) - except: - self._footprint = None - try: - # Get the lat lon corners - lat = [i[0] for i in self.latlon_corners] - lon = [i[1] for i in self.latlon_corners] - - # Compute a ogr geometry for the tiff which - # provides leverage for overlaps - ring = ogr.Geometry(ogr.wkbLinearRing) - for point in [*zip(lon, lat)]: - ring.AddPoint(*point) - ring.AddPoint(lon[0], lat[0]) - - poly = ogr.Geometry(ogr.wkbPolygon) - poly.AddGeometry(ring) - poly.FlattenTo2D() - self._footprint = poly except: self._footprint = None + # If the image does not have a footprint, try getting the image from projected + # coordinates + try: + # Get the lat lon corners + lat = [i[0] for i in self.latlon_corners] + lon = [i[1] for i in self.latlon_corners] + + # Compute a ogr geometry for the tiff which + # provides leverage for overlaps + ring = ogr.Geometry(ogr.wkbLinearRing) + for point in [*zip(lon, lat)]: + ring.AddPoint(*point) + ring.AddPoint(lon[0], lat[0]) + + poly = ogr.Geometry(ogr.wkbPolygon) + poly.AddGeometry(ring) + poly.FlattenTo2D() + self._footprint = poly + + except: + self._footprint = None + return self._footprint @property diff --git a/plio/io/io_moon_minerology_mapper.py b/plio/io/io_moon_minerology_mapper.py index de573ac..d078f85 100644 --- a/plio/io/io_moon_minerology_mapper.py +++ b/plio/io/io_moon_minerology_mapper.py @@ -4,11 +4,11 @@ from .io_gdal import GeoDataset from .hcube import HCube try: - from libpysat.derived import m3, crism - from libpysat.derived.utils import add_derived_funcs + from libpysat.derived import m3 + from libpysat.derived.utils import get_derived_funcs libpysat_enabled = True except: - print('No libpysat module. Unable to attached derived product functions') + print('No libpysat module. Unable to attach derived product functions') libpysat_enabled = False import gdal @@ -23,8 +23,10 @@ class M3(GeoDataset, HCube): GeoDataset.__init__(self, file_name) HCube.__init__(self) + self.derived_funcs = {} + if libpysat_enabled: - self.derived_funcs = add_derived_funcs(m3) + self.derived_funcs = get_derived_funcs(m3) def __getattr__(self, name): try: @@ -33,8 +35,8 @@ class M3(GeoDataset, HCube): setattr(self, name, func.__get__(self)) return getattr(self, name) - except: - raise AttributeError() + except KeyError as keyerr: + raise AttributeError("'M3' object has no attribute '{}'".format(name)) from None @property def wavelengths(self): diff --git a/recipe/meta.yaml b/recipe/meta.yaml index d66bd95..f9b9033 100644 --- a/recipe/meta.yaml +++ b/recipe/meta.yaml @@ -51,6 +51,7 @@ requirements: - usgscam - jinja2 + test: imports: - plio -- GitLab