From 01378ae467b6399a13042f02a67010dfc820aee2 Mon Sep 17 00:00:00 2001 From: Théo de la Hogue Date: Mon, 4 Sep 2023 14:49:27 +0200 Subject: Moving scripting features into a dedicated advanced chapter. --- .../advanced_topics/scripting.md | 160 +++++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 docs/user_guide/gaze_analysis_pipeline/advanced_topics/scripting.md (limited to 'docs/user_guide/gaze_analysis_pipeline/advanced_topics') diff --git a/docs/user_guide/gaze_analysis_pipeline/advanced_topics/scripting.md b/docs/user_guide/gaze_analysis_pipeline/advanced_topics/scripting.md new file mode 100644 index 0000000..2db69fc --- /dev/null +++ b/docs/user_guide/gaze_analysis_pipeline/advanced_topics/scripting.md @@ -0,0 +1,160 @@ +Script the pipeline +=================== + +All gaze analysis pipeline objects are accessible from Python script. +This could be particularly useful for realtime gaze interaction applications. + +## Load ArFrame configuration from dictionary + +First of all, [ArFrame](../../../argaze.md/#argaze.ArFeatures.ArFrame) configuration can be loaded from a python dictionary. + +```python +from argaze import ArFeatures + +# Edit a dict with ArFrame configuration +configuration = { + "name": "My FullHD screen", + "size": (1920, 1080), + ... + "gaze_movement_identifier": { + ... + }, + "scan_path": { + ... + }, + "scan_path_analyzers": { + ... + }, + "heatmap": { + ... + }, + "layers": { + "MyLayer": { + ... + }, + ... + }, + "image_parameters": { + ... + } +} + +# Load ArFrame +ar_frame = ArFeatures.ArFrame.from_dict(configuration) + +# Do something with ArFrame +... +``` + +## Access to ArFrame and ArLayers attributes + +Then, once the configuration is loaded, it is possible to access to its attributes: [read ArFrame code reference](../../../argaze.md/#argaze.ArFeatures.ArFrame) to get a complete list of what is available. + +Thus, the [ArFrame.layers](../../../argaze.md/#argaze.ArFeatures.ArFrame) attribute allows to access each loaded layer and so, access to their attributes: [read ArLayer code reference](../../../argaze.md/#argaze.ArFeatures.ArLayer) to get a complete list of what is available. + +```python +from argaze import ArFeatures + +# Assuming the ArFrame is loaded +... + +# Iterate over each ArFrame layers +for name, ar_layer in ar_frame.layers.items(): + ... +``` + +## Pipeline execution outputs + +[ArFrame.look](../../../argaze.md/#argaze.ArFeatures.ArFrame.look) method returns many data about pipeline execution. + +```python +# Assuming that timestamped gaze positions are available +... + + # Look ArFrame at a timestamped gaze position + gaze_movement, scan_path_analysis, layers_analysis, execution_times, exception = ar_frame.look(timestamp, gaze_position) + + # Check if a gaze movement has been identified + if gaze_movement.valid and gaze_movement.finished: + + # Do something with identified fixation + if GazeFeatures.is_fixation(gaze_movement): + ... + + # Do something with identified saccade + elif GazeFeatures.is_saccade(gaze_movement): + ... + + # Do something with scan path analysis + for module, analysis in scan_path_analysis.items(): + for data, value in analysis.items(): + ... + + # Do something with each layer AOI scan path analysis + for layer_name, layer_aoi_scan_path_analysis in layers_analysis.items(): + for module, analysis in layer_aoi_scan_path_analysis.items(): + for data, value in analysis.items(): + ... + + # Do something with pipeline execution times + ... + + # Do something with pipeline exception + if exception: + ... +``` + +Let's understand the meaning of each returned data. + +### 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). + +This could also be the current gaze movement if [ArFrame.filter_in_progress_fixation](../../../argaze.md/#argaze.ArFeatures.ArFrame) attribute is false. +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. + +### Scan path analysis + +A dictionary with all last scan path analysis if new scan step have been added to the [ArFrame.scan_path](../../../argaze.md/#argaze.ArFeatures.ArFrame) object. + +### Layers analysis + +A dictionary with all layers AOI scan path analysis if new AOI scan step have been added to an [ArLayer.aoi_scan_path](../../../argaze.md/#argaze.ArFeatures.ArLayer) object. + +### Execution times + +A dictionary with each pipeline step execution time. + +### Exception + +A [python Exception](https://docs.python.org/3/tutorial/errors.html#exceptions) object raised during pipeline execution. + +## Setup ArFrame image parameters + +[ArFrame.image](../../argaze.md/#argaze.ArFeatures.ArFrame.image) method parameters can be configured thanks to a python dictionary. + +```python +# Assuming ArFrame is loaded +... + +# Edit a dict with ArFrame image parameters +image_parameters = { + "draw_scan_path": { + ... + }, + "draw_layers": { + "MyLayer": { + ... + } + }, + ... +} + +# Pass image parameters to ArFrame +ar_frame_image = ar_frame.image(**image_parameters) + +# Do something with ArFrame image +... +``` -- cgit v1.1