From 1e410097b5fe63f72928610d0ef77b25471bc88c Mon Sep 17 00:00:00 2001 From: Théo de la Hogue Date: Mon, 29 Jan 2024 10:19:26 +0100 Subject: Harmonizing ArFeatures method names. --- .../advanced_topics/scripting.md | 39 ++++++++++-------- src/argaze/ArFeatures.py | 46 +++++++++++----------- src/argaze/DataFeatures.py | 12 +++--- src/argaze/utils/demo_data/demo_layer_logger.py | 2 +- src/argaze/utils/demo_data/frame_logger.py | 10 ++--- 5 files changed, 58 insertions(+), 51 deletions(-) diff --git a/docs/user_guide/gaze_analysis_pipeline/advanced_topics/scripting.md b/docs/user_guide/gaze_analysis_pipeline/advanced_topics/scripting.md index 12b5dd1..e206a96 100644 --- a/docs/user_guide/gaze_analysis_pipeline/advanced_topics/scripting.md +++ b/docs/user_guide/gaze_analysis_pipeline/advanced_topics/scripting.md @@ -76,35 +76,38 @@ Calling [ArFrame.look](../../../argaze.md/#argaze.ArFeatures.ArFrame.look) metho # Look ArFrame at a timestamped gaze position ar_frame.look(timestamp, gaze_position): - # Do something with calibrated gaze position - ... ar_frame.gaze_position + # Do something with last gaze position + ... ar_frame.last_gaze_position # Check if a gaze movement has been identified - if ar_frame.gaze_movement.valid and ar_frame.gaze_movement.finished: + if ar_frame.last_gaze_movement.valid and ar_frame.last_gaze_movement.finished: # Do something with identified fixation - if GazeFeatures.is_fixation(ar_frame.gaze_movement): + if GazeFeatures.is_fixation(ar_frame.last_gaze_movement): ... # Do something with identified saccade - elif GazeFeatures.is_saccade(ar_frame.gaze_movement): + elif GazeFeatures.is_saccade(ar_frame.last_gaze_movement): ... # Do something with scan path analysis - if ar_frame.scan_path_analyzed: + if ar_frame.analysis_available: - for scan_path_analyzer_name, scan_path_analysis in ar_frame.scan_path_analysis(): + for scan_path_analyzer_name, scan_path_analysis in ar_frame.analysis(): ... # Do something with layers aoi scan path analysis for layer_name, ar_layer in ar_frame.layers.items(): - if ar_layer.aoi_scan_path_analyzed: + # Do something with last looked aoi name + ... ar_frame.last_looked_aoi_name - for aoi_scan_path_analyzer_name, aoi_scan_path_analysis in ar_layer.aoi_scan_path_analysis: + if ar_layer.analysis_available: + + for aoi_scan_path_analyzer_name, aoi_scan_path_analysis in ar_layer.analysis(): ... @@ -116,11 +119,11 @@ Calling [ArFrame.look](../../../argaze.md/#argaze.ArFeatures.ArFrame.look) metho Let's understand the meaning of each data. -### *ar_frame.gaze_position* +### *ar_frame.last_gaze_position* -This is the calibrated [GazePosition](../../../argaze.md/#argaze.GazeFeatures.GazePosition) returned by [GazePositionCalibrator](../../../argaze.md/#argaze.GazeFeatures.GazePositionCalibrator) if one is instanciated else, it is the given [GazePosition](../../../argaze.md/#argaze.GazeFeatures.GazePosition). +This is the last calibrated [GazePosition](../../../argaze.md/#argaze.GazeFeatures.GazePosition) returned by [GazePositionCalibrator](../../../argaze.md/#argaze.GazeFeatures.GazePositionCalibrator) if one is instanciated else, it is the given [GazePosition](../../../argaze.md/#argaze.GazeFeatures.GazePosition). -### *ar_frame.gaze_movement* +### *ar_frame.last_gaze_movement* A [GazeMovement](../../../argaze.md/#argaze.GazeFeatures.GazeMovement) once it have been identified by [ArFrame.gaze_movement_identifier](../../../argaze.md/#argaze.ArFeatures.ArFrame) object from incoming consecutive timestamped gaze positions. If no gaze movement have been identified, it returns an [UnvalidGazeMovement](../../../argaze.md/#argaze.GazeFeatures.UnvalidGazeMovement). @@ -129,19 +132,23 @@ In that case, the returned gaze movement *finished* flag is false. Then, the returned gaze movement type can be tested thanks to [GazeFeatures.is_fixation](../../../argaze.md/#argaze.GazeFeatures.is_fixation) and [GazeFeatures.is_saccade](../../../argaze.md/#argaze.GazeFeatures.is_saccade) functions. -### *ar_frame.scan_path_analyzed* +### *ar_frame.analysis_available* This flag allows to now when new scan path analysis are available. -### *ar_frame.scan_path_analysis()* +### *ar_frame.analysis()* This an iterator to access to all scan path analysis. -### *ar_layer.aoi_scan_path_analyzed* +### *ar_layer.last_looked_aoi_name* + +The name of the last aoi matching a gaze movement returned by [AoiMatcher](../../../argaze.md/#argaze.GazeFeatures.AoiMatcher) if one is instanciated else, it is a None value. + +### *ar_layer.analysis_available* This flag allows to now when new aoi scan path analysis are available. -### *ar_layer.aoi_scan_path_analysis* +### *ar_layer.analysis()* This an iterator to access to all aoi scan path analysis. diff --git a/src/argaze/ArFeatures.py b/src/argaze/ArFeatures.py index e856c74..ed3eb9b 100644 --- a/src/argaze/ArFeatures.py +++ b/src/argaze/ArFeatures.py @@ -190,24 +190,22 @@ class ArLayer(DataFeatures.SharedObject, DataFeatures.PipelineStepObject): return self.__aoi_scan_path_analyzers @property - def draw_parameters(self): + def draw_parameters(self) -> dict: """Get layer's draw parameters dictionary.""" return self.__draw_parameters @property - def looked_aoi_name(self) -> str: - """Get aoi matcher looked aoi name.""" + def last_looked_aoi_name(self) -> bool: + """Get last looked aoi name.""" return self.__looked_aoi_name - + @property - def aoi_scan_path_analyzed(self) -> bool: + def analysis_available(self) -> bool: """Are aoi scan path analysis ready?""" - return self.__aoi_scan_path_analyzed - @property - def aoi_scan_path_analysis(self) -> Iterator[Union[str, dict]]: - """Get aoi scan path analysis. + def analysis(self) -> Iterator[Union[str, dict]]: + """Iterate over aoi scan path analysis. Returns iterator: analyzer module path, analysis dictionary @@ -414,7 +412,7 @@ class ArLayer(DataFeatures.SharedObject, DataFeatures.PipelineStepObject): gaze_movement: gaze movement to project """ - # Use layer locker feature + # Use layer lock feature with self._lock: # Update current gaze movement @@ -474,7 +472,7 @@ class ArLayer(DataFeatures.SharedObject, DataFeatures.PipelineStepObject): return self.draw(image, **self.__draw_parameters) - # Use layer locker feature + # Use layer lock feature with self._lock: # Draw aoi if required @@ -633,22 +631,21 @@ class ArFrame(DataFeatures.SharedObject, DataFeatures.PipelineStepObject): return self.__image_parameters @property - def gaze_position(self) -> object: - """Get current calibrated gaze position""" + def last_gaze_position(self) -> object: + """Get last calibrated gaze position""" return self.__calibrated_gaze_position @property - def gaze_movement(self) -> object: - """Get current identified gaze movement""" + def last_gaze_movement(self) -> object: + """Get last identified gaze movement""" return self.__identified_gaze_movement @property - def scan_path_analyzed(self) -> bool: + def analysis_available(self) -> bool: """Are scan path analysis ready?""" return self.__scan_path_analyzed - @property - def scan_path_analysis(self) -> Iterator[Union[str, dict]]: + def analysis(self) -> Iterator[Union[str, dict]]: """Get scan path analysis. Returns @@ -921,7 +918,7 @@ class ArFrame(DataFeatures.SharedObject, DataFeatures.PipelineStepObject): gaze_position: gaze position to project """ - # Use frame locker feature + # Use frame lock feature with self._lock: # No gaze movement identified by default @@ -1009,7 +1006,7 @@ class ArFrame(DataFeatures.SharedObject, DataFeatures.PipelineStepObject): draw_saccades: [GazeFeatures.Saccade.draw](argaze.md/#argaze.GazeFeatures.Saccade.draw) parameters (if None, no saccade is drawn) """ - # Use frame locker feature + # Use frame lock feature with self._lock: # Draw background only @@ -1165,6 +1162,9 @@ class ArScene(DataFeatures.PipelineStepObject): scene_data: dictionary working_directory: folder path where to load files when a dictionary value is a relative filepath. """ + + # DEBUG + print('ArScene.from_dict self:', self) # Load layers new_layers = {} @@ -1427,7 +1427,6 @@ class ArCamera(ArFrame): """Set camera's visual vertical field of view.""" self.__visual_vfov = value - @property def scene_frames(self) -> Iterator[ArFrame]: """Iterate over all scenes frames""" @@ -1475,7 +1474,7 @@ class ArCamera(ArFrame): # Project gaze position into camera frame super().look(timestamp, gaze_position) - # Use camera frame locker feature + # Use camera frame lock feature with self._lock: # Project gaze position into each scene frames if possible @@ -1504,6 +1503,7 @@ class ArCamera(ArFrame): pass + @DataFeatures.PipelineStepMethod def map(self): """Project camera frame background into scene frames background. @@ -1511,7 +1511,7 @@ class ArCamera(ArFrame): watch method needs to be called first. """ - # Use camera frame locker feature + # Use camera frame lock feature with self._lock: # Project camera frame background into each scene frame if possible diff --git a/src/argaze/DataFeatures.py b/src/argaze/DataFeatures.py index c839b21..3dcc7e4 100644 --- a/src/argaze/DataFeatures.py +++ b/src/argaze/DataFeatures.py @@ -405,6 +405,7 @@ class PipelineStepObject(): self.__name = name self.__observers = observers if observers is not None else {} self.__execution_times = {} + self.__properties = {} # parent attribute will be setup later by parent it self self.__parent = None @@ -544,7 +545,7 @@ class PipelineStepObject(): for name, observer in self.__observers.items(): output += f'{tabs}\t - {Fore.RED}{name}{Style.RESET_ALL}: {Fore.GREEN}{Style.BRIGHT}{observer.__class__.__module__}.{observer.__class__.__name__}{Style.RESET_ALL}\n' - for name, value in self.attributes: + for name, value in self.properties: output += f'{tabs}\t{Style.BRIGHT}{name}{Style.RESET_ALL}: ' @@ -589,8 +590,8 @@ class PipelineStepObject(): return tabs @property - def attributes(self) -> list: - """Iterate over pipeline step attributes values.""" + def properties(self) -> list: + """Iterate over pipeline step properties values.""" for name, item in self.__class__.__dict__.items(): @@ -608,10 +609,9 @@ class PipelineStepObject(): yield name, getattr(self, name) -def PipelineStepAttribute(method): +def PipelineStepProperty(method): - # Mark method as - method._tags = tags + print('PipelineStepProperty', method) return method diff --git a/src/argaze/utils/demo_data/demo_layer_logger.py b/src/argaze/utils/demo_data/demo_layer_logger.py index 8f69b02..b9db10b 100644 --- a/src/argaze/utils/demo_data/demo_layer_logger.py +++ b/src/argaze/utils/demo_data/demo_layer_logger.py @@ -18,7 +18,7 @@ class AOIScanPathAnalysisLogger(DataFeatures.PipelineStepObserver, UtilsFeatures def on_look(self, timestamp, layer): """Log aoi scan path metrics""" - if layer.aoi_scan_path_analyzed: + if layer.analysis_available: log = ( timestamp, diff --git a/src/argaze/utils/demo_data/frame_logger.py b/src/argaze/utils/demo_data/frame_logger.py index a633b84..b6c0b00 100644 --- a/src/argaze/utils/demo_data/frame_logger.py +++ b/src/argaze/utils/demo_data/frame_logger.py @@ -16,13 +16,13 @@ class FixationLogger(DataFeatures.PipelineStepObserver, UtilsFeatures.FileWriter """Log fixations""" # Log fixations - if GazeFeatures.is_fixation(frame.gaze_movement) and frame.gaze_movement.finished: + if GazeFeatures.is_fixation(frame.last_gaze_movement) and frame.last_gaze_movement.finished: log = ( timestamp, - frame.gaze_movement.focus, - frame.gaze_movement.duration, - frame.layers['demo_layer'].looked_aoi_name + frame.last_gaze_movement.focus, + frame.last_gaze_movement.duration, + frame.layers['demo_layer'].last_looked_aoi_name ) self.write(log) @@ -32,7 +32,7 @@ class ScanPathAnalysisLogger(DataFeatures.PipelineStepObserver, UtilsFeatures.Fi def on_look(self, timestamp, frame): """Log scan path metrics""" - if frame.scan_path_analyzed: + if frame.analysis_available: log = ( timestamp, -- cgit v1.1