diff --git a/.travis.yml b/.travis.yml
index f1d26c72f7c5d90006194c0a0409ab86638aa2f1..d38a9bda8959d1aae91654d7b3dca4b2e8c93bb1 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -4,12 +4,6 @@ branches:
 only:
   - master
 
-env:
-  global:
-    - BINSTAR_USER: jlaura
-  matrix:
-    - PYTHON_VERSION: 3.5
-
 os:
   - linux
   - osx
@@ -43,7 +37,6 @@ install:
   # Install not using env because build needs to be in root env
   - conda config --add channels conda-forge
   - conda config --add channels jlaura
-  - conda install python=$PYTHON_VERSION
   - conda install -c conda-forge gdal h5py
   - conda install pandas sqlalchemy pyyaml networkx affine
   - conda install -c jlaura pvl protobuf
@@ -51,22 +44,13 @@ install:
   # Development installation
   - conda install pytest  pytest-cov sh anaconda-client
 
-  # Straight from the menpo team
-  - if [["$TRAVIS_OS_NAME" == "osx"]]; then
-      curl -o condaci.py https://raw.githubusercontent.com/menpo/condaci/v0.4.8/condaci.py;
-    else
-      wget https://raw.githubusercontent.com/menpo/condaci/v0.4.8/condaci.py -O condaci.py;
-    fi
-  - python condaci.py setup
-
 
 script:
-  - pytest --cov=plio 
-  # After test success, package and upload to Anaconda
-  - ~/miniconda/bin/python condaci.py build ./conda
+  - pytest --cov=plio
 
 after_success:
   - coveralls
+  - conda install conda-build && conda install anaconda-client && conda config --set anaconda_upload yes && conda build --token $CONDA_UPLOAD_TOKEN recipe
 
 notifications:
   webhooks:
diff --git a/plio/data/data.db b/plio/data/data.db
index e2a35c8a1100073db89ee98fe564d573b90f3a2e..c1ac0e7c5802a4222a93a6ab400dc3dbc454aeb0 100644
Binary files a/plio/data/data.db and b/plio/data/data.db differ
diff --git a/plio/geofuncs/geofuncs.py b/plio/geofuncs/geofuncs.py
index 9db0f00da7fe4c683d3d420ed72f3d2a794a30b5..bc7b0f05ff0d8ff01a79199e129847b29bf726d5 100644
--- a/plio/geofuncs/geofuncs.py
+++ b/plio/geofuncs/geofuncs.py
@@ -1,4 +1,5 @@
 import json
+import warnings
 import numpy as np
 
 def intersection_to_pixels(inverse_affine, ul, ur, lr, ll):
@@ -27,6 +28,10 @@ def intersection_to_pixels(inverse_affine, ul, ur, lr, ll):
     miny = np.inf
     maxy = -np.inf
 
+    if inverse_affine == None:
+        warnings.warn('Inverse affine transformation not available.')
+        return None
+
     for c in [ul, ur, lr, ll]:
         px, py = map(int, inverse_affine * (c[0], c[1]))
 
@@ -51,7 +56,6 @@ def compute_overlap(geodata_a, geodata_b):
     p1 = geodata_a.footprint
     p2 = geodata_b.footprint
     intersection = json.loads(p1.Intersection(p2).ExportToJson())['coordinates'][0]
-
     ul, ur, lr, ll = find_four_corners(intersection)
 
     a_intersection = intersection_to_pixels(geodata_a.inverse_affine, ul, ur, lr, ll)
@@ -120,7 +124,6 @@ def find_four_corners(coords, threshold=120):
     plio.geofuncs.geofuncs.find_corners
     """
     corners = find_corners(coords, threshold)
-
     corners.sort(key = lambda x:x[1])
     upper = corners[2:]
     lower = corners[:2]
diff --git a/plio/io/io_controlnetwork.py b/plio/io/io_controlnetwork.py
index 6efe11af8f83e466c244b99a488add159dada5ab..b41ced34d512ff326b7edcb0062ed4868fca8969 100644
--- a/plio/io/io_controlnetwork.py
+++ b/plio/io/io_controlnetwork.py
@@ -9,7 +9,6 @@ VERSION = 2
 HEADERSTARTBYTE = 65536
 DEFAULTUSERNAME = 'None'
 
-
 def write_filelist(lst, path="fromlist.lis"):
     """
     Writes a filelist to a file so it can be used in ISIS3.
@@ -86,7 +85,6 @@ def to_isis(path, obj, serials, mode='wb', version=VERSION,
                      Suffix to tbe added to the point id.  If the suffix is '_bar', pointids
                      will be in the form '1_bar, 2_bar, ..., n_bar'.
     """
-
     with IsisStore(path, mode) as store:
         if not creation_date:
             creation_date = strftime("%Y-%m-%d %H:%M:%S", gmtime())
@@ -128,8 +126,8 @@ class IsisStore(object):
     """
 
     def __init__(self, path, mode=None, **kwargs):
-        self.pointid = 0
         self.nmeasures = 0
+        self.npoints = 0
 
         # Conversion from buffer types to Python types
         bt = {1: float,
@@ -196,9 +194,15 @@ class IsisStore(object):
         point_sizes = []
         point_messages = []
         for i, g in df.groupby('point_id'):
+
+            # Get the point specification from the protobuf
             point_spec = cnf.ControlPointFileEntryV0002()
-            point_spec.id = _set_pid(i)
 
+            # Set the ID and then loop over all of the attributes that the
+            # point has and check for corresponding columns in the group and
+            # set with the correct type
+            #point_spec.id = _set_pid(i)
+            point_spec.id = _set_pid(i)
             for attr, attrtype in self.point_attrs:
                 if attr in g.columns:
                     # As per protobuf docs for assigning to a repeated field.
@@ -217,23 +221,25 @@ class IsisStore(object):
 
             for node_id, m in g.iterrows():
                 measure_spec = point_spec.Measure()
-                measure_spec.serialnumber = serials[m.image_index]
                 # For all of the attributes, set if they are an dict accessible attr of the obj.
                 for attr, attrtype in self.measure_attrs:
                     if attr in g.columns:
                         setattr(measure_spec, attr, attrtype(m[attr]))
+
+                measure_spec.serialnumber = serials[m.image_index]
                 measure_spec.sample = m.x
                 measure_spec.line = m.y
                 measure_spec.type = 2
                 measure_iterable.append(measure_spec)
                 self.nmeasures += 1
-            point_spec.measures.extend(measure_iterable)
 
+            self.npoints += 1
+
+            point_spec.measures.extend(measure_iterable)
             point_message = point_spec.SerializeToString()
             point_sizes.append(point_spec.ByteSize())
             point_messages.append(point_message)
 
-            self.pointid += 1
         return point_messages, point_sizes
 
     def create_buffer_header(self, networkid, targetname,
@@ -342,7 +348,7 @@ class IsisStore(object):
                         ('Created', creation_date),
                         ('LastModified', modified_date),
                         ('Description', description),
-                        ('NumberOfPoints', self.pointid),
+                        ('NumberOfPoints', self.npoints),
                         ('NumberOfMeasures', self.nmeasures),
                         ('Version', version)
                         ])
diff --git a/plio/io/io_gdal.py b/plio/io/io_gdal.py
index 44a54913251eb6b41579d4ae0c63ed1221cc9584..5522171d467998859e1854826f59e34ef72beb13 100644
--- a/plio/io/io_gdal.py
+++ b/plio/io/io_gdal.py
@@ -200,6 +200,9 @@ class GeoDataset(object):
 
     @property
     def inverse_affine(self):
+        # If det(A) == 0, the transformation is degenerate
+        if self.forward_affine.is_degenerate:
+            return None
         self._ia = ~self.forward_affine
         return self._ia
 
@@ -475,10 +478,9 @@ class GeoDataset(object):
             # Check that the read start is not outside of the image
             xstart, ystart, xcount, ycount = pixels
             xmax, ymax = map(int, self.xy_extent[1])
-
             # If the image is south up, flip the roi
             if self.north_up == False:
-                ystart = ymax - ystart - ycount
+                ystart = ymax - (ystart + ycount)
             if xstart < 0:
                 xstart = 0
 
@@ -488,10 +490,11 @@ class GeoDataset(object):
             if xstart + xcount > xmax:
                 xcount = xmax - xstart
 
-            if ystart +  ycount > ymax:
+            if ystart + ycount > ymax:
                 ycount = ymax - ystart
-
             array = band.ReadAsArray(xstart, ystart, xcount, ycount).astype(dtype)
+            #if self.north_up == False:
+            #    array = np.flipud(array)
         return array
 
     def compute_overlap(self, geodata, **kwargs):
diff --git a/plio/io/isis_serial_number.py b/plio/io/isis_serial_number.py
index 92ea721c4485b2f71c18d3ffd566e98946a36609..0c187abff1a0ea0fbe70fe3781dca7fc092f035f 100644
--- a/plio/io/isis_serial_number.py
+++ b/plio/io/isis_serial_number.py
@@ -38,7 +38,6 @@ def get_isis_translation(label):
     spacecraft_name = find_in_dict(label, 'SpacecraftName')
     for row in plio.data_session.query(StringToMission).filter(StringToMission.key==spacecraft_name):
         spacecraft_name = row.value.lower()
-
     # Try and pull an instrument identifier
     try:
         instrumentid = find_in_dict(label, 'InstrumentId').capitalize()
@@ -51,7 +50,6 @@ def get_isis_translation(label):
                                                             Translations.instrument==instrumentid):
         # Convert the JSON back to a PVL object
         translation = PVLModule(row.translation)
-
     return translation
 
 
@@ -75,6 +73,7 @@ def generate_serial_number(label):
         label = pvl.load(label, cls=SerialNumberDecoder)
     # Get the translation information
     translation = get_isis_translation(label)
+
     if not translation:
         warnings.warn('Unable to load an appropriate image translation.')
         return
@@ -91,11 +90,11 @@ def generate_serial_number(label):
             search_translation = {group['Translation'][1]:group['Translation'][0]}
             sub_group = find_nested_in_dict(label, search_position)
             serial_entry = sub_group[search_key]
+
             if serial_entry in search_translation.keys():
                 serial_entry = search_translation[serial_entry]
             elif '*' in search_translation.keys() and search_translation['*'] != '*':
                 serial_entry = search_translation['*']
-
             serial_number.append(serial_entry)
         except:
             pass
diff --git a/conda/meta.yaml b/recipe/meta.yaml
similarity index 100%
rename from conda/meta.yaml
rename to recipe/meta.yaml