diff --git a/docs/conf.py b/docs/conf.py
index 7ed992fde1d92177d5ea9fbf8033d64293d458b0..af2d4db80b2e1b6c143f6fc6969862f078052dda 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 0d1ed9fea846067aaa16a3c1be62d7d3f14df75f..5c50699cae7f924a5a4532ba3f35328d6dd84d1d 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 415ec472a92feb0993ec9a2c6de99f591282b678..a65657f02b526da01ec77d4d2ce550f02fe5c575 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 a8900153da2fff22020a6a6c9c4a32836ca52a5b..49f12100520eff8a5dc14a4b9217bba02b0d9074 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 de573ac9b794b0996db4f36a68f84a2b9b4ab40a..d078f854bd52900030ace43b5c9507a65f34f076 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 d66bd95b4e38a8cd6d1e66cab445aa19f7231683..f9b90330a511cec08c7a14f3b5937afd182f7925 100644
--- a/recipe/meta.yaml
+++ b/recipe/meta.yaml
@@ -51,6 +51,7 @@ requirements:
     - usgscam
     - jinja2
 
+
 test:
   imports:
     - plio