diff --git a/plio/io_controlnetwork.py b/plio/io_controlnetwork.py index 31fcf773e1e1241a966386c1e82c1fff14b47851..f7e7a0bc1e91f25da0974de581955a009b85423f 100644 --- a/plio/io_controlnetwork.py +++ b/plio/io_controlnetwork.py @@ -2,7 +2,7 @@ from time import gmtime, strftime import pvl from plio import ControlNetFileV0002_pb2 as cnf -from plio.utils import xstr +from plio.utils.utils import xstr try: import spiceypy diff --git a/plio/io_gdal.py b/plio/io_gdal.py index 78141266a62e58ef3f98e8ace8ac71af39c2bbfe..ae89a89ddf7545a23d5f2baa2091adda1e4d4e46 100644 --- a/plio/io_gdal.py +++ b/plio/io_gdal.py @@ -3,10 +3,11 @@ import warnings import pvl import os -from plio.utils import find_in_dict +from plio.utils.utils import find_in_dict from osgeo import ogr import numpy as np import gdal +import gdalconst import osr from plio import extract_metadata @@ -150,8 +151,6 @@ class GeoDataset(object): if self.dataset is None: raise IOError('File not found :', file_name) - - def __repr__(self): return os.path.basename(self.file_name) @@ -465,6 +464,7 @@ class GeoDataset(object): array = band.ReadAsArray(xstart, ystart, xextent, yextent).astype(dtype) return array + def array_to_raster(array, file_name, projection=None, geotransform=None, outformat='GTiff', ndv=None): @@ -525,3 +525,40 @@ def array_to_raster(array, file_name, projection=None, bnd.SetNoDataValue(ndv) bnd.WriteArray(array[:,:,i - 1]) dataset.FlushCache() + + +def match_rasters(match_to, match_from, destination, + resampling_method='GRA_Bilinear'): + """ + Match a source raster to a match raster, including resolution and extent. + + Parameters + ========== + match : object + A GeoDataSet object to be matched to + + source : object + A GeoDataSet object to be clipped + + destination : str + PATH where the output will be written + + resampling_method : str + Resampling method to use. Options include: + {GRA_NearestNeighbor, GRA_Bilinear (Default), + GRA_Cubic, GRA_CubicSpline, GRA_Lanczos, GRA_Average, + GRA_Mode} + """ + # TODO: If a destination is not provided create an in-memory GeoDataSet object + match_to_srs = match_to.ds.GetProjection() + match_to_gt = match_to.geotransform + width, height = match_to.rastersize + + match_from__srs = match_from.ds.GetProjection() + match_from__gt = match_from.geotransform + + dst = gdal.GetDriverByName('GTiff').Create(destination, width, height, 1, gdalconst.GDT_Float32) + dst.SetGeoTransform(match_to_gt) + dst.SetProjection(match_to_srs) + + gdal.ReprojectImage(match_from.ds, dst, None, None, getattr(gdalconst, resampling_method)) diff --git a/plio/isis_serial_number.py b/plio/isis_serial_number.py index 55a1854bda5fae8e22ce880eaae00d4f0f4352d1..e26399e58d98cb9f6d1865d4e97114b532c48725 100644 --- a/plio/isis_serial_number.py +++ b/plio/isis_serial_number.py @@ -2,7 +2,7 @@ import warnings import plio from plio.data import get_data from plio.io_db import Translations, StringToMission, setup_db_session -from plio.utils import find_in_dict, find_nested_in_dict +from plio.utils.utils import find_in_dict, find_nested_in_dict import pvl from pvl._collections import PVLModule diff --git a/plio/tests/test_io_controlnetwork.py b/plio/tests/test_io_controlnetwork.py index 13c998b96b7c6793e32859282e9736373c61018a..f1d67a638368aa50ef4d005762295de763a7b7c2 100644 --- a/plio/tests/test_io_controlnetwork.py +++ b/plio/tests/test_io_controlnetwork.py @@ -8,7 +8,7 @@ import pvl from .. import io_controlnetwork from .. import ControlNetFileV0002_pb2 as cnf -from plio.utils import find_in_dict +from plio.utils.utils import find_in_dict sys.path.insert(0, os.path.abspath('..')) diff --git a/plio/utils/__init__.py b/plio/utils/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/plio/utils/log.py b/plio/utils/log.py new file mode 100644 index 0000000000000000000000000000000000000000..1ef3cfabfde7f90fa54b2e0a915b2e20dc6a531d --- /dev/null +++ b/plio/utils/log.py @@ -0,0 +1,39 @@ +import os +import json +import logging.config + +def setup_logging(default_path='logging.json', + default_level='INFO', + env_key='LOG_CFG'): + """ + Read a log configuration file, written in JSON + + Parameters + ---------- + default_path : string + The path to the logging configuration file + default_level : object + The logger level at which to report + env_key : str + A potential environment variable where the user defaults logs + """ + + path = default_path + value = os.getenv(env_key, None) + if value: + path = value + + default_level = getattr(logging, default_level.upper()) + if os.path.exists(path): + logtype = os.path.splitext(os.path.basename(path))[1] + with open(path, 'rt') as f: + if logtype == '.json': + config = json.load(f) + elif logtype == '.yaml': + import yaml + config = yaml.load(f.read()) + logging.config.dictConfig(config) + else: + logging.basicConfig(level=default_level) + logger = logging.getLogger() + logger.setLevel(default_level) \ No newline at end of file diff --git a/plio/utils/tests/__init__.py b/plio/utils/tests/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/plio/utils/tests/test_log.py b/plio/utils/tests/test_log.py new file mode 100644 index 0000000000000000000000000000000000000000..2cc848cceb09f78dcc5462ca13290af7de8c5840 --- /dev/null +++ b/plio/utils/tests/test_log.py @@ -0,0 +1,30 @@ +import logging +import unittest + +from plio.examples import get_path +from plio.utils import log + + +class TestLog(unittest.TestCase): + #TODO: These are really weak tests...do they need to be more robust? + #TODO: These are reporting NOSET for the log level...this is wrong + def setUp(self): + pass + + def test_setup_json(self): + log.setup_logging(default_path = get_path('logging.json')) + logger = logging.getLogger(__name__) + self.assertEqual(logger.root.level, logging.DEBUG) + + def test_setup_yaml(self): + log.setup_logging(default_path=get_path('logging.yaml')) + logger = logging.getLogger(__name__) + self.assertEqual(logger.root.level, logging.DEBUG) + + def test_setup(self): + log.setup_logging() + logger = logging.getLogger(__name__) + self.assertEqual(logger.root.level, logging.INFO) + +if __name__ == '__main__': + unittest.main() \ No newline at end of file diff --git a/plio/tests/test_utils.py b/plio/utils/tests/test_utils.py similarity index 97% rename from plio/tests/test_utils.py rename to plio/utils/tests/test_utils.py index 0098c5ecabbd12eb5bb2af779f840c08a7917c8f..eeae946f850a90adb9ddd46649b4086b3d2a84e0 100644 --- a/plio/tests/test_utils.py +++ b/plio/utils/tests/test_utils.py @@ -1,7 +1,7 @@ import os import unittest -from ..examples import get_path +from plio.examples import get_path from .. import utils class TestUtils(unittest.TestCase): diff --git a/plio/utils.py b/plio/utils/utils.py similarity index 100% rename from plio/utils.py rename to plio/utils/utils.py