#!/usr/bin/env python import unittest import math from argaze.AreaOfInterest import AOIFeatures, AOI2DScene from argaze import GazeFeatures import numpy class TestAOI2DSceneClass(unittest.TestCase): """Test AOI2DScene class.""" def test_new(self): """Test AOI2DScene creation.""" # Check empty AOI2DScene creation aoi_2d_scene = AOI2DScene.AOI2DScene() self.assertEqual(aoi_2d_scene.dimension, 2) self.assertEqual(len(aoi_2d_scene.items()), 0) # Check AOI2DScene creation aoi_2D_A = AOIFeatures.AreaOfInterest([[0, 0], [0, 1], [1, 1], [1, 0]]) aoi_2D_B = AOIFeatures.AreaOfInterest([[1, 1], [1, 2], [2, 2], [2, 1]]) aoi_2d_scene = AOI2DScene.AOI2DScene({"A": aoi_2D_A, "B": aoi_2D_B}) self.assertEqual(aoi_2d_scene.dimension, 2) def test_raycast(self): """Test AOI2DScene raycast method.""" aoi_2D_A = AOIFeatures.AreaOfInterest([[0, 0], [0, 1], [1, 1], [1, 0]]) aoi_2D_B = AOIFeatures.AreaOfInterest([[1, 1], [1, 2], [2, 2], [2, 1]]) aoi_2d_scene = AOI2DScene.AOI2DScene({"A": aoi_2D_A, "B": aoi_2D_B}) gaze_position_A = GazeFeatures.GazePosition((0.5, 0.5)) gaze_position_B = GazeFeatures.GazePosition((1.5, 1.5)) gaze_position_C = GazeFeatures.GazePosition((0.5, 1.5)) # Check raycast results for gaze postion A for name, aoi, looked in aoi_2d_scene.raycast(gaze_position_A): if name == "A": self.assertIsNone(numpy.testing.assert_array_equal(aoi, aoi_2D_A)) self.assertEqual(looked, True) elif name == "B": self.assertIsNone(numpy.testing.assert_array_equal(aoi, aoi_2D_B)) self.assertEqual(looked, False) # Check raycast results for gaze postion B for name, aoi, looked in aoi_2d_scene.raycast(gaze_position_B): if name == "A": self.assertIsNone(numpy.testing.assert_array_equal(aoi, aoi_2D_A)) self.assertEqual(looked, False) elif name == "B": self.assertIsNone(numpy.testing.assert_array_equal(aoi, aoi_2D_B)) self.assertEqual(looked, True) # Check raycast results for gaze postion C for name, aoi, looked in aoi_2d_scene.raycast(gaze_position_C): if name == "A": self.assertIsNone(numpy.testing.assert_array_equal(aoi, aoi_2D_A)) self.assertEqual(looked, False) elif name == "B": self.assertIsNone(numpy.testing.assert_array_equal(aoi, aoi_2D_B)) self.assertEqual(looked, False) def test_circlecast(self): """Test AOI2DScene circlecast method.""" aoi_2D_A = AOIFeatures.AreaOfInterest([[0, 0], [0, 1], [1, 1], [1, 0]]) aoi_2D_B = AOIFeatures.AreaOfInterest([[1, 1], [1, 2], [2, 2], [2, 1]]) aoi_2d_scene = AOI2DScene.AOI2DScene({"A": aoi_2D_A, "B": aoi_2D_B}) gaze_position_A = GazeFeatures.GazePosition((0.5, 0.5), precision=0.5) gaze_position_B = GazeFeatures.GazePosition((1.5, 1.5), precision=0.5) gaze_position_C = GazeFeatures.GazePosition((1., 1.), precision=1) gaze_position_D = GazeFeatures.GazePosition((0.5, 1.5), precision=0.25) # Check circlecast results for gaze postion A for name, aoi, looked_region, aoi_ratio, gaze_ratio in aoi_2d_scene.circlecast(gaze_position_A): if name == "A": self.assertIsNone(numpy.testing.assert_array_equal(aoi, aoi_2D_A)) self.assertTrue(math.isclose(aoi_ratio, math.pi / 4, abs_tol=1e-2)) self.assertTrue(math.isclose(gaze_ratio, 1., abs_tol=1e-3)) elif name == "B": self.assertIsNone(numpy.testing.assert_array_equal(aoi, aoi_2D_B)) self.assertEqual(aoi_ratio, 0.) self.assertEqual(gaze_ratio, 0.) # Check circlecast results for gaze postion B for name, aoi, looked_region, aoi_ratio, gaze_ratio in aoi_2d_scene.circlecast(gaze_position_B): if name == "A": self.assertIsNone(numpy.testing.assert_array_equal(aoi, aoi_2D_A)) self.assertEqual(aoi_ratio, 0.) self.assertEqual(gaze_ratio, 0.) elif name == "B": self.assertIsNone(numpy.testing.assert_array_equal(aoi, aoi_2D_B)) self.assertTrue(math.isclose(aoi_ratio, math.pi / 4, abs_tol=1e-2)) self.assertTrue(math.isclose(gaze_ratio, 1., abs_tol=1e-3)) # Check circlecast results for gaze postion C for name, aoi, looked_region, aoi_ratio, gaze_ratio in aoi_2d_scene.circlecast(gaze_position_C): if name == "A": self.assertIsNone(numpy.testing.assert_array_equal(aoi, aoi_2D_A)) self.assertTrue(math.isclose(aoi_ratio, math.pi / 4, abs_tol=1e-2)) self.assertTrue(math.isclose(gaze_ratio, 1 / 4, abs_tol=1e-3)) elif name == "B": self.assertIsNone(numpy.testing.assert_array_equal(aoi, aoi_2D_B)) self.assertTrue(math.isclose(aoi_ratio, math.pi / 4, abs_tol=1e-2)) self.assertTrue(math.isclose(gaze_ratio, 1 / 4, abs_tol=1e-3)) # Check circlecast results for gaze postion D for name, aoi, looked_region, aoi_ratio, gaze_ratio in aoi_2d_scene.circlecast(gaze_position_D): if name == "A": self.assertIsNone(numpy.testing.assert_array_equal(aoi, aoi_2D_A)) self.assertEqual(aoi_ratio, 0.) self.assertEqual(gaze_ratio, 0.) elif name == "B": self.assertIsNone(numpy.testing.assert_array_equal(aoi, aoi_2D_B)) self.assertEqual(aoi_ratio, 0.) self.assertEqual(gaze_ratio, 0.) def test_copy(self): """Test AOI2DScene copy method.""" aoi_2D_A = AOIFeatures.AreaOfInterest([[0, 0], [0, 1], [1, 1], [1, 0]]) aoi_2D_B = AOIFeatures.AreaOfInterest([[1, 1], [1, 2], [2, 2], [2, 1]]) aoi_2d_scene = AOI2DScene.AOI2DScene({"A": aoi_2D_A, "B": aoi_2D_B}) # Check full copy aoi_2d_scene_copy = aoi_2d_scene.copy() self.assertEqual(aoi_2d_scene_copy.dimension, 2) self.assertEqual(len(aoi_2d_scene_copy.items()), 2) self.assertEqual(list(aoi_2d_scene_copy.keys()), ["A", "B"]) # Check cpy with exclusion aoi_2d_scene_copy = aoi_2d_scene.copy(exclude=["B"]) self.assertEqual(aoi_2d_scene_copy.dimension, 2) self.assertEqual(len(aoi_2d_scene_copy.items()), 1) self.assertEqual(list(aoi_2d_scene_copy.keys()), ["A"]) class TestTimeStampedAOIScenesClass(unittest.TestCase): """Test TimeStampedAOIScenes class.""" def test___setitem__(self): """Test TimeStampedAOIScenes creation.""" aoi_2D_A = AOIFeatures.AreaOfInterest([[0, 0], [0, 1], [1, 1], [1, 0]]) aoi_2D_B = AOIFeatures.AreaOfInterest([[1, 1], [1, 2], [2, 2], [2, 1]]) aoi_2d_scene = AOI2DScene.AOI2DScene({"A": aoi_2D_A, "B": aoi_2D_B}) ts_aois_scenes = AOIFeatures.TimeStampedAOIScenes() ts_aois_scenes[0] = aoi_2d_scene # Check that only AOIScene can be added with self.assertRaises(AssertionError): ts_aois_scenes[1] = "This string is not an AOI2DScene" if __name__ == '__main__': unittest.main()