From d1e284af78b65cbda5ee89fc34e80f0c8feffd6b Mon Sep 17 00:00:00 2001
From: Kelvin Rodriguez <kelvinrr@icloud.com>
Date: Sun, 9 Apr 2017 14:13:06 -0700
Subject: [PATCH] Better tests

---
 plio/io/__init__.py          | 34 ++++++++++++++++++
 plio/io/io_tes.py            | 69 ++++++++++--------------------------
 plio/io/tests/test_io_tes.py |  8 +++++
 3 files changed, 61 insertions(+), 50 deletions(-)

diff --git a/plio/io/__init__.py b/plio/io/__init__.py
index 8588fbf..bb74ab8 100644
--- a/plio/io/__init__.py
+++ b/plio/io/__init__.py
@@ -1,3 +1,37 @@
+def tes2numpy(msb_type, num_bytes, nelems=1):
+    """
+    Converts a MSB data type to a numpy datatype
+
+    """
+    valid_bytes = {
+        'MSB_UNSIGNED_INTEGER': [1,2,4,8,16,32,64],
+        'MSB_INTEGER': [1,2,4,8,16,32,64],
+        'IEEE_REAL': [1,2,4,8,16,32,64],
+        'CHARACTER': range(1,128),
+        'MSB_BIT_STRING': range(1,128)
+    }
+
+    msb_bit_string_type = [('byte{}'.format(i), '>u1') for i in range(num_bytes)]
+
+    dtype_map = {
+        'MSB_UNSIGNED_INTEGER': '>u{}'.format(num_bytes),
+        'MSB_INTEGER': '>i{}'.format(num_bytes),
+        'IEEE_REAL': '>f{}'.format(num_bytes),
+        'CHARACTER': 'a{}'.format(num_bytes),
+        'MSB_BIT_STRING': msb_bit_string_type
+    }
+
+    if num_bytes not in valid_bytes[msb_type] and nelems == 1:
+        raise Exception('invalid byte ({}) count for type ({})'.format(num_bytes, msb_type))
+
+    if nelems > 1:
+        # Must be an array
+        return [('elem{}'.format(i), dtype_map[msb_type]) for i in range(nelems)]
+
+
+    return dtype_map[msb_type]
+
+
 tes_dtype_map = {'ATM': [('sclk_time', '>u4'),
   ('srf_pressure', '>u2'),
   ('nadir_pt',
diff --git a/plio/io/io_tes.py b/plio/io/io_tes.py
index 677342d..e7a77b8 100644
--- a/plio/io/io_tes.py
+++ b/plio/io/io_tes.py
@@ -11,6 +11,7 @@ from plio.io.io_json import read_json
 from plio.io import tes_dtype_map
 from plio.io import tes_columns
 from plio.io import tes_scaling_factors
+from plio.io import tes2numpy
 
 class Tes(object):
     """
@@ -28,6 +29,7 @@ class Tes(object):
 
     """
 
+
     def __init__(self, input_data, var_file = None):
         """
         Read the .spc file, parse the label, and extract the spectra
@@ -39,13 +41,13 @@ class Tes(object):
                      The PATH to the input .tab file
 
         """
-        def expand_column(df, expand_column, columns):
+        def expand_column(df, expand_column, columns): # pragma: no cover
             array = np.asarray([np.asarray(list(tup[0])) for tup in df[expand_column].as_matrix()], dtype=np.uint8)
             new_df = pd.concat([df, pd.DataFrame(array, columns=columns)], axis=1)
             del new_df[expand_column]
             return new_df
 
-        def bolquality2arr(arr):
+        def bolquality2arr(arr): # pragma: no cover
             bitarr = np.unpackbits(np.asarray(arr, dtype=np.uint8))
             lis = [(bitarr2int(bitarr[0:3]), bit2bool(bitarr[3:4]))]
 
@@ -53,7 +55,7 @@ class Tes(object):
             arr = np.array(lis, dtype=types)
             return arr
 
-        def obsquality2arr(arr):
+        def obsquality2arr(arr): # pragma: no cover
             bitarr = np.unpackbits(np.asarray(arr, dtype=np.uint8))
             lis = [(bitarr2int(bitarr[0:2]), bitarr2int(bitarr[2:5]),
                     bitarr2int(bitarr[5:6]), bitarr2int(bitarr[6:7]),
@@ -64,7 +66,7 @@ class Tes(object):
             arr = np.array(lis, dtype=types)
             return arr
 
-        def obsclass2arr(arr):
+        def obsclass2arr(arr): # pragma: no cover
             bitarr = np.unpackbits(np.asarray(arr, dtype=np.uint8))
             lis = [(bitarr2int(bitarr[0:3]), bitarr2int(bitarr[3:7]),
                     bitarr2int(bitarr[7:11]), bitarr2int(bitarr[11:13]),
@@ -76,7 +78,7 @@ class Tes(object):
             arr = np.array(lis, dtype=types)
             return arr
 
-        def radquality2arr(arr):
+        def radquality2arr(arr): # pragma: no cover
             bitarr = np.unpackbits(np.asarray(arr, dtype=np.uint8))
             lis = [(bitarr2int(bitarr[0:1]), bitarr2int(bitarr[1:2]),
                     bitarr2int(bitarr[2:3]), bitarr2int(bitarr[3:5]),
@@ -89,7 +91,7 @@ class Tes(object):
             arr = np.array(lis, dtype=types)
             return arr
 
-        def atmquality2arr(arr):
+        def atmquality2arr(arr): # pragma: no cover
             bitarr = np.unpackbits(np.asarray(arr, dtype=np.uint8))
             lis = [(bitarr2int(bitarr[0:2]), bitarr2int(bitarr[2:4]))]
 
@@ -97,13 +99,13 @@ class Tes(object):
             arr = np.array(lis, dtype=types)
             return arr
 
-        def expand_column(df, expand_column, columns):
+        def expand_column(df, expand_column, columns): # pragma: no cover
             array = np.asarray([np.asarray(list(tup[0])) for tup in df[expand_column].as_matrix()], dtype=np.uint8)
             new_df = pd.concat([df, pd.DataFrame(array, columns=columns)], axis=1)
             del new_df[expand_column]
             return new_df
 
-        def bolquality2arr(arr):
+        def bolquality2arr(arr): # pragma: no cover
             bitarr = np.unpackbits(np.asarray(arr, dtype=np.uint8))
             lis = [(bitarr2int(bitarr[0:3]), bit2bool(bitarr[3:4]))]
 
@@ -111,7 +113,7 @@ class Tes(object):
             arr = np.array(lis, dtype=types)
             return arr
 
-        def obsquality2arr(arr):
+        def obsquality2arr(arr): # pragma: no cover
             bitarr = np.unpackbits(np.asarray(arr, dtype=np.uint8))
             lis = [(bitarr2int(bitarr[0:2]), bitarr2int(bitarr[2:5]),
                     bitarr2int(bitarr[5:6]), bitarr2int(bitarr[6:7]),
@@ -122,7 +124,7 @@ class Tes(object):
             arr = np.array(lis, dtype=types)
             return arr
 
-        def obsclass2arr(arr):
+        def obsclass2arr(arr): # pragma: no cover
             bitarr = np.unpackbits(np.asarray(arr, dtype=np.uint8))
             lis = [(bitarr2int(bitarr[0:3]), bitarr2int(bitarr[3:7]),
                     bitarr2int(bitarr[7:11]), bitarr2int(bitarr[11:13]),
@@ -134,7 +136,7 @@ class Tes(object):
             arr = np.array(lis, dtype=types)
             return arr
 
-        def radquality2arr(arr):
+        def radquality2arr(arr): # pragma: no cover
             bitarr = np.unpackbits(np.asarray(arr, dtype=np.uint8))
             lis = [(bitarr2int(bitarr[0:1]), bitarr2int(bitarr[1:2]),
                     bitarr2int(bitarr[2:3]), bitarr2int(bitarr[3:5]),
@@ -147,7 +149,7 @@ class Tes(object):
             arr = np.array(lis, dtype=types)
             return arr
 
-        def atmquality2arr(arr):
+        def atmquality2arr(arr): # pragma: no cover
             bitarr = np.unpackbits(np.asarray(arr, dtype=np.uint8))
             lis = [(bitarr2int(bitarr[0:2]), bitarr2int(bitarr[2:4]))]
 
@@ -155,47 +157,14 @@ class Tes(object):
             arr = np.array(lis, dtype=types)
             return arr
 
-        def tes2numpy(msb_type, num_bytes, nelems=1):
-            """
-            Converts a MSB data type to a numpy datatype
-
-            """
-            valid_bytes = {
-                'MSB_UNSIGNED_INTEGER': [1,2,4,8,16,32,64],
-                'MSB_INTEGER': [1,2,4,8,16,32,64],
-                'IEEE_REAL': [1,2,4,8,16,32,64],
-                'CHARACTER': range(1,128),
-                'MSB_BIT_STRING': range(1,128)
-            }
-
-            msb_bit_string_type = [('byte{}'.format(i), '>u1') for i in range(num_bytes)]
-
-            dtype_map = {
-                'MSB_UNSIGNED_INTEGER': '>u{}'.format(num_bytes),
-                'MSB_INTEGER': '>i{}'.format(num_bytes),
-                'IEEE_REAL': '>f{}'.format(num_bytes),
-                'CHARACTER': 'a{}'.format(num_bytes),
-                'MSB_BIT_STRING': msb_bit_string_type
-            }
-
-            if num_bytes not in valid_bytes[msb_type] and not nelems:
-                raise Exception('invalid byte ({}) count for type ({})'.format(num_bytes, msb_type))
-
-            if nelems > 1:
-                # Must be an array
-                return [('elem{}'.format(i), dtype_map[msb_type]) for i in range(nelems)]
-
-
-            return dtype_map[msb_type]
-
-        def bitarr2int(arr):
+        def bitarr2int(arr): # pragma: no cover
             arr = "".join(str(i) for i in arr)
             return np.uint8(int(arr,2))
 
-        def bit2bool(bit):
+        def bit2bool(bit): # pragma: no cover
             return np.bool_(bit)
 
-        def expand_bitstrings(df, dataset):
+        def expand_bitstrings(df, dataset): # pragma: no cover
             if dataset == 'BOL':
                 quality_columns = ['ti_bol_rating', 'bol_ref_lamp']
                 df['quality'] = df['quality'].apply(bolquality2arr)
@@ -249,7 +218,7 @@ class Tes(object):
         df = pd.DataFrame(data=array, columns=columns[dataset.upper()])
 
         # Read Radiance array if applicable
-        if dataset.upper() == 'RAD':
+        if dataset.upper() == 'RAD': # pragma: no cover
             with open('{}.var'.format(path.splitext(f)[0]) , 'rb') as file:
                 buffer = file.read()
                 def process_rad(index):
@@ -268,7 +237,7 @@ class Tes(object):
                 df["cal_rad"] = df["cal_rad"].apply(process_rad)
 
         # Apply scaling factors
-        for column in scaling_factors[dataset]:
+        for column in scaling_factors[dataset]: # pragma: no cover
             def scale(x):
                  return np.multiply(x, scaling_factors[dataset][column])
             df[column] = df[column].apply(scale)
diff --git a/plio/io/tests/test_io_tes.py b/plio/io/tests/test_io_tes.py
index 5a7e560..2f6f21b 100644
--- a/plio/io/tests/test_io_tes.py
+++ b/plio/io/tests/test_io_tes.py
@@ -9,6 +9,7 @@ sys.path.insert(0, os.path.abspath('..'))
 from plio.examples import get_path
 from plio.io import io_tes
 from plio.io.io_gdal import GeoDataset
+from plio.io import tes2numpy
 
 class Test_Tes_IO(unittest.TestCase):
 
@@ -21,5 +22,12 @@ class Test_Tes_IO(unittest.TestCase):
         self.assertIsInstance(ds.data, pd.DataFrame)
         self.assertEqual(ds.data.columns.tolist(), ['sclk_time', 'et', 'pos', 'sun', 'quat', 'id'])
 
+    def test_tes2numpy(self):
+        self.assertEqual(tes2numpy('MSB_UNSIGNED_INTEGER', 4), '>u4')
+        self.assertEqual(tes2numpy('MSB_UNSIGNED_INTEGER', 4, 2), [('elem0', '>u4'), ('elem1', '>u4')])
+
+        with self.assertRaises(Exception):
+            tes2numpy('IEEE_REAL', 5)
+
 if __name__ == '__main__':
     unittest.main()
-- 
GitLab