diff --git a/doc/source/example/processing/testblubb.py~ b/doc/source/example/processing/testblubb.py~ deleted file mode 100644 index e6755723fa5238687a8e600bc4fc483c1433a1a2..0000000000000000000000000000000000000000 --- a/doc/source/example/processing/testblubb.py~ +++ /dev/null @@ -1,22 +0,0 @@ -import numpy as np -import matplotlib.pyplot as plt - -import os -import sys -sys.path.insert(0, '/media/luiza/Daten/Repos/toolbox-navigation/src/database') -from database import DataBaseLoad -sys.path.insert(0, '/media/luiza/Daten/Repos/toolbox-navigation/src/processing') -import processing - - -# 1) Connect to the database -mydb_filename = os.path.abspath('../database.db') -mydb = DataBaseLoad(mydb_filename) -# 2) Define the position-orinetation at which -# we want the image and get the scene -rowid = 5000 -my_scene = processing.scene(mydb, rowid=rowid) - -print(my_scene.shape) -print(my_scene.type) -print('elevation' in my_scene) diff --git a/navipy/__init__.py~ b/navipy/__init__.py~ deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/navipy/__pycache__/__init__.cpython-35.pyc b/navipy/__pycache__/__init__.cpython-35.pyc deleted file mode 100644 index d77138ae6ab15a1ae937595049e7b6a9a1c3fc02..0000000000000000000000000000000000000000 Binary files a/navipy/__pycache__/__init__.cpython-35.pyc and /dev/null differ diff --git a/navipy/comparing/__init__.py~ b/navipy/comparing/__init__.py~ deleted file mode 100644 index dcc7e6f4e8ba083943af3a140fbd390542c8611e..0000000000000000000000000000000000000000 --- a/navipy/comparing/__init__.py~ +++ /dev/null @@ -1,143 +0,0 @@ -""" -The Place comparator list different methods to -compare a current place to a memorised place or -memorised places. -""" -import numpy as np -from navipy.processing.tools import is_ibpc, is_obpc -from navipy.processing.tools import check_scene - - -def simple_imagediff(current, memory): - """Compute the difference between -the current and memorised place code - - :param current: current place code - :param memory: memorised place code - :returns: the image difference - :rtype: float - - ..ref: Zeil, J., 2012. Visual homing: an insect perspective. - Current opinion in neurobiology - - """ - if not isinstance(current, np.ndarray): - raise TypeError('current place code should be a numpy array') - if not isinstance(memory, np.ndarray): - raise TypeError('memory place code should be a numpy array') - if not np.all(current.shape == memory.shape): - raise Exception('memory and current place code should\ - have the same shape') - check_scene(current) - check_scene(memory) - diff = current - memory - if is_ibpc(current): - return diff - elif is_obpc(current): - return diff - else: - raise TypeError('place code is neither an ibpc nor obpc') - - -def imagediff(current, memory): - """Compute the root mean square difference between -the current and memorised place code - - :param current: current place code - :param memory: memorised place code - :returns: the image difference - :rtype: float #array(1,4) for ibpc and float for obpc - - ..ref: Zeil, J., 2012. Visual homing: an insect perspective. - Current opinion in neurobiology - - """ - simple_diff = simple_imagediff(current, memory) - diff = np.power(simple_diff, 2) - if is_ibpc(current): - return np.sqrt(diff.mean(axis=0).mean(axis=0)) # 1 - elif is_obpc(current): - return np.sqrt(diff.mean(axis=0).mean(axis=0)) - else: - raise TypeError('place code is neither an ibpc nor obpc') - - -def rot_imagediff(current, memory): - """Compute the rotational image difference between -the current and memorised place code. - - :param current: current place code - :param memory: memorised place code - :returns: the rotational image difference - :rtype: (np.ndarray) - - ..ref: Zeil, J., 2012. Visual homing: an insect perspective. - Current opinion in neurobiology - ..note: assume that the image is periodic along the x axis - (the left-right axis) - """ - if not is_ibpc(current): # and not is_obpc(current): - raise TypeError('The current and memory place code\ - should be image based') - if not is_ibpc(memory): # and not is_obpc(memory): - raise TypeError('The current and memory place code\ - should be image based') - check_scene(current) - check_scene(memory) - ridf = np.zeros((current.shape[1], current.shape[2])) - for azimuth_i in range(0, current.shape[1]): - rot_im = np.roll(current, azimuth_i, axis=1) - ridf[azimuth_i, :] = np.squeeze(imagediff(rot_im, memory)) # rot_im - return ridf - - -def diff_optic_flow(current, memory): - """Computes the direction of motion from current -to memory by using the optic flow under the -constrain that the brightness is constant, (small movement), -using a taylor expansion and solving the equation: -0=I_t+\delta I*<u,v> or I_x+I_y+I_t=0 - -afterwards the aperture problem is solved by a -Matrix equation Ax=b, where x=(u,v) and -A=(I_x,I_y) and b = I_t - - :param current: current place code - :param memory: memorised place code - :returns: a directional vectors - :rtype: (np.ndarray) - - ..ref: aperture problem: - Shimojo, Shinsuke, Gerald H. Silverman, and Ken Nakayama: - "Occlusion and the solution to the aperture problem for motion." - Vision research 29.5 (1989): 619-626. - optic flow: - Horn, Berthold KP, and Brian G. Schunck.: - "Determining optical flow." - Artificial intelligence 17.1-3 (1981): 185-203. - """ - if not is_ibpc(current): # and not is_obpc(current): - raise TypeError('The current and memory place code\ - should be image based') - if not is_ibpc(memory): # and not is_obpc(memory): - raise TypeError('The current and memory place code\ - should be image based') - check_scene(current) - check_scene(memory) - currroll = np.roll(current, 1, axis=1) - dx = current - currroll - memroll = np.roll(memory, 1, axis=1) - dy = memory - memroll - dy = np.reshape(dy, (np.prod(dy.shape), 1)) - dx = np.reshape(dx, (np.prod(dx.shape), 1)) - di = current - memory - di = np.reshape(di, (np.prod(di.shape), 1)) - a_matrix = np.column_stack([dy, dx]) - a_matrix_sqr = np.dot(np.transpose(a_matrix), a_matrix) - b_vector = np.dot(np.transpose(a_matrix), di) - res = np.linalg.solve(a_matrix_sqr, b_vector) - return res - - -def gradient(current, memory): - return 0 diff --git a/navipy/comparing/__pycache__/__init__.cpython-35.pyc b/navipy/comparing/__pycache__/__init__.cpython-35.pyc deleted file mode 100644 index bfeb1d2527d0e393eb86a95df0bfb32e98f70153..0000000000000000000000000000000000000000 Binary files a/navipy/comparing/__pycache__/__init__.cpython-35.pyc and /dev/null differ diff --git a/navipy/comparing/__pycache__/test.cpython-35.pyc b/navipy/comparing/__pycache__/test.cpython-35.pyc deleted file mode 100644 index 9107a89e8de76c262b55ba81868acec9bb1438bf..0000000000000000000000000000000000000000 Binary files a/navipy/comparing/__pycache__/test.cpython-35.pyc and /dev/null differ diff --git a/navipy/comparing/test.py~ b/navipy/comparing/test.py~ deleted file mode 100644 index 041eba06e66c0d9958abc0956019d9617f0f6464..0000000000000000000000000000000000000000 --- a/navipy/comparing/test.py~ +++ /dev/null @@ -1,236 +0,0 @@ -import unittest -import numpy as np -import navipy.database as database -import navipy.comparing as comparing -from navipy.processing.tools import is_numeric_array -import pkg_resources - - -class TestCase(unittest.TestCase): - def setUp(self): - self.mydb_filename = pkg_resources.resource_filename( - 'navipy', 'resources/database.db') - self.mydb = database.DataBaseLoad(self.mydb_filename) - - def test_imagediff_curr(self): - curr = self.mydb.read_image(rowid=1) - mem = self.mydb.read_image(rowid=2) - curr = np.expand_dims(curr, axis=3) - mem = np.expand_dims(mem, axis=3) - curr2 = curr.copy() - curr2[3, 5, 2, 0] = np.nan - curr3 = [[1, 2, 3], [1, 2, 3], [1, 2, 3]] - curr3 = [curr3, curr3, curr3] - curr3 = np.array(curr3) - curr4 = np.zeros((3, 4, 5, 0)) - - # put useless stuff here - with self.assertRaises(ValueError): - comparing.imagediff(curr2, mem) - with self.assertRaises(Exception): - comparing.imagediff(curr3, mem) - with self.assertRaises(Exception): - comparing.imagediff(curr4, mem) - - # should be working -> check if result is correct - for s in [curr]: - diff = comparing.imagediff(s, mem) - # self.assertTrue(diff.shape[1] == 1) - self.assertTrue(diff.shape[0] > 0) - self.assertFalse(np.any(np.isnan(diff))) - self.assertTrue(is_numeric_array(diff)) - - def test_imagediff_memory(self): - curr = self.mydb.read_image(rowid=1) - mem = self.mydb.read_image(rowid=2) - curr = np.expand_dims(curr, axis=3) - mem = np.expand_dims(mem, axis=3) - mem2 = curr.copy() - mem2[3, 5, 2] = np.nan - mem3 = [[1, 2], [1, 2], [1, 2]] - mem3 = [mem3, mem3, mem3] - mem3 = np.array(mem3) - mem4 = np.zeros((3, 4, 5)) - - with self.assertRaises(ValueError): - comparing.imagediff(curr, mem2) - with self.assertRaises(Exception): - comparing.imagediff(curr, mem3) - with self.assertRaises(Exception): - comparing.imagediff(curr, mem4) - - # should be working -> check if result is correct - for s in [mem]: - diff = comparing.imagediff(curr, s) - self.assertFalse(diff.shape[0] <= 0) - # self.assertTrue(diff.shape[1] == 1) - self.assertFalse(np.any(np.isnan(diff))) - self.assertTrue(is_numeric_array(diff)) - - def test_rot_imagediff_curr(self): - curr = self.mydb.read_image(rowid=1) - mem = self.mydb.read_image(rowid=2) - curr = np.expand_dims(curr, axis=3) - mem = np.expand_dims(mem, axis=3) - curr2 = curr.copy() - curr2[3, 5, 2] = np.nan - curr3 = [[1, 2, 3], [1, 2, 3], [1, 2, 3]] - curr3 = [curr3, curr3, curr3] - curr3 = np.array(curr3) - curr4 = np.zeros((3, 4, 5)) - - with self.assertRaises(ValueError): - comparing.rot_imagediff(curr2, mem) - with self.assertRaises(Exception): - comparing.rot_imagediff(curr3, mem) - with self.assertRaises(Exception): - comparing.rot_imagediff(curr4, mem) - - # should be working -> check if result is correct - for s in [curr]: - diff = comparing.rot_imagediff(s, mem) - self.assertFalse(diff.shape[0] <= 0) - self.assertTrue(diff.shape[1] == 4) - self.assertFalse(np.any(np.isnan(diff))) - self.assertTrue(is_numeric_array(diff)) - - def test_rotimagediff_memory(self): - curr = self.mydb.read_image(rowid=1) - mem = self.mydb.read_image(rowid=2) - curr = np.expand_dims(curr, axis=3) - mem = np.expand_dims(mem, axis=3) - mem2 = curr.copy() - mem2[3, 5, 2] = np.nan - mem3 = [[1, 2, 3], [1, 2, 3], [1, 2, 3]] - mem3 = [mem3, mem3, mem3] - mem3 = np.array(mem3) - mem4 = np.zeros((3, 4, 5)) - - with self.assertRaises(ValueError): - comparing.rot_imagediff(curr, mem2) - with self.assertRaises(Exception): - comparing.rot_imagediff(curr, mem3) - with self.assertRaises(Exception): - comparing.rot_imagediff(curr, mem4) - - # should be working -> check if result is correct - for s in [mem]: - diff = comparing.rot_imagediff(curr, s) - self.assertFalse(diff.shape[0] <= 0) - self.assertTrue(diff.shape[1] == 4) - self.assertFalse(np.any(np.isnan(diff))) - self.assertTrue(is_numeric_array(diff)) - - def test_simple_imagediff_curr(self): - curr = self.mydb.read_image(rowid=1) - mem = self.mydb.read_image(rowid=2) - curr = np.expand_dims(curr, axis=3) - mem = np.expand_dims(mem, axis=3) - curr2 = curr.copy() - curr2[3, 5, 2] = np.nan - curr3 = [[1, 2, 3], [1, 2, 3], [1, 2, 3]] - curr3 = [curr3, curr3, curr3] - curr3 = np.array(curr3) - curr4 = np.zeros((3, 4, 5)) - - with self.assertRaises(ValueError): - comparing.simple_imagediff(curr2, mem) - with self.assertRaises(Exception): - comparing.simple_imagediff(curr3, mem) - with self.assertRaises(Exception): - comparing.simple_imagediff(curr4, mem) - - # should be working -> check if result is correct - for s in [curr]: - diff = comparing.simple_imagediff(s, mem) - self.assertFalse(diff.shape[0] <= 0) - self.assertTrue(diff.shape[1] > 0) - self.assertFalse(np.any(np.isnan(diff))) - self.assertTrue(is_numeric_array(diff)) - self.assertTrue(diff.shape[2] == 4) - # self.assertTrue(diff.shape[3] == 1) - - def test_simple_imagediff_mem(self): - curr = self.mydb.read_image(rowid=1) - mem = self.mydb.read_image(rowid=2) - curr = np.expand_dims(curr, axis=3) - mem = np.expand_dims(mem, axis=3) - mem2 = curr.copy() - mem2[3, 5, 2] = np.nan - mem3 = [[1, 2, 3], [1, 2, 3], [1, 2, 3]] - mem3 = [mem3, mem3, mem3] - mem3 = np.array(mem3) - mem4 = np.zeros((3, 4, 5)) - - with self.assertRaises(ValueError): - comparing.simple_imagediff(curr, mem2) - with self.assertRaises(Exception): - comparing.simple_imagediff(curr, mem3) - with self.assertRaises(Exception): - comparing.simple_imagediff(curr, mem4) - - # should be working -> check if result is correct - for s in [mem]: - diff = comparing.simple_imagediff(curr, s) - self.assertFalse(diff.shape[0] <= 0) - self.assertTrue(diff.shape[1] > 0) - self.assertFalse(np.any(np.isnan(diff))) - self.assertTrue(is_numeric_array(diff)) - self.assertTrue(diff.shape[2] == 4) - # self.assertTrue(diff.shape[3] == 1) - - def test_diff_optic_flow_memory(self): - curr = self.mydb.read_image(rowid=1) - mem = self.mydb.read_image(rowid=2) - curr = np.expand_dims(curr, axis=3) - mem = np.expand_dims(mem, axis=3) - mem2 = curr.copy() - mem2[3, 5, 2] = np.nan - mem3 = [[1, 2, 3], [1, 2, 3], [1, 2, 3]] - mem3 = [mem3, mem3, mem3] - mem3 = np.array(mem3) - mem4 = np.zeros((3, 4, 5)) - - with self.assertRaises(ValueError): - comparing.diff_optic_flow(curr, mem2) - with self.assertRaises(Exception): - comparing.diff_optic_flow(curr, mem3) - with self.assertRaises(Exception): - comparing.diff_optic_flow(curr, mem4) - - # should be working -> check if result is correct - for s in [mem]: - vec = comparing.diff_optic_flow(curr, s) - self.assertFalse(vec.shape[1] == (1, 2)) - self.assertFalse(np.any(np.isnan(vec))) - self.assertTrue(is_numeric_array(vec)) - - def test_diff_optic_flow_curr(self): - curr = self.mydb.read_image(rowid=1) - mem = self.mydb.read_image(rowid=2) - curr = np.expand_dims(curr, axis=3) - mem = np.expand_dims(mem, axis=3) - curr2 = curr.copy() - curr2[3, 5, 2] = np.nan - curr3 = [[1, 2], [1, 2], [1, 2]] - curr3 = [curr3, curr3, curr3] - curr3 = np.array(curr3) - curr4 = np.zeros((3, 4, 5, 1)) - - with self.assertRaises(ValueError): - comparing.diff_optic_flow(curr2, mem) - with self.assertRaises(Exception): - comparing.diff_optic_flow(curr3, mem) - with self.assertRaises(Exception): - comparing.diff_optic_flow(curr4, mem) - - # should be working -> check if result is correct - for s in [mem]: - vec = comparing.diff_optic_flow(s, curr) - self.assertFalse(vec.shape[1] == (1, 2)) - self.assertFalse(np.any(np.isnan(vec))) - self.assertTrue(is_numeric_array(vec)) - - -if __name__ == '__main__': - unittest.main() diff --git a/navipy/database/__init__.py~ b/navipy/database/__init__.py~ deleted file mode 100644 index 2df843460a1acdec657782cbac74091d54d05847..0000000000000000000000000000000000000000 --- a/navipy/database/__init__.py~ +++ /dev/null @@ -1,623 +0,0 @@ -""" -Database are generated by the rendering module, and contains all \ -images and there corresponding position-orientations. - -* position_orientation: containing all position and orientation of where \ -images were rendered. The position-orientation is described by \ -['x','y','z','alpha_0','alpha_1','alpha_2'] -* image: containing all images ever rendered. Each channel of each image \ -are normalised, so to use the full coding range. -* normalisation: the normalisation constantes - - -How to load a database ----------------------- - -.. code-block:: python - - from database import DataBaseLoad - mydb_filename = 'database.db' - mydb = DataBaseLoad(mydb_filename) - -How to load all position-orientation ------------------------------------- - -The database contains all position-orientation \ -at which an image as been rendered. In certain \ -situation, it may be usefull to know all \ -position-orientation in the database. More technically \ -speaking, loading the full table of position-orientaiton. - -.. code-block:: python - - posorients = mydb.get_posorients() - posorients.head() - -How to load an image --------------------- - -The database contains images which can be processed differently \ -depending on the navigation strategy beeing used. - -Images are at given position-orientations. To load an image \ -the position-orientation can be given. The DataBaseLoader will \ -look if this position-orientation has been rendered. If it is \ -the case, the image will be returned. - -.. code-block:: python - - posorient = pd.Series(index=['x', 'y', 'z', - 'alpha_0', 'alpha_1', 'alpha_2']) - posorient.x = -0.6 - posorient.y = -7.2 - posorient.z = 2.35 - posorient.alpha_0 = np.pi / 2 - posorient.alpha_1 = 0 - posorient.alpha_2 = 0 - image = mydb.read_image(posorient=posorient) - -.. plot:: example/database/load_image_posorient.py - -However, looking in the database if an image has already been \ -rendered at a given position-orientation can cost time. To speed up \ -certain calculation, image can instead be access by row number. \ -Indeed each position-orientation can be identified by a unique row \ -number. This number is consistant through the entire database. Thus, \ -an image can be loaded by providing the row number. - -.. code-block:: python - - rowid = 1000 - image = mydb.read_image(rowid=rowid) - -.. plot:: example/database/load_image_rowid.py - - - -.. todo: channels as part of database - -""" - -import os -import numpy as np -import pandas as pd -import sqlite3 -import io -import warnings -import navipy.processing.tools as tools - - -def adapt_array(arr): - """ - http://stackoverflow.com/a/31312102/190597 (SoulNibbler) - """ - if arr is None: - raise ValueError('array must not be None') - out = io.BytesIO() - np.save(out, arr) - out.seek(0) - return sqlite3.Binary(out.read()) - - -def convert_array(text): - if text is None: - raise ValueError('text must not be None') - out = io.BytesIO(text) - out.seek(0) - return np.load(out) - - -# Converts np.array to TEXT when inserting -sqlite3.register_adapter(np.ndarray, adapt_array) -# Converts TEXT to np.array when selecting -sqlite3.register_converter("array", convert_array) - - -class DataBase(): - """DataBase is the parent class of DataBaseLoad and DataBaseSave. -It creates three sql table on initialisation. - """ - __float_tolerance = 1e-14 - - def __init__(self, filename, channels=['R', 'G', 'B', 'D']): - """Initialisation of the database """ - if not isinstance(filename, str): - raise TypeError('filename should be a string') - if not isinstance(channels, list): - raise TypeError('nb_channel should be a list or np array') - """for c in channels: - if not c in ['R','G','B','D']: - raise ValueError('channels - must be either R,G,B or D (Distance)')""" - self.filename = filename - self.channels = channels - self.normalisation_columns = list() - for chan_n in self.channels: - self.normalisation_columns.append(str(chan_n) + '_max') - self.normalisation_columns.append(str(chan_n) + '_min') - self.normalisation_columns.append(str(chan_n) + '_range') - - self.tablecolumns = dict() - self.tablecolumns['position_orientation'] = dict() - self.tablecolumns['position_orientation']['x'] = 'real' - self.tablecolumns['position_orientation']['y'] = 'real' - self.tablecolumns['position_orientation']['z'] = 'real' - self.tablecolumns['position_orientation']['alpha_0'] = 'real' - self.tablecolumns['position_orientation']['alpha_1'] = 'real' - self.tablecolumns['position_orientation']['alpha_2'] = 'real' - self.tablecolumns['image'] = dict() - self.tablecolumns['image']['data'] = 'array' - self.tablecolumns['normalisation'] = dict() - for col in self.normalisation_columns: - self.tablecolumns['normalisation'][col] = 'real' - - if os.path.exists(filename): - # Check database - self.db = sqlite3.connect( - 'file:' + filename + '?cache=shared', uri=True, - detect_types=sqlite3.PARSE_DECLTYPES, - timeout=10) - self.db_cursor = self.db.cursor() - for tablename, _ in self.tablecolumns.items(): - if not self.table_exist(tablename): - raise Exception('{} does not contain a table\ - named {}'.format(filename, tablename)) - elif self.create: - # Create database - self.db = sqlite3.connect( - filename, detect_types=sqlite3.PARSE_DECLTYPES) - self.db_cursor = self.db.cursor() - for key, val in self.tablecolumns.items(): - columns = "(id integer primary key autoincrement" - for colname, coltype in val.items(): - columns += ' , ' + colname + ' ' + coltype - columns += ')' - self.db_cursor.execute( - "create table {} {}".format(key, columns)) - self.db.commit() - else: - raise NameError('Database {} does not exist'.format(filename)) - - azimuth = np.linspace(-180, 180, 360) - elevation = np.linspace(-90, 90, 180) - [ma, me] = np.meshgrid(azimuth, elevation) - self.viewing_directions = np.zeros((ma.shape[0], ma.shape[1], 2)) - self.viewing_directions[..., 0] = me - self.viewing_directions[..., 1] = ma - - def table_exist(self, tablename): - if not isinstance(tablename, str): - raise TypeError('tablename should be a string') - self.db_cursor.execute( - """ - SELECT count(*) - FROM sqlite_master - WHERE type='table' and name=?; - """, (tablename,)) - return bool(self.db_cursor.fetchone()) - - def check_data_validity(self, rowid): - if not isinstance(rowid, int): - raise TypeError('rowid must be an integer') - if rowid <= 0: - raise ValueError('rowid must be greater zero') - if rowid is np.nan: - raise ValueError('rowid must not be nan') - self.db_cursor.execute( - """ - SELECT count(*) - FROM position_orientation - WHERE rowid=?; - """, (rowid,)) - valid = bool(self.db_cursor.fetchone()[0]) - self.db_cursor.execute( - """ - SELECT count(*) - FROM normalisation - WHERE rowid=?; - """, (rowid,)) - valid = valid and bool(self.db_cursor.fetchone()[0]) - self.db_cursor.execute( - """ - SELECT count(*) - FROM image - WHERE rowid=?; - """, (rowid,)) - valid = valid and bool(self.db_cursor.fetchone()[0]) - return valid - - def get_posid(self, posorient): - if not isinstance(posorient, pd.Series): - raise TypeError('posorient should be a pandas Series') - if posorient is not None: - if not isinstance(posorient, pd.Series): - raise TypeError('posorient should be a pandas Series') - if posorient.empty: - raise Exception('position must not be empty') - if 'x' not in posorient.index: - raise ValueError('missing index x') - if 'y' not in posorient.index: - raise ValueError('missing index y') - if 'z' not in posorient.index: - raise ValueError('missing index z') - if 'alpha_0' not in posorient.index: - raise ValueError('missing index alpha_0') - if 'alpha_1' not in posorient.index: - raise ValueError('missing index alpha_1') - if 'alpha_2' not in posorient.index: - raise ValueError('missing index alpha_2') - if np.any(pd.isnull(posorient)): - raise ValueError('posorient must not contain nan') - where = """x>=? and x<=?""" - where += """and y>=? and y<=?""" - where += """and z>=? and z<=?""" - where += """and alpha_0>=? and alpha_0<=?""" - where += """and alpha_1>=? and alpha_1<=?""" - where += """and alpha_2>=? and alpha_2<=?""" - params = ( - posorient['x'] - self.__float_tolerance, - posorient['x'] + self.__float_tolerance, - posorient['y'] - self.__float_tolerance, - posorient['y'] + self.__float_tolerance, - posorient['z'] - self.__float_tolerance, - posorient['z'] + self.__float_tolerance, - posorient['alpha_0'] - self.__float_tolerance, - posorient['alpha_0'] + self.__float_tolerance, - posorient['alpha_1'] - self.__float_tolerance, - posorient['alpha_1'] + self.__float_tolerance, - posorient['alpha_2'] - self.__float_tolerance, - posorient['alpha_2'] + self.__float_tolerance) - self.db_cursor.execute( - """ - SELECT count(*) - FROM position_orientation - WHERE {};""".format(where), params) - exist = self.db_cursor.fetchone()[0] # [0] because of tupple - if bool(exist): - self.db_cursor.execute( - """ - SELECT rowid - FROM position_orientation - WHERE {}; - """.format(where), params) - return self.db_cursor.fetchone()[0] - elif self.create: - self.db_cursor.execute( - """ - INSERT - INTO position_orientation(x,y,z,alpha_0,alpha_1,alpha_2) - VALUES (?,?,?,?,?,?) - """, ( - posorient['x'], - posorient['y'], - posorient['z'], - posorient['alpha_0'], - posorient['alpha_1'], - posorient['alpha_2'])) - rowid = self.db_cursor.lastrowid - self.db.commit() - return rowid - else: - print(posorient) - raise ValueError('posorient not found') - - @property - def create(self): - return False - - -class DataBaseLoad(DataBase): - """A database generated by the rendering module is based on sqlite3. - """ - - def __init__(self, filename, channels=['R', 'G', 'B', 'D']): - """Initialise the DataBaseLoader""" - if not isinstance(filename, str): - raise TypeError('filename should be a string') - if not isinstance(channels, list): - raise TypeError('nb_channel should be a list or np array') - for c in channels: - if c not in ['R', 'G', 'B', 'D']: - raise ValueError('channels must be either\ - R,G,B or D (Distance)') - DataBase.__init__(self, filename, channels=channels) - - @property - def create(self): - """use to decide weather to alter the database or not - return False because we do not want - to write on database (Load class)""" - return False - - def iter_posorients(self): - """Iter through all position orientation in the database - """ - self.db_cursor.execute( - """ - SELECT * - FROM position_orientation - """) - - columns_names = [] - for col in self.db_cursor.description: - columns_names.append(col[0]) - for row in self.db_cursor: - toyield = pd.Series(data=row, index=columns_names) - toyield.name = toyield.id - toyield.drop('id', inplace=True) - yield toyield - - @property - def posorients(self): - """Return the position orientations of all points in the \ -database - """ - posorient = pd.read_sql_query( - "select * from position_orientation;", self.db) - posorient.set_index('id', inplace=True) - return posorient - - def read_posorient(self, posorient=None, rowid=None): - if not isinstance(posorient, pd.Series): - ('posorient should be a pandas Series') - if posorient is not None: - if not isinstance(posorient, pd.Series): - raise TypeError('posorient should be a pandas Series') - if posorient.empty: - raise Exception('position must not be empty') - if 'x' not in posorient.index: - raise ValueError('missing index x') - if 'y' not in posorient.index: - raise ValueError('missing index y') - if 'z' not in posorient.index: - raise ValueError('missing index z') - if 'alpha_0' not in posorient.index: - raise ValueError('missing index alpha_0') - if 'alpha_1' not in posorient.index: - raise ValueError('missing index alpha_1') - if 'alpha_2' not in posorient.index: - raise ValueError('missing index alpha_2') - if np.any(pd.isnull(posorient)): - raise ValueError('posorient must not contain nan') - if not isinstance(rowid, int): - raise TypeError('rowid must be an integer') - if rowid <= 0: - raise ValueError('rowid must be greater zero') - if rowid is np.nan: - raise ValueError('rowid must not be nan') - if (posorient is None) and (rowid is None): - Exception('posorient and rowid can not be both None') - if posorient is not None: - rowid = self.get_posid(posorient) - # Read images - tablename = 'position_orientation' - toreturn = pd.read_sql_query( - """ - SELECT * - FROM {} - WHERE (rowid={}) - """.format(tablename, rowid), self.db) - toreturn = toreturn.loc[0, :] - toreturn.name = toreturn.id - toreturn.drop('id') - toreturn = toreturn.astype(float) - return toreturn - - def read_image(self, posorient=None, rowid=None): - if not isinstance(posorient, pd.Series): - ('posorient should be a pandas Series') - if posorient is not None: - if not isinstance(posorient, pd.Series): - raise TypeError('posorient should be a pandas Series') - if posorient.empty: - raise Exception('position must not be empty') - if 'x' not in posorient.index: - raise ValueError('missing index x') - if 'y' not in posorient.index: - raise ValueError('missing index y') - if 'z' not in posorient.index: - raise ValueError('missing index z') - if 'alpha_0' not in posorient.index: - raise ValueError('missing index alpha_0') - if 'alpha_1' not in posorient.index: - raise ValueError('missing index alpha_1') - if 'alpha_2' not in posorient.index: - raise ValueError('missing index alpha_2') - if np.any(pd.isnull(posorient)): - raise ValueError('posorient must not contain nan') - if rowid is not None: - if not isinstance(rowid, int): - raise TypeError('rowid must be an integer') - if rowid <= 0: - raise ValueError('rowid must be greater zero') - if rowid is np.nan: - raise ValueError('rowid must not be nan') - if (posorient is None) and (rowid is None): - raise Exception('posorient and rowid can not be both None') - if posorient is not None: - rowid = self.get_posid(posorient) - """Read an image at a given position-orientation or given id of row in the \ - database. - - :param posorient: a pandas Series with index \ - ['x','y','z','alpha_0','alpha_1','alpha_2'] - :param rowid: an integer - :returns: an image - :rtype: numpy.ndarray - """ - if (posorient is None) and (rowid is None): - Exception('posorient and rowid can not be both None') - if posorient is not None: - rowid = self.get_posid(posorient) - # Read images - tablename = 'image' - self.db_cursor.execute( - """ - SELECT data - FROM {} - WHERE (rowid=?) - """.format(tablename), (rowid,)) - image = self.db_cursor.fetchone()[0] - # Read cmaxminrange - tablename = 'normalisation' - cmaxminrange = pd.read_sql_query( - """ - SELECT * - FROM {} - WHERE (rowid={}) - """.format(tablename, rowid), self.db) - if cmaxminrange.shape[0] != 1: - raise Exception('Error while reading normalisation factors') - cmaxminrange = cmaxminrange.iloc[0, :] - cmaxminrange.name = cmaxminrange.id - cmaxminrange.drop('id') - cmaxminrange = cmaxminrange.astype(float) - return self.denormalise_image(image, cmaxminrange) - - def denormalise_image(self, image, cmaxminrange): - if len(image.shape) != 3: - raise Exception('image should be 3D array') - if image.shape[2] != len(self.channels): - raise Exception('image does not have the required\ - number of channels {}'.format( - len(self.channels))) - if not isinstance(cmaxminrange, pd.Series): - raise Exception('cmaxminrange should be a pandas Series') - if cmaxminrange.empty: - raise Exception('cmaxminrange must not be empty') - for chan_n in self.channels: - if str(chan_n) + '_max' not in cmaxminrange.index: - raise ValueError('cminmax range is missing index ' - + str(chan_n) + '_max') - if str(chan_n) + '_min' not in cmaxminrange.index: - raise ValueError('cminmax range is missing index ' - + str(chan_n) + '_min') - if str(chan_n) + '_range' not in cmaxminrange.index: - raise ValueError('cminmax range is missing index ' - + str(chan_n) + '_range') - if np.any(np.isnan(cmaxminrange.loc[str(chan_n) + '_max'])): - raise ValueError('cmaxminrange contains nans') - if np.any(np.isnan(cmaxminrange.loc[str(chan_n) + '_min'])): - raise ValueError('cmaxminrange contains nans') - if np.any(np.isnan(cmaxminrange.loc[str(chan_n) + '_range'])): - raise ValueError('cmaxminrange contains nans') - denormed_im = np.zeros(image.shape, dtype=np.float) - maxval_nim = np.iinfo(image.dtype).max - # - for chan_i, chan_n in enumerate(self.channels): - cimage = image[:, :, chan_i].astype(float) - cmax = cmaxminrange.loc[str(chan_n) + '_max'] - cmin = cmaxminrange.loc[str(chan_n) + '_min'] - crange = cmaxminrange.loc[str(chan_n) + '_range'] - cimage /= maxval_nim - cimage *= crange - cimage += cmin - denormed_im[:, :, chan_i] = cimage - if np.max(cimage) != cmax: - print(cmaxminrange.name) - # raise ValueError( - # 'denormalisation failed {}!={} - # '.format(np.max(cimage), cmax)) - return denormed_im - - -class DataBaseSave(DataBase): - def __init__(self, filename, channels=['R', 'G', 'B', 'D'], - arr_dtype=np.uint8): - """ - """ - DataBase.__init__(self, filename, channels=channels) - self.arr_dtype = arr_dtype - - def create(self): - """use to decide weather to alter the database or not - return True because we will need - to write on database (Save class)""" - return True - - def write_image(self, posorient, image): - normed_im, cmaxminrange = self.normalise_image(image, self.arr_dtype) - rowid = self.get_posid(posorient) - # Write image - tablename = 'image' - params = dict() - params['rowid'] = rowid - params['data'] = normed_im - self.insert_replace(tablename, params) - # - tablename = 'normalisation' - params = dict() - params['rowid'] = rowid - for chan_n in self.normalisation_columns: - params[chan_n] = cmaxminrange.loc[chan_n] - self.insert_replace(tablename, params) - - def insert_replace(self, tablename, params): - if not isinstance(tablename, str): - raise ValueError('table are named by string') - if not isinstance(params, dict): - raise ValueError('params should be dictionary columns:val') - params_list = list() - columns_str = '' - for key, val in params.items(): - columns_str += key + ',' - params_list.append(val) - columns_str = columns_str[:-1] # remove last comma - if len(params_list) == 0: - warnings.warn('nothing to be done in {}'.format(tablename)) - return - questionsmarks = '?' - for _ in range(1, len(params_list)): - questionsmarks += ',?' - self.db_cursor.execute( - """ - INSERT OR REPLACE - INTO {} ({}) - VALUES ({}) - """.format(tablename, - columns_str, - questionsmarks), - tuple(params_list) - ) - self.db.commit() - - def normalise_image(self, image, dtype=np.uint8): - if not isinstance(image, np.ndarray): - raise TypeError('image must be np.array') - if np.any(np.isnan(image)): - raise ValueError('image must not contain nan values') - if image.shape[0] <= 0 or image.shape[1] <= 0: - raise Exception('image dimensions incorrect') - if image.shape[2] != len(self.channels): - raise Exception('image channels number differs from\ - given channel number') - if not tools.is_numeric_array(image): - raise TypeError('scene is of non numeric type') - normed_im = np.zeros(image.shape, dtype=dtype) - maxval_nim = np.iinfo(normed_im.dtype).max - # - columns = list() - for chan_n in self.channels: - columns.append(str(chan_n) + '_max') - columns.append(str(chan_n) + '_min') - columns.append(str(chan_n) + '_range') - - cmaxminrange = pd.Series(index=columns) - for chan_i, chan_n in enumerate(self.channels): - cimage = image[:, :, chan_i].astype(float) - cmax = cimage.max() - cmin = cimage.min() - crange = cmax - cmin - cimage -= cmin - if np.isclose(crange, 0): - # cimage should be equal to 0 - # so crange is irelevant we can assign it to 1 - crange = 1 - cimage /= crange - cimage *= maxval_nim - cimage = cimage.astype(normed_im.dtype) - normed_im[:, :, chan_i] = cimage - cmaxminrange.loc[str(chan_n) + '_max'] = cmax - cmaxminrange.loc[str(chan_n) + '_min'] = cmin - cmaxminrange.loc[str(chan_n) + '_range'] = crange - return normed_im, cmaxminrange diff --git a/navipy/database/__pycache__/__init__.cpython-35.pyc b/navipy/database/__pycache__/__init__.cpython-35.pyc deleted file mode 100644 index 3bfd065f5b9480e6ed59d81e03ef5c21a0c2e838..0000000000000000000000000000000000000000 Binary files a/navipy/database/__pycache__/__init__.cpython-35.pyc and /dev/null differ diff --git a/navipy/database/__pycache__/database.cpython-35.pyc b/navipy/database/__pycache__/database.cpython-35.pyc deleted file mode 100644 index 39556f7eb80af088dfe0d6a01b7bb98eeda27f1e..0000000000000000000000000000000000000000 Binary files a/navipy/database/__pycache__/database.cpython-35.pyc and /dev/null differ diff --git a/navipy/moving/__pycache__/__init__.cpython-35.pyc b/navipy/moving/__pycache__/__init__.cpython-35.pyc deleted file mode 100644 index 9fba1b965c52102713da30cfa1546b76f4973c0c..0000000000000000000000000000000000000000 Binary files a/navipy/moving/__pycache__/__init__.cpython-35.pyc and /dev/null differ diff --git a/navipy/moving/__pycache__/agent.cpython-35.pyc b/navipy/moving/__pycache__/agent.cpython-35.pyc deleted file mode 100644 index 3501c939970e1f0f1e0577baf5253c7be2df08b7..0000000000000000000000000000000000000000 Binary files a/navipy/moving/__pycache__/agent.cpython-35.pyc and /dev/null differ diff --git a/navipy/moving/__pycache__/maths.cpython-35.pyc b/navipy/moving/__pycache__/maths.cpython-35.pyc deleted file mode 100644 index 54a569a60906dc1a11576ddf359469ec20246340..0000000000000000000000000000000000000000 Binary files a/navipy/moving/__pycache__/maths.cpython-35.pyc and /dev/null differ diff --git a/navipy/moving/__pycache__/test_agent.cpython-35.pyc b/navipy/moving/__pycache__/test_agent.cpython-35.pyc deleted file mode 100644 index aa4058d63e97924dd19098b73d86c8fe532523f7..0000000000000000000000000000000000000000 Binary files a/navipy/moving/__pycache__/test_agent.cpython-35.pyc and /dev/null differ diff --git a/navipy/moving/__pycache__/test_maths.cpython-35.pyc b/navipy/moving/__pycache__/test_maths.cpython-35.pyc deleted file mode 100644 index c9562c6a7391a164142221e8d1638f6fb06a0aaa..0000000000000000000000000000000000000000 Binary files a/navipy/moving/__pycache__/test_maths.cpython-35.pyc and /dev/null differ diff --git a/navipy/moving/agent.py~ b/navipy/moving/agent.py~ deleted file mode 100644 index c6b42101f4c7fb8494fe630906b5c34411b5b45f..0000000000000000000000000000000000000000 --- a/navipy/moving/agent.py~ +++ /dev/null @@ -1,361 +0,0 @@ -""" - -""" -import numpy as np -import pandas as pd -import networkx as nx -import multiprocessing -from multiprocessing import Queue, JoinableQueue, Process -import inspect -try: - from pandas.api.types import is_numeric_dtype -except ImportError: - from pandas.core.common import is_numeric_dtype -from navipy.database import DataBaseLoad -import navipy.moving.maths as navimomath - - -def defaultcallback(database, posorients): - raise NameError('No Callback') - - -class AbstractAgent(): - """ - An abtract class for agent - """ - - def __init__(self, - database_filename, - memory_friendly=False): - - self.db = DataBaseLoad(database_filename) - self.dbname = database_filename - if memory_friendly: - self.__posorients = None - else: - self.__posorients = self.db.posorients - # set mode of motion - mode_move = {'mode': 'on_cubic_grid', - 'param': {'grid_spacing': - pd.Series(data=1, - index=['dx', 'dy', 'dz'])}} - self.mode_of_motion = mode_move - - @property - def posorients(self): - toreturn = self.__posorients - if toreturn is not None: - toreturn = toreturn.copy() - return toreturn - - @property - def mode_of_motion(self): - """ - """ - toreturn = self.__mode_move - toreturn['describe'] = \ - navimomath.mode_moves_supported()[ - self.__mode_move['mode']]['describe'] - return toreturn - - @mode_of_motion.setter - def mode_of_motion(self, mode): - """ - - """ - if not isinstance(mode, dict): - raise TypeError('Mode is not a dictionary') - if 'mode' not in mode: - raise KeyError("'mode' is not a key of mode") - if 'param' not in mode: - raise KeyError("'param' is not a key of mode") - if mode['mode'] in navimomath.mode_moves_supported().keys(): - for param in navimomath.mode_moves_supported()[ - mode['mode']]['param']: - if param not in mode['param']: - raise KeyError( - "'{}' is not in mode['param']".format(param)) - self.__mode_move = mode - else: - raise ValueError('mode is not supported') - - def abstractmove(self, posorients_vel): - if isinstance(posorients_vel, pd.Series) is False: - raise TypeError('posorients_vel should be a pandas Series') - for col in ['x', 'y', 'z', 'alpha_0', 'alpha_1', 'alpha_2', - 'dx', 'dy', 'dz', 'dalpha_0', 'dalpha_1', 'dalpha_2']: - if col not in posorients_vel.index: - raise KeyError( - 'posorients_vel should have {} as index'.format(col)) - # Compute the next position - posorients_vel = navimomath.next_pos( - posorients_vel, - move_mode=self.__mode_move['mode'], - move_param=self.__mode_move['param']) - - # Compute the closest possible position - if posorients_vel is None: - tmp = navimomath.closest_pos_memory_friendly( - posorients_vel, - self.db) - posorients_vel[['x', 'y', 'z', - 'alpha_0', 'alpha_1', 'alpha_2']] = tmp - posorients_vel.name = tmp.name - else: - tmp = navimomath.closest_pos( - posorients_vel, - self.__posorients) - posorients_vel[['x', 'y', 'z', - 'alpha_0', 'alpha_1', 'alpha_2']] = tmp - posorients_vel.name = tmp.name - return posorients_vel - - -class Single(AbstractAgent, Process): - - def __init__(self, - database_filename, - initial_condition, - memory_friendly=False, - posorients_queue=None, - results_queue=None): - if (posorients_queue is not None) and (results_queue is not None): - multiprocessing.Process.__init__(self) - AbstractAgent.__init__(self, database_filename, - memory_friendly) - - self.__posorientvel = pd.Series( - data=0, - index=['x', 'y', 'z', - 'alpha_0', 'alpha_1', 'alpha_2', - 'dx', 'dy', 'dz', - 'dalpha_0', 'dalpha_1', 'dalpha_2'], - dtype=np.float) - - if isinstance(initial_condition, pd.Series): - if is_numeric_dtype(initial_condition): - common_id = list(set(initial_condition.index).intersection( - self.__posorientvel.index)) - self.__posorientvel.loc[common_id] = \ - initial_condition.loc[common_id] - else: - raise TypeError('vel should be numeric') - - else: - raise TypeError('vel should be a pandas Series') - - self.__posorients_queue = posorients_queue - self.__results_queue = results_queue - self.__callback_function = defaultcallback - - def move(self): - # Compute the next position - tmp = self.__callback_function(database=self.db, - posorient=self.__posorientvel) - common_id = list(set(tmp.index).intersection( - self.__posorientvel.index)) - self.__posorientvel.loc[common_id] = tmp.loc[common_id] - self.__posorientvel = self.abstractmove(self.__posorientvel) - - def fly(self, nsteps): - """move until either speed is null, or nsteps has been reached""" - prev_move = self.__posorientvel - for stepi in range(nsteps): - self.move() - if prev_move.equals(self.__posorientvel): - break - prev_move = self.__posorientvel - - def run(self): - """ Only supported when multiprocess""" - if self.__posorients_queue is None or self.__results_queue is None: - raise NameError('Single agent class has not be inititialised ' - + 'with multiprocessing suppport') - proc_name = self.name - print('Process {} started'.format(proc_name)) - while True: - start_posorient = self.__posorients_queue.get(timeout=1) - if start_posorient is None: - # Poison pill means shutdown) - break - common_id = list(set(start_posorient.index).intersection( - self.__posorientvel.index)) - self.__posorientvel.loc[common_id] = start_posorient.loc[common_id] - self.move() - next_posorient = self.__posorientvel - - self.__posorients_queue.task_done() - self.__results_queue.put((start_posorient, next_posorient)) - self.__posorients_queue.task_done() - print('Process {} done'.format(proc_name)) - - @property - def callback_function(self): - return inspect.getsourcelines(self.__callback_function) - - @callback_function.setter - def callback_function(self, callback_function): - self.__callback_function = callback_function - - @property - def position(self): - return self.__posorientvel.loc[['x', 'y', 'z']] - - @property - def velocity(self): - return self.__posorientvel.loc[['dx', 'dy', 'dz']] - - @property - def orientation(self): - return self.__posorientvel.loc[['alpha_0', 'alpha_1', 'alpha_2']] - - @property - def angular_velocity(self): - return self.__posorientvel.loc[['dalpha_0', 'dalpha_1', 'dalpha_2']] - - -class Multi(AbstractAgent): - - def __init__(self, database_filename): - super().__init__(database_filename, False) - # Init the graph - self.__graph = nx.DiGraph() - for row_id, posor in self.db.posorients.iterrows(): - posor.name = row_id - self.__graph.add_node(row_id, - posorient=posor) - - @property - def graph(self): - return self.__graph - - @graph.setter - def graph(self, graph): - if isinstance(graph, nx.DiGraph) is False: - raise TypeError('graph is not a nx.DiGraph') - self.__graph = graph.copy() - self.check_graph() - - def build_graph(self, callback_function, - ncpu=5, - timeout=1): - # Build a list of nodes - results_edges = [] - posorients_queue = JoinableQueue() - results_queue = Queue() - for node in self.__graph.nodes: - posorients_queue.put(self.__graph.nodes[node]['posorient']) - initpos = 0 * self.__graph.nodes[node]['posorient'] - - # Start ndatabase loader - num_agents = ncpu - agents = [Single(self.dbname, - initial_condition=initpos, - memory_friendly=False, - posorients_queue=posorients_queue, - results_queue=results_queue) - for _ in range(num_agents)] - for w in agents: - w.callback_function = callback_function - w.start() - - # Add a poison pill for each agent - for _ in range(num_agents): - posorients_queue.put(None) - - # Wait for all of the tasks to finish - # posorients_queue.join() - - for _ in range(nx.number_of_nodes(self.__graph)): - result = results_queue.get(timeout=timeout) - results_edges.append((result[0].name, - result[1].name)) - # print(results_edges[-1]) - self.__graph.add_edges_from(results_edges) - self.check_graph() - - def check_graph(self): - self.check_single_target() - - def check_single_target(self): - for node in self.__graph.nodes: - # not connected -> loop not ran - for count, _ in enumerate(self.__graph.neighbors(node)): - # count == 0 -> connected to one node - # count == 1 -> connected to two nodes - if count > 0: - raise ValueError( - 'Node {} leads to several locations'.format(node)) - - def find_attractors(self): - """Return a list of node going to each attractor in a graph - """ - attractors = list() - for attractor in nx.attracting_components(self.__graph): - att = dict() - att['attractor'] = attractor - attractors.append(att) - return attractors - - def find_attractors_sources(self, attractors=None): - """Find all sources going to each attractors - """ - if attractors is None: - attractors = self.find_attractors() - - if isinstance(attractors, list) is False: - raise TypeError('Attractors should be a list of dict') - elif len(attractors) == 0: - raise ValueError('No attractors found') - - # Check attractor - for att in attractors: - keyatt = att.keys() - if 'attractor' not in keyatt: - raise ValueError( - 'Each attractors should contain the key attractor') - - # Calculate connection - for att_i, att in enumerate(attractors): - - # [0] because one node of the attractor is enough - # all other node of the attractor are connected to this one - target = list(att['attractor'])[0] - attractors[att_i]['paths'] = \ - nx.shortest_path(self.graph, target=target) - attractors[att_i]['sources'] = \ - list(attractors[att_i]['paths'].keys()) - return attractors - - def catchment_area(self, attractors=None): - """Return the catchment area for attractors - """ - if attractors is None: - attractors = self.find_attractors_sources() - - if isinstance(attractors, list) is False: - raise TypeError('Attractors should be a list of dict') - elif len(attractors) == 0: - raise ValueError('No attractors found') - - # Check attractor - for att in attractors: - keyatt = att.keys() - if 'sources' not in keyatt: - raise ValueError( - 'Each attractors should contains a list of sources') - - return [len(att['sources']) for att in attractors] - - def reach_goals(self, goals): - """ Return all paths to the goals """ - return nx.shortest_path(self.__graph, target=goals) - - def neighboring_nodes(self, target): - """ Return the nodes going to the target """ - # Reverse graph because nx.neighbors give the end node - # and we want to find the start node going to target - # not where target goes. - tmpgraph = self.__graph.reverse(copy=True) - neighbors = tmpgraph.neighbors(target) - return neighbors diff --git a/navipy/moving/maths.py~ b/navipy/moving/maths.py~ deleted file mode 100644 index 4fd7a5baeb4906a31bc4db58ee3cb4e8b189c3cd..0000000000000000000000000000000000000000 --- a/navipy/moving/maths.py~ +++ /dev/null @@ -1,30 +0,0 @@ -""" -Mathematical computation are done in this module. Those involve mostly -geometry, and predefined grids shapes -""" -import numpy as np -import pandas as pd - - -def next_pos(motion_vec, grid_spacing=1, grid_mode='cubic'): - """ - - """ - supported_grid_mode = ['cubic', - None] - assert isinstance(motion_vec, pd.Series),\ - 'motion vector must be a pandas Series' - assert grid_mode in supported_grid_mode, - 'grid mode must is not supported {}'.format(grid_mode) - - speed = motion_vec.loc[['dx', 'dy', 'dz']] - position = motion_vec.loc[['x', 'y', 'z']] - if grid_mode == 'cubic': - speed /= np.linalg.norm(speed) - scaling = grid_spacing / (2 * np.sin(np.pi / 8)) - elif grid_mode == None: - scaling = 1 - else: - raise ValueError('grid_mode is not supported') - - return position + speed.rename({'dx': 'x', 'dy': 'y', 'dz': 'z'}) * scaling diff --git a/navipy/processing/__pycache__/Scene_processing.cpython-35.pyc b/navipy/processing/__pycache__/Scene_processing.cpython-35.pyc deleted file mode 100644 index bf537c91768bc07de71d68e914b807e94f2d4152..0000000000000000000000000000000000000000 Binary files a/navipy/processing/__pycache__/Scene_processing.cpython-35.pyc and /dev/null differ diff --git a/navipy/processing/__pycache__/__init__.cpython-35.pyc b/navipy/processing/__pycache__/__init__.cpython-35.pyc deleted file mode 100644 index dcc89be0a4833923e1595f5f3f18d97c1f3e153e..0000000000000000000000000000000000000000 Binary files a/navipy/processing/__pycache__/__init__.cpython-35.pyc and /dev/null differ diff --git a/navipy/processing/__pycache__/constants.cpython-35.pyc b/navipy/processing/__pycache__/constants.cpython-35.pyc deleted file mode 100644 index 8de0152796b7d7ec0ddbe8ced40f12d156c84a0e..0000000000000000000000000000000000000000 Binary files a/navipy/processing/__pycache__/constants.cpython-35.pyc and /dev/null differ diff --git a/navipy/processing/__pycache__/pcode.cpython-35.pyc b/navipy/processing/__pycache__/pcode.cpython-35.pyc deleted file mode 100644 index b72a525ba7f6eba6b6841a27d11412b61ff87267..0000000000000000000000000000000000000000 Binary files a/navipy/processing/__pycache__/pcode.cpython-35.pyc and /dev/null differ diff --git a/navipy/processing/__pycache__/processing.cpython-35.pyc b/navipy/processing/__pycache__/processing.cpython-35.pyc deleted file mode 100644 index 060aeb1c51a4334d3fc721c83b0fde930c0c4c57..0000000000000000000000000000000000000000 Binary files a/navipy/processing/__pycache__/processing.cpython-35.pyc and /dev/null differ diff --git a/navipy/processing/__pycache__/scene.cpython-35.pyc b/navipy/processing/__pycache__/scene.cpython-35.pyc deleted file mode 100644 index eb3ef2c60648b7f1112519518355f4eef2d8e8c5..0000000000000000000000000000000000000000 Binary files a/navipy/processing/__pycache__/scene.cpython-35.pyc and /dev/null differ diff --git a/navipy/processing/__pycache__/test.cpython-35.pyc b/navipy/processing/__pycache__/test.cpython-35.pyc deleted file mode 100644 index 5215b9e25c7fc208e484f01cff0f3a4f069ef965..0000000000000000000000000000000000000000 Binary files a/navipy/processing/__pycache__/test.cpython-35.pyc and /dev/null differ diff --git a/navipy/processing/__pycache__/tools.cpython-35.pyc b/navipy/processing/__pycache__/tools.cpython-35.pyc deleted file mode 100644 index 4b13d82876b9b00e7c5067fa526792351985f8b9..0000000000000000000000000000000000000000 Binary files a/navipy/processing/__pycache__/tools.cpython-35.pyc and /dev/null differ diff --git a/navipy/processing/constants.py~ b/navipy/processing/constants.py~ deleted file mode 100644 index 1839e292fe194dbfa0c3f2bd952c6958bc3a0ba5..0000000000000000000000000000000000000000 --- a/navipy/processing/constants.py~ +++ /dev/null @@ -1,22 +0,0 @@ -""" -Define some constant -""" - -__spherical_indeces__ = {'elevation': 0, - 'azimuth': 1, - 'radius': 2} -__cartesian_indeces__ = {'x': 0, - 'y': 1, - 'z': 2} -__ibpc_indeces__ = {'elevation': 0, - 'azimuth': 1, - 'channel': 2, - 'component': 3} -__obpc_indeces__ = {'ommatidia': 0, - 'channel': 1, - 'component': 2} -__eye_indeces__ = {'elevation': 0, - 'azimuth': 1, - 'component': 2} -__ommadia_indeces__ = {'ommatidia': 0, - 'component': 1} diff --git a/navipy/processing/test.py~ b/navipy/processing/test.py~ deleted file mode 100644 index daa12edf988a007de54ab8007f8f01289554c8e4..0000000000000000000000000000000000000000 --- a/navipy/processing/test.py~ +++ /dev/null @@ -1,368 +0,0 @@ -import unittest -import sqlite3 -import numpy as np -import pandas as pd -import navipy.database as database -import navipy.processing.pcode as pcode -from navipy.processing.tools import is_numeric_array -import pkg_resources - - -class TestCase(unittest.TestCase): - def setUp(self): - self.mydb_filename = pkg_resources.resource_filename( - 'navipy', 'resources/database.db') - self.mydb = database.DataBaseLoad(self.mydb_filename) - - def test_scene_posorient(self): - conn = sqlite3.connect(self.mydb_filename) - c = conn.cursor() - c.execute(""" SELECT * FROM position_orientation WHERE (rowid=1) """) - rows = c.fetchall()[0] - # 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] - image = self.mydb.read_image(posorient=posorient) - image = np.expand_dims(image, axis=3) - 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): - image = self.mydb.read_image(posorient=posorient2) - - # 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(ValueError): - image = self.mydb.read_image(posorient=posorient2) - - # 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(ValueError): - image = self.mydb.read_image(posorient=posorient2) - - # 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(TypeError): - image = self.mydb.read_image(posorient=posorient2) - - # not working case empty - posorient2 = pd.Series(index=['x', 'y', 'z', - 'alpha_0', 'alpha_1', 'alpha_2']) - - with self.assertRaises(Exception): - image = self.mydb.read_image(posorient=posorient2) - - def test_skyline_scene(self): - scene = self.mydb.read_image(rowid=1) - scene2 = scene.copy() - scene = np.expand_dims(scene, axis=3) - scene2 = np.expand_dims(scene2, axis=3) - 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)) - - # put useless stuff here - with self.assertRaises(ValueError): - pcode.skyline(scene2) - with self.assertRaises(TypeError): - pcode.skyline(scene3) - with self.assertRaises(Exception): - pcode.skyline(scene4) - - # should be working -> check if result(skyline) is correct - for s in [scene]: - skyline = pcode.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): - for rowid in [0, -2]: - with self.assertRaises(ValueError): - # print("rowid",rowid) - self.mydb.read_image(rowid=rowid) - with self.assertRaises(TypeError): - self.mydb.read_image(rowid='T') - with self.assertRaises(TypeError): - self.mydb.read_image(rowid=None) - with self.assertRaises(TypeError): - self.mydb.read_image(rowid=np.nan) - with self.assertRaises(TypeError): - self.mydb.read_image(rowid=4.5) - - for rowid in [1, 2, 3, 4, 5]: - image = self.mydb.read_image(rowid=rowid) - image = np.expand_dims(image, axis=3) - # 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 = self.mydb.read_image(rowid=1) - scene = np.expand_dims(scene, axis=3) - # should not be working - for d in ['g', None, np.nan, 8.4]: - with self.assertRaises(TypeError): - pcode.contrast_weighted_nearness(scene, - distance_channel=d) - with self.assertRaises(ValueError): - pcode.contrast_weighted_nearness(scene, - distance_channel=-1) - - # should work - d = 3 - weighted_scene = \ - pcode.contrast_weighted_nearness(scene, - distance_channel=d) - # print("last channel",d) - self.assertTrue(is_numeric_array(weighted_scene)) - self.assertTrue(~np.any(np.isnan(weighted_scene))) - self.assertEqual(weighted_scene.shape, scene.shape) - - def test_contr_weight_scene(self): - scene = self.mydb.read_image(rowid=1) - scene = np.expand_dims(scene, axis=3) - # working cases - contrast = pcode.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)) - with self.assertRaises(ValueError): - contrast = pcode.contrast_weighted_nearness(scene2) - with self.assertRaises(Exception): - contrast = pcode.contrast_weighted_nearness(scene3) - with self.assertRaises(Exception): - contrast = pcode.contrast_weighted_nearness(scene4) - - def test_contr_weight_contrast(self): - scene = self.mydb.read_image(rowid=1) - scene = np.expand_dims(scene, axis=3) - for size in [9.4, 'g', None, np.nan]: - with self.assertRaises(TypeError): - contrast = pcode.contrast_weighted_nearness( - scene, contrast_size=size) - for size in [8, 1, 0, -4]: - with self.assertRaises(ValueError): - contrast = \ - pcode.contrast_weighted_nearness( - scene, contrast_size=size) - - # working cases - for size in [2, 3, 4, 5]: - contrast = pcode.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.assertEqual(contrast.shape[3], 1) - self.assertEqual(contrast.shape[2], scene.shape[2]) - self.assertEqual(contrast.shape[0], scene.shape[0]) - self.assertEqual(contrast.shape[1], scene.shape[1]) - - def test_pcv(self): - # working case - rowid = 1 - my_scene = self.mydb.read_image(rowid=rowid) - my_scene = np.expand_dims(my_scene, axis=3) - directions = self.mydb.viewing_directions - my_pcv = pcode.pcv(my_scene, directions) - 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): - my_pcv = pcode.pcv(my_scene, testdirection) - - # not working cases wrong last dimension - testdirection = np.zeros((180, 360, 1)) - with self.assertRaises(Exception): - my_pcv = pcode.pcv(my_scene, testdirection) - - # not working cases too many dimensions - testdirection = np.zeros((180, 360, 2, 4)) - with self.assertRaises(Exception): - my_pcv = pcode.pcv(my_scene, testdirection) - - # not working cases empty - testdirection = np.zeros(()) - with self.assertRaises(Exception): - my_pcv = pcode.pcv(my_scene, testdirection) - - # not working cases nans - testdirection = np.zeros((180, 360, 2, 4)) - testdirection[2, 3, 0] = np.nan - with self.assertRaises(ValueError): - my_pcv = pcode.pcv(my_scene, testdirection) - - def test_apcv(self): - # working case - rowid = 1 - my_scene = self.mydb.read_image(rowid=rowid) - my_scene = np.expand_dims(my_scene, axis=3) - # print("scene shape",my_scene.shape) - directions = self.mydb.viewing_directions - print("directions", directions.shape) - my_pcv = pcode.apcv(my_scene, directions) - - 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): - my_pcv = pcode.apcv(my_scene, testdirection) - - # not working cases wrong last dimension - testdirection = np.zeros((180, 360, 1)) - with self.assertRaises(Exception): - my_pcv = pcode.apcv(my_scene, testdirection) - - # not working cases too many dimensions - testdirection = np.zeros((180, 360, 2, 4)) - with self.assertRaises(Exception): - my_pcv = pcode.apcv(my_scene, testdirection) - - # not working cases empty - testdirection = np.zeros(()) - with self.assertRaises(Exception): - my_pcv = pcode.apcv(my_scene, testdirection) - - # not working cases nans - testdirection = np.zeros((180, 360, 2, 4)) - testdirection[2, 3, 0] = np.nan - with self.assertRaises(ValueError): - my_pcv = pcode.apcv(my_scene, testdirection) - - def test_size(self): - # not working cases: - scene = self.mydb.read_image(rowid=1) - scene = np.expand_dims(scene, axis=3) - for size in [8, 1, 0, -4]: - with self.assertRaises(ValueError): - contrast = pcode.michelson_contrast( - scene, size=size) - for size in [9.4, 'g', None, np.nan]: - with self.assertRaises(TypeError): - contrast = pcode.michelson_contrast( - scene, size=size) - - # working cases - for size in [2, 3, 4, 5]: - contrast = pcode.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 = self.mydb.read_image(rowid=1) - scene = np.expand_dims(scene, axis=3) - - # working cases - contrast = pcode.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 = pcode.michelson_contrast(s,) - print("wanted exception occured", cm.exception) - - -if __name__ == '__main__': - unittest.main() diff --git a/navipy/processing/tools.py~ b/navipy/processing/tools.py~ deleted file mode 100644 index a1c3e0fb9db8ec00ba86423dd5cce4e2ca3140f5..0000000000000000000000000000000000000000 --- a/navipy/processing/tools.py~ +++ /dev/null @@ -1,165 +0,0 @@ -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 - - -def check_scene(scene): - if is_ibpc(scene): - # print("normal") - if not is_numeric_array(scene): - raise TypeError('scene is of non numeric type') - if not ~np.any(np.isnan(scene)): - raise ValueError('scene contains nans') - if not len(scene.shape) == 4: - raise Exception('scene has wrong shape, must have 4 dimensions') - if not (scene.shape[1] > 0): - raise Exception('scenes first dimension is empty') - if not (scene.shape[0] > 0): - raise Exception('scenes second dimension is empty') - if not (scene.shape[2] == 4): - raise Exception('3rd dimension of scene must be four') - if not (scene.shape[3] == 1): - raise Exception('4rd dimension of scene must be one') - # assert ~(np.any(np.isNone(scene))) - return True - - elif is_obpc(scene): - if not is_numeric_array(scene): - raise TypeError('scene is of non numeric type') - if not ~np.any(np.isnan(scene)): - raise ValueError('scene contains nans') - if not len(scene.shape) == 3: - raise Exception('scene has wrong shape, must have 4 dimensions') - if not ~(scene.shape[1] <= 0): - raise Exception('scenes first dimension is empty') - if not ~(scene.shape[0] <= 0): - raise Exception('scenes second dimension is empty') - if not (scene.shape[2] == 4): - raise Exception('3rd dimension of scene must be four') - # assert ~(np.any(np.isNone(scene))) - return True - - -def check_viewing_direction(viewing_direction): - if not is_numeric_array(viewing_direction): - raise TypeError('viewing direction is of non numeric type') - if not ~np.any(np.isnan(viewing_direction)): - raise ValueError('viewing direction contains nans') - if len(viewing_direction.shape) < 3: - raise Exception('viewing direction must have at least 3 dimensions') - if not (viewing_direction.shape[1] > 0): - raise Exception('viewing direction has empty second dimension') - if not (viewing_direction.shape[0] > 0): - raise Exception('viewing direction has empty first dimension') - if not (viewing_direction.shape[-1] == 2): - raise Exception(' last dimension of viewing direction must equal 2') - return True - - -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. - - :param array : `numpy.ndarray`-like The array to check. - :returns: True if it is a recognized numerical and False \ - if object or string. - :rtype:bool - """ - 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 is_ibpc(place_code): - """Test if a place code is image based - - :param place_code: a place-code - :returns: True if image based place-code - :rtype: bool - - """ - toreturn = isinstance(place_code, np.ndarray) - toreturn = toreturn and (len(place_code.shape) == - len(__ibpc_indeces__)) - return toreturn - - -def is_obpc(place_code): - """Test if a place code is ommatidia based - - :param place_code: a place-code - :returns: True if ommatidia based place-code - :rtype: bool - - """ - toreturn = isinstance(place_code, np.ndarray) - toreturn = toreturn and (len(place_code.shape) == - len(__obpc_indeces__)) - return toreturn - - -def ibs_to_obs(scene, eye_map): - """Convert an image based scene to an ommatidium based scene. - - :param scene: The scene to be converted - :param eye_map: The eye_map to use - :returns: (obs_scene,ommatidia_map) - :rtype: (np.ndarray,np.ndarray) - """ - 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(__eye_indeces__),\ - 'eye_map should have {} dimensions to be an ibs scene'.format( - len(__eye_indeces__)) - for index_name in ['elevation', 'azimuth']: - 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[__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[__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) - - -def cartesian_to_spherical(x, y, z): - radius = np.sqrt(x**2 + y**2 + z**2) - elevation = np.arctan2(z, np.sqrt(x**2 + y**2)) - azimuth = np.arctan2(y, x) - spherical = np.zeros_like(x) - spherical = np.tile(spherical[..., np.newaxis], (3,)) - 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[..., __cartesian_indeces__['x']] = np.cos( - elevation) * np.cos(azimuth) - cartesian[..., __cartesian_indeces__['y']] = np.cos( - elevation) * np.sin(azimuth) - cartesian[..., __cartesian_indeces__['z']] = np.sin(elevation) - cartesian = radius * cartesian - return cartesian diff --git a/navipy/rendering/__pycache__/DataBase.cpython-35.pyc b/navipy/rendering/__pycache__/DataBase.cpython-35.pyc deleted file mode 100644 index ef0c231ef7a111188cecc98060abab9e4b806656..0000000000000000000000000000000000000000 Binary files a/navipy/rendering/__pycache__/DataBase.cpython-35.pyc and /dev/null differ diff --git a/navipy/rendering/__pycache__/__init__.cpython-35.pyc b/navipy/rendering/__pycache__/__init__.cpython-35.pyc deleted file mode 100644 index a2503f97bf18d28410e60c9e97814282d10886d8..0000000000000000000000000000000000000000 Binary files a/navipy/rendering/__pycache__/__init__.cpython-35.pyc and /dev/null differ diff --git a/navipy/rendering/bee_sampling.py~ b/navipy/rendering/bee_sampling.py~ deleted file mode 100644 index c1f388a237d0dfa1eb4ac24c3de2256202aab837..0000000000000000000000000000000000000000 --- a/navipy/rendering/bee_sampling.py~ +++ /dev/null @@ -1,164 +0,0 @@ -""" -The beesampling class - -.. tothinkof: conditional bpy import to build doc from comments -""" -import bpy -import os -import numpy as np -import pandas as pd -import warnings -from navipy.rendering.cyber_bee import Cyberbee -from navipy.database import DataBaseSave - - -class BeeSampling(Cyberbee): - """ - BeeSampling is a class deriving from Cyberbee. - The BeeSampling can be used to generate a database of -images taken on a rectangular regular grid. For the database, -the BeeSampling rely on DataBase - It worth noting that the generated database can take a large -harddrive space, as each image is composed of 4 channels of 180x360 pixels. - """ - - def __init__(self): - """Initialise the BeeSampling""" - Cyberbee.__init__(self) - self.blenddirname = os.path.dirname(bpy.data.filepath) - self.blendfilename = os.path.basename(bpy.data.filepath) - self.__grid_posorients = None - self.__grid_size = None - self.world_dim = np.inf - - def create_sampling_grid(self, x, y, z, alpha1, alpha2, alpha3): - """Create a cubic grid from all the sampling points - - :param x: the positions along the x-axis - :param y: the positions along the y-axis - :param z: the positions along the z-axis - :param alpha1: the first euler angles - :param alpha2: the 2nd euler angles - :param alpha3: the 3rd euler angles - """ - if not (isinstance(x, int) or isinstance(x, float)): - raise TypeError('x must be integer') - if not (isinstance(y, int) or isinstance(y, float)): - raise TypeError('y must be integer') - if not (isinstance(z, int) or isinstance(z, float)): - raise TypeError('z must be integer') - if not (isinstance(alpha1, float) or isinstance(alpha1, int)): - raise TypeError('alpha1 must be float') - if not (isinstance(alpha2, float) or isinstance(alpha2, int)): - raise TypeError('alpha2 must be float') - if not (isinstance(alpha3, float) or isinstance(alpha3, int)): - raise TypeError('alpha3 must be float') - [mx, my, mz, ma1, ma2, ma3] = np.meshgrid(x, - y, - z, - alpha1, - alpha2, - alpha3) - self.grid_size = mx.shape - mx = mx.flatten() - my = my.flatten() - mz = mz.flatten() - ma1 = ma1.flatten() - ma2 = ma2.flatten() - ma3 = ma3.flatten() - self.__grid_posorients = pd.DataFrame(index=range(mx.shape[0]), - columns=['x', 'y', 'z', - 'alpha_0', - 'alpha_1', - 'alpha_2']) - self.__grid_posorients.loc[:, 'x'] = mx - self.__grid_posorients.loc[:, 'y'] = my - self.__grid_posorients.loc[:, 'z'] = mz - self.__grid_posorients.loc[:, 'alpha_0'] = ma1 - self.__grid_posorients.loc[:, 'alpha_1'] = ma2 - self.__grid_posorients.loc[:, 'alpha_2'] = ma3 - self.__grid_posorients.index.name = 'grid_index' - self.__grid_posorients.name = 'grid_position_orientation' - - @property - def grid_posorients(self): - """return a copy of the posorientation matrix - - :returns: position-orientations of the grid - :rtype: pandas array - - .. todo: use @property - def grid_posorients(self) - - .. todo: create @property.setter - def grid_posorients(self,posorients) - (need a type check, and col check, and copy of df) - """ - return self.__grid_posorients.copy() - - def set_gridindeces2nan(self, indeces): - """Set certain grid point to nan, so they will be ignore in the rendering - - :param indeces: a list of indeces to be set to nan - - .. todo: use @property.setter - def blacklist_indeces(self,indeces) - """ - if not isinstance(indeces, list): - raise TypeError('indeces must be a list') - if any(np.isnan(indeces)): - raise ValueError('indeces must not contain nans') - self.__grid_posorients.loc[indeces, :] = np.nan - - def render(self, database_filename): - if not isinstance(database_filename, str): - raise TypeError('filename must be a string') - database_folder = os.path.dirname(database_filename) - if not os.path.exists(database_folder): - os.makedirs(database_folder) - dataloger = DataBaseSave(database_filename, - channels=['R', 'G', 'B', 'D'], - arr_dtype=np.uint8) - for frame_i, posorient in self.__grid_posorients.iloc[::-1].iterrows(): - print(frame_i) - if np.any(np.isnan(posorient)): - # warnings.warn('frame_i: {} posorient nans'.format(frame_i)) - continue - rowid = dataloger.posid(posorient) - if dataloger.check_data_validity(rowid): - warnings.warn( - 'frame_i: {} data is valid rowid {}'.format(frame_i, - rowid)) - continue - # The position-orientatios is valid (none nan) - # and the cmaxminrange has not already been assigned - # so the image need to be rendered - self.update(posorient) - distance = self.distance - distance[distance > self.world_dim] = self.world_dim - image = self.image - image[:, :, 3] = distance - dataloger.write_image(posorient, image) - print('rendering completed') - - -if __name__ == "__main__": - import tempfile - bee_samp = BeeSampling() - # Create mesh - world_dim = 15.0 - x = np.linspace(-7.5, 7.5, 5) - y = np.linspace(-7.5, 7.5, 5) - z = np.arange(1, 8, 2) - alpha_1 = np.array([0]) + np.pi / 2 - alpha_2 = np.array([0]) - alpha_3 = np.array([0]) - bee_samp.create_sampling_grid( - x, y, z, alpha1=alpha_1, alpha2=alpha_2, alpha3=alpha_3) - bee_samp.world_dim = world_dim - grid_pos = bee_samp.grid_posorients - condition = (grid_pos.x**2 + grid_pos.y**2) < ((bee_samp.world_dim / 2)**2) - bee_samp.set_gridindeces2nan(condition[condition == 0].index) - bee_samp.cycle_samples(samples=5) - with tempfile.TemporaryDirectory() as folder: - bee_samp.render(folder + '/database.db') diff --git a/navipy/rendering/cyber_bee.py~ b/navipy/rendering/cyber_bee.py~ deleted file mode 100644 index 6d80fbfb5f3af8990800c48967b5ea31cf17e5c2..0000000000000000000000000000000000000000 --- a/navipy/rendering/cyber_bee.py~ +++ /dev/null @@ -1,379 +0,0 @@ -""" - How to test the script: - ----------------------- - >>> blender test.blend --background --python Cyberbee.py - - :Author: Olivier Bertrand (olivier.bertrand@uni-bielefeld.de) - :Parent module: Scene_rendering - - ..tothinkof for the doc bpy will raise an issue. - conditional import of bpy -""" -import bpy -import numpy as np -import tempfile -import os - - -class Cyberbee(): - """ - Cyberbee is a small class binding python with blender. - With Cyberbee one can move the bee to a position, and render what - the bee see at this position. - - The Bee eye is a panoramic camera with equirectangular projection - The light rays attaining the eyes are filtered with a gaussian. - """ - - def __init__(self): - """Initialise the Cyberbee - ..todo check that TemporaryDirectory is writtable and readable - """ - # Rendering engine needs to be Cycles to support panoramic - # equirectangular camera - bpy.context.scene.render.engine = 'CYCLES' - bpy.context.scene.render.layers["RenderLayer"].use_pass_z = True - # Look for object camera - camera_found = False - for obj in bpy.context.scene.objects: - if obj.type == 'CAMERA': - self.camera = obj - camera_found = True - break - assert camera_found, 'The blender file does not contain a camera' - # The bee eye is panoramic, and with equirectangular projection - self.camera.data.type = 'PANO' - self.camera.data.cycles.panorama_type = 'EQUIRECTANGULAR' - # Filtering props - bpy.context.scene.cycles.filter_type = 'GAUSSIAN' - # Call all set function with default values - self.camera_rotation_mode = 'XYZ' - self.camera_fov = [[-90, 90], [-180, 180]] - self.camera_gaussian_width = 1.5 - self.camera_resolution = [360, 180] - self.cycle_samples = 30 - # switch on nodes - # Create render link to OutputFile with Image and Z buffer - bpy.context.scene.use_nodes = True - scene = bpy.context.scene - nodes = scene.node_tree.nodes - - render_layers = nodes['Render Layers'] - output_file = nodes.new("CompositorNodeOutputFile") - output_file.format.file_format = "OPEN_EXR" - output_file.file_slots.remove(output_file.inputs[0]) - tmp_fileoutput = dict() - tmp_fileoutput['Image'] = 'Image' - tmp_fileoutput['Depth'] = 'Depth' - tmp_fileoutput['Folder'] = tempfile.TemporaryDirectory().name - tmp_fileoutput['ext'] = '.exr' - output_file.file_slots.new(tmp_fileoutput['Image']) - output_file.file_slots.new(tmp_fileoutput['Depth']) - output_file.base_path = tmp_fileoutput['Folder'] - scene.node_tree.links.new( - render_layers.outputs['Image'], - output_file.inputs['Image'] - ) - scene.node_tree.links.new( - render_layers.outputs['Z'], - output_file.inputs['Depth'] - ) - self.tmp_fileoutput = tmp_fileoutput - - @property - def camera_rotation_mode(self): - """get the current camera rotation mode - - :returns: the mode of rotation used by the camera - :rtype: string - - ..todo: Use @property - def camera_rotation_mode(self) - """ - return bpy.data.scenes["Scene"].camera.rotation_mode - - @camera_rotation_mode.setter - def camera_rotation_mode(self, mode='XYZ'): - """change the camera rotation mode - - - - :param mode: the mode of rotation for the camera see blender doc - - (default: 'XYZ'). - - :type mode: a string - - .. seealso: blender bpy.data.scenes["Scene"].camera.rotation_mode - - - - ..todo: Use @property.setter - - def camera_rotation_mode(self, mode='XYZ') - - """ - if not isinstance(mode, str): - - raise TypeError('mode must be a string') - bpy.data.scenes["Scene"].camera.rotation_mode = mode - - @property - def cycle_samples(self): - """get the samples for rendering with cycle - - :returns: the number of samples used for the rendering - :rtype: int - - ..todo use @property - def cycle_samples(self) - """ - return bpy.context.scene.cycles.samples - - @cycle_samples.setter - def cycle_samples(self, samples=30): - """change the samples for rendering with cycle - - - :param samples: the number of samples to use when rendering images - - :type samples: int - - - ..todo: Use @property.setter - - def cycle_samples(self, samples=30) - """ - if not isinstance(samples, int): - raise TypeError('samples must be an integer') - bpy.context.scene.cycles.samples = samples - - @property - def camera_fov(self): - """get fov of camera - - - - :returns: the field of view of the camera as min/max,longitude/latitude - - in degrees - - :rtype: dict - - - - ..todo use @property - - def camera_fov() - - - - ..todo Change assert to if -> raise TypeError/KeyError - - """ - assert self.camera.data.type == 'PANO', 'Camera is not panoramic' - assert self.camera.cycles.panorama_type == 'EQUIRECTANGULAR',\ - 'Camera is not equirectangular' - fov = dict() - fov['latitude_min'] = np.rad2ged(self.camera.data.cycles.latitude_min) - fov['latitude_max'] = np.rad2ged(self.camera.data.cycles.latitude_max) - fov['longitude_min'] = np.rad2ged( - self.camera.data.cycles.longitude_min) - fov['longitude_max'] = np.rad2ged( - self.camera.data.cycles.longitude_max) - return fov - - @camera_fov.setter - def camera_fov(self, resolution=[[-90, 90], [-180, 180]]): - """change the field of view of the panoramic camera - - :param resolution: [[minimum latitude, maximum latitude], - [minimum longitude, maximum longitude]] - (in deg) - :type latmin: 2x2 float array or list - - ..todo use @property.setter - def camera_fov(self, latlongrange) - here latlongrange is a a 2x2 list or array: - [[latmin,latmax],[longmin,longmax]] - - ..todo Change assert to if -> raise TypeError()/KeyError() - """ - if not (isinstance(resolution, list) or - isinstance(resolution, np.ndarray)): - raise TypeError('resolution must be list or array') - if not self.camera.data.type == 'PANO': - raise Exception('Camera is not panoramic') - if not self.camera.data.cycles.panorama_type == 'EQUIRECTANGULAR': - raise Exception('Camera is not equirectangular') - self.camera.data.cycles.latitude_min = np.deg2rad(resolution[0, 0]) - self.camera.data.cycles.latitude_max = np.deg2rad(resolution[0, 1]) - self.camera.data.cycles.longitude_min = np.deg2rad(resolution[1, 0]) - self.camera.data.cycles.longitude_max = np.deg2rad(resolution[1, 1]) - - @property - def camera_gaussian_width(self, gauss_w=1.5): - """get width of the gaussian spatial filter - - :returns: the width of the gaussian filter - :rtype: float - - ..todo use @property - def camera_gaussian_width(self) - """ - if not (isinstance(gauss_w, int) or isinstance(gauss_w, float)): - raise TypeError('gauss window must be integer or float') - return bpy.context.scene.cycles.filter_width - - @camera_gaussian_width.setter - def camera_gaussian_width(self, gauss_w=1.5): - """change width of the gaussian spatial filter - - :param gauss_w: width of the gaussian filter - - :type gauss_w: float - - ..todo use @property.setter - def camera_gaussian_width(self) - - - ..todo check that input argument is of correct type, - if not raise TypeError() - - """ - if not (isinstance(gauss_w, int) or isinstance(gauss_w, float)): - raise TypeError('gauss window must be integer or float') - bpy.context.scene.cycles.filter_width = gauss_w - - @property - def camera_resolution(self): - """return camera resolution (x,y) - - :returns: the resolution of the camera along (x-axis,y-axis) - :rtype: (int,int) - - ..todo use @property - def camera_resolution(self) - """ - resolution_x = bpy.context.scene.render.resolution_x - resolution_y = bpy.context.scene.render.resolution_y - return resolution_x, resolution_y - - @camera_resolution.setter - def set_camera_resolution(self, resolution=[360, 180]): - """change the camera resolution (nb of pixels) - - - :param resolution_x: number of pixels along the x-axis of the camera - :type resolution_x: int - - :param resolution_y: number of pixels along the y-axis of the camera - - :type resolution_y: int - - - ..todo use @property.setter - - def camera_resolution(self,resolution) - - here resolution is [res_x,res_y] - - - - ..todo check type and raise TypeError - - """ - if not (isinstance(resolution, list) or isinstance(resolution, np.ndarray)): - raise TypeError('resolution list or array') - bpy.context.scene.render.resolution_x = resolution[0] - bpy.context.scene.render.resolution_y = resolution[1] - bpy.context.scene.render.resolution_percentage = 100 - - def update(self, posorient): - """assign the position and the orientation of the camera. - - :param posorient: is a 1x6 vector containing: - x,y,z, angle_1, angle_2, angle_3, - here the angles are euler rotation around the axis - specified by scene.camera.rotation_mode - :type posorient: 1x6 double array - """ - if len(posorient) != 6: - raise Exception('posorient should be a 1x6 double array') - if not (isinstance(posorient, np.ndarray) or - isinstance(posorient, list)): - raise TypeError('posorient must be of type array or list') - self.camera.location = posorient[:3] - self.camera.rotation_euler = posorient[3:] - # Render - bpy.ops.render.render() - - @property - def image(self): - """return the last rendered image as a numpy array - - :returns: the image (height,width,4) - :rtype: a double numpy array - - .. note: A temporary file will be written on the harddrive, - due to API blender limitation - - .. todo: use @property - def image(self) - """ - # save image as a temporary file, and then loaded - # sadly the rendered image pixels can not directly be access - filename = os.path.join(self.tmp_fileoutput['Folder'], - self.tmp_fileoutput['Image'] + '0001' + - self.tmp_fileoutput['ext']) - im_width, im_height = self.camera_resolution - im = bpy.data.images.load(filename) - pixels = np.array(im.pixels) - # im=PIL.Image.open(filename) - # pixels=np.asarray(im) - pixels = pixels.reshape([im_height, im_width, 4]) - return pixels - - @property - def distance(self): - """return the last rendered distance map as a numpy array - - :returns: the distance map (height, width) - :rtype: a double numpy array - - .. note: A temporary file will be written on the harddrive, - due to API blender limitation - - .. todo: use @property - def distance(self) - """ - # save image as a temporary file, and then loaded - # sadly the rendered image pixels can not directly be access - filename = os.path.join(self.tmp_fileoutput['Folder'], - self.tmp_fileoutput['Depth'] + '0001' + - self.tmp_fileoutput['ext']) - im_width, im_height = self.camera_resolution - im = bpy.data.images.load(filename) - distance = np.array(im.pixels) - # im=PIL.Image.open(filename) - # distance=np.asarray(im) - distance = distance.reshape([im_height, im_width, 4]) - distance = distance[:, :, 0] - return distance - - -if __name__ == "__main__": - # Initiate the Cyberbee - mybee = Cyberbee() - frames_per_revolution = 5.0 - step_size = 2 * np.pi / frames_per_revolution - posorients = np.zeros((frames_per_revolution, 6)) - posorients[:, 0] = np.sin(np.arange(frames_per_revolution) * step_size) * 5 - posorients[:, 1] = np.cos(np.arange(frames_per_revolution) * step_size) * 5 - for frame_i, posorient in enumerate(posorients): - mybee.update(posorient) - # Test image - image = mybee.image - # Test distance - distance = mybee.distance - print('Cyberbee OK')