From a6adb80a40304fe9479fec3a2b38bcd1dd121a8b Mon Sep 17 00:00:00 2001 From: lodenthal <lodenthal@uni-bielefeld.de> Date: Mon, 20 Nov 2017 11:34:58 +0300 Subject: [PATCH] added tests for processing --- src/processing/test.py | 467 ++++++++++++++++++++++++++++++++++++++++ src/processing/tools.py | 42 ++-- 2 files changed, 490 insertions(+), 19 deletions(-) create mode 100644 src/processing/test.py diff --git a/src/processing/test.py b/src/processing/test.py new file mode 100644 index 0000000..4759bb4 --- /dev/null +++ b/src/processing/test.py @@ -0,0 +1,467 @@ +import unittest +import sqlite3 +import numpy as np +import pandas as pd +import os.path as path +from ..database import database +import __init__ as processing + + +def is_numeric_array(array): + """Checks if the dtype of the array is numeric. + + Booleans, unsigned integer, signed integer, floats and complex are + considered numeric. + + Parameters + ---------- + array : `numpy.ndarray`-like + The array to check. + + Returns + ------- + is_numeric : `bool` + True if it is a recognized numerical and False if object or + string. + """ + numerical_dtype_kinds = {'b', # boolean + 'u', # unsigned integer + 'i', # signed integer + 'f', # floats + 'c'} # complex + try: + return array.dtype.kind in numerical_dtype_kinds + except AttributeError: + # in case it's not a numpy array it will probably have no dtype. + return np.asarray(array).dtype.kind in numerical_dtype_kinds + + +def build_test_db(): + db_filename = 'test_db_1' + + conn = sqlite3.connect(db_filename) + c = conn.cursor() + conn.close() + + db_filename = 'test_db_2' + + conn = sqlite3.connect(db_filename) + c = conn.cursor() + + c.execute('''CREATE TABLE normalisation + (R_max, R_min, R_range, + G_max, G_min, G_range, + B_max, B_min, B_range, + D_max, D_min, D_range)''') + + c.execute('''CREATE TABLE position_orientation + (x,y,z,alpha_0,alpha_1,alpha_2)''') + + c.execute('''CREATE TABLE image + (data)''') + conn.close() + + +class TestCase(unittest.TestCase): + def setUp(self): + one_up = path.abspath(path.join(__file__, "../")) + self.mydb_filename = one_up+'/database.db' + self.mydb = database.DataBaseLoad(self.mydb_filename) + + +# def test_scene_rowID(self): +# for rowid in [-1,-6,9.4,3.0,5.4,'e',np.nan,None]: +# with self.assertRaises(TypeError): +# image = self.mydb.read_image(rowid=rowid) +# self.assertIsNotNone(image) +# self.assertFalse(sum(image.shape)==0) + + def test_scene_posorient(self): + # get existing position for which also an image is contained in the db + # db_filename='/media/luiza/Daten/Repos/proj-ASV3Dnavi/data/raw/ASV_data_0_db.npy' + + conn = sqlite3.connect(self.mydb_filename) + c = conn.cursor() + c.execute(""" SELECT * FROM position_orientation WHERE (rowid=1) """) + rows = c.fetchall()[0] + # print(rows) + # convert to pd.series + + # working case + posorient = pd.Series(index=['x', 'y', 'z', + 'alpha_0', 'alpha_1', 'alpha_2']) + posorient.x = rows[5] + posorient.y = rows[6] + posorient.z = rows[1] + posorient.alpha_0 = rows[3] + posorient.alpha_1 = rows[2] + posorient.alpha_2 = rows[4] + # conn.close() + # print("posorient",posorient) + # print(posorientall.head()) + image = processing.scene(self.mydb, posorient=posorient) + self.assertIsNotNone(image) + self.assertFalse(sum(image.shape) == 0) + # print("shape",image.shape) + self.assertTrue(len(image.shape) == 4) + self.assertTrue(image.shape[3] == 1) + + # incorrect case missing column + posorient2 = pd.Series(index=['y', 'z', + 'alpha_0', 'alpha_1', 'alpha_2']) + posorient2.y = posorient.y + posorient2.z = posorient.z + posorient2.alpha_0 = posorient.alpha_0 + posorient2.alpha_1 = posorient.alpha_1 + posorient2.alpha_2 = posorient.alpha_2 + with self.assertRaises(Exception) as cm: + image = processing.scene(self.mydb, posorient=posorient2) + # print("missing column") + print(cm.exception) + + # incorrect case None + posorient2 = pd.Series(index=['x', 'y', 'z', + 'alpha_0', 'alpha_1', 'alpha_2']) + posorient2.x = None + posorient2.y = posorient.y + posorient2.z = posorient.z + posorient2.alpha_0 = posorient.alpha_0 + posorient2.alpha_1 = posorient.alpha_1 + posorient2.alpha_2 = posorient.alpha_2 + with self.assertRaises(Exception) as cm: + image = processing.scene(self.mydb, posorient=posorient2) + print(cm.exception) + + # incorrect case nan + posorient2 = pd.Series(index=['x', 'y', 'z', + 'alpha_0', 'alpha_1', 'alpha_2']) + posorient2.x = np.nan + posorient2.y = posorient.y + posorient2.z = posorient.z + posorient2.alpha_0 = posorient.alpha_0 + posorient2.alpha_1 = posorient.alpha_1 + posorient2.alpha_2 = posorient.alpha_2 + with self.assertRaises(Exception) as cm: + image = processing.scene(self.mydb, posorient=posorient2) + print(cm.exception) + + # incorrect case no pandas series but dict + posorient2 = {} + posorient2['x'] = posorient.x + posorient2['y'] = posorient.y + posorient2['z'] = posorient.z + posorient2['alpha_0'] = posorient.alpha_0 + posorient2['alpha_1'] = posorient.alpha_1 + posorient2['alpha_2'] = posorient.alpha_2 + with self.assertRaises(Exception) as cm: + image = processing.scene(self.mydb, posorient=posorient2) + print(cm.exception) + + # not working case empty + posorient2 = pd.Series(index=['x', 'y', 'z', + 'alpha_0', 'alpha_1', 'alpha_2']) + + with self.assertRaises(Exception) as cm: + image = processing.scene(self.mydb, posorient=posorient2) + print(cm.exception) + + """ + def test_db(self): + + #build_test_db() + #empty database -> should not work + db_filename='test_db_1' + #loading should not work cuz not + #all required tables are in this database + with self.assertRaises(Exception) as cm: + db=database.DataBaseLoad(db_filename) + print("a wanted error occured", cm.exception) + #reading should not anyway + with self.assertRaises(Exception) as cm: + image = db.read_image(rowid=1) + + #empty database -> should work?? + db_filename='test_db_2' + #loading should work + db=database.DataBaseLoad(db_filename) + #reading should not + with self.assertRaises(Exception) as cm: + image = db.read_image(rowid=1) + """ + + def test_skyline_scene(self): + # image = processing.scene(self.mydb,posorient=posorient) + # print("image size skyline test",image.shape) + scene = processing.scene(self.mydb, rowid=1) + # print("scene size skypline test",scene.shape) + scene2 = scene.copy() + scene2[3, 5, 2, 0] = np.nan + scene3 = [[1, 2, 3], [1, 2, 3], [1, 2, 3]] + scene3 = [scene3, scene3, scene3] + scene3 = np.array(scene3) + scene4 = np.zeros((3, 4, 5, 0)) + + for s in [scene2, scene3, scene4]: # put useless stuff here + with self.assertRaises(Exception) as cm: + processing.skyline(s) + print("wanted exception occured", cm.exception) + + # should be working -> check if result(skyline) is correct + for s in [scene]: + skyline = processing.skyline(s) + self.assertFalse(skyline.shape[1] <= 0) + self.assertTrue(skyline.shape[2] == 4) + self.assertFalse(np.any(np.isnan(skyline))) + # self.assertFalse(np.any(np.isNone(skyline))) + self.assertTrue(is_numeric_array(skyline)) + self.assertTrue(skyline.shape[3] == 1) + self.assertTrue(skyline.shape[0] > 0) + self.assertTrue(skyline.shape[1] > 0) + + def test_id(self): + # print("test_id") + # check for wrong cases + # my_scene = processing.scene(self.mydb, rowid=-2) + for rowid in [0, 't', -2, 4.5, np.nan, None]: + + with self.assertRaises(Exception) as cm: + # print("rowid",rowid) + processing.scene(self.mydb, rowid=rowid) + the_exception = cm.exception + print("error occured", the_exception) + + for rowid in [1, 2, 3, 4, 5]: + image = processing.scene(self.mydb, rowid=rowid) + # image=np.array(image) + self.assertIsNotNone(image) + self.assertFalse(sum(image.shape) == 0) + self.assertTrue(len(image.shape) == 4) + self.assertFalse(np.any(np.isnan(image))) + self.assertTrue(image.shape[3] == 1) + self.assertTrue(image.shape[2] == 4) + self.assertTrue(image.shape[0] > 0) + self.assertTrue(image.shape[1] > 0) + + def test_distance_channel(self): + scene = processing.scene(self.mydb, rowid=1) + # print("scene sizejhghghhg",scene.shape) + # should not be working + for d in [-1, 'g', None, np.nan, 8.4]: + with self.assertRaises(Exception) as cm: + processing.contrast_weighted_nearness(scene, + distance_channel=d) + print("wanted error occured", cm.exception) + + # should work + for d in [0, 1, 2, 3]: + weighted_scene = \ + processing.contrast_weighted_nearness(scene, + distance_channel=d) + # print("last channel",d) + assert is_numeric_array(weighted_scene) + assert ~np.any(np.isnan(weighted_scene)) + assert len(weighted_scene.shape) == 4 + assert ~(weighted_scene.shape[1] <= 0) + assert ~(weighted_scene.shape[0] <= 0) + assert (weighted_scene.shape[2] == 4) + assert ~(np.any(np.isNone(weighted_scene))) + + def test_contr_weight_scene(self): + scene = processing.scene(self.mydb, rowid=1) + + # working cases + contrast = processing.contrast_weighted_nearness(scene) + self.assertIsNotNone(contrast) + self.assertFalse(sum(contrast.shape) == 0) + self.assertTrue(len(contrast.shape) == 4) + self.assertFalse(np.any(np.isnan(contrast))) + self.assertTrue(contrast.shape[3] == 1) + self.assertTrue(contrast.shape[2] == 4) + self.assertTrue(contrast.shape[0] > 0) + self.assertTrue(contrast.shape[1] > 0) + + # not working case + scene2 = scene.copy() + scene2[3, 2, 1, 0] = np.nan + scene3 = [[1, 2, 3], [1, 2, 3], [1, 2, 3]] + scene3 = [scene3, scene3, scene3] + scene3 = np.array(scene3) + scene4 = np.zeros((3, 4, 5, 0)) + for s in [scene2, scene3, scene4]: + with self.assertRaises(Exception) as cm: + contrast = processing.contrast_weighted_nearness(scene) + print("wanted excption occured", cm.exception) + + def test_contr_weight_contrast(self): + scene = processing.scene(self.mydb, rowid=1) + for size in [8, 1, 0, -4, 9.4, 'g', None, np.nan]: + with self.assertRaises(Exception) as cm: + contrast = \ + processing.contrast_weighted_nearness(scene, + contrast_size=size) + print("wanted error occured", cm.exception) + + # working cases + for size in [2, 3, 4, 5]: + contrast = \ + processing.contrast_weighted_nearness(scene, + contrast_size=size) + self.assertIsNotNone(contrast) + self.assertFalse(sum(contrast.shape) == 0) + self.assertTrue(len(contrast.shape) == 4) + self.assertFalse(np.any(np.isnan(contrast))) + self.assertTrue(contrast.shape[3] == 1) + self.assertTrue(contrast.shape[2] == 4) + self.assertTrue(contrast.shape[0] > 0) + self.assertTrue(contrast.shape[1] > 0) + + def test_pcv(self): + # working case + rowid = 1 + my_scene = processing.scene(self.mydb, rowid=rowid) + # print("scene shape",my_scene.shape) + directions = self.mydb.viewing_directions + # print("directions",directions.shape) + my_pcv = processing.pcv(my_scene, directions) + # print("place code shape",my_pcv.shape) + + self.assertIsNotNone(my_pcv) + self.assertFalse(sum(my_pcv.shape) == 0) + self.assertTrue(len(my_pcv.shape) == 4) + self.assertFalse(np.any(np.isnan(my_pcv))) + self.assertTrue(my_pcv.shape[3] == 3) + self.assertTrue(my_pcv.shape[2] == 4) + self.assertTrue(my_pcv.shape[0] > 0) + self.assertTrue(my_pcv.shape[1] > 0) + + # not working cases doesnt match with shape of place code + testdirection = np.zeros((2, 4, 2)) + with self.assertRaises(Exception) as cm: + my_pcv = processing.pcv(my_scene, testdirection) + print("wanted exception occured", cm.exception) + + # not working cases wrong last dimension + testdirection = np.zeros((180, 360, 1)) + with self.assertRaises(Exception) as cm: + my_pcv = processing.pcv(my_scene, testdirection) + print("wanted exception occured", cm.exception) + + # not working cases too many dimensions + testdirection = np.zeros((180, 360, 2, 4)) + with self.assertRaises(Exception) as cm: + my_pcv = processing.pcv(my_scene, testdirection) + print("wanted exception occured", cm.exception) + + # not working cases empty + testdirection = np.zeros(()) + with self.assertRaises(Exception) as cm: + my_pcv = processing.pcv(my_scene, testdirection) + print("wanted exception occured", cm.exception) + + # not working cases nans + testdirection = np.zeros((180, 360, 2, 4)) + testdirection[2, 3, 0] = np.nan + with self.assertRaises(Exception) as cm: + my_pcv = processing.pcv(my_scene, testdirection) + print("wanted exception occured", cm.exception) + + def test_apcv(self): + # working case + rowid = 1 + my_scene = processing.scene(self.mydb, rowid=rowid) + # print("scene shape",my_scene.shape) + directions = self.mydb.viewing_directions + # print("directions",directions.shape) + my_pcv = processing.apcv(my_scene, directions) + print("place code shape", my_pcv.shape) + + self.assertIsNotNone(my_pcv) + self.assertFalse(sum(my_pcv.shape) == 0) + self.assertTrue(len(my_pcv.shape) == 4) + self.assertFalse(np.any(np.isnan(my_pcv))) + self.assertTrue(my_pcv.shape[3] == 3) + self.assertTrue(my_pcv.shape[2] == 4) + self.assertTrue(my_pcv.shape[0] == 1) + self.assertTrue(my_pcv.shape[1] == 1) + + # not working cases doesnt match with shape of place code + testdirection = np.zeros((2, 4, 2)) + with self.assertRaises(Exception) as cm: + my_pcv = processing.apcv(my_scene, testdirection) + print("wanted exception occured", cm.exception) + + # not working cases wrong last dimension + testdirection = np.zeros((180, 360, 1)) + with self.assertRaises(Exception) as cm: + my_pcv = processing.apcv(my_scene, testdirection) + print("wanted exception occured", cm.exception) + + # not working cases too many dimensions + testdirection = np.zeros((180, 360, 2, 4)) + with self.assertRaises(Exception) as cm: + my_pcv = processing.apcv(my_scene, testdirection) + print("wanted exception occured", cm.exception) + + # not working cases empty + testdirection = np.zeros(()) + with self.assertRaises(Exception) as cm: + my_pcv = processing.apcv(my_scene, testdirection) + print("wanted exception occured", cm.exception) + + # not working cases nans + testdirection = np.zeros((180, 360, 2, 4)) + testdirection[2, 3, 0] = np.nan + with self.assertRaises(Exception) as cm: + my_pcv = processing.apcv(my_scene, testdirection) + print("wanted exception occured", cm.exception) + + def test_size(self): + # not working cases: + scene = processing.scene(self.mydb, rowid=1) + for size in [8, 1, 0, -4, 9.4, 'g', None, np.nan]: + with self.assertRaises(Exception) as cm: + contrast = processing.michelson_contrast(scene, size=size) + print("wanted error occured", cm.exception) + + # working cases + for size in [2, 3, 4, 5]: + contrast = processing.michelson_contrast(scene, size=size) + self.assertIsNotNone(contrast) + self.assertFalse(sum(contrast.shape) == 0) + self.assertTrue(len(contrast.shape) == 4) + self.assertFalse(np.any(np.isnan(contrast))) + self.assertTrue(contrast.shape[3] == 1) + self.assertTrue(contrast.shape[2] == 4) + self.assertTrue(contrast.shape[0] > 0) + self.assertTrue(contrast.shape[1] > 0) + + def test_michelsoncontrast_scene(self): + + scene = processing.scene(self.mydb, rowid=1) + + # working cases + contrast = processing.michelson_contrast(scene) + self.assertIsNotNone(contrast) + self.assertFalse(sum(contrast.shape) == 0) + self.assertTrue(len(contrast.shape) == 4) + self.assertFalse(np.any(np.isnan(contrast))) + self.assertTrue(contrast.shape[3] == 1) + self.assertTrue(contrast.shape[2] == 4) + self.assertTrue(contrast.shape[0] > 0) + self.assertTrue(contrast.shape[1] > 0) + + # not working case + scene2 = scene.copy() + scene2[3, 2, 1, 0] = np.nan + scene3 = [[1, 2, 3], [1, 2, 3], [1, 2, 3]] + scene3 = [scene3, scene3, scene3] + scene3 = np.array(scene3) + scene4 = np.zeros((3, 4, 5, 0)) + for s in [scene2, scene3, scene4]: + with self.assertRaises(Exception) as cm: + contrast = processing.michelson_contrast(s,) + print("wanted exception occured", cm.exception) + + +if __name__ == '__main__': + unittest.main() diff --git a/src/processing/tools.py b/src/processing/tools.py index d77f133..d61aefa 100644 --- a/src/processing/tools.py +++ b/src/processing/tools.py @@ -1,4 +1,8 @@ -import processing.constants as prc +from .constants import __ibpc_indeces__ +from .constants import __spherical_indeces__ +from .constants import __cartesian_indeces__ +from .constants import __obpc_indeces__ +from .constants import __eye_indeces__ import numpy as np @@ -12,7 +16,7 @@ def is_ibpc(place_code): """ toreturn = isinstance(place_code, np.ndarray) toreturn = toreturn and (len(place_code.shape) == - len(prc.__ibpc_indeces__)) + len(__ibpc_indeces__)) return toreturn @@ -26,7 +30,7 @@ def is_obpc(place_code): """ toreturn = isinstance(place_code, np.ndarray) toreturn = toreturn and (len(place_code.shape) == - len(prc.__obpc_indeces__)) + len(__obpc_indeces__)) return toreturn @@ -41,22 +45,22 @@ def ibs_to_obs(scene, eye_map): assert is_ibpc(scene),\ 'scene should be an ibs scene' assert isinstance(eye_map, np.ndarray), 'eye_map should be a numpy array' - assert len(eye_map.shape) == len(prc.__eye_indeces__),\ + assert len(eye_map.shape) == len(__eye_indeces__),\ 'eye_map should have {} dimensions to be an ibs scene'.format( - len(prc.__eye_indeces__)) + len(__eye_indeces__)) for index_name in ['elevation', 'azimuth']: - index = prc.__ibpc_indeces__[index_name] + index = __ibpc_indeces__[index_name] assert eye_map.shape[index] == scene.shape[index],\ 'eye_map and scene should have the same number of {}'.format( index_name) - obs_size = (scene.shape[prc.__ibpc_indeces__['elevation']] * - scene.shape[prc.__ibpc_indeces__['azimuth']], - scene.shape[prc.__ibpc_indeces__['channel']], - scene.shape[prc.__ibpc_indeces__['component']]) + obs_size = (scene.shape[__ibpc_indeces__['elevation']] * + scene.shape[__ibpc_indeces__['azimuth']], + scene.shape[__ibpc_indeces__['channel']], + scene.shape[__ibpc_indeces__['component']]) obs_scene = scene.reshape(obs_size) - omm_size = (eye_map.shape[prc.__ibpc_indeces__['elevation']] * - eye_map.shape[prc.__ibpc_indeces__['azimuth']], - eye_map.shape[prc.__ibpc_indeces__['component']]) + omm_size = (eye_map.shape[__ibpc_indeces__['elevation']] * + eye_map.shape[__ibpc_indeces__['azimuth']], + eye_map.shape[__ibpc_indeces__['component']]) ommatidia_map = eye_map.reshape(omm_size) return (obs_scene, ommatidia_map) @@ -67,19 +71,19 @@ def cartesian_to_spherical(x, y, z): azimuth = np.arctan2(y, x) spherical = np.zeros_like(x) spherical = np.tile(spherical[..., np.newaxis], (3,)) - spherical[..., prc.__spherical_indeces__['elevation']] = elevation - spherical[..., prc.__spherical_indeces__['azimuth']] = azimuth - spherical[..., prc.__spherical_indeces__['radius']] = radius + spherical[..., __spherical_indeces__['elevation']] = elevation + spherical[..., __spherical_indeces__['azimuth']] = azimuth + spherical[..., __spherical_indeces__['radius']] = radius return spherical def spherical_to_cartesian(elevation, azimuth, radius=1): cartesian = np.zeros_like(elevation) cartesian = np.tile(cartesian[..., np.newaxis], (3,)) - cartesian[..., prc.__cartesian_indeces__['x']] = np.cos( + cartesian[..., __cartesian_indeces__['x']] = np.cos( elevation) * np.cos(azimuth) - cartesian[..., prc.__cartesian_indeces__['y']] = np.cos( + cartesian[..., __cartesian_indeces__['y']] = np.cos( elevation) * np.sin(azimuth) - cartesian[..., prc.__cartesian_indeces__['z']] = np.sin(elevation) + cartesian[..., __cartesian_indeces__['z']] = np.sin(elevation) cartesian = radius * cartesian return cartesian -- GitLab