diff options
author | Théo de la Hogue | 2023-05-31 18:39:16 +0200 |
---|---|---|
committer | Théo de la Hogue | 2023-05-31 18:39:16 +0200 |
commit | b41077e071877cd95a2ae25a60ab6f34f3c31529 (patch) | |
tree | 3e9a28dcc49c3011e99fe685fbcfb62c20f1e795 /src/argaze/GazeAnalysis/ExploitExploreRatio.py | |
parent | 9773ae5a0811f56950a062fbd8b3063e5698d02a (diff) | |
download | argaze-b41077e071877cd95a2ae25a60ab6f34f3c31529.zip argaze-b41077e071877cd95a2ae25a60ab6f34f3c31529.tar.gz argaze-b41077e071877cd95a2ae25a60ab6f34f3c31529.tar.bz2 argaze-b41077e071877cd95a2ae25a60ab6f34f3c31529.tar.xz |
Adding new ExploitExploreRatio analyser.
Diffstat (limited to 'src/argaze/GazeAnalysis/ExploitExploreRatio.py')
-rw-r--r-- | src/argaze/GazeAnalysis/ExploitExploreRatio.py | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/src/argaze/GazeAnalysis/ExploitExploreRatio.py b/src/argaze/GazeAnalysis/ExploitExploreRatio.py new file mode 100644 index 0000000..eba8ec2 --- /dev/null +++ b/src/argaze/GazeAnalysis/ExploitExploreRatio.py @@ -0,0 +1,63 @@ +#!/usr/bin/env python + +"""Implementation of exploit vs explore ratio algorithm as described in: + + **Goldberg J. H., Kotval X. P. (1999).** + *Computer interface evaluation using eye movements: methods and constructs.* + International Journal of Industrial Ergonomics (631–645). + [https://doi.org/10.1016/S0169-8141(98)00068-7](https://doi.org/10.1016/S0169-8141\\(98\\)00068-7) + + **Dehais F., Peysakhovich V., Scannella S., Fongue J., Gateau T. (2015).** + *Automation surprise in aviation: Real-time solutions.* + Proceedings of the 33rd annual ACM conference on Human Factors in Computing Systems (2525–2534). + [https://doi.org/10.1145/2702123.2702521](https://doi.org/10.1145/2702123.2702521) +""" + +__author__ = "Théo de la Hogue" +__credits__ = [] +__copyright__ = "Copyright 2023, Ecole Nationale de l'Aviation Civile (ENAC)" +__license__ = "BSD" + +from dataclasses import dataclass + +from argaze import GazeFeatures + +import numpy + +@dataclass +class ScanPathAnalyzer(GazeFeatures.ScanPathAnalyzer): + + def __post_init__(self): + + pass + + def analyze(self, scan_path: GazeFeatures.ScanPathType, long_fixation_duration_threshold: float = 0.) -> float: + """Analyze scan path.""" + + assert(len(scan_path) > 1) + + short_fixations_durations = [] + long_fixations_durations = [] + saccades_durations = [] + + for scan_step in scan_path: + + if scan_step.first_fixation.duration > long_fixation_duration_threshold: + + long_fixations_durations.append(scan_step.first_fixation.duration) + + else: + + short_fixations_durations.append(scan_step.first_fixation.duration) + + saccades_durations.append(scan_step.last_saccade.duration) + + short_fixations_duration = numpy.array(short_fixations_durations).sum() + long_fixations_duration = numpy.array(long_fixations_durations).sum() + saccades_duration = numpy.array(saccades_durations).sum() + + print(short_fixations_duration, long_fixations_duration, saccades_duration) + + assert(saccades_duration + short_fixations_duration > 0) + + return long_fixations_duration / (saccades_duration + short_fixations_duration) |