Skip to content

Commit

Permalink
Adds tests for GDAL not installed (#71)
Browse files Browse the repository at this point in the history
* Adds tests for GDAL not installed

* typo in travis else

* proper matrix build

* semicolons...I write python

* updates test with conditional osr

* Proper pytest skipping enabled for conditional imports

* missed pytest import

* Typos

* Mixing pytest and unittest

* typos and imports

* typos city

* removes hasosr

* fixes wrapper for conditional gdal

* Removes test for non-available gdal
  • Loading branch information
jlaura committed Aug 23, 2018
1 parent 1fa01a2 commit db62ee3
Show file tree
Hide file tree
Showing 11 changed files with 155 additions and 116 deletions.
14 changes: 10 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ os:
- osx

env:
- PYTHON_VERSION=3.5
- PYTHON_VERSION=3.6
- PYTHON_VERSION=3.5 HAS_GDAL=true
- PYTHON_VERSION=3.6 HAS_GDAL=true
- PYTHON_VERSION=3.5 HAS_GDAL=false
- PYTHON_VERSION=3.6 HAS_GDAL=false

before_install:
# We do this conditionally because it saves us some downloading if the
Expand All @@ -36,8 +38,12 @@ before_install:

install:
- conda config --add channels usgs-astrogeology
- conda config --add channels conda-forge
- conda install libgdal gdal numpy pyproj h5py pvl scipy protobuf affine jinja2 networkx pandas sqlalchemy pyyaml ncurses usgscam pytest pytest-cov sh coveralls nbsphinx
- conda config --add channels conda-forge
- if $HAS_GDAL; then
conda install libgdal gdal numpy pyproj h5py pvl scipy protobuf affine jinja2 networkx pandas sqlalchemy pyyaml ncurses pytest pytest-cov sh coveralls nbsphinx;
else
conda install numpy pyproj h5py pvl scipy protobuf affine jinja2 networkx pandas sqlalchemy pyyaml ncurses pytest pytest-cov sh coveralls nbsphinx;
fi

script:
- pytest --cov=plio
Expand Down
20 changes: 20 additions & 0 deletions plio/camera/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import importlib
import warnings

cam = importlib.find_loader('usgscam')
cycsm_isd = importlib.find_loader('cycsm.isd')

if cam:
cam = cam.load_module()

if cycsm_isd:
cycsm_isd = cycsm_isd.load_module()

def conditional_cameras(func):
def cam_check(*args, **kwargs):
if cam:
return func(*args, **kwargs)
else:
warning.warn('Trying to call a camera method, but usgscam is not installed.')
return None
return cam_check
13 changes: 3 additions & 10 deletions plio/camera/csm.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,11 @@
import datetime
import json

try:
import usgscam as cam
from cycsm.isd import Isd
camera_support = True
except:
camera_support = False
import requests

from plio.utils.utils import find_in_dict
from plio.io.io_json import NumpyEncoder

from plio.camera import conditional_cameras, cam, cycsm_isd

def data_from_cube(header):
data = {}
Expand All @@ -28,16 +22,15 @@ def data_from_cube(header):
data['SPACECRAFT_CLOCK_START_COUNT'] = find_in_dict(header, 'SpacecraftClockCount')
return data

@conditional_cameras
def create_camera(obj, url='http://smalls:8002/api/1.0/missions/mars_reconnaissance_orbiter/csm_isd'):
if not camera_support:
print("Usgscam library not installed. Camera capabilities are disabled")

data = json.dumps(data_from_cube(obj.metadata), cls=NumpyEncoder)
r = requests.post(url, data=data)

# Get the ISD back and instantiate a local ISD for the image
isd = r.json()['data']['isd']
i = Isd.loads(isd)
i = cycsm_isd.Isd.loads(isd)

# Create the plugin and camera as usual
plugin = cam.genericls.Plugin()
Expand Down
10 changes: 5 additions & 5 deletions plio/camera/tests/test_csm.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@
import pytest
import pvl

import usgscam

from plio.camera import csm
from plio.camera import csm, cam, conditional_cameras
from plio.examples import get_path

def mock_requests_post(*args, **kwargs):
Expand Down Expand Up @@ -35,11 +33,13 @@ def header():
def req_obj():
return

@pytest.mark.skipif(cam is None, reason="Cameras not installed")
def test_data_from_cube(header):
data = csm.data_from_cube(header)
assert data['START_TIME'] == datetime.datetime(2008, 9, 17, 5, 8, 10, 820000)

@pytest.mark.skipif(cam is None, reason="Cameras not installed")
@mock.patch('requests.post', side_effect=mock_requests_post)
def test_create_camera(header):
cam = csm.create_camera(header)
assert isinstance(cam, usgscam.genericls.SensorModel)
created_camera = csm.create_camera(header)
assert isinstance(create_camera, cam.genericls.SensorModel)
23 changes: 23 additions & 0 deletions plio/io/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,26 @@
# Conditional imports for GDAL
import importlib
import warnings

gdal = importlib.find_loader('gdal')
ogr = importlib.find_loader('osgeo.ogr')
osr = importlib.find_loader('osr')

if gdal:
gdal = gdal.load_module()
ogr = ogr.load_module()
osr = osr.load_module()
gdal.UseExceptions()

def conditional_gdal(func):
def has_gdal(*args, **kwargs):
if gdal:
return func(*args, **kwargs)
else:
warning.warn('Trying to call a GDAL method, but GDAL is not installed.')
return None
return has_gdal

from . import io_autocnetgraph
from . import io_controlnetwork
from . import io_db
Expand Down
21 changes: 11 additions & 10 deletions plio/io/extract_metadata.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
try:
from osgeo import osr
hasosr = True
except:
hasosr = False

from plio.io import osr, conditional_gdal

import_options = ['ImportFromWkt', 'ImportFromProj4',
'ImportFromEPSG', 'ImportFromUSGS',
'ImportFromXML']

@conditional_gdal
def extract_projstring(proj_string):
"""
Import an OSR supported projection string into
Expand All @@ -25,10 +21,7 @@ def extract_projstring(proj_string):
OSR spatial reference object
"""
if hasosr:
srs = osr.SpatialReference()
else:
return
srs = osr.SpatialReference()
for import_option in import_options:
try:
func = getattr(srs, import_option)
Expand All @@ -42,6 +35,7 @@ def extract_projstring(proj_string):
srs.MorphFromESRI()
return srs

@conditional_gdal
def get_standard_parallels(srs):
"""
Get all standard parallels for a given map projection
Expand All @@ -62,6 +56,7 @@ def get_standard_parallels(srs):
parallels[i] = srs.GetProjParm('Standard_Parallel_{}'.format(i+1), 0.0)
return parallels

@conditional_gdal
def get_central_meridian(srs):
"""
Get the central meridian of the projection
Expand All @@ -79,6 +74,7 @@ def get_central_meridian(srs):

return srs.GetProjParm('central_meridian', 0.0)

@conditional_gdal
def get_spheroid(srs):
"""
Get the semi-major, semi-minor, and inverse flattening
Expand All @@ -100,6 +96,7 @@ def get_spheroid(srs):
invflattening = srs.GetInvFlattening()
return semimajor, semiminor, invflattening

@conditional_gdal
def get_projection_name(srs):
"""
Extract the projection name from a
Expand All @@ -118,6 +115,7 @@ def get_projection_name(srs):
proj_name = srs.GetAttrValue("PROJECTION", 0)
return proj_name

@conditional_gdal
def get_false_easting(srs):
"""
Extract the false easting parameter from a
Expand All @@ -136,6 +134,7 @@ def get_false_easting(srs):

return srs.GetProjParm('False_Easting', 0)

@conditional_gdal
def get_false_northing(srs):
"""
Extract the false northing parameter from a
Expand All @@ -154,6 +153,7 @@ def get_false_northing(srs):

return srs.GetProjParm('False_Northing', 0)

@conditional_gdal
def get_scale_factor(srs):
"""
Extract the scale factor, k, from a spatial reference system (if present)
Expand All @@ -171,6 +171,7 @@ def get_scale_factor(srs):

return srs.GetProjParm('scale_factor', 1.0)

@conditional_gdal
def get_latitude_of_origin(srs):
"""
Extract the latitude of origin from
Expand Down
25 changes: 7 additions & 18 deletions plio/io/io_gdal.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,12 @@
import affine
import numpy as np
import pvl
try:
# Try the full GDAL stack
import gdal
from osgeo import ogr
import osr
gdal.UseExceptions()
has_gdal = True
except:
has_gdal = False

from plio.io import extract_metadata


from plio.io import extract_metadata, conditional_gdal
from plio.geofuncs import geofuncs
from plio.utils.utils import find_in_dict

from plio.io import gdal, ogr, osr

NP2GDAL_CONVERSION = {
"uint8": 1,
Expand Down Expand Up @@ -158,7 +150,7 @@ def __init__(self, file_name):
"""
self.file_name = file_name
if not has_gdal:
if not gdal:
raise ImportError('No module name gdal.')
self.dataset = gdal.Open(file_name)
if self.dataset is None:
Expand Down Expand Up @@ -581,7 +573,7 @@ def array_to_raster(array, file_name, projection=None,
A GDAL supported bittype, e.g. GDT_Int32
Default: GDT_Float64
"""
if not has_gdal:
if not gdal:
raise ImportError('No module named gdal.')
driver = gdal.GetDriverByName(outformat)
try:
Expand Down Expand Up @@ -617,7 +609,7 @@ def array_to_raster(array, file_name, projection=None,
bnd.WriteArray(array[:,:,i - 1])
dataset.FlushCache()


@conditional_gdal
def match_rasters(match_to, match_from, destination,
resampling_method='GRA_Bilinear', ndv=0):
"""
Expand Down Expand Up @@ -658,9 +650,6 @@ def match_rasters(match_to, match_from, destination,
match_from__srs = match_from.dataset.GetProjection()
match_from__gt = match_from.geotransform

if not has_gdal:
raise ImportError('No module named gdal.')

dst = gdal.GetDriverByName('GTiff').Create(destination, width, height, 1,
gdalconst.GDT_Float64)

Expand Down
3 changes: 2 additions & 1 deletion plio/io/io_spectral_profiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import numpy as np

from plio.utils.utils import find_in_dict
from plio.io.io_gdal import GeoDataset

class Spectral_Profiler(object):

Expand Down Expand Up @@ -169,5 +168,7 @@ def open_browse(self, extension='.jpg'):
-------
"""

from plio.io.io_gdal import GeoDataset
path, ext = os.path.splitext(self.input_data)
self.browse = GeoDataset(path + extension)
15 changes: 6 additions & 9 deletions plio/io/tests/test_io_gdal.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@
import unittest

import numpy as np
import pytest

from plio.examples import get_path

sys.path.insert(0, os.path.abspath('..'))

from plio.io import io_gdal
from plio.io import gdal


@pytest.mark.skipif(gdal is None, reason="GDAL not installed")
class TestMercator(unittest.TestCase):
def setUp(self):
self.dataset = io_gdal.GeoDataset(get_path('Mars_MGS_MOLA_ClrShade_MAP2_0.0N0.0_MERC.tif'))
Expand Down Expand Up @@ -101,7 +104,7 @@ def test_read_array_set_dtype(self):
self.assertEqual(arr.dtype, np.int8)
self.assertAlmostEqual(np.mean(arr), 10.10353227, 6)


@pytest.mark.skipif(gdal is None, reason="GDAL not installed")
class TestLambert(unittest.TestCase):
def setUp(self):
self.dataset = io_gdal.GeoDataset(get_path('Lunar_LRO_LOLA_Shade_MAP2_90.0N20.0_LAMB.tif'))
Expand Down Expand Up @@ -143,6 +146,7 @@ def test_standard_parallels(self):
self.assertEqual(sp, [73.0, 42.0])


@pytest.mark.skipif(gdal is None, reason="GDAL not installed")
class TestPolar(unittest.TestCase):
def setUp(self):
self.dataset = io_gdal.GeoDataset(get_path('Mars_MGS_MOLA_ClrShade_MAP2_90.0N0.0_POLA.tif'))
Expand Down Expand Up @@ -171,6 +175,7 @@ def test_latlon_to_pixel(self):
self.assertAlmostEqual(pixel[0], 0.0, 6)
self.assertAlmostEqual(pixel[1], 0.0, 6)

@pytest.mark.skipif(gdal is None, reason="GDAL not installed")
class TestWriter(unittest.TestCase):
def setUp(self):
self.arr = np.random.random((100,100))
Expand Down Expand Up @@ -240,11 +245,3 @@ def tearDown(self):
except:
pass

class TestWithoutGdal(unittest.TestCase):
def test_without_gdal(self):
io_gdal.has_gdal = False
with self.assertRaises(ImportError):
io_gdal.GeoDataset('foo')

def tearDown(self):
io_gdal.has_gdal = True
6 changes: 5 additions & 1 deletion plio/io/tests/test_io_spectral_profiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@
import unittest

import pandas as pd
import pytest

sys.path.insert(0, os.path.abspath('..'))

from plio.examples import get_path
from plio.io import io_spectral_profiler
from plio.io.io_gdal import GeoDataset
from plio.io import gdal


class Test_Spectral_Profiler_IO(unittest.TestCase):

Expand All @@ -19,7 +22,8 @@ def test_openspc(self):
ds = io_spectral_profiler.Spectral_Profiler(self.examplefile)
self.assertEqual(ds.nspectra, 38)
self.assertEqual(ds.spectra[0].columns.tolist(), ['RAW', 'REF1', 'REF2', 'QA', 'RAD'])


@pytest.mark.skipif(gdal is None, reason="GDAL not installed")
def test_read_browse(self):
ds = io_spectral_profiler.Spectral_Profiler(self.examplefile)
ds.open_browse()
Expand Down
Loading

0 comments on commit db62ee3

Please sign in to comment.