aboutsummaryrefslogtreecommitdiff
path: root/docs/user_guide/gaze_features/scan_path.md
diff options
context:
space:
mode:
Diffstat (limited to 'docs/user_guide/gaze_features/scan_path.md')
-rw-r--r--docs/user_guide/gaze_features/scan_path.md169
1 files changed, 169 insertions, 0 deletions
diff --git a/docs/user_guide/gaze_features/scan_path.md b/docs/user_guide/gaze_features/scan_path.md
new file mode 100644
index 0000000..46af28b
--- /dev/null
+++ b/docs/user_guide/gaze_features/scan_path.md
@@ -0,0 +1,169 @@
+Scan path
+=========
+
+[GazeFeatures](../../argaze.md/#argaze.GazeFeatures) defines classes to handle successive fixations/saccades and analyse their spatial or temporal properties.
+
+## Fixation based scan path
+
+### Definition
+
+The [ScanPath](../../argaze.md/#argaze.GazeFeatures.ScanPath) class is defined as a list of [ScanSteps](../../argaze.md/#argaze.GazeFeatures.ScanStep) which are defined as a fixation and a consecutive saccade.
+
+![Fixation based scan path](../../img/scan_path.png)
+
+As fixations and saccades are identified, the scan path is built by calling respectively [append_fixation](../../argaze.md/#argaze.GazeFeatures.ScanPath.append_fixation) and [append_saccade](../../argaze.md/#argaze.GazeFeatures.ScanPath.append_saccade) methods.
+
+### Analysis
+
+[GazeFeatures](../../argaze.md/#argaze.GazeFeatures) defines abstract [ScanPathAnalyzer](../../argaze.md/#argaze.GazeFeatures.ScanPathAnalyzer) classe to let add various analysis algorithms.
+
+Some scan path analysis are available thanks to [GazeAnalysis](../../argaze.md/#argaze.GazeAnalysis) submodule:
+
+* [K-Coefficient](../../argaze.md/#argaze.GazeAnalysis.KCoefficient)
+* [Nearest Neighbor Index](../../argaze.md/#argaze.GazeAnalysis.NearestNeighborIndex)
+* [Exploit Explore Ratio](../../argaze.md/#argaze.GazeAnalysis.ExploitExploreRatio)
+
+### Example
+
+Here is a sample of code to illustrate how to built a scan path and analyze it:
+
+``` python
+from argaze import GazeFeatures
+from argaze.GazeAnalysis import KCoefficient
+
+# Create a empty scan path
+scan_path = GazeFeatures.ScanPath()
+
+# Create a K coefficient analyzer
+kc_analyzer = KCoefficient.ScanPathAnalyzer()
+
+# Assuming a gaze movement is identified at ts time
+...:
+
+ # Fixation identified
+ if GazeFeatures.is_fixation(gaze_movement):
+
+ # Append fixation to scan path : no step is created
+ scan_path.append_fixation(ts, gaze_movement)
+
+ # Saccade identified
+ elif GazeFeatures.is_saccade(gaze_movement):
+
+ # Append saccade to scan path : a new step should be created
+ new_step = scan_path.append_saccade(data_ts, gaze_movement)
+
+ # Analyse scan path
+ if new_step:
+
+ K = kc_analyzer.analyze(scan_path)
+
+ # Do something with K metric
+ ...
+```
+
+## AOI based scan path
+
+### Definition
+
+The [AOIScanPath](../../argaze.md/#argaze.GazeFeatures.AOIScanPath) class is defined as a list of [AOIScanSteps](../../argaze.md/#argaze.GazeFeatures.AOIScanStep) which are defined as set of consecutives fixations looking at a same Area Of Interest (AOI) and a consecutive saccade.
+
+![AOI based scan path](../../img/aoi_scan_path.png)
+
+As fixations and saccades are identified, the scan path is built by calling respectively [append_fixation](../../argaze.md/#argaze.GazeFeatures.AOIScanPath.append_fixation) and [append_saccade](../../argaze.md/#argaze.GazeFeatures.AOIScanPath.append_saccade) methods.
+
+### Analysis
+
+[GazeFeatures](../../argaze.md/#argaze.GazeFeatures) defines abstract [AOIScanPathAnalyzer](../../argaze.md/#argaze.GazeFeatures.AOIScanPathAnalyzer) classe to let add various analysis algorithms.
+
+Some scan path analysis are available thanks to [GazeAnalysis](../../argaze.md/#argaze.GazeAnalysis) submodule:
+
+* [Transition matrix](../../argaze.md/#argaze.GazeAnalysis.TransitionMatrix)
+* [Entropy](../../argaze.md/#argaze.GazeAnalysis.Entropy)
+* [Lempel-Ziv complexity](../../argaze.md/#argaze.GazeAnalysis.LempelZivComplexity)
+* [N-Gram](../../argaze.md/#argaze.GazeAnalysis.NGram)
+* [K-modified coefficient](../../argaze.md/#argaze.GazeAnalysis.KCoefficient)
+
+### Example
+
+Here is a sample of code to illustrate how to built a AOI scan path and analyze it:
+
+``` python
+from argaze import GazeFeatures
+from argaze.GazeAnalysis import LempelZivComplexity
+
+# Assuming all AOI names are listed
+...
+
+# Create a empty AOI scan path
+aoi_scan_path = GazeFeatures.AOIScanPath(aoi_names)
+
+# Create a Lempel-Ziv complexity analyzer
+lzc_analyzer = LempelZivComplexity.AOIScanPathAnalyzer()
+
+# Assuming a gaze movement is identified at ts time
+...:
+
+ # Fixation identified
+ if GazeFeatures.is_fixation(gaze_movement):
+
+ # Assuming fixation is detected as inside an AOI
+ ...
+
+ # Append fixation to AOI scan path : a new step should be created
+ new_step = aoi_scan_path.append_fixation(ts, gaze_movement, looked_aoi_name)
+
+ # Analyse AOI scan path
+ if new_step:
+
+ LZC = kc_analyzer.analyze(aoi_scan_path)
+
+ # Do something with LZC metric
+ ...
+
+ # Saccade identified
+ elif GazeFeatures.is_saccade(gaze_movement):
+
+ # Append saccade to scan path : no step is created
+ aoi_scan_path.append_saccade(data_ts, gaze_movement)
+
+```
+
+### Advanced
+
+The [AOIScanPath](../../argaze.md/#argaze.GazeFeatures.AOIScanPath) class provides some advanced features to analyse it.
+
+#### Letter sequence
+
+When a new [AOIScanStep](../../argaze.md/#argaze.GazeFeatures.AOIScanStep) is created, the [AOIScanPath](../../argaze.md/#argaze.GazeFeatures.AOIScanPath) internally affects a unique letter index related to its AOI to ease pattern analysis.
+Then, the [AOIScanPath letter_sequence](../../argaze.md/#argaze.GazeFeatures.AOIScanPath.letter_sequence) property returns the concatenation of each [AOIScanStep](../../argaze.md/#argaze.GazeFeatures.AOIScanStep) letter.
+The [AOIScanPath get_letter_aoi](../../argaze.md/#argaze.GazeFeatures.AOIScanPath.get_letter_aoi) method helps to get back the AOI related to a letter index.
+
+``` python
+# Assuming the following AOI scan path is built: Foo > Bar > Shu > Foo
+aoi_scan_path = ...
+
+# Letter sequence representation should be: 'ABCA'
+print(aoi_scan_path.letter_sequence)
+
+# Output should be: 'Bar'
+print(aoi_scan_path.get_letter_aoi('B'))
+
+```
+
+#### Transition matrix
+
+When a new [AOIScanStep](../../argaze.md/#argaze.GazeFeatures.AOIScanStep) is created, the [AOIScanPath](../../argaze.md/#argaze.GazeFeatures.AOIScanPath) internally counts the number of transitions from an AOI to another AOI to ease Markov chain analysis.
+Then, the [AOIScanPath transition_matrix](../../argaze.md/#argaze.GazeFeatures.AOIScanPath.transition_matrix) property returns a [Pandas DataFrame](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.html) where indexes are transition departures and columns are transition destinations.
+
+Here is an exemple of transition matrix for the following [AOIScanPath](../../argaze.md/#argaze.GazeFeatures.AOIScanPath): Foo > Bar > Shu > Foo > Bar
+
+| |Foo|Bar|Shu|
+|:--|:--|:--|:--|
+|Foo|0 |2 |0 |
+|Bar|0 |0 |1 |
+|Shu|1 |0 |0 |
+
+
+#### Fixations count
+
+The [AOIScanPath fixations_count](../../argaze.md/#argaze.GazeFeatures.AOIScanPath.fixations_count) method returns the total number of fixations in the whole scan path and a dictionary to get the fixations count per AOI.