aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThéo de la Hogue2023-05-16 10:10:20 +0200
committerThéo de la Hogue2023-05-16 10:10:20 +0200
commit14e7955c16ad8ed73824c811b54b46dc54203d34 (patch)
tree8ce7f8cd5f05f7e5c2f42feae595d7df2011c9cb
parent2d5ba9e7a292e71c1ae78da1e0a284ff6edb9ac1 (diff)
downloadargaze-14e7955c16ad8ed73824c811b54b46dc54203d34.zip
argaze-14e7955c16ad8ed73824c811b54b46dc54203d34.tar.gz
argaze-14e7955c16ad8ed73824c811b54b46dc54203d34.tar.bz2
argaze-14e7955c16ad8ed73824c811b54b46dc54203d34.tar.xz
Renaming visual scan into aoi scan.
-rw-r--r--src/argaze.test/GazeFeatures.py78
-rw-r--r--src/argaze/GazeAnalysis/CoefficientK.py20
-rw-r--r--src/argaze/GazeAnalysis/TransitionProbabilityMatrix.py12
-rw-r--r--src/argaze/GazeFeatures.py38
-rw-r--r--src/argaze/utils/demo_gaze_features_run.py28
5 files changed, 88 insertions, 88 deletions
diff --git a/src/argaze.test/GazeFeatures.py b/src/argaze.test/GazeFeatures.py
index aebbcfc..4679929 100644
--- a/src/argaze.test/GazeFeatures.py
+++ b/src/argaze.test/GazeFeatures.py
@@ -209,11 +209,11 @@ 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 TestVisualScanStepClass(unittest.TestCase):
- """Test VisualScanStep class."""
+class TestAOIScanStepClass(unittest.TestCase):
+ """Test AOIScanStep class."""
def test_new(self):
- """Test VisualScanStep creation."""
+ """Test AOIScanStep creation."""
movements = GazeFeatures.TimeStampedGazeMovements()
@@ -225,17 +225,17 @@ class TestVisualScanStepClass(unittest.TestCase):
ts, _ = saccade.positions.first
movements[ts] = saccade
- visual_scan_step = GazeFeatures.VisualScanStep(movements, 'Test')
+ aoi_scan_step = GazeFeatures.AOIScanStep(movements, 'Test')
- # Check visual scan step creation
- self.assertEqual(len(visual_scan_step.movements), 2)
- self.assertEqual(visual_scan_step.aoi, 'Test')
- self.assertEqual(visual_scan_step.first_fixation, fixation)
- self.assertEqual(visual_scan_step.last_saccade, saccade)
- self.assertGreater(visual_scan_step.duration, 0)
+ # Check aoi scan step creation
+ self.assertEqual(len(aoi_scan_step.movements), 2)
+ self.assertEqual(aoi_scan_step.aoi, 'Test')
+ self.assertEqual(aoi_scan_step.first_fixation, fixation)
+ self.assertEqual(aoi_scan_step.last_saccade, saccade)
+ self.assertGreater(aoi_scan_step.duration, 0)
def test_error(self):
- """Test VisualScanStep creation error."""
+ """Test AOIScanStep creation error."""
movements = GazeFeatures.TimeStampedGazeMovements()
@@ -247,81 +247,81 @@ class TestVisualScanStepClass(unittest.TestCase):
ts, _ = fixation.positions.first
movements[ts] = fixation
- # Check that visual scan step creation fail
- with self.assertRaises(GazeFeatures.VisualScanStepError):
+ # Check that aoi scan step creation fail
+ with self.assertRaises(GazeFeatures.AOIScanStepError):
- visual_scan_step = GazeFeatures.VisualScanStep(movements, 'Test')
+ aoi_scan_step = GazeFeatures.AOIScanStep(movements, 'Test')
-class TestVisualScanPathClass(unittest.TestCase):
- """Test VisualScanPath class."""
+class TestAOIScanPathClass(unittest.TestCase):
+ """Test AOIScanPath class."""
def test_new(self):
- """Test VisualScanPath creation."""
+ """Test AOIScanPath creation."""
- # Check visual scan step creation
- visual_scan_path = GazeFeatures.VisualScanPath()
+ # Check aoi scan step creation
+ aoi_scan_path = GazeFeatures.AOIScanPath()
- self.assertEqual(len(visual_scan_path), 0)
+ self.assertEqual(len(aoi_scan_path), 0)
def test_append(self):
- """Test VisualScanPath append methods."""
+ """Test AOIScanPath append methods."""
- visual_scan_path = GazeFeatures.VisualScanPath()
+ aoi_scan_path = GazeFeatures.AOIScanPath()
# Append fixation on A aoi
fixation = GazeFeatures.Fixation(random_gaze_positions(10))
ts, _ = fixation.positions.first
- new_step = visual_scan_path.append_fixation(ts, fixation, 'A')
+ new_step = aoi_scan_path.append_fixation(ts, fixation, 'A')
- # Check that no visual scan step have been created yet
- self.assertEqual(len(visual_scan_path), 0)
+ # Check that no aoi scan step have been created yet
+ self.assertEqual(len(aoi_scan_path), 0)
self.assertEqual(new_step, None)
# Append saccade
saccade = GazeFeatures.Saccade(random_gaze_positions(2))
ts, _ = saccade.positions.first
- new_step = visual_scan_path.append_saccade(ts, saccade)
+ new_step = aoi_scan_path.append_saccade(ts, saccade)
- # Check that no visual scan step have been created yet
- self.assertEqual(len(visual_scan_path), 0)
+ # Check that no aoi scan step have been created yet
+ self.assertEqual(len(aoi_scan_path), 0)
self.assertEqual(new_step, None)
# Append fixation on B aoi
fixation = GazeFeatures.Fixation(random_gaze_positions(10))
ts, _ = fixation.positions.first
- new_step = visual_scan_path.append_fixation(ts, fixation, 'B')
+ new_step = aoi_scan_path.append_fixation(ts, fixation, 'B')
- # Check a new visual scan step have been created
- self.assertEqual(len(visual_scan_path), 1)
+ # Check a new aoi scan step have been created
+ self.assertEqual(len(aoi_scan_path), 1)
self.assertEqual(len(new_step.movements), 2)
self.assertEqual(new_step.aoi, 'A')
def test_append_error(self):
- """Test VisualScanPath append error."""
+ """Test AOIScanPath append error."""
- visual_scan_path = GazeFeatures.VisualScanPath()
+ aoi_scan_path = GazeFeatures.AOIScanPath()
# Append fixation on A aoi
fixation = GazeFeatures.Fixation(random_gaze_positions(10))
ts, _ = fixation.positions.first
- new_step = visual_scan_path.append_fixation(ts, fixation, 'A')
+ new_step = aoi_scan_path.append_fixation(ts, fixation, 'A')
- # Check that no visual scan step have been created yet
- self.assertEqual(len(visual_scan_path), 0)
+ # Check that no aoi scan step have been created yet
+ self.assertEqual(len(aoi_scan_path), 0)
self.assertEqual(new_step, None)
# Append fixation on B aoi
fixation = GazeFeatures.Fixation(random_gaze_positions(10))
ts, _ = fixation.positions.first
- # Check that visual scan step creation fail
- with self.assertRaises(GazeFeatures.VisualScanStepError):
+ # Check that aoi scan step creation fail
+ with self.assertRaises(GazeFeatures.AOIScanStepError):
- new_step = visual_scan_path.append_fixation(ts, fixation, 'B')
+ new_step = aoi_scan_path.append_fixation(ts, fixation, 'B')
if __name__ == '__main__':
diff --git a/src/argaze/GazeAnalysis/CoefficientK.py b/src/argaze/GazeAnalysis/CoefficientK.py
index 724faac..7bcb3b3 100644
--- a/src/argaze/GazeAnalysis/CoefficientK.py
+++ b/src/argaze/GazeAnalysis/CoefficientK.py
@@ -9,26 +9,26 @@ from argaze import GazeFeatures
import numpy
@dataclass
-class VisualScanPathAnalyzer(GazeFeatures.VisualScanPathAnalyzer):
- """Implementation of transition probability matrix algorithm as described by Christophe Lounis in its thesis "Monitor the monitoring: pilot assistance through gaze tracking and visual scanning analyses".
+class AOIScanPathAnalyzer(GazeFeatures.AOIScanPathAnalyzer):
+ """Implementation of transition probability matrix algorithm as described by Christophe Lounis in its thesis "Monitor the monitoring: pilot assistance through gaze tracking and aoi scanning analyses".
"""
def __post_init__(self):
pass
- def analyze(self, visual_scan_path: GazeFeatures.VisualScanPathType) -> Any:
- """Analyze visual scan."""
+ def analyze(self, aoi_scan_path: GazeFeatures.AOIScanPathType) -> Any:
+ """Analyze aoi scan."""
- assert(len(visual_scan_path) > 1)
+ assert(len(aoi_scan_path) > 1)
durations = []
amplitudes = []
- for visual_scan_step in visual_scan_path:
+ for aoi_scan_step in aoi_scan_path:
- durations.append(visual_scan_step.duration)
- amplitudes.append(visual_scan_step.last_saccade.amplitude)
+ durations.append(aoi_scan_step.duration)
+ amplitudes.append(aoi_scan_step.last_saccade.amplitude)
durations = numpy.array(durations)
amplitudes = numpy.array(amplitudes)
@@ -40,9 +40,9 @@ class VisualScanPathAnalyzer(GazeFeatures.VisualScanPathAnalyzer):
amplitude_std = numpy.std(amplitudes)
Ks = []
- for visual_scan_step in visual_scan_path:
+ for aoi_scan_step in aoi_scan_path:
- Ks.append(((visual_scan_step.duration - duration_mean) / duration_std) - ((visual_scan_step.last_saccade.amplitude - amplitude_mean) / amplitude_std))
+ Ks.append(((aoi_scan_step.duration - duration_mean) / duration_std) - ((aoi_scan_step.last_saccade.amplitude - amplitude_mean) / amplitude_std))
K = numpy.array(Ks).mean()
diff --git a/src/argaze/GazeAnalysis/TransitionProbabilityMatrix.py b/src/argaze/GazeAnalysis/TransitionProbabilityMatrix.py
index 55ea43b..9adabc5 100644
--- a/src/argaze/GazeAnalysis/TransitionProbabilityMatrix.py
+++ b/src/argaze/GazeAnalysis/TransitionProbabilityMatrix.py
@@ -9,7 +9,7 @@ from argaze import GazeFeatures
import pandas
@dataclass
-class VisualScanPathAnalyzer(GazeFeatures.VisualScanPathAnalyzer):
+class AOIScanPathAnalyzer(GazeFeatures.AOIScanPathAnalyzer):
"""Implementation of transition probability matrix algorithm as described in ...
"""
@@ -17,16 +17,16 @@ class VisualScanPathAnalyzer(GazeFeatures.VisualScanPathAnalyzer):
pass
- def analyze(self, visual_scan_path: GazeFeatures.VisualScanPathType) -> Any:
- """Analyze visual scan."""
+ def analyze(self, aoi_scan_path: GazeFeatures.AOIScanPathType) -> Any:
+ """Analyze aoi scan."""
- assert(len(visual_scan_path) > 1)
+ assert(len(aoi_scan_path) > 1)
sequence = []
- for visual_scan_step in visual_scan_path:
+ for aoi_scan_step in aoi_scan_path:
- sequence.append(visual_scan_step.aoi)
+ sequence.append(aoi_scan_step.aoi)
return pandas.crosstab(pandas.Series(sequence[1:], name='to'), pandas.Series(sequence[:-1], name='from'), normalize=1)
diff --git a/src/argaze/GazeFeatures.py b/src/argaze/GazeFeatures.py
index fd43824..f0600bd 100644
--- a/src/argaze/GazeFeatures.py
+++ b/src/argaze/GazeFeatures.py
@@ -307,11 +307,11 @@ class GazeMovementIdentifier():
return ts_fixations, ts_saccades, ts_status
-VisualScanStepType = TypeVar('VisualScanStep', bound="VisualScanStep")
+AOIScanStepType = TypeVar('AOIScanStep', bound="AOIScanStep")
# Type definition for type annotation convenience
-class VisualScanStepError(Exception):
- """Exception raised at VisualScanStepError creation if a visual scan step doesn't start by a fixation or doesn't end by a saccade."""
+class AOIScanStepError(Exception):
+ """Exception raised at AOIScanStepError creation if a aoi scan step doesn't start by a fixation or doesn't end by a saccade."""
def __init__(self, message, aoi=''):
@@ -320,8 +320,8 @@ class VisualScanStepError(Exception):
self.aoi = aoi
@dataclass(frozen=True)
-class VisualScanStep():
- """Define a visual scan step as a set of successive gaze movements onto a same AOI.
+class AOIScanStep():
+ """Define a aoi scan step as a set of successive gaze movements onto a same AOI.
.. warning::
Visual scan step have to start by a fixation and then end by a saccade."""
@@ -339,12 +339,12 @@ class VisualScanStep():
# First movement have to be a fixation
if not is_fixation(self.first_fixation):
- raise VisualScanStepError('First step movement is not a fixation', self.aoi)
+ raise AOIScanStepError('First step movement is not a fixation', self.aoi)
# Last movement have to be a saccade
if not is_saccade(self.last_saccade):
- raise VisualScanStepError('Last step movement is not a saccade', self.aoi)
+ raise AOIScanStepError('Last step movement is not a saccade', self.aoi)
@property
def first_fixation(self):
@@ -372,11 +372,11 @@ class VisualScanStep():
return last_ts - first_ts
-VisualScanPathType = TypeVar('VisualScanPathType', bound="VisualScanPathType")
+AOIScanPathType = TypeVar('AOIScanPathType', bound="AOIScanPathType")
# Type definition for type annotation convenience
-class VisualScanPath(list):
- """List of visual scan steps over successive AOI."""
+class AOIScanPath(list):
+ """List of aoi scan steps over successive AOI."""
def __init__(self):
@@ -405,12 +405,12 @@ class VisualScanPath(list):
@property
def current_aoi(self):
- """AOI name of visual scan step under construction"""
+ """AOI name of aoi scan step under construction"""
return self.__current_aoi
def append_saccade(self, ts, saccade):
- """Append new saccade to visual scan path."""
+ """Append new saccade to aoi scan path."""
# Ignore saccade if no fixation have been stored before
if len(self.__movements) > 0:
@@ -418,10 +418,10 @@ class VisualScanPath(list):
self.__movements[ts] = saccade
def append_fixation(self, ts, fixation, looked_aoi: str) -> bool:
- """Append new fixation to visual scan path and return last new visual scan step if one have been created.
+ """Append new fixation to aoi scan path and return last new aoi scan step if one have been created.
.. warning::
- It could raise VisualScanStepError"""
+ It could raise AOIScanStepError"""
# Is it fixation onto a new aoi?
if looked_aoi != self.__current_aoi and len(self.__movements) > 0:
@@ -429,7 +429,7 @@ class VisualScanPath(list):
try:
# Edit new step
- new_step = VisualScanStep(self.__movements, self.__current_aoi)
+ new_step = AOIScanStep(self.__movements, self.__current_aoi)
# Append new step
super().append(new_step)
@@ -457,10 +457,10 @@ class VisualScanPath(list):
return None
-class VisualScanPathAnalyzer():
- """Abstract class to define what should provide a visual scan path analyzer."""
+class AOIScanPathAnalyzer():
+ """Abstract class to define what should provide a aoi scan path analyzer."""
- def analyze(self, visual_scan_path: VisualScanPathType) -> Any:
- """Analyze visual scan path."""
+ def analyze(self, aoi_scan_path: AOIScanPathType) -> Any:
+ """Analyze aoi scan path."""
raise NotImplementedError('analyze() method not implemented')
diff --git a/src/argaze/utils/demo_gaze_features_run.py b/src/argaze/utils/demo_gaze_features_run.py
index 4fdc10d..022ad59 100644
--- a/src/argaze/utils/demo_gaze_features_run.py
+++ b/src/argaze/utils/demo_gaze_features_run.py
@@ -54,12 +54,12 @@ def main():
}
identification_mode = 'I-DT'
- visual_scan_path = GazeFeatures.VisualScanPath()
+ aoi_scan_path = GazeFeatures.AOIScanPath()
- tpm = TransitionProbabilityMatrix.VisualScanPathAnalyzer()
+ tpm = TransitionProbabilityMatrix.AOIScanPathAnalyzer()
tpm_analysis = pandas.DataFrame()
- cK = CoefficientK.VisualScanPathAnalyzer()
+ cK = CoefficientK.AOIScanPathAnalyzer()
cK_analysis = 0
gaze_movement_lock = threading.Lock()
@@ -107,24 +107,24 @@ def main():
try:
- # Append fixation to visual scan path
- new_step = visual_scan_path.append_fixation(data_ts, gaze_movement, look_at)
+ # Append fixation to aoi scan path
+ new_step = aoi_scan_path.append_fixation(data_ts, gaze_movement, look_at)
# Analyse transition probabilities
- if new_step and len(visual_scan_path) > 1:
+ if new_step and len(aoi_scan_path) > 1:
- tpm_analysis = tpm.analyze(visual_scan_path)
+ tpm_analysis = tpm.analyze(aoi_scan_path)
- cK_analysis = cK.analyze(visual_scan_path)
+ cK_analysis = cK.analyze(aoi_scan_path)
- except GazeFeatures.VisualScanStepError as e:
+ except GazeFeatures.AOIScanStepError as e:
print(f'Error on {e.aoi} step:', e)
elif GazeFeatures.is_saccade(gaze_movement):
- # Append saccade to visual scan path
- visual_scan_path.append_saccade(data_ts, gaze_movement)
+ # Append saccade to aoi scan path
+ aoi_scan_path.append_saccade(data_ts, gaze_movement)
# Unlock gaze movement exploitation
gaze_movement_lock.release()
@@ -198,11 +198,11 @@ def main():
# Draw movement from start to next
cv2.line(aoi_matrix, start_gaze_position, next_gaze_position, (0, 0, 255), 1)
- # Write last 5 steps of visual scan path
+ # Write last 5 steps of aoi scan path
path = ''
- for step in visual_scan_path[-5:]:
+ for step in aoi_scan_path[-5:]:
path += f'> {step.aoi} '
- path += f'> {visual_scan_path.current_aoi}'
+ path += f'> {aoi_scan_path.current_aoi}'
cv2.putText(aoi_matrix, path, (20, window_size[1]-40), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 1, cv2.LINE_AA)