aboutsummaryrefslogtreecommitdiff
path: root/docs/user_guide
diff options
context:
space:
mode:
Diffstat (limited to 'docs/user_guide')
-rw-r--r--docs/user_guide/gaze_analysis_pipeline/logging.md118
1 files changed, 62 insertions, 56 deletions
diff --git a/docs/user_guide/gaze_analysis_pipeline/logging.md b/docs/user_guide/gaze_analysis_pipeline/logging.md
index db3cf9a..c5fe15a 100644
--- a/docs/user_guide/gaze_analysis_pipeline/logging.md
+++ b/docs/user_guide/gaze_analysis_pipeline/logging.md
@@ -1,97 +1,103 @@
Log gaze analysis
=================
-[ArFrame](../../argaze.md/#argaze.ArFeatures.ArFrame) and [ArLayer](../../argaze.md/#argaze.ArFeatures.ArLayer) logging are optional pipeline steps. They are executed at each new scan path step to update logs.
+[ArFrame](../../argaze.md/#argaze.ArFeatures.ArFrame) and [ArLayer](../../argaze.md/#argaze.ArFeatures.ArLayer) analysis can be logged by registering observers to their **look** method.
-## Enable ArFrame and ArLayer logging
+## Enable ArFrame and ArLayer analysis logging
-[ArFrame](../../argaze.md/#argaze.ArFeatures.ArFrame) and [ArLayer](../../argaze.md/#argaze.ArFeatures.ArLayer) have a log attribute to enable analysis logging.
+[ArFrame](../../argaze.md/#argaze.ArFeatures.ArFrame) and [ArLayer](../../argaze.md/#argaze.ArFeatures.ArLayer) have an observers attribute to enable pipeline execution logging.
-Here is an extract from the JSON ArFrame configuration file where logging is enabled for the [ArFrame](../../argaze.md/#argaze.ArFeatures.ArFrame) and for one [ArLayer](../../argaze.md/#argaze.ArFeatures.ArLayer):
+Here is an extract from the JSON ArFrame configuration file where logging is enabled for the [ArFrame](../../argaze.md/#argaze.ArFeatures.ArFrame) and for one [ArLayer](../../argaze.md/#argaze.ArFeatures.ArLayer) by pointing to dedicated Python files:
```json
{
"name": "My FullHD screen",
"size": [1920, 1080],
- "log": true,
+ "observers": "my_frame_logger.py",
...
"layers": {
"MyLayer": {
- "log": true,
+ "observers": "my_layer_logger.py",
...
}
}
}
```
-Then, here is how to access to logs dictionaries:
+!!! note
+ [ArFrame](../../argaze.md/#argaze.ArFeatures.ArFrame) and its [ArLayers](../../argaze.md/#argaze.ArFeatures.ArLayer) automatically notify **look** method observers after each call.
+
+Here is *my_frame_logger.py* file:
```python
-# Assuming that all timestamped gaze positions have been processed by ArFrame.look method
-...
+from argaze import DataFeatures
+from argaze.utils import UtilsFeatures
-# Access to ArFame scan path analysis logs
-for analysis, log in ar_frame.logs.items():
-
- # Do something with scan path analysis log
- ...
+class ScanPathAnalysisLogger(DataFeatures.PipelineStepObserver, UtilsFeatures.FileWriter):
-# Access to ArLayers AOI scan path analysis logs
-for layer_name, layer in ar_frame.layers.items():
+ def on_look(self, timestamp, frame):
+ """Log scan path metrics"""
- for analysis, log in layer.logs.items():
+ if frame.analysis_available:
- # Do something with AOI scan path analysis log
- ...
+ log = (
+ timestamp,
+ frame.scan_path_analyzers['argaze.GazeAnalysis.Basic'].path_duration,
+ frame.scan_path_analyzers['argaze.GazeAnalysis.Basic'].steps_number
+ )
+
+ # Write to file
+ self.write(log)
+
+# Export logger as observer
+__observers__ = {
+ "Scan path analysis logger": ScanPathAnalysisLogger(path="./scan_path_metrics.csv", header="Timestamp (ms), Duration (ms), Steps number")
+ }
```
-!!! note
- [ArFrame](../../argaze.md/#argaze.ArFeatures.ArFrame) and its [ArLayers](../../argaze.md/#argaze.ArFeatures.ArLayer) logging are automatically done each time the [ArFrame.look](../../argaze.md/#argaze.ArFeatures.ArFrame.look) method is called.
- [ArFrame](../../argaze.md/#argaze.ArFeatures.ArFrame) logging records each scan path analysis into a dedicated timestamped data buffer each time a new scan step happens.
- [ArLayer](../../argaze.md/#argaze.ArFeatures.ArLayer) logging records each AOI scan path analysis into a dedicated timestamped data buffer each time a new AOI scan step happens.
+Assuming that [ArGaze.GazeAnalysis.Basic](../../argaze.md/#argaze.GazeAnalysis.Basic) scan path analysis module is enabled for 'My FullHD screen' ArFrame, a ***scan_path_metrics.csv*** file would be created:
-## Export gaze analysis logs to CSV file
+|Timestamp (ms)|Duration (ms)|Steps number|
+|:-------------|:------------|:-----------|
+|3460 |1750 |2 |
+|4291 |2623 |3 |
+|4769 |3107 |4 |
+|6077 |4411 |5 |
+|6433 |4760 |6 |
+|7719 |6050 |7 |
+|... |... |... |
-It is possible to convert gaze analysis log as [Pandas DataFrame](https://pandas.pydata.org/docs/getting_started/intro_tutorials/01_table_oriented.html#min-tut-01-tableoriented) object which can be writen into a CSV file.
+Here is *my_layer_logger.py* file:
```python
-import pandas
+from argaze import DataFeatures
+from argaze.utils import UtilsFeatures
-# Assuming that all timestamped gaze positions have been processed by ArFrame.look method
-...
+class AOIScanPathAnalysisLogger(DataFeatures.PipelineStepObserver, UtilsFeatures.FileWriter):
-# Export ArFame scan path analysis logs
-for analysis, log in ar_frame.logs.items():
-
- log.as_dataframe().to_csv(f'./{ar_frame.name}_{analysis}.csv')
+ def on_look(self, timestamp, layer):
+ """Log aoi scan path metrics"""
-# Export ArLayers layers AOI scan path analysis logs
-for layer_name, layer in ar_frame.layers.items():
+ if layer.analysis_available:
- for analysis, log in layer.logs.items():
+ log = (
+ timestamp,
+ layer.aoi_scan_path_analyzers['argaze.GazeAnalysis.NGram'].ngrams_count
+ )
- log.as_dataframe().to_csv(f'./{ar_frame.name}_{layer_name}_{analysis}.csv')
+ # Write to file
+ self.write(log)
+# Export logger as observer
+__observers__ = {
+ "AOI Scan path analysis logger": AOIScanPathAnalysisLogger(path="./aoi_scan_path_metrics.csv", header="Timestamp (ms), NGram counts")
+ }
```
-Assuming that [ArGaze.GazeAnalysis.Basic](../../argaze.md/#argaze.GazeAnalysis.Basic) scan path analysis module is enabled for 'My FullHD screen' ArFrame, a ***My FullHD screen_argaze.GazeAnalysis.Basic.csv*** file would be created:
-
-|timestamped|path_duration|step_fixation_durations_average|steps_number|
-|:----------|:------------|:------------------------------|:-----------|
-|3460 |1750 |563.0 |2 |
-|4291 |2623 |652.0 |3 |
-|4769 |3107 |544.0 |4 |
-|6077 |4411 |652.8 |5 |
-|6433 |4760 |595.1 |6 |
-|7719 |6050 |652.8 |7 |
-|... |... |... |... |
-
-Assuming that [ArGaze.GazeAnalysis.NGram](../../argaze.md/#argaze.GazeAnalysis.NGram) AOI scan path analysis module is enabled for 'MyLayer' ArLayer, a ***My FullHD screen_MyLayer_argaze.GazeAnalysis.NGram.csv*** file would be created:
-
-|timestamped|ngrams_count|
-|:----------|:-----------|
-|5687 |"{3: {}, 4: {}, 5: {}}"|
-|6208 |"{3: {('LeftPanel', 'GeoSector', 'CircularWidget'): 1}, 4: {}, 5: {}}"|
-|... |... |
-
+Assuming that [ArGaze.GazeAnalysis.NGram](../../argaze.md/#argaze.GazeAnalysis.NGram) AOI scan path analysis module is enabled for 'MyLayer' ArLayer, a ***aoi_scan_path_metrics.csv*** file would be created:
+|Timestamp (ms)|NGram counts|
+|:-------------|:-----------|
+|5687 |"{3: {}, 4: {}, 5: {}}"|
+|6208 |"{3: {('LeftPanel', 'GeoSector', 'CircularWidget'): 1}, 4: {}, 5: {}}"|
+|... |... |