From d2ba00c2375fe7accfccfdc8143373c307fc4288 Mon Sep 17 00:00:00 2001 From: Théo de la Hogue Date: Tue, 30 May 2023 14:30:02 +0200 Subject: Testing scan path and AOI scan path --- src/argaze.test/GazeFeatures.py | 187 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 178 insertions(+), 9 deletions(-) (limited to 'src/argaze.test/GazeFeatures.py') diff --git a/src/argaze.test/GazeFeatures.py b/src/argaze.test/GazeFeatures.py index f440a4e..ac0f0cc 100644 --- a/src/argaze.test/GazeFeatures.py +++ b/src/argaze.test/GazeFeatures.py @@ -216,6 +216,98 @@ class TestTimeStampedGazePositionsClass(unittest.TestCase): self.assertEqual(ts_gaze_positions_dataframe["value"].dtype, 'object') self.assertEqual(ts_gaze_positions_dataframe["precision"].dtype, 'O') # Python object type +class TestScanStepClass(unittest.TestCase): + """Test ScanStep class.""" + + def test_new(self): + """Test ScanStep creation.""" + + fixation = GazeFeatures.Fixation(random_gaze_positions(10)) + saccade = GazeFeatures.Saccade(random_gaze_positions(2)) + + scan_step = GazeFeatures.ScanStep(fixation, saccade) + + # Check aoi scan step creation + self.assertEqual(scan_step.first_fixation, fixation) + self.assertEqual(scan_step.last_saccade, saccade) + self.assertGreater(scan_step.duration, 0) + +class TestScanPathClass(unittest.TestCase): + """Test ScanPath class.""" + + def test_new(self): + """Test ScanPath creation.""" + + # Check aoi scan step creation + scan_path = GazeFeatures.ScanPath() + + self.assertEqual(len(scan_path), 0) + + def test_append(self): + """Test ScanPath append methods.""" + + scan_path = GazeFeatures.ScanPath() + + # Append a saccade that should be ignored + saccade = GazeFeatures.Saccade(random_gaze_positions(2)) + ts, _ = saccade.positions.first + + new_step = scan_path.append_saccade(ts, saccade) + + # Check that no scan step have been created yet + self.assertEqual(len(scan_path), 0) + self.assertEqual(new_step, None) + + # Append first fixation + fixation_A = GazeFeatures.Fixation(random_gaze_positions(10)) + ts, _ = fixation_A.positions.first + + new_step = scan_path.append_fixation(ts, fixation_A) + + # Check that no scan step have been created yet + self.assertEqual(len(scan_path), 0) + self.assertEqual(new_step, None) + + # Append consecutive saccade + saccade_A = GazeFeatures.Saccade(random_gaze_positions(2)) + ts, _ = saccade_A.positions.first + + new_step = scan_path.append_saccade(ts, saccade_A) + + # Check that new scan step have been created + self.assertEqual(len(scan_path), 1) + self.assertEqual(new_step.first_fixation, fixation_A) + self.assertEqual(new_step.last_saccade, saccade_A) + + # Append 2 consecutive fixations then a saccade + fixation_B1 = GazeFeatures.Fixation(random_gaze_positions(10)) + ts, _ = fixation_B1.positions.first + + new_step = scan_path.append_fixation(ts, fixation_B1) + + # Check that no scan step have been created yet + self.assertEqual(len(scan_path), 1) + self.assertEqual(new_step, None) + + fixation_B2 = GazeFeatures.Fixation(random_gaze_positions(10)) + ts, _ = fixation_B2.positions.first + + new_step = scan_path.append_fixation(ts, fixation_B2) + + # Check that no scan step have been created yet + self.assertEqual(len(scan_path), 1) + self.assertEqual(new_step, None) + + saccade_B = GazeFeatures.Saccade(random_gaze_positions(2)) + ts, _ = saccade_B.positions.first + + new_step = scan_path.append_saccade(ts, saccade_B) + + # Check that new scan step have been created + self.assertEqual(len(scan_path), 2) + self.assertEqual(new_step.first_fixation, fixation_B2) + self.assertEqual(new_step.last_saccade, saccade_B) + class TestAOIScanStepClass(unittest.TestCase): """Test AOIScanStep class.""" @@ -273,13 +365,13 @@ class TestAOIScanPathClass(unittest.TestCase): def test_append(self): """Test AOIScanPath append methods.""" - aoi_scan_path = GazeFeatures.AOIScanPath(['A', 'B']) + aoi_scan_path = GazeFeatures.AOIScanPath(['Foo', 'Bar']) # Append fixation on A aoi fixation = GazeFeatures.Fixation(random_gaze_positions(10)) ts, _ = fixation.positions.first - new_step = aoi_scan_path.append_fixation(ts, fixation, 'A') + new_step = aoi_scan_path.append_fixation(ts, fixation, 'Foo') # Check that no aoi scan step have been created yet self.assertEqual(len(aoi_scan_path), 0) @@ -299,23 +391,27 @@ class TestAOIScanPathClass(unittest.TestCase): fixation = GazeFeatures.Fixation(random_gaze_positions(10)) ts, _ = fixation.positions.first - new_step = aoi_scan_path.append_fixation(ts, fixation, 'B') + new_step = aoi_scan_path.append_fixation(ts, fixation, 'Bar') - # Check a new aoi scan step have been created + # Check a first aoi scan step have been created once a new fixation is appened self.assertEqual(len(aoi_scan_path), 1) self.assertEqual(len(new_step.movements), 2) - self.assertEqual(new_step.aoi, 'A') + self.assertEqual(new_step.aoi, 'Foo') + self.assertEqual(new_step.letter, 'A') + + # Check letter affectation + self.assertEqual(aoi_scan_path.get_letter_aoi('A'), 'Foo') def test_append_error(self): """Test AOIScanPath append error.""" - aoi_scan_path = GazeFeatures.AOIScanPath(['A', 'B']) + aoi_scan_path = GazeFeatures.AOIScanPath(['Foo', 'Bar']) # Append fixation on A aoi fixation = GazeFeatures.Fixation(random_gaze_positions(10)) ts, _ = fixation.positions.first - new_step = aoi_scan_path.append_fixation(ts, fixation, 'A') + new_step = aoi_scan_path.append_fixation(ts, fixation, 'Foo') # Check that no aoi scan step have been created yet self.assertEqual(len(aoi_scan_path), 0) @@ -328,12 +424,85 @@ class TestAOIScanPathClass(unittest.TestCase): # Check that aoi scan step creation fail when fixation is appened after another fixation with self.assertRaises(GazeFeatures.AOIScanStepError): - new_step = aoi_scan_path.append_fixation(ts, fixation, 'B') + new_step = aoi_scan_path.append_fixation(ts, fixation, 'Bar') # Check that unexpected aoi scan step creation fail with self.assertRaises(GazeFeatures.AOIScanStepError): - new_step = aoi_scan_path.append_fixation(ts, fixation, 'C') + new_step = aoi_scan_path.append_fixation(ts, fixation, 'Shu') + + def test_transition_matrix(self): + """Test AOIScanPath transition_matrix features.""" + + aoi_scan_path = GazeFeatures.AOIScanPath(['Foo', 'Bar', 'Shu']) + + # First step on Bar aoi + fixation = GazeFeatures.Fixation(random_gaze_positions(10)) + ts, _ = fixation.positions.first + aoi_scan_path.append_fixation(ts, fixation, 'Bar') + + saccade = GazeFeatures.Saccade(random_gaze_positions(2)) + ts, _ = saccade.positions.first + no_step_yet = aoi_scan_path.append_saccade(ts, saccade) + + # Second step on Shu aoi + fixation = GazeFeatures.Fixation(random_gaze_positions(10)) + ts, _ = fixation.positions.first + step_1 = aoi_scan_path.append_fixation(ts, fixation, 'Shu') + + saccade = GazeFeatures.Saccade(random_gaze_positions(2)) + ts, _ = saccade.positions.first + aoi_scan_path.append_saccade(ts, saccade) + + # Check first step once second step ends + self.assertEqual(step_1.aoi, 'Bar') + self.assertEqual(step_1.letter, 'A') + + # Third step on Foo aoi + fixation = GazeFeatures.Fixation(random_gaze_positions(10)) + ts, _ = fixation.positions.first + step_2 = aoi_scan_path.append_fixation(ts, fixation, 'Foo') + + saccade = GazeFeatures.Saccade(random_gaze_positions(2)) + ts, _ = saccade.positions.first + aoi_scan_path.append_saccade(ts, saccade) + + # Check second step once third step ends + self.assertEqual(step_2.aoi, 'Shu') + self.assertEqual(step_2.letter, 'B') + + # Last step on Bar aoi + fixation = GazeFeatures.Fixation(random_gaze_positions(10)) + ts, _ = fixation.positions.first + step_3 = aoi_scan_path.append_fixation(ts, fixation, 'Bar') + + saccade = GazeFeatures.Saccade(random_gaze_positions(2)) + ts, _ = saccade.positions.first + aoi_scan_path.append_saccade(ts, saccade) + + # Check thrird step once last step ends + self.assertEqual(step_3.aoi, 'Foo') + self.assertEqual(step_3.letter, 'C') + + # Check letter affectation + self.assertEqual(aoi_scan_path.get_letter_aoi('A'), 'Bar') + self.assertEqual(aoi_scan_path.get_letter_aoi('B'), 'Shu') + self.assertEqual(aoi_scan_path.get_letter_aoi('C'), 'Foo') + + # Check transition matrix ([destination][departure]) + self.assertEqual(aoi_scan_path.transition_matrix['Foo']['Foo'], 0) + self.assertEqual(aoi_scan_path.transition_matrix['Bar']['Bar'], 0) + self.assertEqual(aoi_scan_path.transition_matrix['Shu']['Shu'], 0) + + self.assertEqual(aoi_scan_path.transition_matrix['Foo']['Bar'], 0) + self.assertEqual(aoi_scan_path.transition_matrix['Foo']['Shu'], 1) + + self.assertEqual(aoi_scan_path.transition_matrix['Bar']['Foo'], 0) + self.assertEqual(aoi_scan_path.transition_matrix['Bar']['Shu'], 0) + + self.assertEqual(aoi_scan_path.transition_matrix['Shu']['Foo'], 0) + self.assertEqual(aoi_scan_path.transition_matrix['Shu']['Bar'], 1) + if __name__ == '__main__': -- cgit v1.1