From 49cc1aff416079fc6c9ced7105d3379b9a93e506 Mon Sep 17 00:00:00 2001 From: Théo de la Hogue Date: Wed, 12 Jul 2023 16:10:48 +0200 Subject: Laoding duration_max attribute to check scan path duration. Updating utils script. --- src/argaze/ArFeatures.py | 41 +++++++++++++++++-- src/argaze/GazeFeatures.py | 46 ++++++++++++++++++++-- .../demo_environment/demo_gaze_features_setup.json | 6 +++ 3 files changed, 86 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/argaze/ArFeatures.py b/src/argaze/ArFeatures.py index 1a7cec4..154050f 100644 --- a/src/argaze/ArFeatures.py +++ b/src/argaze/ArFeatures.py @@ -167,6 +167,17 @@ class ArFrame(): finished_gaze_movement_identifier = None + # Load scan path + try: + + new_scan_path_data = frame_data.pop('scan_path') + new_scan_path = GazeFeatures.ScanPath(**new_scan_path_data) + + except KeyError: + + new_scan_path_data = {} + new_scan_path = None + # Load scan path analyzers new_scan_path_analyzers = {} @@ -207,10 +218,29 @@ class ArFrame(): new_scan_path_analyzers[scan_path_analyzer_type] = scan_path_analyzer + # Force scan path creation + if len(new_scan_path_analyzers) > 0 and new_scan_path == None: + + new_scan_path = GazeFeatures.ScanPath(**new_scan_path_data) + except KeyError: pass - + + # Load AOI scan path + try: + + new_aoi_scan_path_data = frame_data.pop('aoi_scan_path') + new_aoi_scan_path = GazeFeatures.AOIScanPath(**new_aoi_scan_path_data) + + except KeyError: + + new_aoi_scan_path_data = {} + new_aoi_scan_path = None + + # Append expected AOI to AOI scan path data + new_aoi_scan_path_data['expected_aois'] = list(new_aoi_2d_scene.keys()) + # Load AOI scan path analyzers new_aoi_scan_path_analyzers = {} @@ -251,6 +281,11 @@ class ArFrame(): new_aoi_scan_path_analyzers[aoi_scan_path_analyzer_type] = aoi_scan_path_analyzer + # Force AOI scan path creation + if len(new_aoi_scan_path_analyzers) > 0 and new_aoi_scan_path == None: + + new_aoi_scan_path = GazeFeatures.AOIScanPath(**new_aoi_scan_path_data) + except KeyError: pass @@ -270,9 +305,9 @@ class ArFrame(): new_aoi_2d_scene, \ new_frame_background, \ finished_gaze_movement_identifier, \ - GazeFeatures.ScanPath() if len(new_scan_path_analyzers) > 0 else None, \ + new_scan_path, \ new_scan_path_analyzers, \ - GazeFeatures.AOIScanPath(list(new_aoi_2d_scene.keys())) if len(new_aoi_scan_path_analyzers) > 0 else None, \ + new_aoi_scan_path, \ new_aoi_scan_path_analyzers, \ AOIFeatures.Heatmap(new_frame_size) if new_heatmap_value else None \ ) diff --git a/src/argaze/GazeFeatures.py b/src/argaze/GazeFeatures.py index 8afe2eb..e92e41c 100644 --- a/src/argaze/GazeFeatures.py +++ b/src/argaze/GazeFeatures.py @@ -588,10 +588,12 @@ ScanPathType = TypeVar('ScanPathType', bound="ScanPathType") class ScanPath(list): """List of scan steps.""" - def __init__(self): + def __init__(self, duration_max: int|float = 0): super().__init__() - + + self.duration_max = duration_max + self.__last_fixation = None self.__duration = 0 @@ -605,6 +607,17 @@ class ScanPath(list): return self.__duration + def __check_duration(self): + """Constrain path duration to maximal duration.""" + + if self.duration_max > 0: + + while self.__duration > self.duration_max: + + oldest_step = self.pop(0) + + self.__duration -= oldest_step.duration + def append_saccade(self, ts, saccade) -> ScanStepType: """Append new saccade to scan path and return last new scan step if one have been created.""" @@ -622,6 +635,9 @@ class ScanPath(list): # Update duration self.__duration += new_step.duration + # Constrain path duration to maximal duration + self.__check_duration() + # Return new step return new_step @@ -767,10 +783,12 @@ AOIScanPathType = TypeVar('AOIScanPathType', bound="AOIScanPathType") class AOIScanPath(list): """List of aoi scan steps over successive aoi.""" - def __init__(self, expected_aois: list[str] = []): + def __init__(self, expected_aois: list[str] = [], duration_max: int|float = 0): super().__init__() - + + self.duration_max = duration_max + self.expected_aois = expected_aois self.__duration = 0 @@ -785,6 +803,23 @@ class AOIScanPath(list): return self.__duration + def __check_duration(self): + """Constrain path duration to maximal duration.""" + + if self.duration_max > 0: + + while self.__duration > self.duration_max: + + oldest_step = self.pop(0) + + self.__duration -= oldest_step.duration + + # Edit transition matrix + if len(self) > 0: + + # Decrement [index: source, columns: destination] value + self.__transition_matrix.loc[oldest_step.aoi, self[0].aoi,] -= 1 + def __get_aoi_letter(self, aoi): try : @@ -893,6 +928,9 @@ class AOIScanPath(list): # Update duration self.__duration += new_step.duration + # Constrain path duration to maximal duration + self.__check_duration() + # Return new step return new_step diff --git a/src/argaze/utils/demo_environment/demo_gaze_features_setup.json b/src/argaze/utils/demo_environment/demo_gaze_features_setup.json index fbf0bec..7822a8c 100644 --- a/src/argaze/utils/demo_environment/demo_gaze_features_setup.json +++ b/src/argaze/utils/demo_environment/demo_gaze_features_setup.json @@ -13,6 +13,9 @@ "duration_min_threshold": 200 } }, + "scan_path": { + "duration_max": 10000 + }, "scan_path_analyzers": { "Basic": {}, "KCoefficient": {}, @@ -23,6 +26,9 @@ "short_fixation_duration_threshold": 0 } }, + "aoi_scan_path": { + "duration_max": 10000 + }, "aoi_scan_path_analyzers": { "Basic": {}, "TransitionMatrix": {}, -- cgit v1.1