aboutsummaryrefslogtreecommitdiff
path: root/src/argaze.test/GazeFeatures.py
diff options
context:
space:
mode:
authorThéo de la Hogue2023-05-31 15:35:28 +0200
committerThéo de la Hogue2023-05-31 15:35:28 +0200
commite35e90d161ffb9202459631a0049448cde905b3c (patch)
tree0ad987c3ffcea30f739cc8e106df2a5f00ad22da /src/argaze.test/GazeFeatures.py
parentd1cdae406d349023eb9e221fd226c05744064dfd (diff)
downloadargaze-e35e90d161ffb9202459631a0049448cde905b3c.zip
argaze-e35e90d161ffb9202459631a0049448cde905b3c.tar.gz
argaze-e35e90d161ffb9202459631a0049448cde905b3c.tar.bz2
argaze-e35e90d161ffb9202459631a0049448cde905b3c.tar.xz
Testing all gaze analysis algorithm. Unifying paper citation.
Diffstat (limited to 'src/argaze.test/GazeFeatures.py')
-rw-r--r--src/argaze.test/GazeFeatures.py72
1 files changed, 48 insertions, 24 deletions
diff --git a/src/argaze.test/GazeFeatures.py b/src/argaze.test/GazeFeatures.py
index 8206baf..f73eefe 100644
--- a/src/argaze.test/GazeFeatures.py
+++ b/src/argaze.test/GazeFeatures.py
@@ -8,12 +8,13 @@ __copyright__ = "Copyright 2023, Ecole Nationale de l'Aviation Civile (ENAC)"
__license__ = "BSD"
import unittest
+from dataclasses import dataclass
from argaze import GazeFeatures
import numpy
-def random_gaze_positions(size):
+def random_gaze_positions(size, screen_dimension: tuple[float, float] = (1, 1)):
""" Generate random TimeStampedGazePsoitions for testing purpose.
Timestamps are current time.
GazePositions are random values.
@@ -27,13 +28,36 @@ def random_gaze_positions(size):
for i in range(0, size):
# Edit gaze position
- random_gaze_position = GazeFeatures.GazePosition((random.random(), random.random()))
+ random_gaze_position = GazeFeatures.GazePosition((random.random() * screen_dimension[0], random.random() * screen_dimension[1]))
# Store gaze position
ts_gaze_positions[time.time()] = random_gaze_position
return ts_gaze_positions
+@dataclass(frozen=True)
+class TestFixation(GazeFeatures.Fixation):
+ """Define basic fixation class for test."""
+
+ def __post_init__(self):
+
+ super().__post_init__()
+
+ points = self.positions.values()
+ points_x, points_y = [p[0] for p in points], [p[1] for p in points]
+ points_array = numpy.column_stack([points_x, points_y])
+ centroid_array = numpy.array([numpy.mean(points_x), numpy.mean(points_y)])
+
+ # Update frozen focus attribute using centroid
+ object.__setattr__(self, 'focus', (centroid_array[0], centroid_array[1]))
+
+@dataclass(frozen=True)
+class TestSaccade(GazeFeatures.Saccade):
+ """Define basic saccade for test."""
+
+ def __post_init__(self):
+ super().__post_init__()
+
class TestGazePositionClass(unittest.TestCase):
"""Test GazePosition class."""
@@ -222,8 +246,8 @@ class TestScanStepClass(unittest.TestCase):
def test_new(self):
"""Test ScanStep creation."""
- fixation = GazeFeatures.Fixation(random_gaze_positions(10))
- saccade = GazeFeatures.Saccade(random_gaze_positions(2))
+ fixation = TestFixation(random_gaze_positions(10))
+ saccade = TestSaccade(random_gaze_positions(2))
scan_step = GazeFeatures.ScanStep(fixation, saccade)
@@ -232,18 +256,18 @@ class TestScanStepClass(unittest.TestCase):
self.assertEqual(scan_step.last_saccade, saccade)
self.assertGreater(scan_step.duration, 0)
-def build_scan_path(size):
+def build_scan_path(size, screen_dimension: tuple[float, float] = (1, 1)):
"""Build scan path"""
scan_path = GazeFeatures.ScanPath()
for i in range(size):
- fixation = GazeFeatures.Fixation(random_gaze_positions(10))
+ fixation = TestFixation(random_gaze_positions(10, screen_dimension))
ts, _ = fixation.positions.first
scan_path.append_fixation(ts, fixation)
- saccade = GazeFeatures.Saccade(random_gaze_positions(2))
+ saccade = TestSaccade(random_gaze_positions(2, screen_dimension))
ts, _ = saccade.positions.first
scan_path.append_saccade(ts, saccade)
@@ -266,7 +290,7 @@ class TestScanPathClass(unittest.TestCase):
scan_path = GazeFeatures.ScanPath()
# Append a saccade that should be ignored
- saccade = GazeFeatures.Saccade(random_gaze_positions(2))
+ saccade = TestSaccade(random_gaze_positions(2))
ts, _ = saccade.positions.first
new_step = scan_path.append_saccade(ts, saccade)
@@ -276,7 +300,7 @@ class TestScanPathClass(unittest.TestCase):
self.assertEqual(new_step, None)
# Append first fixation
- fixation_A = GazeFeatures.Fixation(random_gaze_positions(10))
+ fixation_A = TestFixation(random_gaze_positions(10))
ts, _ = fixation_A.positions.first
new_step = scan_path.append_fixation(ts, fixation_A)
@@ -286,7 +310,7 @@ class TestScanPathClass(unittest.TestCase):
self.assertEqual(new_step, None)
# Append consecutive saccade
- saccade_A = GazeFeatures.Saccade(random_gaze_positions(2))
+ saccade_A = TestSaccade(random_gaze_positions(2))
ts, _ = saccade_A.positions.first
new_step = scan_path.append_saccade(ts, saccade_A)
@@ -297,7 +321,7 @@ class TestScanPathClass(unittest.TestCase):
self.assertEqual(new_step.last_saccade, saccade_A)
# Append 2 consecutive fixations then a saccade
- fixation_B1 = GazeFeatures.Fixation(random_gaze_positions(10))
+ fixation_B1 = TestFixation(random_gaze_positions(10))
ts, _ = fixation_B1.positions.first
new_step = scan_path.append_fixation(ts, fixation_B1)
@@ -306,7 +330,7 @@ class TestScanPathClass(unittest.TestCase):
self.assertEqual(len(scan_path), 1)
self.assertEqual(new_step, None)
- fixation_B2 = GazeFeatures.Fixation(random_gaze_positions(10))
+ fixation_B2 = TestFixation(random_gaze_positions(10))
ts, _ = fixation_B2.positions.first
new_step = scan_path.append_fixation(ts, fixation_B2)
@@ -315,7 +339,7 @@ class TestScanPathClass(unittest.TestCase):
self.assertEqual(len(scan_path), 1)
self.assertEqual(new_step, None)
- saccade_B = GazeFeatures.Saccade(random_gaze_positions(2))
+ saccade_B = TestSaccade(random_gaze_positions(2))
ts, _ = saccade_B.positions.first
new_step = scan_path.append_saccade(ts, saccade_B)
@@ -333,11 +357,11 @@ class TestAOIScanStepClass(unittest.TestCase):
movements = GazeFeatures.TimeStampedGazeMovements()
- fixation = GazeFeatures.Fixation(random_gaze_positions(10))
+ fixation = TestFixation(random_gaze_positions(10))
ts, _ = fixation.positions.first
movements[ts] = fixation
- saccade = GazeFeatures.Saccade(random_gaze_positions(2))
+ saccade = TestSaccade(random_gaze_positions(2))
ts, _ = saccade.positions.first
movements[ts] = saccade
@@ -355,11 +379,11 @@ class TestAOIScanStepClass(unittest.TestCase):
movements = GazeFeatures.TimeStampedGazeMovements()
- saccade = GazeFeatures.Saccade(random_gaze_positions(2))
+ saccade = TestSaccade(random_gaze_positions(2))
ts, _ = saccade.positions.first
movements[ts] = saccade
- fixation = GazeFeatures.Fixation(random_gaze_positions(10))
+ fixation = TestFixation(random_gaze_positions(10))
ts, _ = fixation.positions.first
movements[ts] = fixation
@@ -378,11 +402,11 @@ def build_aoi_scan_path(expected_aois, aoi_path):
for aoi in aoi_path:
- fixation = GazeFeatures.Fixation(random_gaze_positions(10))
+ fixation = TestFixation(random_gaze_positions(10))
ts, _ = fixation.positions.first
aoi_scan_path.append_fixation(ts, fixation, aoi)
- saccade = GazeFeatures.Saccade(random_gaze_positions(2))
+ saccade = TestSaccade(random_gaze_positions(2))
ts, _ = saccade.positions.first
aoi_scan_path.append_saccade(ts, saccade)
@@ -405,7 +429,7 @@ class TestAOIScanPathClass(unittest.TestCase):
aoi_scan_path = GazeFeatures.AOIScanPath(['Foo', 'Bar'])
# Append fixation on A aoi
- fixation = GazeFeatures.Fixation(random_gaze_positions(10))
+ fixation = TestFixation(random_gaze_positions(10))
ts, _ = fixation.positions.first
new_step = aoi_scan_path.append_fixation(ts, fixation, 'Foo')
@@ -415,7 +439,7 @@ class TestAOIScanPathClass(unittest.TestCase):
self.assertEqual(new_step, None)
# Append saccade
- saccade = GazeFeatures.Saccade(random_gaze_positions(2))
+ saccade = TestSaccade(random_gaze_positions(2))
ts, _ = saccade.positions.first
new_step = aoi_scan_path.append_saccade(ts, saccade)
@@ -425,7 +449,7 @@ class TestAOIScanPathClass(unittest.TestCase):
self.assertEqual(new_step, None)
# Append fixation on B aoi
- fixation = GazeFeatures.Fixation(random_gaze_positions(10))
+ fixation = TestFixation(random_gaze_positions(10))
ts, _ = fixation.positions.first
new_step = aoi_scan_path.append_fixation(ts, fixation, 'Bar')
@@ -445,7 +469,7 @@ class TestAOIScanPathClass(unittest.TestCase):
aoi_scan_path = GazeFeatures.AOIScanPath(['Foo', 'Bar'])
# Append fixation on A aoi
- fixation = GazeFeatures.Fixation(random_gaze_positions(10))
+ fixation = TestFixation(random_gaze_positions(10))
ts, _ = fixation.positions.first
new_step = aoi_scan_path.append_fixation(ts, fixation, 'Foo')
@@ -455,7 +479,7 @@ class TestAOIScanPathClass(unittest.TestCase):
self.assertEqual(new_step, None)
# Append fixation on B aoi
- fixation = GazeFeatures.Fixation(random_gaze_positions(10))
+ fixation = TestFixation(random_gaze_positions(10))
ts, _ = fixation.positions.first
# Check that aoi scan step creation fail when fixation is appened after another fixation