aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/argaze/ArFeatures.py76
1 files changed, 73 insertions, 3 deletions
diff --git a/src/argaze/ArFeatures.py b/src/argaze/ArFeatures.py
index 4811a0b..ad755e8 100644
--- a/src/argaze/ArFeatures.py
+++ b/src/argaze/ArFeatures.py
@@ -77,6 +77,7 @@ class ArLayer():
aoi_matcher: AOI matcher object
aoi_scan_path: AOI scan path object
aoi_scan_path_analyzers: dictionary of AOI scan path analyzers
+ log: enable aoi scan path analysis logging
"""
name: str
@@ -85,6 +86,7 @@ class ArLayer():
aoi_matcher: GazeFeatures.AOIMatcher = field(default_factory=GazeFeatures.AOIMatcher)
aoi_scan_path: GazeFeatures.AOIScanPath = field(default_factory=GazeFeatures.AOIScanPath)
aoi_scan_path_analyzers: dict = field(default_factory=dict)
+ log: bool = field(default=False)
def __post_init__(self):
@@ -106,6 +108,16 @@ class ArLayer():
self.aoi_scene = AOI3DScene.AOI3DScene(self.aoi_scene)
+ # Prepare logging if needed
+ self.__ts_logs = {}
+
+ if self.log:
+
+ # Create timestamped buffers to log each aoi scan path analysis
+ for aoi_scan_path_analyzer_module_path in self.aoi_scan_path_analyzers.keys():
+
+ self.__ts_logs[aoi_scan_path_analyzer_module_path] = DataStructures.TimeStampedBuffer()
+
@classmethod
def from_dict(self, layer_data, working_directory: str = None) -> ArLayerType:
"""Load attributes from dictionary.
@@ -262,13 +274,23 @@ class ArLayer():
pass
+ # Load log status
+ try:
+
+ new_layer_log = layer_data.pop('log')
+
+ except KeyError:
+
+ new_layer_log = False
+
# Create layer
return ArLayer(new_layer_name, \
new_aoi_color, \
new_aoi_scene, \
new_aoi_matcher, \
new_aoi_scan_path, \
- new_aoi_scan_path_analyzers \
+ new_aoi_scan_path_analyzers, \
+ new_layer_log \
)
@classmethod
@@ -299,6 +321,14 @@ class ArLayer():
self.__parent = parent
+ @property
+ def logs(self):
+ """
+ Get stored logs
+ """
+
+ return self.__ts_logs
+
def look(self, timestamp: int|float, gaze_movement: GazeFeatures.GazePosition = GazeFeatures.UnvalidGazePosition()) -> dict:
"""
Project timestamped gaze movement into layer.
@@ -380,6 +410,11 @@ class ArLayer():
# Store analysis
aoi_scan_path_analysis[aoi_scan_path_analyzer_module_path] = aoi_scan_path_analyzer.analysis
+ # Log analysis
+ if self.log:
+
+ self.__ts_logs[aoi_scan_path_analyzer_module_path][timestamp] = aoi_scan_path_analyzer.analysis
+
elif GazeFeatures.is_saccade(gaze_movement):
# Append saccade to aoi scan path
@@ -477,6 +512,7 @@ class ArFrame():
scan_path_analyzers: dictionary of scan path analyzers
heatmap: heatmap object
aoi_layers: dictionary of AOI layers
+ log: enable scan path analysis logging
"""
name: str
@@ -488,7 +524,8 @@ class ArFrame():
scan_path_analyzers: dict = field(default_factory=dict)
heatmap: AOIFeatures.Heatmap = field(default_factory=AOIFeatures.Heatmap)
layers: dict = field(default_factory=dict)
-
+ log: bool = field(default=False)
+
def __post_init__(self):
# Define parent attribute: it will be setup by parent later
@@ -505,6 +542,16 @@ class ArFrame():
# Init lock to share looked data with multiples threads
self.__look_lock = threading.Lock()
+ # Prepare logging if needed
+ self.__ts_logs = {}
+
+ if self.log:
+
+ # Create timestamped buffers to log each aoi scan path analysis
+ for scan_path_analyzer_module_path in self.scan_path_analyzers.keys():
+
+ self.__ts_logs[scan_path_analyzer_module_path] = DataStructures.TimeStampedBuffer()
+
@classmethod
def from_dict(self, frame_data, working_directory: str = None) -> ArFrameType:
"""Load attributes from dictionary.
@@ -672,6 +719,15 @@ class ArFrame():
pass
+ # Load log status
+ try:
+
+ new_frame_log = frame_data.pop('log')
+
+ except KeyError:
+
+ new_frame_log = False
+
# Create frame
return ArFrame(new_frame_name, \
new_frame_size, \
@@ -681,7 +737,8 @@ class ArFrame():
new_scan_path, \
new_scan_path_analyzers, \
new_heatmap, \
- new_layers \
+ new_layers, \
+ new_frame_log \
)
@classmethod
@@ -734,6 +791,14 @@ class ArFrame():
return image
+ @property
+ def logs(self):
+ """
+ Get stored logs
+ """
+
+ return self.__ts_logs
+
def look(self, timestamp: int|float, gaze_position: GazeFeatures.GazePosition = GazeFeatures.UnvalidGazePosition()) -> Tuple[GazeFeatures.GazeMovement, dict, dict, dict]:
"""
Project gaze position into frame.
@@ -826,6 +891,11 @@ class ArFrame():
# Store analysis
scan_step_analysis[scan_path_analyzer_module_path] = scan_path_analyzer.analysis
+ # Log analysis
+ if self.log:
+
+ self.__ts_logs[scan_path_analyzer_module_path][timestamp] = scan_path_analyzer.analysis
+
# No valid finished gaze movement: optionnaly stop in progress fixation filtering
elif self.gaze_movement_identifier and not self.filter_in_progress_fixation: