├── .gitignore ├── 01_load_exported_data_and_visualize_pupillometry.ipynb ├── 02_load_exported_surfaces_and_visualize_aggregate_heatmap.ipynb ├── 03_visualize_scan_path_on_surface.ipynb ├── 04_visualize_surface_positions_in_world_camera_pixel_space.ipynb ├── 05_visualize_gaze_velocity.ipynb ├── 06_fixation_pupil_diameter.ipynb ├── 07_frame_extraction.ipynb ├── 08_post_hoc_time_sync.ipynb ├── 09_frame_identification.ipynb ├── 10_merge_fixation_and_blink_ids_into_gaze_dataframe.ipynb ├── 11_undistortion_and_unprojection.ipynb ├── LICENSE ├── README.md ├── data ├── 10_merge_fixation_and_blink_ids_into_gaze_dataframe │ ├── blinks.csv │ ├── fixations.csv │ └── gaze_positions.csv ├── cover_image.png ├── extracted_frames │ └── .gitignore └── gaze_positions.csv ├── recordings └── .gitignore └── requirements-all-tutorials.txt /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | 28 | # PyInstaller 29 | # Usually these files are written by a python script from a template 30 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 31 | *.manifest 32 | *.spec 33 | 34 | # Installer logs 35 | pip-log.txt 36 | pip-delete-this-directory.txt 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .coverage 42 | .coverage.* 43 | .cache 44 | nosetests.xml 45 | coverage.xml 46 | *.cover 47 | .hypothesis/ 48 | 49 | # Translations 50 | *.mo 51 | *.pot 52 | 53 | # Django stuff: 54 | *.log 55 | local_settings.py 56 | 57 | # Flask stuff: 58 | instance/ 59 | .webassets-cache 60 | 61 | # Scrapy stuff: 62 | .scrapy 63 | 64 | # Sphinx documentation 65 | docs/_build/ 66 | 67 | # PyBuilder 68 | target/ 69 | 70 | # Jupyter Notebook 71 | .ipynb_checkpoints 72 | 73 | # pyenv 74 | .python-version 75 | 76 | # celery beat schedule file 77 | celerybeat-schedule 78 | 79 | # SageMath parsed files 80 | *.sage.py 81 | 82 | # dotenv 83 | .env 84 | 85 | # virtualenv 86 | .venv 87 | venv/ 88 | ENV/ 89 | 90 | # Spyder project settings 91 | .spyderproject 92 | .spyproject 93 | 94 | # Rope project settings 95 | .ropeproject 96 | 97 | # mkdocs documentation 98 | /site 99 | 100 | # mypy 101 | .mypy_cache/ 102 | 103 | .DS_Store 104 | .vscode/ 105 | -------------------------------------------------------------------------------- /06_fixation_pupil_diameter.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Tutorial 06 - Pupil Diameter By Fixation On Surface\n", 8 | "In this tutorial we will look at how to calculate the mean pupil diameter for each fixation on a given surface.\n", 9 | "We will follow these steps:\n", 10 | "1. Define the necessary file paths\n", 11 | "1. Load the data using `Pandas`.\n", 12 | "1. Select required columns\n", 13 | "1. Group fixations by id\n", 14 | "1. Extract pupil data for each fixation\n", 15 | "1. Calculate mean pupil diameter for based on the extracted pupil data\n", 16 | "\n", 17 | "To re-execute this notebook, please download the [sample recording](https://drive.google.com/file/d/1vzjZkjoi8kESw8lBnsa_k_8hXPf3fMMC/view?usp=sharing) for Pupil Player, unpack it and place it inside the `recordings` directory.\n", 18 | "\n", 19 | "## 1 - Define the necessary file paths\n", 20 | "Let's start by importing the necessary Python modules and defining the necessary file paths." 21 | ] 22 | }, 23 | { 24 | "cell_type": "code", 25 | "execution_count": 1, 26 | "metadata": {}, 27 | "outputs": [], 28 | "source": [ 29 | "import pathlib\n", 30 | "\n", 31 | "import numpy as np\n", 32 | "import pandas as pd\n", 33 | "import seaborn as sns\n", 34 | "sns.set(context=\"notebook\", style=\"whitegrid\", font_scale=1.2)\n", 35 | "\n", 36 | "import matplotlib.pyplot as plt\n", 37 | "import matplotlib.colors as colors\n", 38 | "%matplotlib inline" 39 | ] 40 | }, 41 | { 42 | "cell_type": "code", 43 | "execution_count": 2, 44 | "metadata": {}, 45 | "outputs": [ 46 | { 47 | "name": "stdout", 48 | "output_type": "stream", 49 | "text": [ 50 | "Necessary files:\n", 51 | "recordings/sample_recording_v2/exports/000/pupil_positions.csv\n", 52 | "recordings/sample_recording_v2/exports/000/surfaces/fixations_on_surface_Spread Text.csv\n" 53 | ] 54 | } 55 | ], 56 | "source": [ 57 | "surface_name = \"Spread Text\"\n", 58 | "\n", 59 | "recording = pathlib.Path(\"recordings\") / \"sample_recording_v2\"\n", 60 | "export_dir = recording / \"exports\" / \"000\"\n", 61 | "surface_dir = export_dir / \"surfaces\"\n", 62 | "\n", 63 | "pupil_positions_file = export_dir / \"pupil_positions.csv\"\n", 64 | "fixations_on_surface_file = surface_dir / f\"fixations_on_surface_{surface_name}.csv\"\n", 65 | "\n", 66 | "print(\"Necessary files:\")\n", 67 | "print(pupil_positions_file)\n", 68 | "print(fixations_on_surface_file)" 69 | ] 70 | }, 71 | { 72 | "cell_type": "markdown", 73 | "metadata": {}, 74 | "source": [ 75 | "## 2 - Load the data using `Pandas`\n", 76 | "In the next steps we use the [Pandas](https://pypi.org/project/pandas/) project to load and filter the data.\n" 77 | ] 78 | }, 79 | { 80 | "cell_type": "code", 81 | "execution_count": 3, 82 | "metadata": {}, 83 | "outputs": [], 84 | "source": [ 85 | "pupil_positions = pd.read_csv(pupil_positions_file)\n", 86 | "fixations_on_surface = pd.read_csv(fixations_on_surface_file)\n", 87 | "\n", 88 | "# we are only interested in 3D pupil data\n", 89 | "pupil_positions = pupil_positions[pupil_positions.method == \"3d c++\"]" 90 | ] 91 | }, 92 | { 93 | "cell_type": "markdown", 94 | "metadata": {}, 95 | "source": [ 96 | "## 3 - Select required columns\n", 97 | "We only need a subset of the loaded columns:\n", 98 | "- `pupil_positions.csv`\n", 99 | " - `pupil_timestamp`: Used for temporal correlation with fixations\n", 100 | " - `diameter_3d`: Used for aggregation to diameter mean\n", 101 | " - `confidence`: Used to filter low confidence data\n", 102 | "- `fixations_on_surface_.csv`:\n", 103 | " - `fixation_id`: Used to group fixations by id (see the [v1.15 release notes](https://github.com/pupil-labs/pupil/releases/tag/v1.15) on the reason for duplicated entries)\n", 104 | " - `start_timestamp`: Used for temporal correlation with pupil positions\n", 105 | " - `duration`: In ms, used for temporal correlation with pupil positions\n", 106 | " - `on_surf`: Used to filter fixations that are not positioned on the selected surface" 107 | ] 108 | }, 109 | { 110 | "cell_type": "code", 111 | "execution_count": 4, 112 | "metadata": {}, 113 | "outputs": [ 114 | { 115 | "name": "stdout", 116 | "output_type": "stream", 117 | "text": [ 118 | "\n", 119 | "Int64Index: 31971 entries, 0 to 31970\n", 120 | "Data columns (total 3 columns):\n", 121 | " # Column Non-Null Count Dtype \n", 122 | "--- ------ -------------- ----- \n", 123 | " 0 pupil_timestamp 31971 non-null float64\n", 124 | " 1 diameter_3d 31971 non-null float64\n", 125 | " 2 confidence 31971 non-null float64\n", 126 | "dtypes: float64(3)\n", 127 | "memory usage: 999.1 KB\n", 128 | "\n", 129 | "\n", 130 | "RangeIndex: 1650 entries, 0 to 1649\n", 131 | "Data columns (total 4 columns):\n", 132 | " # Column Non-Null Count Dtype \n", 133 | "--- ------ -------------- ----- \n", 134 | " 0 fixation_id 1650 non-null int64 \n", 135 | " 1 start_timestamp 1650 non-null float64\n", 136 | " 2 duration 1650 non-null float64\n", 137 | " 3 on_surf 1650 non-null bool \n", 138 | "dtypes: bool(1), float64(2), int64(1)\n", 139 | "memory usage: 40.4 KB\n" 140 | ] 141 | } 142 | ], 143 | "source": [ 144 | "pupil_positions = pupil_positions[[\"pupil_timestamp\", \"diameter_3d\", \"confidence\"]]\n", 145 | "fixations_on_surface = fixations_on_surface[[\"fixation_id\", \"start_timestamp\", \"duration\", \"on_surf\"]]\n", 146 | "\n", 147 | "pupil_positions.info()\n", 148 | "print()\n", 149 | "fixations_on_surface.info()" 150 | ] 151 | }, 152 | { 153 | "cell_type": "markdown", 154 | "metadata": {}, 155 | "source": [ 156 | "## 4 - Data processing\n", 157 | "\n", 158 | "1. Group fixations by id\n", 159 | "1. Extract pupil data for each fixation\n", 160 | " 1. Check if fixation was on surface\n", 161 | " 1. Calculate start and end point of each fixation\n", 162 | " 1. Select all pupil data that lies between start and end point of each fixation\n", 163 | " 1. Remove low confidence data\n", 164 | "1. Calculate mean pupil diameter for based on the extracted pupil data" 165 | ] 166 | }, 167 | { 168 | "cell_type": "code", 169 | "execution_count": 5, 170 | "metadata": {}, 171 | "outputs": [], 172 | "source": [ 173 | "MIN_CONFIDENCE = 0.8\n", 174 | "\n", 175 | "results = []\n", 176 | "\n", 177 | "for _, fixations in fixations_on_surface.groupby(\"fixation_id\"): # group fixations by id\n", 178 | " first_fixation = fixations.iloc[0]\n", 179 | " if not first_fixation.on_surf:\n", 180 | " continue # skip fixation since it is not on the surface\n", 181 | "\n", 182 | " # calculate start and end point\n", 183 | " fixation_id = first_fixation.fixation_id\n", 184 | " fixation_start = first_fixation.start_timestamp\n", 185 | " fixation_end = fixation_start + first_fixation.duration / 1000 # duration is in ms\n", 186 | " \n", 187 | " # boolean masks to filter pupil positions\n", 188 | " mask_after_start = fixation_start <= pupil_positions.pupil_timestamp\n", 189 | " mask_before_end = pupil_positions.pupil_timestamp <= fixation_end\n", 190 | " mask_high_confidence = pupil_positions.confidence >= MIN_CONFIDENCE\n", 191 | "\n", 192 | " # Extract pupil data for each fixation\n", 193 | " pupil_positions_during_fixation = pupil_positions[mask_after_start & mask_before_end & mask_high_confidence]\n", 194 | " diameter_3d_during_fixation = pupil_positions_during_fixation.diameter_3d\n", 195 | " \n", 196 | " # Calculate mean pupil diameter for based on the extracted pupil data\n", 197 | " results.append([fixation_id, diameter_3d_during_fixation.mean()])\n", 198 | "\n", 199 | "# Create new data frame from results\n", 200 | "mean_diameter_3d_by_fixation = pd.DataFrame(results, columns=[\"fixation_id\", \"mean_pupil_diameter_3d\"])" 201 | ] 202 | }, 203 | { 204 | "cell_type": "markdown", 205 | "metadata": {}, 206 | "source": [ 207 | "## 5 - Visualize results\n", 208 | "\n", 209 | "Below we plot the mean diameter for each fixation." 210 | ] 211 | }, 212 | { 213 | "cell_type": "code", 214 | "execution_count": 6, 215 | "metadata": {}, 216 | "outputs": [ 217 | { 218 | "data": { 219 | "text/plain": [ 220 | "Text(0, 0.5, 'mean diameter_3d [mm]')" 221 | ] 222 | }, 223 | "execution_count": 6, 224 | "metadata": {}, 225 | "output_type": "execute_result" 226 | }, 227 | { 228 | "data": { 229 | "image/png": "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\n", 230 | "text/plain": [ 231 | "
" 232 | ] 233 | }, 234 | "metadata": { 235 | "needs_background": "light" 236 | }, 237 | "output_type": "display_data" 238 | } 239 | ], 240 | "source": [ 241 | "plt.scatter(mean_diameter_3d_by_fixation.fixation_id, mean_diameter_3d_by_fixation.mean_pupil_diameter_3d)\n", 242 | "plt.xlabel(\"fixation_id\")\n", 243 | "plt.ylabel(\"mean diameter_3d [mm]\")" 244 | ] 245 | } 246 | ], 247 | "metadata": { 248 | "kernelspec": { 249 | "display_name": "Python 3", 250 | "language": "python", 251 | "name": "python3" 252 | }, 253 | "language_info": { 254 | "codemirror_mode": { 255 | "name": "ipython", 256 | "version": 3 257 | }, 258 | "file_extension": ".py", 259 | "mimetype": "text/x-python", 260 | "name": "python", 261 | "nbconvert_exporter": "python", 262 | "pygments_lexer": "ipython3", 263 | "version": "3.7.7" 264 | } 265 | }, 266 | "nbformat": 4, 267 | "nbformat_minor": 4 268 | } 269 | -------------------------------------------------------------------------------- /08_post_hoc_time_sync.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Tutorial 08 - Post-hoc Time Sync\n", 8 | "\n", 9 | "Pupil Core distinguishes between `System Time` and `Pupil Time`, measured in seconds.\n", 10 | "\n", 11 | "`System Time` is the current time of the device running Pupil Core software and uses the Unix epoc, while `Pupil Time` has an arbitrary that can be used to synchronize the clock between multiple devices.\n", 12 | "\n", 13 | "Since the exported data (pupil, gaze, fixations, blinks, surface, etc.) uses timestamps in `Pupil Time`, it is often desireable to convert these timestamps into Unix timestamps (`System Time`), or into `datetime` objects in Python.\n", 14 | "\n", 15 | "This tutorial shows how to easily perform the conversion and save the data in a new file.\n", 16 | "\n", 17 | "---\n", 18 | "\n", 19 | "> To execute this notebook, download the [sample recording](https://drive.google.com/file/d/1vzjZkjoi8kESw8lBnsa_k_8hXPf3fMMC/view?usp=sharing). Unzip and move it into the `recordings` directory for this repository." 20 | ] 21 | }, 22 | { 23 | "cell_type": "code", 24 | "execution_count": 1, 25 | "metadata": {}, 26 | "outputs": [], 27 | "source": [ 28 | "import pathlib\n", 29 | "import json\n", 30 | "\n", 31 | "import numpy as np\n", 32 | "import pandas as pd\n", 33 | "\n", 34 | "pd.options.display.float_format = '{:}'.format\n", 35 | "\n", 36 | "DATAFRAME_HEAD_COUNT = 3" 37 | ] 38 | }, 39 | { 40 | "cell_type": "markdown", 41 | "metadata": {}, 42 | "source": [ 43 | "First, we define the path to the recording directory, as well as the export directory within the recording." 44 | ] 45 | }, 46 | { 47 | "cell_type": "code", 48 | "execution_count": 2, 49 | "metadata": {}, 50 | "outputs": [ 51 | { 52 | "data": { 53 | "text/plain": [ 54 | "PosixPath('/Users/rom/work/pupil-tutorials/recordings/sample_recording_v2')" 55 | ] 56 | }, 57 | "execution_count": 2, 58 | "metadata": {}, 59 | "output_type": "execute_result" 60 | } 61 | ], 62 | "source": [ 63 | "rec_dir = pathlib.Path(\".\").joinpath(\"recordings\").joinpath(\"sample_recording_v2\").absolute()\n", 64 | "assert rec_dir.is_dir(), \"Please download the sample recording into 'recordings' directory.\"\n", 65 | "rec_dir" 66 | ] 67 | }, 68 | { 69 | "cell_type": "code", 70 | "execution_count": 3, 71 | "metadata": {}, 72 | "outputs": [ 73 | { 74 | "data": { 75 | "text/plain": [ 76 | "PosixPath('/Users/rom/work/pupil-tutorials/recordings/sample_recording_v2/exports/000')" 77 | ] 78 | }, 79 | "execution_count": 3, 80 | "metadata": {}, 81 | "output_type": "execute_result" 82 | } 83 | ], 84 | "source": [ 85 | "export_dir = rec_dir.joinpath(\"exports\").joinpath(\"000\")\n", 86 | "assert export_dir.is_dir(), \"Please create at least one export.\"\n", 87 | "export_dir" 88 | ] 89 | }, 90 | { 91 | "cell_type": "markdown", 92 | "metadata": {}, 93 | "source": [ 94 | "The recording contains a meta-data file (`info.player.json`) which provide essential information about the recording itself, as well as the context in which it was made. More information about the format can be found [here](https://github.com/pupil-labs/pupil/blob/master/pupil_src/shared_modules/pupil_recording/README.md)." 95 | ] 96 | }, 97 | { 98 | "cell_type": "code", 99 | "execution_count": 4, 100 | "metadata": {}, 101 | "outputs": [ 102 | { 103 | "data": { 104 | "text/plain": [ 105 | "{'duration_s': 100.0,\n", 106 | " 'meta_version': '2.2',\n", 107 | " 'min_player_version': '2.0',\n", 108 | " 'recording_name': '2019_10_24',\n", 109 | " 'recording_software_name': 'Pupil Capture',\n", 110 | " 'recording_software_version': '1.15.67',\n", 111 | " 'recording_uuid': 'fbd7d03b-fd91-47c7-9c61-120c2af37779',\n", 112 | " 'start_time_synced_s': 329353.31413932703,\n", 113 | " 'start_time_system_s': 1571931006.836434,\n", 114 | " 'system_info': 'User: mkassner, Platform: Darwin, Machine: moritzs-air.fritz.box, Release: 13.4.0, Version: Darwin Kernel Version 13.4.0: Mon Jan 11 18:17:34 PST 2016; root:xnu-2422.115.15~1/RELEASE_X86_64'}" 115 | ] 116 | }, 117 | "execution_count": 4, 118 | "metadata": {}, 119 | "output_type": "execute_result" 120 | } 121 | ], 122 | "source": [ 123 | "with rec_dir.joinpath(\"info.player.json\").open() as file:\n", 124 | " meta_info = json.load(file)\n", 125 | "\n", 126 | "meta_info" 127 | ] 128 | }, 129 | { 130 | "cell_type": "markdown", 131 | "metadata": {}, 132 | "source": [ 133 | "Using the start time of the recording in `System Time` (`start_time_system_s` field) and in `Pupil Time` (`start_time_synced_s` field), we calculate the offset which will be applied to timestamps in other data files to convert them to Unix timestamps." 134 | ] 135 | }, 136 | { 137 | "cell_type": "code", 138 | "execution_count": 5, 139 | "metadata": {}, 140 | "outputs": [], 141 | "source": [ 142 | "start_timestamp_unix = meta_info[\"start_time_system_s\"]\n", 143 | "start_timestamp_pupil = meta_info[\"start_time_synced_s\"]\n", 144 | "start_timestamp_diff = start_timestamp_unix - start_timestamp_pupil" 145 | ] 146 | }, 147 | { 148 | "cell_type": "markdown", 149 | "metadata": {}, 150 | "source": [ 151 | "## Pupil Positions Timestamps\n", 152 | "\n", 153 | "The code bellow implements the following steps:\n", 154 | "- Load the `pupil_positions.csv` file from the export directory into a Pandas dataframe\n", 155 | "- Convert the `pupil_timestamp` column values to Unix timestamps (new `pupil_timestamp_unix` column)\n", 156 | "- Convert the `pupil_timestamp` column values to datetime objects (new `pupil_timestamp_datetime` column)\n", 157 | "- Save the updated dataframe into `pupil_positions_unix_datetime` file in the export directory" 158 | ] 159 | }, 160 | { 161 | "cell_type": "code", 162 | "execution_count": 6, 163 | "metadata": {}, 164 | "outputs": [ 165 | { 166 | "data": { 167 | "text/html": [ 168 | "
\n", 169 | "\n", 182 | "\n", 183 | " \n", 184 | " \n", 185 | " \n", 186 | " \n", 187 | " \n", 188 | " \n", 189 | " \n", 190 | " \n", 191 | " \n", 192 | " \n", 193 | " \n", 194 | " \n", 195 | " \n", 196 | " \n", 197 | " \n", 198 | " \n", 199 | " \n", 200 | " \n", 201 | " \n", 202 | " \n", 203 | " \n", 204 | " \n", 205 | " \n", 206 | " \n", 207 | " \n", 208 | " \n", 209 | " \n", 210 | " \n", 211 | " \n", 212 | " \n", 213 | " \n", 214 | " \n", 215 | " \n", 216 | " \n", 217 | " \n", 218 | " \n", 219 | " \n", 220 | " \n", 221 | " \n", 222 | " \n", 223 | " \n", 224 | " \n", 225 | " \n", 226 | " \n", 227 | " \n", 228 | " \n", 229 | " \n", 230 | " \n", 231 | " \n", 232 | " \n", 233 | " \n", 234 | " \n", 235 | " \n", 236 | " \n", 237 | " \n", 238 | " \n", 239 | " \n", 240 | " \n", 241 | " \n", 242 | " \n", 243 | " \n", 244 | " \n", 245 | " \n", 246 | " \n", 247 | " \n", 248 | " \n", 249 | " \n", 250 | " \n", 251 | " \n", 252 | " \n", 253 | " \n", 254 | " \n", 255 | " \n", 256 | " \n", 257 | " \n", 258 | " \n", 259 | " \n", 260 | " \n", 261 | " \n", 262 | " \n", 263 | " \n", 264 | " \n", 265 | " \n", 266 | " \n", 267 | " \n", 268 | " \n", 269 | " \n", 270 | " \n", 271 | " \n", 272 | " \n", 273 | " \n", 274 | " \n", 275 | " \n", 276 | " \n", 277 | " \n", 278 | " \n", 279 | " \n", 280 | " \n", 281 | " \n", 282 | " \n", 283 | "
pupil_timestampworld_indexeye_idconfidencenorm_pos_xnorm_pos_ydiametermethodellipse_center_xellipse_center_y...circle_3d_normal_ycircle_3d_normal_zcircle_3d_radiusthetaphiprojected_sphere_center_xprojected_sphere_center_yprojected_sphere_axis_aprojected_sphere_axis_bprojected_sphere_angle
0329353.721339010.99926984957630640.5457271663213380.630094475599254450.193099544519883d c++104.7796159336968771.02186068494316...-0.13445288198078242-0.76119913869966533.17005169772325651.4359350164184437-2.265608188206017157.3353788312821384.97669413085066169.9658683385669169.965868338566990.0
1329353.72249699995000.88219039595412880.47324105759004590.416580552287115347.713854064932333d c++90.86228305728882112.01653396087386...0.06312584154879393-0.81602148654100843.2494972629903681.6339641684333268-2.184271545863164136.35058824450832105.40722431475041157.8160656718055157.816065671805590.0
2329353.726346010.99901739376080260.54565518175415260.630194780435396950.324672392304293d c++104.7657948967972971.0026021564038...-0.13466918975814415-0.76101855670391673.17843946868228281.4357167233320438-2.265857229927503157.3353788312821384.97669413085066169.9658683385669169.965868338566990.0
\n", 284 | "

3 rows × 34 columns

\n", 285 | "
" 286 | ], 287 | "text/plain": [ 288 | " pupil_timestamp world_index eye_id confidence \\\n", 289 | "0 329353.721339 0 1 0.9992698495763064 \n", 290 | "1 329353.72249699995 0 0 0.8821903959541288 \n", 291 | "2 329353.726346 0 1 0.9990173937608026 \n", 292 | "\n", 293 | " norm_pos_x norm_pos_y diameter method \\\n", 294 | "0 0.545727166321338 0.6300944755992544 50.19309954451988 3d c++ \n", 295 | "1 0.4732410575900459 0.4165805522871153 47.71385406493233 3d c++ \n", 296 | "2 0.5456551817541526 0.6301947804353969 50.32467239230429 3d c++ \n", 297 | "\n", 298 | " ellipse_center_x ellipse_center_y ... circle_3d_normal_y \\\n", 299 | "0 104.77961593369687 71.02186068494316 ... -0.13445288198078242 \n", 300 | "1 90.86228305728882 112.01653396087386 ... 0.06312584154879393 \n", 301 | "2 104.76579489679729 71.0026021564038 ... -0.13466918975814415 \n", 302 | "\n", 303 | " circle_3d_normal_z circle_3d_radius theta \\\n", 304 | "0 -0.7611991386996653 3.1700516977232565 1.4359350164184437 \n", 305 | "1 -0.8160214865410084 3.249497262990368 1.6339641684333268 \n", 306 | "2 -0.7610185567039167 3.1784394686822828 1.4357167233320438 \n", 307 | "\n", 308 | " phi projected_sphere_center_x projected_sphere_center_y \\\n", 309 | "0 -2.265608188206017 157.33537883128213 84.97669413085066 \n", 310 | "1 -2.184271545863164 136.35058824450832 105.40722431475041 \n", 311 | "2 -2.265857229927503 157.33537883128213 84.97669413085066 \n", 312 | "\n", 313 | " projected_sphere_axis_a projected_sphere_axis_b projected_sphere_angle \n", 314 | "0 169.9658683385669 169.9658683385669 90.0 \n", 315 | "1 157.8160656718055 157.8160656718055 90.0 \n", 316 | "2 169.9658683385669 169.9658683385669 90.0 \n", 317 | "\n", 318 | "[3 rows x 34 columns]" 319 | ] 320 | }, 321 | "execution_count": 6, 322 | "metadata": {}, 323 | "output_type": "execute_result" 324 | } 325 | ], 326 | "source": [ 327 | "pupil_positions_df = pd.read_csv(export_dir.joinpath(\"pupil_positions.csv\"))\n", 328 | "pupil_positions_df.head(DATAFRAME_HEAD_COUNT)" 329 | ] 330 | }, 331 | { 332 | "cell_type": "code", 333 | "execution_count": 7, 334 | "metadata": {}, 335 | "outputs": [ 336 | { 337 | "data": { 338 | "text/html": [ 339 | "
\n", 340 | "\n", 353 | "\n", 354 | " \n", 355 | " \n", 356 | " \n", 357 | " \n", 358 | " \n", 359 | " \n", 360 | " \n", 361 | " \n", 362 | " \n", 363 | " \n", 364 | " \n", 365 | " \n", 366 | " \n", 367 | " \n", 368 | " \n", 369 | " \n", 370 | " \n", 371 | " \n", 372 | " \n", 373 | " \n", 374 | " \n", 375 | " \n", 376 | " \n", 377 | " \n", 378 | " \n", 379 | " \n", 380 | " \n", 381 | " \n", 382 | " \n", 383 | " \n", 384 | " \n", 385 | " \n", 386 | " \n", 387 | " \n", 388 | " \n", 389 | " \n", 390 | " \n", 391 | " \n", 392 | " \n", 393 | " \n", 394 | " \n", 395 | " \n", 396 | " \n", 397 | " \n", 398 | " \n", 399 | " \n", 400 | " \n", 401 | " \n", 402 | " \n", 403 | " \n", 404 | " \n", 405 | " \n", 406 | " \n", 407 | " \n", 408 | " \n", 409 | " \n", 410 | " \n", 411 | " \n", 412 | " \n", 413 | " \n", 414 | " \n", 415 | " \n", 416 | " \n", 417 | " \n", 418 | " \n", 419 | " \n", 420 | " \n", 421 | " \n", 422 | " \n", 423 | " \n", 424 | " \n", 425 | " \n", 426 | " \n", 427 | " \n", 428 | " \n", 429 | " \n", 430 | " \n", 431 | " \n", 432 | " \n", 433 | " \n", 434 | " \n", 435 | " \n", 436 | " \n", 437 | " \n", 438 | " \n", 439 | " \n", 440 | " \n", 441 | " \n", 442 | " \n", 443 | " \n", 444 | " \n", 445 | " \n", 446 | " \n", 447 | " \n", 448 | " \n", 449 | " \n", 450 | " \n", 451 | " \n", 452 | " \n", 453 | " \n", 454 | "
pupil_timestampworld_indexeye_idconfidencenorm_pos_xnorm_pos_ydiametermethodellipse_center_xellipse_center_y...circle_3d_normal_zcircle_3d_radiusthetaphiprojected_sphere_center_xprojected_sphere_center_yprojected_sphere_axis_aprojected_sphere_axis_bprojected_sphere_anglepupil_timestamp_unix
0329353.721339010.99926984957630640.5457271663213380.630094475599254450.193099544519883d c++104.7796159336968771.02186068494316...-0.76119913869966533.17005169772325651.4359350164184437-2.265608188206017157.3353788312821384.97669413085066169.9658683385669169.965868338566990.01571931007.2436335
1329353.72249699995000.88219039595412880.47324105759004590.416580552287115347.713854064932333d c++90.86228305728882112.01653396087386...-0.81602148654100843.2494972629903681.6339641684333268-2.184271545863164136.35058824450832105.40722431475041157.8160656718055157.816065671805590.01571931007.2447915
2329353.726346010.99901739376080260.54565518175415260.630194780435396950.324672392304293d c++104.7657948967972971.0026021564038...-0.76101855670391673.17843946868228281.4357167233320438-2.265857229927503157.3353788312821384.97669413085066169.9658683385669169.965868338566990.01571931007.2486405
\n", 455 | "

3 rows × 35 columns

\n", 456 | "
" 457 | ], 458 | "text/plain": [ 459 | " pupil_timestamp world_index eye_id confidence \\\n", 460 | "0 329353.721339 0 1 0.9992698495763064 \n", 461 | "1 329353.72249699995 0 0 0.8821903959541288 \n", 462 | "2 329353.726346 0 1 0.9990173937608026 \n", 463 | "\n", 464 | " norm_pos_x norm_pos_y diameter method \\\n", 465 | "0 0.545727166321338 0.6300944755992544 50.19309954451988 3d c++ \n", 466 | "1 0.4732410575900459 0.4165805522871153 47.71385406493233 3d c++ \n", 467 | "2 0.5456551817541526 0.6301947804353969 50.32467239230429 3d c++ \n", 468 | "\n", 469 | " ellipse_center_x ellipse_center_y ... circle_3d_normal_z \\\n", 470 | "0 104.77961593369687 71.02186068494316 ... -0.7611991386996653 \n", 471 | "1 90.86228305728882 112.01653396087386 ... -0.8160214865410084 \n", 472 | "2 104.76579489679729 71.0026021564038 ... -0.7610185567039167 \n", 473 | "\n", 474 | " circle_3d_radius theta phi \\\n", 475 | "0 3.1700516977232565 1.4359350164184437 -2.265608188206017 \n", 476 | "1 3.249497262990368 1.6339641684333268 -2.184271545863164 \n", 477 | "2 3.1784394686822828 1.4357167233320438 -2.265857229927503 \n", 478 | "\n", 479 | " projected_sphere_center_x projected_sphere_center_y \\\n", 480 | "0 157.33537883128213 84.97669413085066 \n", 481 | "1 136.35058824450832 105.40722431475041 \n", 482 | "2 157.33537883128213 84.97669413085066 \n", 483 | "\n", 484 | " projected_sphere_axis_a projected_sphere_axis_b projected_sphere_angle \\\n", 485 | "0 169.9658683385669 169.9658683385669 90.0 \n", 486 | "1 157.8160656718055 157.8160656718055 90.0 \n", 487 | "2 169.9658683385669 169.9658683385669 90.0 \n", 488 | "\n", 489 | " pupil_timestamp_unix \n", 490 | "0 1571931007.2436335 \n", 491 | "1 1571931007.2447915 \n", 492 | "2 1571931007.2486405 \n", 493 | "\n", 494 | "[3 rows x 35 columns]" 495 | ] 496 | }, 497 | "execution_count": 7, 498 | "metadata": {}, 499 | "output_type": "execute_result" 500 | } 501 | ], 502 | "source": [ 503 | "pupil_positions_df[\"pupil_timestamp_unix\"] = pupil_positions_df[\"pupil_timestamp\"] + start_timestamp_diff\n", 504 | "pupil_positions_df.head(DATAFRAME_HEAD_COUNT)" 505 | ] 506 | }, 507 | { 508 | "cell_type": "code", 509 | "execution_count": 8, 510 | "metadata": {}, 511 | "outputs": [ 512 | { 513 | "data": { 514 | "text/html": [ 515 | "
\n", 516 | "\n", 529 | "\n", 530 | " \n", 531 | " \n", 532 | " \n", 533 | " \n", 534 | " \n", 535 | " \n", 536 | " \n", 537 | " \n", 538 | " \n", 539 | " \n", 540 | " \n", 541 | " \n", 542 | " \n", 543 | " \n", 544 | " \n", 545 | " \n", 546 | " \n", 547 | " \n", 548 | " \n", 549 | " \n", 550 | " \n", 551 | " \n", 552 | " \n", 553 | " \n", 554 | " \n", 555 | " \n", 556 | " \n", 557 | " \n", 558 | " \n", 559 | " \n", 560 | " \n", 561 | " \n", 562 | " \n", 563 | " \n", 564 | " \n", 565 | " \n", 566 | " \n", 567 | " \n", 568 | " \n", 569 | " \n", 570 | " \n", 571 | " \n", 572 | " \n", 573 | " \n", 574 | " \n", 575 | " \n", 576 | " \n", 577 | " \n", 578 | " \n", 579 | " \n", 580 | " \n", 581 | " \n", 582 | " \n", 583 | " \n", 584 | " \n", 585 | " \n", 586 | " \n", 587 | " \n", 588 | " \n", 589 | " \n", 590 | " \n", 591 | " \n", 592 | " \n", 593 | " \n", 594 | " \n", 595 | " \n", 596 | " \n", 597 | " \n", 598 | " \n", 599 | " \n", 600 | " \n", 601 | " \n", 602 | " \n", 603 | " \n", 604 | " \n", 605 | " \n", 606 | " \n", 607 | " \n", 608 | " \n", 609 | " \n", 610 | " \n", 611 | " \n", 612 | " \n", 613 | " \n", 614 | " \n", 615 | " \n", 616 | " \n", 617 | " \n", 618 | " \n", 619 | " \n", 620 | " \n", 621 | " \n", 622 | " \n", 623 | " \n", 624 | " \n", 625 | " \n", 626 | " \n", 627 | " \n", 628 | " \n", 629 | " \n", 630 | "
pupil_timestampworld_indexeye_idconfidencenorm_pos_xnorm_pos_ydiametermethodellipse_center_xellipse_center_y...circle_3d_radiusthetaphiprojected_sphere_center_xprojected_sphere_center_yprojected_sphere_axis_aprojected_sphere_axis_bprojected_sphere_anglepupil_timestamp_unixpupil_timestamp_datetime
0329353.721339010.99926984957630640.5457271663213380.630094475599254450.193099544519883d c++104.7796159336968771.02186068494316...3.17005169772325651.4359350164184437-2.265608188206017157.3353788312821384.97669413085066169.9658683385669169.965868338566990.01571931007.24363352019-10-24 15:30:07.243633509
1329353.72249699995000.88219039595412880.47324105759004590.416580552287115347.713854064932333d c++90.86228305728882112.01653396087386...3.2494972629903681.6339641684333268-2.184271545863164136.35058824450832105.40722431475041157.8160656718055157.816065671805590.01571931007.24479152019-10-24 15:30:07.244791508
2329353.726346010.99901739376080260.54565518175415260.630194780435396950.324672392304293d c++104.7657948967972971.0026021564038...3.17843946868228281.4357167233320438-2.265857229927503157.3353788312821384.97669413085066169.9658683385669169.965868338566990.01571931007.24864052019-10-24 15:30:07.248640537
\n", 631 | "

3 rows × 36 columns

\n", 632 | "
" 633 | ], 634 | "text/plain": [ 635 | " pupil_timestamp world_index eye_id confidence \\\n", 636 | "0 329353.721339 0 1 0.9992698495763064 \n", 637 | "1 329353.72249699995 0 0 0.8821903959541288 \n", 638 | "2 329353.726346 0 1 0.9990173937608026 \n", 639 | "\n", 640 | " norm_pos_x norm_pos_y diameter method \\\n", 641 | "0 0.545727166321338 0.6300944755992544 50.19309954451988 3d c++ \n", 642 | "1 0.4732410575900459 0.4165805522871153 47.71385406493233 3d c++ \n", 643 | "2 0.5456551817541526 0.6301947804353969 50.32467239230429 3d c++ \n", 644 | "\n", 645 | " ellipse_center_x ellipse_center_y ... circle_3d_radius \\\n", 646 | "0 104.77961593369687 71.02186068494316 ... 3.1700516977232565 \n", 647 | "1 90.86228305728882 112.01653396087386 ... 3.249497262990368 \n", 648 | "2 104.76579489679729 71.0026021564038 ... 3.1784394686822828 \n", 649 | "\n", 650 | " theta phi projected_sphere_center_x \\\n", 651 | "0 1.4359350164184437 -2.265608188206017 157.33537883128213 \n", 652 | "1 1.6339641684333268 -2.184271545863164 136.35058824450832 \n", 653 | "2 1.4357167233320438 -2.265857229927503 157.33537883128213 \n", 654 | "\n", 655 | " projected_sphere_center_y projected_sphere_axis_a \\\n", 656 | "0 84.97669413085066 169.9658683385669 \n", 657 | "1 105.40722431475041 157.8160656718055 \n", 658 | "2 84.97669413085066 169.9658683385669 \n", 659 | "\n", 660 | " projected_sphere_axis_b projected_sphere_angle pupil_timestamp_unix \\\n", 661 | "0 169.9658683385669 90.0 1571931007.2436335 \n", 662 | "1 157.8160656718055 90.0 1571931007.2447915 \n", 663 | "2 169.9658683385669 90.0 1571931007.2486405 \n", 664 | "\n", 665 | " pupil_timestamp_datetime \n", 666 | "0 2019-10-24 15:30:07.243633509 \n", 667 | "1 2019-10-24 15:30:07.244791508 \n", 668 | "2 2019-10-24 15:30:07.248640537 \n", 669 | "\n", 670 | "[3 rows x 36 columns]" 671 | ] 672 | }, 673 | "execution_count": 8, 674 | "metadata": {}, 675 | "output_type": "execute_result" 676 | } 677 | ], 678 | "source": [ 679 | "pupil_positions_df[\"pupil_timestamp_datetime\"] = pd.to_datetime(pupil_positions_df[\"pupil_timestamp_unix\"], unit=\"s\")\n", 680 | "pupil_positions_df.head(DATAFRAME_HEAD_COUNT)" 681 | ] 682 | }, 683 | { 684 | "cell_type": "code", 685 | "execution_count": 9, 686 | "metadata": {}, 687 | "outputs": [], 688 | "source": [ 689 | "pupil_positions_df.to_csv(export_dir.joinpath(\"pupil_positions_unix_datetime.csv\"))" 690 | ] 691 | }, 692 | { 693 | "cell_type": "markdown", 694 | "metadata": {}, 695 | "source": [ 696 | "Bellow, the same steps are used to convert and save Unix and datetime timestamps for gaze and fixation data" 697 | ] 698 | }, 699 | { 700 | "cell_type": "markdown", 701 | "metadata": {}, 702 | "source": [ 703 | "## Gaze Positions Timestamps" 704 | ] 705 | }, 706 | { 707 | "cell_type": "code", 708 | "execution_count": 10, 709 | "metadata": {}, 710 | "outputs": [ 711 | { 712 | "data": { 713 | "text/html": [ 714 | "
\n", 715 | "\n", 728 | "\n", 729 | " \n", 730 | " \n", 731 | " \n", 732 | " \n", 733 | " \n", 734 | " \n", 735 | " \n", 736 | " \n", 737 | " \n", 738 | " \n", 739 | " \n", 740 | " \n", 741 | " \n", 742 | " \n", 743 | " \n", 744 | " \n", 745 | " \n", 746 | " \n", 747 | " \n", 748 | " \n", 749 | " \n", 750 | " \n", 751 | " \n", 752 | " \n", 753 | " \n", 754 | " \n", 755 | " \n", 756 | " \n", 757 | " \n", 758 | " \n", 759 | " \n", 760 | " \n", 761 | " \n", 762 | " \n", 763 | " \n", 764 | " \n", 765 | " \n", 766 | " \n", 767 | " \n", 768 | " \n", 769 | " \n", 770 | " \n", 771 | " \n", 772 | " \n", 773 | " \n", 774 | " \n", 775 | " \n", 776 | " \n", 777 | " \n", 778 | " \n", 779 | " \n", 780 | " \n", 781 | " \n", 782 | " \n", 783 | " \n", 784 | " \n", 785 | " \n", 786 | " \n", 787 | " \n", 788 | " \n", 789 | " \n", 790 | " \n", 791 | " \n", 792 | " \n", 793 | " \n", 794 | " \n", 795 | " \n", 796 | " \n", 797 | " \n", 798 | " \n", 799 | " \n", 800 | " \n", 801 | " \n", 802 | " \n", 803 | " \n", 804 | " \n", 805 | " \n", 806 | " \n", 807 | " \n", 808 | " \n", 809 | " \n", 810 | " \n", 811 | " \n", 812 | " \n", 813 | " \n", 814 | " \n", 815 | " \n", 816 | " \n", 817 | " \n", 818 | " \n", 819 | " \n", 820 | " \n", 821 | " \n", 822 | " \n", 823 | " \n", 824 | " \n", 825 | " \n", 826 | " \n", 827 | " \n", 828 | " \n", 829 | "
gaze_timestampworld_indexconfidencenorm_pos_xnorm_pos_ybase_datagaze_point_3d_xgaze_point_3d_ygaze_point_3d_zeye_center0_3d_x...gaze_normal0_ygaze_normal0_zeye_center1_3d_xeye_center1_3d_yeye_center1_3d_zgaze_normal1_xgaze_normal1_ygaze_normal1_zgaze_timestamp_unixgaze_timestamp_datetime
0329353.7219179999700.88219039595412880.46698966175042120.5883357161056366329353.722497-0 329353.721339-1-11.80305702217247-15.088218530226529156.3294341401377217.945315826323466...-0.19314681588063910.9679276177449296-39.4379081617011515.124464001056335-21.5175938287076820.15172623172116334-0.133904369159789070.97931035454937121571931007.24421262019-10-24 15:30:07.244212627
1329353.724421500.88219039595412880.46703389394214310.58843611171472329353.722497-0 329353.726346-1-11.782673101225898-15.09009305597325156.201174417625417.945315826323466...-0.19314681588063910.9679276177449296-39.4379081617011515.124464001056335-21.5175938287076820.15193816728966852-0.134147792295307320.97924417952978021571931007.2467162019-10-24 15:30:07.246716022
2329353.726924500.99870129673880260.46641443650370530.5887387216742821329353.727503-0 329353.726346-1-11.883739759778681-15.070357239116314155.541515309981117.945315826323466...-0.194079562438781740.9675583224652202-39.4379081617011515.124464001056335-21.5175938287076820.15193816728966852-0.134147792295307320.97924417952978021571931007.2492192019-10-24 15:30:07.249218941
\n", 830 | "

3 rows × 23 columns

\n", 831 | "
" 832 | ], 833 | "text/plain": [ 834 | " gaze_timestamp world_index confidence norm_pos_x \\\n", 835 | "0 329353.72191799997 0 0.8821903959541288 0.4669896617504212 \n", 836 | "1 329353.7244215 0 0.8821903959541288 0.4670338939421431 \n", 837 | "2 329353.7269245 0 0.9987012967388026 0.4664144365037053 \n", 838 | "\n", 839 | " norm_pos_y base_data gaze_point_3d_x \\\n", 840 | "0 0.5883357161056366 329353.722497-0 329353.721339-1 -11.80305702217247 \n", 841 | "1 0.58843611171472 329353.722497-0 329353.726346-1 -11.782673101225898 \n", 842 | "2 0.5887387216742821 329353.727503-0 329353.726346-1 -11.883739759778681 \n", 843 | "\n", 844 | " gaze_point_3d_y gaze_point_3d_z eye_center0_3d_x ... \\\n", 845 | "0 -15.088218530226529 156.32943414013772 17.945315826323466 ... \n", 846 | "1 -15.09009305597325 156.2011744176254 17.945315826323466 ... \n", 847 | "2 -15.070357239116314 155.5415153099811 17.945315826323466 ... \n", 848 | "\n", 849 | " gaze_normal0_y gaze_normal0_z eye_center1_3d_x \\\n", 850 | "0 -0.1931468158806391 0.9679276177449296 -39.43790816170115 \n", 851 | "1 -0.1931468158806391 0.9679276177449296 -39.43790816170115 \n", 852 | "2 -0.19407956243878174 0.9675583224652202 -39.43790816170115 \n", 853 | "\n", 854 | " eye_center1_3d_y eye_center1_3d_z gaze_normal1_x \\\n", 855 | "0 15.124464001056335 -21.517593828707682 0.15172623172116334 \n", 856 | "1 15.124464001056335 -21.517593828707682 0.15193816728966852 \n", 857 | "2 15.124464001056335 -21.517593828707682 0.15193816728966852 \n", 858 | "\n", 859 | " gaze_normal1_y gaze_normal1_z gaze_timestamp_unix \\\n", 860 | "0 -0.13390436915978907 0.9793103545493712 1571931007.2442126 \n", 861 | "1 -0.13414779229530732 0.9792441795297802 1571931007.246716 \n", 862 | "2 -0.13414779229530732 0.9792441795297802 1571931007.249219 \n", 863 | "\n", 864 | " gaze_timestamp_datetime \n", 865 | "0 2019-10-24 15:30:07.244212627 \n", 866 | "1 2019-10-24 15:30:07.246716022 \n", 867 | "2 2019-10-24 15:30:07.249218941 \n", 868 | "\n", 869 | "[3 rows x 23 columns]" 870 | ] 871 | }, 872 | "execution_count": 10, 873 | "metadata": {}, 874 | "output_type": "execute_result" 875 | } 876 | ], 877 | "source": [ 878 | "gaze_positions_df = pd.read_csv(export_dir.joinpath(\"gaze_positions.csv\"))\n", 879 | "gaze_positions_df[\"gaze_timestamp_unix\"] = gaze_positions_df[\"gaze_timestamp\"] + start_timestamp_diff\n", 880 | "gaze_positions_df[\"gaze_timestamp_datetime\"] = pd.to_datetime(gaze_positions_df[\"gaze_timestamp_unix\"], unit=\"s\")\n", 881 | "gaze_positions_df.to_csv(export_dir.joinpath(\"gaze_positions_unix_datetime.csv\"))\n", 882 | "gaze_positions_df.head(DATAFRAME_HEAD_COUNT)" 883 | ] 884 | }, 885 | { 886 | "cell_type": "markdown", 887 | "metadata": {}, 888 | "source": [ 889 | "## Fixations Timestamps" 890 | ] 891 | }, 892 | { 893 | "cell_type": "code", 894 | "execution_count": 11, 895 | "metadata": {}, 896 | "outputs": [ 897 | { 898 | "data": { 899 | "text/html": [ 900 | "
\n", 901 | "\n", 914 | "\n", 915 | " \n", 916 | " \n", 917 | " \n", 918 | " \n", 919 | " \n", 920 | " \n", 921 | " \n", 922 | " \n", 923 | " \n", 924 | " \n", 925 | " \n", 926 | " \n", 927 | " \n", 928 | " \n", 929 | " \n", 930 | " \n", 931 | " \n", 932 | " \n", 933 | " \n", 934 | " \n", 935 | " \n", 936 | " \n", 937 | " \n", 938 | " \n", 939 | " \n", 940 | " \n", 941 | " \n", 942 | " \n", 943 | " \n", 944 | " \n", 945 | " \n", 946 | " \n", 947 | " \n", 948 | " \n", 949 | " \n", 950 | " \n", 951 | " \n", 952 | " \n", 953 | " \n", 954 | " \n", 955 | " \n", 956 | " \n", 957 | " \n", 958 | " \n", 959 | " \n", 960 | " \n", 961 | " \n", 962 | " \n", 963 | " \n", 964 | " \n", 965 | " \n", 966 | " \n", 967 | " \n", 968 | " \n", 969 | " \n", 970 | " \n", 971 | " \n", 972 | " \n", 973 | " \n", 974 | " \n", 975 | " \n", 976 | " \n", 977 | " \n", 978 | " \n", 979 | " \n", 980 | " \n", 981 | " \n", 982 | " \n", 983 | " \n", 984 | " \n", 985 | " \n", 986 | " \n", 987 | " \n", 988 | " \n", 989 | " \n", 990 | " \n", 991 | " \n", 992 | " \n", 993 | " \n", 994 | " \n", 995 | "
idstart_timestampdurationstart_frame_indexend_frame_indexnorm_pos_xnorm_pos_ydispersionconfidencemethodgaze_point_3d_xgaze_point_3d_ygaze_point_3d_zbase_datastart_timestamp_unixstart_timestamp_datetime
02329353.6292975217.78349997475743010.46423230256724980.58808295894430631.23886154458879340.96788536808649723d gaze-12.347013257806694-14.903240119408679154.76171455502785329353.6292975 329353.6318005 329353.6343035 3...1571931007.1515922019-10-24 15:30:07.151592016
13329353.84958449996142.6859999774024130.4522013890961780.60085390117134471.00184691247799230.98938626128735713d gaze-15.282994775465676-16.74477203268101154.72124511514812329353.8495845 329353.85208750004 329353.85459...1571931007.3718792019-10-24 15:30:07.371879101
24329354.2400935217.7839999785646810170.44991592686277870.61852097699395351.41327140858490430.94513625251421443d gaze-16.638742114802927-20.200096359756838162.2076645605484329354.2400935 329354.2451 329354.247603 32935...1571931007.7623882019-10-24 15:30:07.762387991
\n", 996 | "
" 997 | ], 998 | "text/plain": [ 999 | " id start_timestamp duration start_frame_index \\\n", 1000 | "0 2 329353.6292975 217.78349997475743 0 \n", 1001 | "1 3 329353.84958449996 142.6859999774024 1 \n", 1002 | "2 4 329354.2400935 217.78399997856468 10 \n", 1003 | "\n", 1004 | " end_frame_index norm_pos_x norm_pos_y dispersion \\\n", 1005 | "0 1 0.4642323025672498 0.5880829589443063 1.2388615445887934 \n", 1006 | "1 3 0.452201389096178 0.6008539011713447 1.0018469124779923 \n", 1007 | "2 17 0.4499159268627787 0.6185209769939535 1.4132714085849043 \n", 1008 | "\n", 1009 | " confidence method gaze_point_3d_x gaze_point_3d_y \\\n", 1010 | "0 0.9678853680864972 3d gaze -12.347013257806694 -14.903240119408679 \n", 1011 | "1 0.9893862612873571 3d gaze -15.282994775465676 -16.74477203268101 \n", 1012 | "2 0.9451362525142144 3d gaze -16.638742114802927 -20.200096359756838 \n", 1013 | "\n", 1014 | " gaze_point_3d_z base_data \\\n", 1015 | "0 154.76171455502785 329353.6292975 329353.6318005 329353.6343035 3... \n", 1016 | "1 154.72124511514812 329353.8495845 329353.85208750004 329353.85459... \n", 1017 | "2 162.2076645605484 329354.2400935 329354.2451 329354.247603 32935... \n", 1018 | "\n", 1019 | " start_timestamp_unix start_timestamp_datetime \n", 1020 | "0 1571931007.151592 2019-10-24 15:30:07.151592016 \n", 1021 | "1 1571931007.371879 2019-10-24 15:30:07.371879101 \n", 1022 | "2 1571931007.762388 2019-10-24 15:30:07.762387991 " 1023 | ] 1024 | }, 1025 | "execution_count": 11, 1026 | "metadata": {}, 1027 | "output_type": "execute_result" 1028 | } 1029 | ], 1030 | "source": [ 1031 | "fixations_df = pd.read_csv(export_dir.joinpath(\"fixations.csv\"))\n", 1032 | "fixations_df[\"start_timestamp_unix\"] = fixations_df[\"start_timestamp\"] + start_timestamp_diff\n", 1033 | "fixations_df[\"start_timestamp_datetime\"] = pd.to_datetime(fixations_df[\"start_timestamp_unix\"], unit=\"s\")\n", 1034 | "fixations_df.to_csv(export_dir.joinpath(\"fixations_unix_datetime.csv\"))\n", 1035 | "fixations_df.head(DATAFRAME_HEAD_COUNT)" 1036 | ] 1037 | }, 1038 | { 1039 | "cell_type": "markdown", 1040 | "metadata": {}, 1041 | "source": [ 1042 | "## Surfaces Timestamps" 1043 | ] 1044 | }, 1045 | { 1046 | "cell_type": "code", 1047 | "execution_count": 12, 1048 | "metadata": {}, 1049 | "outputs": [ 1050 | { 1051 | "data": { 1052 | "text/plain": [ 1053 | "PosixPath('/Users/rom/work/pupil-tutorials/recordings/sample_recording_v2/exports/000/surfaces')" 1054 | ] 1055 | }, 1056 | "execution_count": 12, 1057 | "metadata": {}, 1058 | "output_type": "execute_result" 1059 | } 1060 | ], 1061 | "source": [ 1062 | "surfaces_dir = export_dir.joinpath(\"surfaces\")\n", 1063 | "assert surfaces_dir.is_dir(), \"Please add at least one surface to the export.\"\n", 1064 | "surfaces_dir" 1065 | ] 1066 | }, 1067 | { 1068 | "cell_type": "markdown", 1069 | "metadata": {}, 1070 | "source": [ 1071 | "To aid in converting multiple files, some of which have more than one column with timestamp values, the `convert_and_save_timestamps` function is defined bellow, which replicates the steps previously described." 1072 | ] 1073 | }, 1074 | { 1075 | "cell_type": "code", 1076 | "execution_count": 13, 1077 | "metadata": {}, 1078 | "outputs": [], 1079 | "source": [ 1080 | "def convert_and_save_timestamps(input_path, column_names, timestamp_offset=start_timestamp_diff):\n", 1081 | " \n", 1082 | " output_path = input_path.with_name(input_path.stem + \"_unix_datetime\").with_suffix(input_path.suffix)\n", 1083 | "\n", 1084 | " df = pd.read_csv(input_path)\n", 1085 | "\n", 1086 | " for column_name in column_names:\n", 1087 | " unix_column_name = column_name + \"_unix\"\n", 1088 | " datetime_column_name = column_name + \"_datetime\"\n", 1089 | "\n", 1090 | " df[unix_column_name] = df[column_name] + timestamp_offset\n", 1091 | " df[datetime_column_name] = pd.to_datetime(df[unix_column_name], unit=\"s\")\n", 1092 | "\n", 1093 | " df.to_csv(output_path)\n", 1094 | "\n", 1095 | " return df.head(DATAFRAME_HEAD_COUNT)" 1096 | ] 1097 | }, 1098 | { 1099 | "cell_type": "code", 1100 | "execution_count": 14, 1101 | "metadata": {}, 1102 | "outputs": [ 1103 | { 1104 | "data": { 1105 | "text/html": [ 1106 | "
\n", 1107 | "\n", 1120 | "\n", 1121 | " \n", 1122 | " \n", 1123 | " \n", 1124 | " \n", 1125 | " \n", 1126 | " \n", 1127 | " \n", 1128 | " \n", 1129 | " \n", 1130 | " \n", 1131 | " \n", 1132 | " \n", 1133 | " \n", 1134 | " \n", 1135 | " \n", 1136 | " \n", 1137 | " \n", 1138 | " \n", 1139 | " \n", 1140 | " \n", 1141 | " \n", 1142 | " \n", 1143 | " \n", 1144 | " \n", 1145 | " \n", 1146 | " \n", 1147 | " \n", 1148 | " \n", 1149 | " \n", 1150 | " \n", 1151 | " \n", 1152 | " \n", 1153 | " \n", 1154 | " \n", 1155 | " \n", 1156 | " \n", 1157 | " \n", 1158 | " \n", 1159 | " \n", 1160 | " \n", 1161 | "
world_indexworld_timestampsurface_nameevent_typeworld_timestamp_unixworld_timestamp_datetime
0115329357.774241Coverenter1571931011.29653552019-10-24 15:30:11.296535492
1129329358.243387Coverexit1571931011.76568152019-10-24 15:30:11.765681505
2160329359.282209Coverenter1571931012.80450342019-10-24 15:30:12.804503441
\n", 1162 | "
" 1163 | ], 1164 | "text/plain": [ 1165 | " world_index world_timestamp surface_name event_type world_timestamp_unix \\\n", 1166 | "0 115 329357.774241 Cover enter 1571931011.2965355 \n", 1167 | "1 129 329358.243387 Cover exit 1571931011.7656815 \n", 1168 | "2 160 329359.282209 Cover enter 1571931012.8045034 \n", 1169 | "\n", 1170 | " world_timestamp_datetime \n", 1171 | "0 2019-10-24 15:30:11.296535492 \n", 1172 | "1 2019-10-24 15:30:11.765681505 \n", 1173 | "2 2019-10-24 15:30:12.804503441 " 1174 | ] 1175 | }, 1176 | "execution_count": 14, 1177 | "metadata": {}, 1178 | "output_type": "execute_result" 1179 | } 1180 | ], 1181 | "source": [ 1182 | "convert_and_save_timestamps(\n", 1183 | " input_path=surfaces_dir.joinpath(\"surface_events.csv\"),\n", 1184 | " column_names=[\"world_timestamp\"]\n", 1185 | ")" 1186 | ] 1187 | }, 1188 | { 1189 | "cell_type": "code", 1190 | "execution_count": 15, 1191 | "metadata": {}, 1192 | "outputs": [ 1193 | { 1194 | "data": { 1195 | "text/html": [ 1196 | "
\n", 1197 | "\n", 1210 | "\n", 1211 | " \n", 1212 | " \n", 1213 | " \n", 1214 | " \n", 1215 | " \n", 1216 | " \n", 1217 | " \n", 1218 | " \n", 1219 | " \n", 1220 | " \n", 1221 | " \n", 1222 | " \n", 1223 | " \n", 1224 | " \n", 1225 | " \n", 1226 | " \n", 1227 | " \n", 1228 | " \n", 1229 | " \n", 1230 | " \n", 1231 | " \n", 1232 | " \n", 1233 | " \n", 1234 | " \n", 1235 | " \n", 1236 | " \n", 1237 | " \n", 1238 | " \n", 1239 | " \n", 1240 | " \n", 1241 | " \n", 1242 | " \n", 1243 | " \n", 1244 | " \n", 1245 | " \n", 1246 | " \n", 1247 | " \n", 1248 | " \n", 1249 | " \n", 1250 | " \n", 1251 | " \n", 1252 | " \n", 1253 | " \n", 1254 | " \n", 1255 | " \n", 1256 | " \n", 1257 | " \n", 1258 | " \n", 1259 | " \n", 1260 | " \n", 1261 | " \n", 1262 | " \n", 1263 | "
world_indexworld_timestampimg_to_surf_transsurf_to_img_transnum_detected_markersdist_img_to_surf_transsurf_to_dist_img_transworld_timestamp_unixworld_timestamp_datetime
0115329357.774241[[ 2.63960561e-03 2.58024554e-04 -1.48712940e...[[ 4.32782785e+02 2.29303603e+02 4.93747392e...2[[ 3.02851290e-03 1.94267257e-04 -1.67875971e...[[ 3.65641730e+02 1.45952680e+02 5.10581853e...1571931011.29653552019-10-24 15:30:11.296535492
1116329357.807752[[ 2.61582559e-03 1.98508430e-04 -1.40122220e...[[ 4.35723386e+02 2.11060864e+02 4.81434227e...2[[ 3.02976495e-03 1.12532247e-04 -1.59118345e...[[ 3.59978569e+02 1.28609103e+02 4.99827144e...1571931011.33004642019-10-24 15:30:11.330046415
2117329357.841262[[ 2.61877390e-03 1.73288569e-04 -1.35359237e...[[ 4.32540891e+02 1.99779003e+02 4.69328973e...2[[ 3.06237719e-03 7.00499775e-05 -1.54690935e...[[ 3.49716350e+02 1.17193549e+02 4.89468255e...1571931011.36355662019-10-24 15:30:11.363556623
\n", 1264 | "
" 1265 | ], 1266 | "text/plain": [ 1267 | " world_index world_timestamp \\\n", 1268 | "0 115 329357.774241 \n", 1269 | "1 116 329357.807752 \n", 1270 | "2 117 329357.841262 \n", 1271 | "\n", 1272 | " img_to_surf_trans \\\n", 1273 | "0 [[ 2.63960561e-03 2.58024554e-04 -1.48712940e... \n", 1274 | "1 [[ 2.61582559e-03 1.98508430e-04 -1.40122220e... \n", 1275 | "2 [[ 2.61877390e-03 1.73288569e-04 -1.35359237e... \n", 1276 | "\n", 1277 | " surf_to_img_trans num_detected_markers \\\n", 1278 | "0 [[ 4.32782785e+02 2.29303603e+02 4.93747392e... 2 \n", 1279 | "1 [[ 4.35723386e+02 2.11060864e+02 4.81434227e... 2 \n", 1280 | "2 [[ 4.32540891e+02 1.99779003e+02 4.69328973e... 2 \n", 1281 | "\n", 1282 | " dist_img_to_surf_trans \\\n", 1283 | "0 [[ 3.02851290e-03 1.94267257e-04 -1.67875971e... \n", 1284 | "1 [[ 3.02976495e-03 1.12532247e-04 -1.59118345e... \n", 1285 | "2 [[ 3.06237719e-03 7.00499775e-05 -1.54690935e... \n", 1286 | "\n", 1287 | " surf_to_dist_img_trans world_timestamp_unix \\\n", 1288 | "0 [[ 3.65641730e+02 1.45952680e+02 5.10581853e... 1571931011.2965355 \n", 1289 | "1 [[ 3.59978569e+02 1.28609103e+02 4.99827144e... 1571931011.3300464 \n", 1290 | "2 [[ 3.49716350e+02 1.17193549e+02 4.89468255e... 1571931011.3635566 \n", 1291 | "\n", 1292 | " world_timestamp_datetime \n", 1293 | "0 2019-10-24 15:30:11.296535492 \n", 1294 | "1 2019-10-24 15:30:11.330046415 \n", 1295 | "2 2019-10-24 15:30:11.363556623 " 1296 | ] 1297 | }, 1298 | "execution_count": 15, 1299 | "metadata": {}, 1300 | "output_type": "execute_result" 1301 | } 1302 | ], 1303 | "source": [ 1304 | "convert_and_save_timestamps(\n", 1305 | " input_path=surfaces_dir.joinpath(\"surf_positions_Cover.csv\"),\n", 1306 | " column_names=[\"world_timestamp\"]\n", 1307 | ")" 1308 | ] 1309 | }, 1310 | { 1311 | "cell_type": "code", 1312 | "execution_count": 16, 1313 | "metadata": {}, 1314 | "outputs": [ 1315 | { 1316 | "data": { 1317 | "text/html": [ 1318 | "
\n", 1319 | "\n", 1332 | "\n", 1333 | " \n", 1334 | " \n", 1335 | " \n", 1336 | " \n", 1337 | " \n", 1338 | " \n", 1339 | " \n", 1340 | " \n", 1341 | " \n", 1342 | " \n", 1343 | " \n", 1344 | " \n", 1345 | " \n", 1346 | " \n", 1347 | " \n", 1348 | " \n", 1349 | " \n", 1350 | " \n", 1351 | " \n", 1352 | " \n", 1353 | " \n", 1354 | " \n", 1355 | " \n", 1356 | " \n", 1357 | " \n", 1358 | " \n", 1359 | " \n", 1360 | " \n", 1361 | " \n", 1362 | " \n", 1363 | " \n", 1364 | " \n", 1365 | " \n", 1366 | " \n", 1367 | " \n", 1368 | " \n", 1369 | " \n", 1370 | " \n", 1371 | " \n", 1372 | " \n", 1373 | " \n", 1374 | " \n", 1375 | " \n", 1376 | " \n", 1377 | " \n", 1378 | " \n", 1379 | " \n", 1380 | " \n", 1381 | " \n", 1382 | " \n", 1383 | " \n", 1384 | " \n", 1385 | " \n", 1386 | " \n", 1387 | " \n", 1388 | " \n", 1389 | " \n", 1390 | " \n", 1391 | " \n", 1392 | " \n", 1393 | " \n", 1394 | " \n", 1395 | " \n", 1396 | " \n", 1397 | " \n", 1398 | " \n", 1399 | " \n", 1400 | " \n", 1401 | "
world_timestampworld_indexgaze_timestampx_normy_normx_scaledy_scaledon_surfconfidenceworld_timestamp_unixworld_timestamp_datetimegaze_timestamp_unixgaze_timestamp_datetime
0329357.774241115329357.7577560.74601185321807860.4544361531734466156.6624891757965131.7864844202995True0.45026350286084381571931011.29653552019-10-24 15:30:11.2965354921571931011.28005052019-10-24 15:30:11.280050516
1329357.774241115329357.7616050.20595632493495940.337037771940231343.25082823634147697.74095386266708True0.89693459394862671571931011.29653552019-10-24 15:30:11.2965354921571931011.28389952019-10-24 15:30:11.283899546
2329357.774241115329357.762761999970.71737730503082280.4465508460998535150.64923405647278129.49974536895752True0.49211315272762271571931011.29653552019-10-24 15:30:11.2965354921571931011.28505662019-10-24 15:30:11.285056591
\n", 1402 | "
" 1403 | ], 1404 | "text/plain": [ 1405 | " world_timestamp world_index gaze_timestamp x_norm \\\n", 1406 | "0 329357.774241 115 329357.757756 0.7460118532180786 \n", 1407 | "1 329357.774241 115 329357.761605 0.2059563249349594 \n", 1408 | "2 329357.774241 115 329357.76276199997 0.7173773050308228 \n", 1409 | "\n", 1410 | " y_norm x_scaled y_scaled on_surf \\\n", 1411 | "0 0.4544361531734466 156.6624891757965 131.7864844202995 True \n", 1412 | "1 0.3370377719402313 43.250828236341476 97.74095386266708 True \n", 1413 | "2 0.4465508460998535 150.64923405647278 129.49974536895752 True \n", 1414 | "\n", 1415 | " confidence world_timestamp_unix world_timestamp_datetime \\\n", 1416 | "0 0.4502635028608438 1571931011.2965355 2019-10-24 15:30:11.296535492 \n", 1417 | "1 0.8969345939486267 1571931011.2965355 2019-10-24 15:30:11.296535492 \n", 1418 | "2 0.4921131527276227 1571931011.2965355 2019-10-24 15:30:11.296535492 \n", 1419 | "\n", 1420 | " gaze_timestamp_unix gaze_timestamp_datetime \n", 1421 | "0 1571931011.2800505 2019-10-24 15:30:11.280050516 \n", 1422 | "1 1571931011.2838995 2019-10-24 15:30:11.283899546 \n", 1423 | "2 1571931011.2850566 2019-10-24 15:30:11.285056591 " 1424 | ] 1425 | }, 1426 | "execution_count": 16, 1427 | "metadata": {}, 1428 | "output_type": "execute_result" 1429 | } 1430 | ], 1431 | "source": [ 1432 | "convert_and_save_timestamps(\n", 1433 | " input_path=surfaces_dir.joinpath(\"gaze_positions_on_surface_Cover.csv\"),\n", 1434 | " column_names=[\"world_timestamp\", \"gaze_timestamp\"]\n", 1435 | ")" 1436 | ] 1437 | }, 1438 | { 1439 | "cell_type": "code", 1440 | "execution_count": 17, 1441 | "metadata": {}, 1442 | "outputs": [ 1443 | { 1444 | "data": { 1445 | "text/html": [ 1446 | "
\n", 1447 | "\n", 1460 | "\n", 1461 | " \n", 1462 | " \n", 1463 | " \n", 1464 | " \n", 1465 | " \n", 1466 | " \n", 1467 | " \n", 1468 | " \n", 1469 | " \n", 1470 | " \n", 1471 | " \n", 1472 | " \n", 1473 | " \n", 1474 | " \n", 1475 | " \n", 1476 | " \n", 1477 | " \n", 1478 | " \n", 1479 | " \n", 1480 | " \n", 1481 | " \n", 1482 | " \n", 1483 | " \n", 1484 | " \n", 1485 | " \n", 1486 | " \n", 1487 | " \n", 1488 | " \n", 1489 | " \n", 1490 | " \n", 1491 | " \n", 1492 | " \n", 1493 | " \n", 1494 | " \n", 1495 | " \n", 1496 | " \n", 1497 | " \n", 1498 | " \n", 1499 | " \n", 1500 | " \n", 1501 | " \n", 1502 | " \n", 1503 | " \n", 1504 | " \n", 1505 | " \n", 1506 | " \n", 1507 | " \n", 1508 | " \n", 1509 | " \n", 1510 | " \n", 1511 | " \n", 1512 | " \n", 1513 | " \n", 1514 | " \n", 1515 | " \n", 1516 | " \n", 1517 | " \n", 1518 | " \n", 1519 | " \n", 1520 | " \n", 1521 | " \n", 1522 | " \n", 1523 | " \n", 1524 | " \n", 1525 | " \n", 1526 | " \n", 1527 | " \n", 1528 | " \n", 1529 | " \n", 1530 | " \n", 1531 | " \n", 1532 | " \n", 1533 | " \n", 1534 | " \n", 1535 | " \n", 1536 | " \n", 1537 | "
world_timestampworld_indexfixation_idstart_timestampdurationdispersionnorm_pos_xnorm_pos_yx_scaledy_scaledon_surfworld_timestamp_unixworld_timestamp_datetimestart_timestamp_unixstart_timestamp_datetime
0329357.97530412118329357.97245880.10399999329821.48319849750943990.80569946765899660.93309485912323169.19688820838928270.5975091457367True1571931011.49759842019-10-24 15:30:11.4975984101571931011.49475242019-10-24 15:30:11.494752407
1329358.00881412218329357.97245880.10399999329821.48319849750943990.83560091257095340.9337056279182434175.47619163990018270.7746320962906True1571931011.53110862019-10-24 15:30:11.5311086181571931011.49475242019-10-24 15:30:11.494752407
2329358.04232412318329357.97245880.10399999329821.48319849750943990.86002242565155030.9362438917160034180.6047093868256271.510728597641True1571931011.56461862019-10-24 15:30:11.5646185871571931011.49475242019-10-24 15:30:11.494752407
\n", 1538 | "
" 1539 | ], 1540 | "text/plain": [ 1541 | " world_timestamp world_index fixation_id start_timestamp \\\n", 1542 | "0 329357.975304 121 18 329357.972458 \n", 1543 | "1 329358.008814 122 18 329357.972458 \n", 1544 | "2 329358.042324 123 18 329357.972458 \n", 1545 | "\n", 1546 | " duration dispersion norm_pos_x norm_pos_y \\\n", 1547 | "0 80.1039999932982 1.4831984975094399 0.8056994676589966 0.93309485912323 \n", 1548 | "1 80.1039999932982 1.4831984975094399 0.8356009125709534 0.9337056279182434 \n", 1549 | "2 80.1039999932982 1.4831984975094399 0.8600224256515503 0.9362438917160034 \n", 1550 | "\n", 1551 | " x_scaled y_scaled on_surf world_timestamp_unix \\\n", 1552 | "0 169.19688820838928 270.5975091457367 True 1571931011.4975984 \n", 1553 | "1 175.47619163990018 270.7746320962906 True 1571931011.5311086 \n", 1554 | "2 180.6047093868256 271.510728597641 True 1571931011.5646186 \n", 1555 | "\n", 1556 | " world_timestamp_datetime start_timestamp_unix \\\n", 1557 | "0 2019-10-24 15:30:11.497598410 1571931011.4947524 \n", 1558 | "1 2019-10-24 15:30:11.531108618 1571931011.4947524 \n", 1559 | "2 2019-10-24 15:30:11.564618587 1571931011.4947524 \n", 1560 | "\n", 1561 | " start_timestamp_datetime \n", 1562 | "0 2019-10-24 15:30:11.494752407 \n", 1563 | "1 2019-10-24 15:30:11.494752407 \n", 1564 | "2 2019-10-24 15:30:11.494752407 " 1565 | ] 1566 | }, 1567 | "execution_count": 17, 1568 | "metadata": {}, 1569 | "output_type": "execute_result" 1570 | } 1571 | ], 1572 | "source": [ 1573 | "convert_and_save_timestamps(\n", 1574 | " input_path=surfaces_dir.joinpath(\"fixations_on_surface_Cover.csv\"),\n", 1575 | " column_names=[\"world_timestamp\", \"start_timestamp\"]\n", 1576 | ")" 1577 | ] 1578 | }, 1579 | { 1580 | "cell_type": "code", 1581 | "execution_count": null, 1582 | "metadata": {}, 1583 | "outputs": [], 1584 | "source": [] 1585 | } 1586 | ], 1587 | "metadata": { 1588 | "kernelspec": { 1589 | "display_name": "Python 3", 1590 | "language": "python", 1591 | "name": "python3" 1592 | }, 1593 | "language_info": { 1594 | "codemirror_mode": { 1595 | "name": "ipython", 1596 | "version": 3 1597 | }, 1598 | "file_extension": ".py", 1599 | "mimetype": "text/x-python", 1600 | "name": "python", 1601 | "nbconvert_exporter": "python", 1602 | "pygments_lexer": "ipython3", 1603 | "version": "3.6.10" 1604 | } 1605 | }, 1606 | "nbformat": 4, 1607 | "nbformat_minor": 4 1608 | } 1609 | -------------------------------------------------------------------------------- /10_merge_fixation_and_blink_ids_into_gaze_dataframe.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Tutorial 10 - Merge fixation and blink ids into gaze dataframe\n", 8 | "\n", 9 | "The goal of this tutorial is to teach you how to merge fixation, blink, and gaze data\n", 10 | "into one dataframe. The result will allow you to quickly find or filter gaze samples\n", 11 | "that belong to fixations and/or blinks.\n", 12 | "\n", 13 | "We will follow these steps:\n", 14 | "1. Load the data using `Pandas`\n", 15 | "1. For each fixation and blink, find and annotate the corresponding gaze data\n", 16 | " 1. Select the start and end timestamp of the corresponding detection\n", 17 | " 1. Find all gaze samples whose timestamps fall into that period\n", 18 | " 1. Mark these gaze samples accordingly\n", 19 | "1. Visualize the resulting dataframe\n", 20 | "\n", 21 | "Please check the documentation of [Pupil Player](https://docs.pupil-labs.com/core/software/pupil-player/#pupil-player)\n", 22 | "on how to detect blinks and fixations and how to export data.\n", 23 | "\n", 24 | "This notebook is accompanied by a short example export. You can find it in the\n", 25 | "`data/10_merge_fixation_and_blink_ids_into_gaze_dataframe/` subfolder which contains the\n", 26 | "three files that are important for this tutorial:\n", 27 | "\n", 28 | "- `gaze_positions.csv`\n", 29 | "- `blinks.csv`\n", 30 | "- `fixations.csv`\n", 31 | "\n", 32 | "## 1 - Loading Exported Data\n", 33 | "Let's start by importing the necessary Python modules and loading the exported data." 34 | ] 35 | }, 36 | { 37 | "cell_type": "code", 38 | "execution_count": 6, 39 | "metadata": {}, 40 | "outputs": [], 41 | "source": [ 42 | "import pandas as pd\n" 43 | ] 44 | }, 45 | { 46 | "cell_type": "code", 47 | "execution_count": 7, 48 | "metadata": {}, 49 | "outputs": [], 50 | "source": [ 51 | "export_folder = \"data/10_merge_fixation_and_blink_ids_into_gaze_dataframe/\"\n", 52 | "gaze = pd.read_csv(export_folder + \"gaze_positions.csv\")\n", 53 | "blinks = pd.read_csv(export_folder + \"blinks.csv\")\n", 54 | "fixations = pd.read_csv(export_folder + \"fixations.csv\")\n" 55 | ] 56 | }, 57 | { 58 | "cell_type": "markdown", 59 | "metadata": {}, 60 | "source": [ 61 | "### Gaze data\n", 62 | "\n", 63 | "You can find information on how the exported gaze data looks like in our previous tutorials.\n", 64 | "Below, we only preview the data that is necessary for the blink and fixation matching:\n", 65 | "The `gaze_timestamp` field." 66 | ] 67 | }, 68 | { 69 | "cell_type": "code", 70 | "execution_count": 8, 71 | "metadata": {}, 72 | "outputs": [ 73 | { 74 | "data": { 75 | "text/plain": [ 76 | "0 329367.897894\n", 77 | "1 329367.905404\n", 78 | "2 329367.907907\n", 79 | "Name: gaze_timestamp, dtype: float64" 80 | ] 81 | }, 82 | "execution_count": 8, 83 | "metadata": {}, 84 | "output_type": "execute_result" 85 | } 86 | ], 87 | "source": [ 88 | "gaze[\"gaze_timestamp\"].head(3) # .head(n): only display the first n entries\n" 89 | ] 90 | }, 91 | { 92 | "cell_type": "markdown", 93 | "metadata": {}, 94 | "source": [ 95 | "### Blink data\n", 96 | "\n", 97 | "The exported section contains three blinks of which we will need the `id`,\n", 98 | "`start_timestamp`, and `end_timestamp`.\n", 99 | "\n", 100 | "**Note**: The blink ids do not start at 0 or 1 because the exported data only represents\n", 101 | "a short slice of a longer recording." 102 | ] 103 | }, 104 | { 105 | "cell_type": "code", 106 | "execution_count": 9, 107 | "metadata": {}, 108 | "outputs": [ 109 | { 110 | "data": { 111 | "text/html": [ 112 | "
\n", 113 | "\n", 126 | "\n", 127 | " \n", 128 | " \n", 129 | " \n", 130 | " \n", 131 | " \n", 132 | " \n", 133 | " \n", 134 | " \n", 135 | " \n", 136 | " \n", 137 | " \n", 138 | " \n", 139 | " \n", 140 | " \n", 141 | " \n", 142 | " \n", 143 | " \n", 144 | " \n", 145 | " \n", 146 | " \n", 147 | " \n", 148 | " \n", 149 | " \n", 150 | " \n", 151 | " \n", 152 | " \n", 153 | " \n", 154 | " \n", 155 | "
idstart_timestampend_timestamp
05329368.551824329368.927313
16329372.045221329372.495808
27329373.668492329374.104060
\n", 156 | "
" 157 | ], 158 | "text/plain": [ 159 | " id start_timestamp end_timestamp\n", 160 | "0 5 329368.551824 329368.927313\n", 161 | "1 6 329372.045221 329372.495808\n", 162 | "2 7 329373.668492 329374.104060" 163 | ] 164 | }, 165 | "execution_count": 9, 166 | "metadata": {}, 167 | "output_type": "execute_result" 168 | } 169 | ], 170 | "source": [ 171 | "blinks[[\"id\", \"start_timestamp\", \"end_timestamp\"]] # only display the desired columns\n" 172 | ] 173 | }, 174 | { 175 | "cell_type": "markdown", 176 | "metadata": {}, 177 | "source": [ 178 | "### Fixation data\n", 179 | "\n", 180 | "In contrast to the blinks, the exported fixations do not have an `end_timestamp` field.\n", 181 | "We can calculate the corresponding values by summing the `start_timestamp` and `duration`\n", 182 | "values.\n", 183 | "\n", 184 | "**Note**: `duration` is in milliseconds." 185 | ] 186 | }, 187 | { 188 | "cell_type": "code", 189 | "execution_count": 10, 190 | "metadata": {}, 191 | "outputs": [ 192 | { 193 | "data": { 194 | "text/html": [ 195 | "
\n", 196 | "\n", 209 | "\n", 210 | " \n", 211 | " \n", 212 | " \n", 213 | " \n", 214 | " \n", 215 | " \n", 216 | " \n", 217 | " \n", 218 | " \n", 219 | " \n", 220 | " \n", 221 | " \n", 222 | " \n", 223 | " \n", 224 | " \n", 225 | " \n", 226 | " \n", 227 | " \n", 228 | " \n", 229 | " \n", 230 | " \n", 231 | " \n", 232 | " \n", 233 | " \n", 234 | " \n", 235 | " \n", 236 | " \n", 237 | " \n", 238 | "
idstart_timestampduration
065329367.872861202.7645
166329368.078129172.7250
267329368.308429172.7250
\n", 239 | "
" 240 | ], 241 | "text/plain": [ 242 | " id start_timestamp duration\n", 243 | "0 65 329367.872861 202.7645\n", 244 | "1 66 329368.078129 172.7250\n", 245 | "2 67 329368.308429 172.7250" 246 | ] 247 | }, 248 | "execution_count": 10, 249 | "metadata": {}, 250 | "output_type": "execute_result" 251 | } 252 | ], 253 | "source": [ 254 | "fixations[[\"id\", \"start_timestamp\", \"duration\"]].head(3)\n" 255 | ] 256 | }, 257 | { 258 | "cell_type": "code", 259 | "execution_count": 11, 260 | "metadata": {}, 261 | "outputs": [ 262 | { 263 | "data": { 264 | "text/html": [ 265 | "
\n", 266 | "\n", 279 | "\n", 280 | " \n", 281 | " \n", 282 | " \n", 283 | " \n", 284 | " \n", 285 | " \n", 286 | " \n", 287 | " \n", 288 | " \n", 289 | " \n", 290 | " \n", 291 | " \n", 292 | " \n", 293 | " \n", 294 | " \n", 295 | " \n", 296 | " \n", 297 | " \n", 298 | " \n", 299 | " \n", 300 | " \n", 301 | " \n", 302 | " \n", 303 | " \n", 304 | " \n", 305 | " \n", 306 | " \n", 307 | " \n", 308 | "
idstart_timestampend_timestamp
065329367.872861329368.075625
166329368.078129329368.250853
267329368.308429329368.481154
\n", 309 | "
" 310 | ], 311 | "text/plain": [ 312 | " id start_timestamp end_timestamp\n", 313 | "0 65 329367.872861 329368.075625\n", 314 | "1 66 329368.078129 329368.250853\n", 315 | "2 67 329368.308429 329368.481154" 316 | ] 317 | }, 318 | "execution_count": 11, 319 | "metadata": {}, 320 | "output_type": "execute_result" 321 | } 322 | ], 323 | "source": [ 324 | "fixations[\"end_timestamp\"] = fixations.start_timestamp + fixations.duration / 1_000\n", 325 | "\n", 326 | "fixations[[\"id\", \"start_timestamp\", \"end_timestamp\"]].head(3) # display result\n" 327 | ] 328 | }, 329 | { 330 | "cell_type": "markdown", 331 | "metadata": {}, 332 | "source": [ 333 | "## 2 - Find gaze data for each fixation and blink\n", 334 | "\n", 335 | "We will save the matching blink and fixation ids for each gaze sample in a dedicated\n", 336 | "column. To start, we set this column to `None` to indicate that the samples are neither\n", 337 | "a blink nor a fixation." 338 | ] 339 | }, 340 | { 341 | "cell_type": "code", 342 | "execution_count": 12, 343 | "metadata": {}, 344 | "outputs": [], 345 | "source": [ 346 | "gaze[\"blink_id\"] = None\n", 347 | "gaze[\"fixation_id\"] = None\n" 348 | ] 349 | }, 350 | { 351 | "cell_type": "markdown", 352 | "metadata": {}, 353 | "source": [ 354 | "Next, we iterate over all blinks and fixations, extract their start and end timestamps,\n", 355 | "and find the corresponding gaze samples.\n", 356 | "\n", 357 | "For this, we use [`pandas.Series.between()`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.between.html)." 358 | ] 359 | }, 360 | { 361 | "cell_type": "code", 362 | "execution_count": 13, 363 | "metadata": {}, 364 | "outputs": [ 365 | { 366 | "name": "stdout", 367 | "output_type": "stream", 368 | "text": [ 369 | "Found 124 gaze samples for blink 5\n", 370 | "Found 121 gaze samples for blink 6\n", 371 | "Found 117 gaze samples for blink 7\n" 372 | ] 373 | } 374 | ], 375 | "source": [ 376 | "for blink in blinks.itertuples():\n", 377 | " # https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.between.html\n", 378 | " # Return boolean Series equivalent to left <= series <= right.\n", 379 | " # `found_sample_mask` has the size as `gaze` and is True for all gaze samples\n", 380 | " # whose `gaze_timestamp` lies between the blink start end end time.\n", 381 | " found_sample_mask = gaze.gaze_timestamp.between(\n", 382 | " blink.start_timestamp, blink.end_timestamp\n", 383 | " )\n", 384 | " gaze.loc[found_sample_mask, \"blink_id\"] = blink.id\n", 385 | "\n", 386 | " # To count the found samples, we sum the boolean values (True = 1, False = 0).\n", 387 | " num_samples = found_sample_mask.sum()\n", 388 | " print(f\"Found {num_samples} gaze samples for blink {blink.id}\")\n" 389 | ] 390 | }, 391 | { 392 | "cell_type": "code", 393 | "execution_count": 14, 394 | "metadata": {}, 395 | "outputs": [], 396 | "source": [ 397 | "for fixation in fixations.itertuples():\n", 398 | " # Here we repeat the procedure\n", 399 | " found_sample_mask = gaze.gaze_timestamp.between(\n", 400 | " fixation.start_timestamp, fixation.end_timestamp\n", 401 | " )\n", 402 | " gaze.loc[found_sample_mask, \"fixation_id\"] = fixation.id\n" 403 | ] 404 | }, 405 | { 406 | "cell_type": "markdown", 407 | "metadata": {}, 408 | "source": [ 409 | "## 3 - Visualize results\n", 410 | "\n", 411 | "To keep the example clear, we only display a subset of the available gaze dataframe\n", 412 | "columns, including the new `blink_id` and `fixation_id` columns." 413 | ] 414 | }, 415 | { 416 | "cell_type": "code", 417 | "execution_count": 16, 418 | "metadata": {}, 419 | "outputs": [ 420 | { 421 | "data": { 422 | "text/html": [ 423 | "
\n", 424 | "\n", 437 | "\n", 438 | " \n", 439 | " \n", 440 | " \n", 441 | " \n", 442 | " \n", 443 | " \n", 444 | " \n", 445 | " \n", 446 | " \n", 447 | " \n", 448 | " \n", 449 | " \n", 450 | " \n", 451 | " \n", 452 | " \n", 453 | " \n", 454 | " \n", 455 | " \n", 456 | " \n", 457 | " \n", 458 | " \n", 459 | " \n", 460 | " \n", 461 | " \n", 462 | " \n", 463 | " \n", 464 | " \n", 465 | " \n", 466 | " \n", 467 | " \n", 468 | " \n", 469 | " \n", 470 | " \n", 471 | " \n", 472 | " \n", 473 | " \n", 474 | " \n", 475 | " \n", 476 | " \n", 477 | " \n", 478 | " \n", 479 | " \n", 480 | " \n", 481 | " \n", 482 | " \n", 483 | " \n", 484 | " \n", 485 | " \n", 486 | " \n", 487 | " \n", 488 | " \n", 489 | " \n", 490 | " \n", 491 | " \n", 492 | " \n", 493 | " \n", 494 | " \n", 495 | " \n", 496 | " \n", 497 | " \n", 498 | " \n", 499 | " \n", 500 | " \n", 501 | " \n", 502 | " \n", 503 | " \n", 504 | " \n", 505 | " \n", 506 | " \n", 507 | " \n", 508 | " \n", 509 | " \n", 510 | " \n", 511 | " \n", 512 | " \n", 513 | " \n", 514 | " \n", 515 | " \n", 516 | " \n", 517 | " \n", 518 | " \n", 519 | " \n", 520 | " \n", 521 | " \n", 522 | " \n", 523 | " \n", 524 | " \n", 525 | " \n", 526 | " \n", 527 | " \n", 528 | " \n", 529 | " \n", 530 | " \n", 531 | " \n", 532 | " \n", 533 | " \n", 534 | " \n", 535 | " \n", 536 | " \n", 537 | " \n", 538 | " \n", 539 | " \n", 540 | " \n", 541 | " \n", 542 | " \n", 543 | " \n", 544 | " \n", 545 | " \n", 546 | " \n", 547 | " \n", 548 | " \n", 549 | " \n", 550 | "
gaze_timestampconfidencenorm_pos_xnorm_pos_yblink_idfixation_id
0329367.8978940.9800580.5010130.489436None65
1329367.9054040.9964930.5006260.489527None65
2329367.9079070.9964930.5005970.490593None65
3329367.9104100.9977560.5012190.491356None65
4329367.9154170.9977560.5014310.490214None65
.....................
2049329374.8149870.2813570.3999560.300403None100
2050329374.8169110.7520560.4364520.308474None100
2051329374.8199930.3728580.4116410.329027None100
2052329374.8250000.4240300.4021460.330951None100
2053329374.8300060.4075850.4090450.330038None100
\n", 551 | "

2054 rows × 6 columns

\n", 552 | "
" 553 | ], 554 | "text/plain": [ 555 | " gaze_timestamp confidence norm_pos_x norm_pos_y blink_id fixation_id\n", 556 | "0 329367.897894 0.980058 0.501013 0.489436 None 65\n", 557 | "1 329367.905404 0.996493 0.500626 0.489527 None 65\n", 558 | "2 329367.907907 0.996493 0.500597 0.490593 None 65\n", 559 | "3 329367.910410 0.997756 0.501219 0.491356 None 65\n", 560 | "4 329367.915417 0.997756 0.501431 0.490214 None 65\n", 561 | "... ... ... ... ... ... ...\n", 562 | "2049 329374.814987 0.281357 0.399956 0.300403 None 100\n", 563 | "2050 329374.816911 0.752056 0.436452 0.308474 None 100\n", 564 | "2051 329374.819993 0.372858 0.411641 0.329027 None 100\n", 565 | "2052 329374.825000 0.424030 0.402146 0.330951 None 100\n", 566 | "2053 329374.830006 0.407585 0.409045 0.330038 None 100\n", 567 | "\n", 568 | "[2054 rows x 6 columns]" 569 | ] 570 | }, 571 | "execution_count": 16, 572 | "metadata": {}, 573 | "output_type": "execute_result" 574 | } 575 | ], 576 | "source": [ 577 | "gaze[\n", 578 | " [\n", 579 | " \"gaze_timestamp\",\n", 580 | " \"confidence\",\n", 581 | " \"norm_pos_x\",\n", 582 | " \"norm_pos_y\",\n", 583 | " \"blink_id\",\n", 584 | " \"fixation_id\",\n", 585 | " ]\n", 586 | "]\n" 587 | ] 588 | }, 589 | { 590 | "cell_type": "code", 591 | "execution_count": null, 592 | "metadata": {}, 593 | "outputs": [], 594 | "source": [] 595 | } 596 | ], 597 | "metadata": { 598 | "interpreter": { 599 | "hash": "949d465c8a19e81b16f08f10c49754b1fda564991086691d4389bb1865107ba8" 600 | }, 601 | "kernelspec": { 602 | "display_name": "Python 3.9.7 ('.venv39': venv)", 603 | "language": "python", 604 | "name": "python3" 605 | }, 606 | "language_info": { 607 | "codemirror_mode": { 608 | "name": "ipython", 609 | "version": 3 610 | }, 611 | "file_extension": ".py", 612 | "mimetype": "text/x-python", 613 | "name": "python", 614 | "nbconvert_exporter": "python", 615 | "pygments_lexer": "ipython3", 616 | "version": "3.9.7" 617 | }, 618 | "orig_nbformat": 4 619 | }, 620 | "nbformat": 4, 621 | "nbformat_minor": 2 622 | } 623 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 3, 29 June 2007 3 | 4 | Copyright (C) 2007 Free Software Foundation, Inc. 5 | Everyone is permitted to copy and distribute verbatim copies 6 | of this license document, but changing it is not allowed. 7 | 8 | 9 | This version of the GNU Lesser General Public License incorporates 10 | the terms and conditions of version 3 of the GNU General Public 11 | License, supplemented by the additional permissions listed below. 12 | 13 | 0. Additional Definitions. 14 | 15 | As used herein, "this License" refers to version 3 of the GNU Lesser 16 | General Public License, and the "GNU GPL" refers to version 3 of the GNU 17 | General Public License. 18 | 19 | "The Library" refers to a covered work governed by this License, 20 | other than an Application or a Combined Work as defined below. 21 | 22 | An "Application" is any work that makes use of an interface provided 23 | by the Library, but which is not otherwise based on the Library. 24 | Defining a subclass of a class defined by the Library is deemed a mode 25 | of using an interface provided by the Library. 26 | 27 | A "Combined Work" is a work produced by combining or linking an 28 | Application with the Library. The particular version of the Library 29 | with which the Combined Work was made is also called the "Linked 30 | Version". 31 | 32 | The "Minimal Corresponding Source" for a Combined Work means the 33 | Corresponding Source for the Combined Work, excluding any source code 34 | for portions of the Combined Work that, considered in isolation, are 35 | based on the Application, and not on the Linked Version. 36 | 37 | The "Corresponding Application Code" for a Combined Work means the 38 | object code and/or source code for the Application, including any data 39 | and utility programs needed for reproducing the Combined Work from the 40 | Application, but excluding the System Libraries of the Combined Work. 41 | 42 | 1. Exception to Section 3 of the GNU GPL. 43 | 44 | You may convey a covered work under sections 3 and 4 of this License 45 | without being bound by section 3 of the GNU GPL. 46 | 47 | 2. Conveying Modified Versions. 48 | 49 | If you modify a copy of the Library, and, in your modifications, a 50 | facility refers to a function or data to be supplied by an Application 51 | that uses the facility (other than as an argument passed when the 52 | facility is invoked), then you may convey a copy of the modified 53 | version: 54 | 55 | a) under this License, provided that you make a good faith effort to 56 | ensure that, in the event an Application does not supply the 57 | function or data, the facility still operates, and performs 58 | whatever part of its purpose remains meaningful, or 59 | 60 | b) under the GNU GPL, with none of the additional permissions of 61 | this License applicable to that copy. 62 | 63 | 3. Object Code Incorporating Material from Library Header Files. 64 | 65 | The object code form of an Application may incorporate material from 66 | a header file that is part of the Library. You may convey such object 67 | code under terms of your choice, provided that, if the incorporated 68 | material is not limited to numerical parameters, data structure 69 | layouts and accessors, or small macros, inline functions and templates 70 | (ten or fewer lines in length), you do both of the following: 71 | 72 | a) Give prominent notice with each copy of the object code that the 73 | Library is used in it and that the Library and its use are 74 | covered by this License. 75 | 76 | b) Accompany the object code with a copy of the GNU GPL and this license 77 | document. 78 | 79 | 4. Combined Works. 80 | 81 | You may convey a Combined Work under terms of your choice that, 82 | taken together, effectively do not restrict modification of the 83 | portions of the Library contained in the Combined Work and reverse 84 | engineering for debugging such modifications, if you also do each of 85 | the following: 86 | 87 | a) Give prominent notice with each copy of the Combined Work that 88 | the Library is used in it and that the Library and its use are 89 | covered by this License. 90 | 91 | b) Accompany the Combined Work with a copy of the GNU GPL and this license 92 | document. 93 | 94 | c) For a Combined Work that displays copyright notices during 95 | execution, include the copyright notice for the Library among 96 | these notices, as well as a reference directing the user to the 97 | copies of the GNU GPL and this license document. 98 | 99 | d) Do one of the following: 100 | 101 | 0) Convey the Minimal Corresponding Source under the terms of this 102 | License, and the Corresponding Application Code in a form 103 | suitable for, and under terms that permit, the user to 104 | recombine or relink the Application with a modified version of 105 | the Linked Version to produce a modified Combined Work, in the 106 | manner specified by section 6 of the GNU GPL for conveying 107 | Corresponding Source. 108 | 109 | 1) Use a suitable shared library mechanism for linking with the 110 | Library. A suitable mechanism is one that (a) uses at run time 111 | a copy of the Library already present on the user's computer 112 | system, and (b) will operate properly with a modified version 113 | of the Library that is interface-compatible with the Linked 114 | Version. 115 | 116 | e) Provide Installation Information, but only if you would otherwise 117 | be required to provide such information under section 6 of the 118 | GNU GPL, and only to the extent that such information is 119 | necessary to install and execute a modified version of the 120 | Combined Work produced by recombining or relinking the 121 | Application with a modified version of the Linked Version. (If 122 | you use option 4d0, the Installation Information must accompany 123 | the Minimal Corresponding Source and Corresponding Application 124 | Code. If you use option 4d1, you must provide the Installation 125 | Information in the manner specified by section 6 of the GNU GPL 126 | for conveying Corresponding Source.) 127 | 128 | 5. Combined Libraries. 129 | 130 | You may place library facilities that are a work based on the 131 | Library side by side in a single library together with other library 132 | facilities that are not Applications and are not covered by this 133 | License, and convey such a combined library under terms of your 134 | choice, if you do both of the following: 135 | 136 | a) Accompany the combined library with a copy of the same work based 137 | on the Library, uncombined with any other library facilities, 138 | conveyed under the terms of this License. 139 | 140 | b) Give prominent notice with the combined library that part of it 141 | is a work based on the Library, and explaining where to find the 142 | accompanying uncombined form of the same work. 143 | 144 | 6. Revised Versions of the GNU Lesser General Public License. 145 | 146 | The Free Software Foundation may publish revised and/or new versions 147 | of the GNU Lesser General Public License from time to time. Such new 148 | versions will be similar in spirit to the present version, but may 149 | differ in detail to address new problems or concerns. 150 | 151 | Each version is given a distinguishing version number. If the 152 | Library as you received it specifies that a certain numbered version 153 | of the GNU Lesser General Public License "or any later version" 154 | applies to it, you have the option of following the terms and 155 | conditions either of that published version or of any later version 156 | published by the Free Software Foundation. If the Library as you 157 | received it does not specify a version number of the GNU Lesser 158 | General Public License, you may choose any version of the GNU Lesser 159 | General Public License ever published by the Free Software Foundation. 160 | 161 | If the Library as you received it specifies that a proxy can decide 162 | whether future versions of the GNU Lesser General Public License shall 163 | apply, that proxy's public statement of acceptance of any version is 164 | permanent authorization for you to choose that version for the 165 | Library. 166 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # pupil-tutorials 2 | 3 | A series of Jupyter notebooks that demonstrate how to visualize and analyze [Pupil Labs](https://pupil-labs.com) eye tracking data. 4 | 5 | These tutorials assume that you already have a working understanding of Pupil hardware and software, and are looking to perform deeper analysis with a few lines of code. 6 | 7 | For an introduction to Pupil and detailed descriptoin of data formats please refer to [Pupil docs](https://docs.pupil-labs.com). 8 | 9 | To install all required dependencies, run 10 | ``` 11 | pip install -r requirements-all-tutorials.txt 12 | ``` 13 | in your Python environment. -------------------------------------------------------------------------------- /data/10_merge_fixation_and_blink_ids_into_gaze_dataframe/blinks.csv: -------------------------------------------------------------------------------- 1 | id,start_timestamp,duration,end_timestamp,start_frame_index,index,end_frame_index,confidence,filter_response,base_data 2 | 5,329368.551824,0.37548899999819696,329368.927313,437,442,448,0.4168608524575816,0.5142445885512759 0.5347724803758699 0.5695129354636452 0.5979711747689334 0.6351770222089482 0.6613698573379826 0.6967064263065605 0.7165702673231242 0.7539894345946968 0.783339635597582 0.8212530991628011 0.8551766826050753 0.8881774517375904 0.9217356959909595 0.950832438817726 0.968571552795045 0.9483311658286958 0.9335652260966034 0.908109861293254 0.8673557406817426 0.8303684086263663 0.7896304216935233 0.7493339816971479 0.7147739742485629 0.6747032796806564 0.6442711744893681 0.6682259064282124 0.6335223082728985 0.5920084516737026 0.5500876299582707 0.5095533115439362 0.46937596207561555 0.4201281005760935 0.40289984104042653 0.3560610059283195 0.32857471386798454 0.2797561891746213 0.2576222014707967 0.2114258615276213 0.19175562448207253 0.14582554245443738 0.11589185523955782 0.04699514045755384 0.009775049335560827 -0.05158411032900402 -0.08874778765179647 -0.14704768514669406 -0.17435144094763694 -0.20614613032378848 -0.21187088853133831 -0.24999891595722454 -0.24074192068563618 -0.2648921944179201 -0.2575331181043382 -0.2759820807718819 -0.2798253308237342 -0.3003651960259585 -0.3055441399802634 -0.3594209895190244 -0.36483661371008225 -0.3786145435299896 -0.34247480886481296 -0.36374452684827524 -0.3413331326922833 -0.34491236402713443 -0.34967474825488903 -0.3578190189764207 -0.35705987024986746 -0.3616347336260174 -0.367954263743558 -0.3764119905112029 -0.40074129208072934 -0.4093864726766169 -0.4290331792618597 -0.39326855083602585 -0.4094377807499916 -0.38418400326586827 -0.3920990973421385 -0.361575890145214 -0.3845514686889444 -0.3597981522897958 -0.3880205810891138 -0.35071562192939504 -0.37892082656207593 -0.35696181349525186 -0.38645616742618916 -0.3657508669145882 -0.38615452828255364 -0.3623684697065985 -0.38477396367522576 -0.3530771245398155 -0.3687702414721991 -0.3540685633849341 -0.40021091747388937 -0.3676735643882173 -0.4080127805090381 -0.386009989514211 -0.4144648204530261 -0.3894757367605612 -0.41352505964266156 -0.3961292906419114 -0.41410398306868235 -0.397461528120552 -0.3797524245930452 -0.3635301347798591 -0.34335852917332477 -0.3380669382593626 -0.32735506342563103 -0.31656015317430863 -0.3221653456911887 -0.32150836690470946 -0.3037310969194579 -0.29650364898336584 -0.2749951795352306 -0.28092790659019135 -0.2562172071599822 -0.24989305070370743 -0.21757556485048224 -0.19785262273784632 -0.17534972520199796 -0.170044106499935 -0.1249581455023038 -0.134658800119962 -0.1087081498141489,329368.551824 329368.555673 329368.55683 329368.560679 329368.561837 329368.565686 329368.566843 329368.570692 329368.57185 329368.575699 329368.576856 329368.580706 329368.591876 329368.595725 329368.600732 329368.610745 329368.611902 329368.615751 329368.625764 329368.626922 329368.635777 329368.640784 329368.641941 329368.650797 329368.651954 329368.655803 329368.656961 329368.661967 329368.665816 329368.666974 329368.675829 329368.676987 329368.680836 329368.681993 329368.690849 329368.692007 329368.695856 329368.697013 329368.700862 329368.70202 329368.710875 329368.712033 329368.715882 329368.717039 329368.720888 329368.722046 329368.725895 329368.727052 329368.732059 329368.735908 329368.737065 329368.740914 329368.742072 329368.747078 329368.750927 329368.752085 329368.755934 329368.757091 329368.76094 329368.762098 329368.765947 329368.767104 329368.770953 329368.77596 329368.777117 329368.780967 329368.782124 329368.785973 329368.787131 329368.79098 329368.792137 329368.795986 329368.797144 329368.800993 329368.80215 329368.805999 329368.807157 329368.811006 329368.812163 329368.816012 329368.81717 329368.821019 329368.822176 329368.826025 329368.827183 329368.831032 329368.832189 329368.836038 329368.837196 329368.841045 329368.842202 329368.846051 329368.847209 329368.851058 329368.852215 329368.856064 329368.857222 329368.861071 329368.862228 329368.866077 329368.867235 329368.871084 329368.872241 329368.87609 329368.877248 329368.881097 329368.882254 329368.886104 329368.887261 329368.89111 329368.892268 329368.896117 329368.897274 329368.901123 329368.902281 329368.90613 329368.907287 329368.911136 329368.912294 329368.916143 329368.9173 329368.921149 329368.922307 329368.926156 3 | 6,329372.045221,0.45058699999935925,329372.495808,541,548,555,0.45743682036105004,0.5098978897935281 0.544633599649856 0.5791216470287845 0.6138809868645024 0.6441490402442126 0.6788395155343551 0.7135426746563128 0.7445565366940177 0.7743512240602997 0.8090740477560209 0.8404939732595138 0.873018056605691 0.9060951875154251 0.9374609323751538 0.9637764808255977 0.9829810499463683 0.989127085110953 0.9944545108502345 0.9740909359950021 0.9649047571912238 0.950061792073822 0.9146473273641019 0.8823484492836098 0.8427340734977719 0.8006339032694699 0.760057692588245 0.7192548495250553 0.6827221322451371 0.6412520020655685 0.6047099064491442 0.5634201527927959 0.5256288297797853 0.4856380567927348 0.4487819768353085 0.4078061309179715 0.3723743794571904 0.3415129729148696 0.3023738253547203 0.26379659039869796 0.23218462937938972 0.20367697001062757 0.16527580972640613 0.13428075618548274 0.09722914645950463 0.06337951265512043 0.03186499827435256 0.0023758259740180396 -0.021023748923397763 -0.0635473244319013 -0.08219800276863685 -0.11302101311883997 -0.12002695167047947 -0.12676690531127144 -0.1490079590466903 -0.14587795652674593 -0.16997532059626463 -0.15579395477509114 -0.14719599444868858 -0.13798958834345115 -0.16741686419083296 -0.15466962907108578 -0.152711182674535 -0.17305932521864542 -0.19538807401649205 -0.21052887391088657 -0.23920726095228956 -0.2610627770879738 -0.2942140637157749 -0.3224253233116008 -0.34662871872748513 -0.36335282985833595 -0.39301617727900334 -0.41854038567643986 -0.44194315613270607 -0.4740243711603283 -0.49385454382961846 -0.5068143133273985 -0.5356510544539621 -0.5651668798075582 -0.5876346897911198 -0.5679781843663383 -0.5884305583054655 -0.5632957689770294 -0.5937699437937682 -0.6072383572108945 -0.581974052968631 -0.6074501671675053 -0.569337154911162 -0.6042311848990413 -0.6344044896589967 -0.6692360332009006 -0.6393792787441982 -0.6739471733245486 -0.7054562131743279 -0.6726307013440092 -0.6533564295264932 -0.635257767226484 -0.5989616842776911 -0.5708315294148353 -0.5328746574480934 -0.5051354597789847 -0.4711895622798054 -0.4608423256967228 -0.42207252017857716 -0.40438095714703254 -0.37311118366397483 -0.31592165990607673 -0.3004456531228042 -0.3050661201618198 -0.2548965719654131 -0.22161912779754323 -0.20542043434222584 -0.20523758983277118 -0.19425617041513787 -0.19780552897127668 -0.1721477396382588 -0.18002867750314425 -0.18128863360642034 -0.1634119724622695 -0.1824362245324945 -0.15489178236040405,329372.045221 329372.046378 329372.050227 329372.051385 329372.056391 329372.06024 329372.061398 329372.065247 329372.070253 329372.07526 329372.076417 329372.080266 329372.085273 329372.09028 329372.095286 329372.096444 329372.10145 329372.110306 329372.111463 329372.11647 329372.125325 329372.126483 329372.131489 329372.136496 329372.140345 329372.141502 329372.145351 329372.151515 329372.156522 329372.160371 329372.166535 329372.171541 329372.17539 329372.176548 329372.181554 329372.185404 329372.186561 329372.191567 329372.195417 329372.200423 329372.201581 329372.20543 329372.206587 329372.210436 329372.211594 329372.215443 329372.2166 329372.220449 329372.221607 329372.226613 329372.230462 329372.23162 329372.240475 329372.241633 329372.245482 329372.250488 329372.251646 329372.255495 329372.256652 329372.260501 329372.261659 329372.265508 329372.266665 329372.270514 329372.271672 329372.275521 329372.276678 329372.280528 329372.281685 329372.285534 329372.286691 329372.290541 329372.291698 329372.295547 329372.296705 329372.300554 329372.301711 329372.30556 329372.306718 329372.310567 329372.311724 329372.315573 329372.316731 329372.321737 329372.325586 329372.326744 329372.330593 329372.33175 329372.34677 329372.351776 329372.355625 329372.356783 329372.361789 329372.365638 329372.366796 329372.371802 329372.375651 329372.380658 329372.385665 329372.390671 329372.395678 329372.396835 329372.400684 329372.401842 329372.406848 329372.415704 329372.416861 329372.421868 329372.425717 329372.430723 329372.431881 329372.43573 329372.436887 329372.440736 329372.445743 329372.4469 329372.450749 329372.451907 329372.456913 329372.471933 329372.491959 4 | 7,329373.668492,0.43556799995712936,329374.10406,590,596,603,0.35023588467879996,0.5269719361295961 0.5612454134769318 0.5964964723474706 0.6312121986752564 0.6498316451127099 0.683917005476974 0.7087280206126084 0.7242103132661176 0.7522368807351065 0.7802211305421335 0.8067109785581373 0.8346077808849666 0.8654814263249919 0.8504089899846402 0.8366582868759175 0.817104236289812 0.7983646208583688 0.8129234642732709 0.797496466685596 0.7728282175454722 0.7585015548859071 0.7376696383083405 0.7213789274223578 0.6995013434495093 0.6701856369270475 0.6355006947075086 0.6008214149266764 0.6283290729057414 0.6045526601711673 0.5773765478407288 0.5426907661450873 0.5107252427872625 0.44847239688536145 0.4139759739703387 0.37927043744697886 0.33228978897189965 0.313655008038092 0.2686215564526153 0.24573301100499134 0.24123684717381377 0.21985718403749704 0.19019132084899693 0.16894404739424587 0.13423633101631868 0.09567789286338473 0.09762228492768998 0.08601317996551677 0.09195679998252523 0.08021938975499825 0.05800096739558933 0.02822328674281399 0.02471765403809536 0.014558800285695925 -0.0032637175841834453 -0.011838896044253859 -0.02955409401885442 -0.05935014012118516 -0.06815130858564075 -0.08369601984659641 -0.12943866790336642 -0.16037349103139203 -0.17815664232056752 -0.19002339216578107 -0.2003853725054516 -0.1714339876495811 -0.18078397879090732 -0.1954863571483045 -0.1980698816900711 -0.19718636904424366 -0.18960471571765053 -0.20291961909161926 -0.22187015663387516 -0.23808663239271263 -0.2582719126333761 -0.29078550564299055 -0.2840523131008407 -0.27784757119810777 -0.3114348819367782 -0.3107847231563977 -0.3330759916202682 -0.32592744605025464 -0.34085327858621967 -0.30067073290119956 -0.31964838677164753 -0.3313901517514305 -0.33042157321965065 -0.3574980950695915 -0.3629855476953083 -0.32070734495347475 -0.3291710684388838 -0.3270078296179275 -0.3249595926217926 -0.2837563103650495 -0.2856263825541118 -0.2732288094454835 -0.28116213611348145 -0.2849394052304671 -0.27829705952907513 -0.27445999608484606 -0.24183202220627922 -0.2456360921609125 -0.23855755163129821 -0.2321666728040188 -0.24278216189486926 -0.25192125833842605 -0.2291452070207878 -0.20255044994112026 -0.19888926483115865 -0.1969305445552449 -0.17127061664887003 -0.17289382064244915 -0.15493968405450684 -0.17149504369867544 -0.1711305804064418 -0.19227385976812983 -0.16820725015090313 -0.15797579575973913,329373.668492 329373.672341 329373.677348 329373.683512 329373.687361 329373.692368 329373.697374 329373.702381 329373.703538 329373.707387 329373.708545 329373.712394 329373.7174 329373.718558 329373.722407 329373.723564 329373.727413 329373.728571 329373.73242 329373.733577 329373.737426 329373.738584 329373.74359 329373.748597 329373.752446 329373.753603 329373.75861 329373.763616 329373.768623 329373.772472 329373.778636 329373.783642 329373.787492 329373.788649 329373.792498 329373.793656 329373.802511 329373.803669 329373.807518 329373.808675 329373.812524 329373.813682 329373.817531 329373.823695 329373.827544 329373.828701 329373.83255 329373.838714 329373.842563 329373.843721 329373.84757 329373.852576 329373.853734 329373.85874 329373.863747 329373.867596 329373.868753 329373.872602 329373.877609 329373.878766 329373.882615 329373.883773 329373.887622 329373.888779 329373.892629 329373.897635 329373.898793 329373.903799 329373.908806 329373.922668 329373.923825 329373.937687 329373.938845 329373.942694 329373.943851 329373.948858 329373.952707 329373.953864 329373.957713 329373.963877 329373.967726 329373.968884 329373.97389 329373.977739 329373.983903 329373.987753 329373.98891 329373.992759 329374.00393 329374.007779 329374.012785 329374.017792 329374.018949 329374.022798 329374.023956 329374.027805 329374.028962 329374.032811 329374.037818 329374.038975 329374.042824 329374.043982 329374.047831 329374.048988 329374.052837 329374.053995 329374.057844 329374.059001 329374.06285 329374.064008 329374.067857 329374.069014 329374.072863 329374.084034 329374.087883 329374.09289 329374.102903 5 | -------------------------------------------------------------------------------- /data/10_merge_fixation_and_blink_ids_into_gaze_dataframe/fixations.csv: -------------------------------------------------------------------------------- 1 | id,start_timestamp,duration,start_frame_index,end_frame_index,norm_pos_x,norm_pos_y,dispersion,confidence,method,gaze_point_3d_x,gaze_point_3d_y,gaze_point_3d_z,base_data 2 | 65,329367.8728605,202.7644999907352,417,423,0.5006076206214289,0.489283007793768,1.3250615347918457,0.9967425785870072,3d gaze,-3.0810223717447003,-0.8953849025213014,133.38907096380365,329367.8728605 329367.882874 329367.890384 329367.897894 329367.90540349996 329367.90790650004 329367.91041 329367.9154165 329367.920423 329367.9229265 329367.9254295 329367.9279325 329367.930436 329367.9354425 329367.940449 329367.94295249996 329367.94545550004 329367.9479585 329367.950462 329367.95546850003 329367.9579715 329367.96047499997 329367.9629785 329367.977998 329367.98050099995 329367.9830045 329367.9905145 329367.998024 329368.005534 329368.013044 329368.01805049996 329368.02055350004 329368.0230565 329368.02556 329368.03307 329368.035573 329368.0380765 329368.0405795 329368.0430825 329368.0505925 329368.053096 329368.05810250004 329368.06811550003 329368.0706185 329368.075625 3 | 66,329368.0781285,172.72499995306134,423,428,0.49889353019458693,0.4650111608783833,0.6369050528813954,0.9945254745719202,3d gaze,-3.4271709304306017,2.0175769832536177,133.1147472683141,329368.0781285 329368.0806315 329368.08313499996 329368.088142 329368.090645 329368.09314849996 329368.09565150004 329368.0981545 329368.100658 329368.1031615 329368.108168 329368.110671 329368.1131745 329368.1156775 329368.1181805 329368.12068399996 329368.1231875 329368.1256905 329368.1281935 329368.13069699996 329368.1332005 329368.1357035 329368.1382065 329368.14071 329368.14321350004 329368.150723 329368.15823249996 329368.1682455 329368.17074900004 329368.1757555 329368.178259 329368.18076250004 329368.1832655 329368.188272 329368.1907755 329368.1932785 329368.19578199997 329368.1982855 329368.2007885 329368.2032915 329368.20579499996 329368.2082985 329368.2108015 329368.2133045 329368.215808 329368.21831150004 329368.2208145 329368.2233175 329368.225821 329368.2283245 329368.2308275 329368.23333049996 329368.235834 329368.2383375 329368.2408405 329368.2433435 329368.2508535 4 | 67,329368.3084285,172.725000011269,430,435,0.6186783165759111,0.7199574785406402,1.4522158247243444,0.9229101576749379,3d gaze,24.321821333621866,-32.790829713779516,148.17260347504148,329368.3084285 329368.31093200005 329368.313435 329368.3159385 329368.3184415 329368.32094500004 329368.3234485 329368.328455 329368.33095800004 329368.3334615 329368.3359645 329368.3384675 329368.3484805 329368.350984 329368.35849350004 329368.3660035 329368.36850700004 329368.3735135 329368.3760165 329368.37852 329368.38603 329368.388533 329368.3910365 329368.39353949996 329368.396043 329368.3985465 329368.40605600004 329368.408559 329368.4110625 329368.4135655 329368.416069 329368.4185725 329368.42107549997 329368.4235785 329368.428585 329368.43108849996 329368.43359150004 329368.436095 329368.4385985 329368.4411015 329368.44360450003 329368.446108 329368.4486115 329368.4511145 329368.4536175 329368.456121 329368.45862449997 329368.4611275 329368.4636305 329368.466134 329368.46863749996 329368.47114050004 329368.473644 329368.4761475 329368.4786505 329368.48115350003 5 | 68,329368.483657,90.11749998899177,435,438,0.6082861521308008,0.6972183296549711,1.4893549134125117,0.9676243601318761,3d gaze,20.501723897000716,-27.799192439735933,139.75119606597104,329368.483657 329368.4861605 329368.49116700003 329368.4936705 329368.49617349997 329368.50118 329368.5036835 329368.50618649996 329368.50868950004 329368.511193 329368.5136965 329368.5161995 329368.51870250003 329368.523709 329368.5262125 329368.5287155 329368.531219 329368.53372249997 329368.5362255 329368.5387285 329368.541232 329368.54373549996 329368.54623850004 329368.5487415 329368.551245 329368.5537485 329368.55625150003 329368.5587545 329368.561258 329368.5637615 329368.5662645 329368.5687675 329368.57127099996 329368.5737745 6 | 69,329368.84663000004,92.62049995595589,446,449,0.5642881126960845,0.48945116505910885,1.3933282849034674,0.808368937337931,3d gaze,10.073465291540016,-0.9193212132877407,133.70293758699012,329368.84663000004 329368.849133 329368.8516365 329368.8541395 329368.85664300004 329368.859146 329368.8616495 329368.8641525 329368.866656 329368.869159 329368.87166249997 329368.8741655 329368.876669 329368.8791725 329368.88167549996 329368.884179 329368.889186 329368.891689 329368.89419250004 329368.8966955 329368.8991985 329368.901702 329368.90420550003 329368.9067085 329368.90921149997 329368.911715 329368.9142185 329368.9167215 329368.91922449996 329368.921728 329368.9242315 329368.9267345 329368.93174100004 329368.9342445 329368.9367475 329368.9392505 7 | 70,329368.941754,82.60799996787682,449,451,0.565402386831241,0.4595196628542341,1.464410072324505,0.7872284311231619,3d gaze,10.239678097944932,2.6776411533762827,132.79391769926326,329368.941754 329368.951767 329368.95427 329368.96178 329368.96929000004 329368.9767995 329368.97930300003 329368.9818065 329368.989316 329368.99432249996 329368.996826 329368.9993295 329369.00683900004 329369.0143485 329369.01685200003 329369.0193555 329369.024362 8 | 71,329369.04438750003,87.61449996381998,452,454,0.603946734469311,0.47312949637128976,1.1031523661433869,0.8365670467651106,3d gaze,18.839911092886094,1.0833218956757944,137.06431191624995,329369.04438750003 329369.046891 329369.049394 329369.0518975 329369.0544005 329369.056904 329369.05940749997 329369.0619105 329369.0644135 329369.066917 329369.0719235 329369.0744265 329369.07693 329369.0794335 329369.0869435 329369.0944535 329369.1044665 329369.1144795 329369.121989 329369.124492 329369.1269955 329369.132002 9 | 72,329369.4524195,182.73800000315532,464,469,0.4828643255285945,0.32226140158114963,1.4412223263616875,0.8387263851263713,3d gaze,-5.681029248783456,16.165426789599017,111.25130078183226,329369.4524195 329369.459929 329369.4624325 329369.46743900003 329369.4699425 329369.47244549997 329369.474949 329369.48245899996 329369.484962 329369.4899685 329369.492472 329369.49497550004 329369.4974785 329369.502485 329369.50498850003 329369.5074915 329369.50999449997 329369.512498 329369.5150015 329369.5175045 329369.52000749996 329369.525014 329369.5300205 329369.53252400004 329369.5350275 329369.54253700003 329369.54754349997 329369.5500465 329369.55255 329369.5550535 329369.55755649996 329369.562563 329369.5675695 329369.57007250004 329369.572576 329369.5750795 329369.5775825 329369.58008600003 329369.5825895 329369.58509249997 329369.587596 329369.5900995 329369.5926025 329369.59510549996 329369.597609 329369.6001125 329369.6026155 329369.6051185 329369.60762200004 329369.6101255 329369.6126285 329369.6151315 329369.61763500003 329369.625145 329369.63265449996 329369.6351575 10 | 73,329369.637661,95.12399998493493,470,472,0.4782910299494852,0.3458243675539427,1.3889904703349016,0.7550173335944337,3d gaze,-6.508836055891039,13.849134941952126,112.11466818861494,329369.637661 329369.64517100004 329369.6501775 329369.6526805 329369.6551835 329369.657687 329369.66019049997 329369.665197 329369.6677 329369.67020349996 329369.67270650005 329369.6752095 329369.677713 329369.6877265 329369.69773949997 329369.705249 329369.712759 329369.7152625 329369.71776549995 329369.725275 329369.73028150003 329369.732785 11 | 74,329369.817896,80.10449999710545,475,477,0.5090263280748893,0.38407589620710814,1.4822710165014503,0.7437648230791462,3d gaze,-1.1969054402193562,10.46314070522539,118.43759184563902,329369.817896 329369.825406 329369.83291550004 329369.84292850003 329369.8529415 329369.8554445 329369.860451 329369.8654575 329369.867961 329369.87046450004 329369.877974 329369.880477 329369.8829805 329369.88548399997 329369.8879875 329369.8904905 329369.89549699996 329369.8980005 12 | 75,329369.9005035,80.10449999710545,477,480,0.5213228401622644,0.3967812528075211,1.4932919617105327,0.7867419492736835,3d gaze,1.0635380815937676,9.160296110720672,119.27750475857135,329369.9005035 329369.903007 329369.90551049996 329369.90801350004 329369.9105165 329369.91302 329369.9155235 329369.91802650003 329369.925536 329369.9305425 329369.93304599996 329369.943059 329369.94556200004 329369.9505685 329369.953072 329369.95557550003 329369.9580785 329369.963085 329369.9655885 329369.9680915 329369.97059449996 329369.973098 329369.9756015 329369.9781045 329369.980608 13 | 76,329369.985615,165.21449998253956,480,485,0.5403767117545041,0.4055100893386643,1.4539363388316537,0.7754150842233272,3d gaze,4.660670301696381,8.361772411681406,121.31711450980916,329369.985615 329369.988118 329369.9906215 329370.005641 329370.00814399996 329370.0106475 329370.0131505 329370.015654 329370.018157 329370.02066050004 329370.0231635 329370.0256665 329370.02817 329370.03067350003 329370.0331765 329370.03567949997 329370.040686 329370.0431895 329370.04569249996 329370.048196 329370.0506995 329370.0532025 329370.0557055 329370.05820900004 329370.0607125 329370.0632155 329370.0657185 329370.06822200003 329370.0707255 329370.07322849997 329370.0757315 329370.078235 329370.0807385 329370.08324149996 329370.085745 329370.0882485 329370.0907515 329370.0982615 329370.103268 329370.10577150004 329370.113281 329370.115784 329370.1182875 329370.12079049996 329370.123294 329370.1257975 329370.1283005 329370.1308035 329370.13330700004 329370.1358105 329370.140817 329370.14332000003 329370.1458235 329370.14832649997 329370.1508295 14 | 77,329370.21841800003,125.16299996059388,487,491,0.5627703878189455,0.12757381797296038,0.6495247323223199,0.7515131595978176,3d gaze,8.145545040931877,35.79101450917365,106.55857508484898,329370.21841800003 329370.2209215 329370.22342449997 329370.228431 329370.2309345 329370.23343749996 329370.2359405 329370.238444 329370.2409475 329370.24345049995 329370.25096 329370.2534635 329370.2634765 329370.268483 329370.27098649996 329370.2809995 329370.28350300004 329370.286006 329370.2885095 329370.2910125 329370.2985225 329370.301026 329370.303529 329370.3060325 329370.3160455 329370.31854849996 329370.321052 329370.323555 329370.3260585 329370.3360715 329370.3385745 329370.341078 329370.343581 15 | 78,329370.44371150003,82.60799996787682,494,496,0.4415229116257812,0.5535284743322924,1.4712862801551851,0.895499715188252,3d gaze,-14.316070950382457,-8.092467351203709,124.27618564138308,329370.44371150003 329370.44871799997 329370.4512215 329370.4537245 329370.4562275 329370.45873099996 329370.4612345 329370.4637375 329370.4662405 329370.468744 329370.47124750004 329370.4737505 329370.476254 329370.4787575 329370.483764 329370.486267 329370.4887705 329370.4912735 329370.493777 329370.4987835 329370.50379 329370.50629349996 329370.50879650004 329370.5112995 329370.513803 329370.5163065 329370.51880950003 329370.5213125 329370.523816 329370.5263195 16 | 79,329370.5288225,82.60799996787682,496,499,0.4506633121239345,0.5581754126230084,1.3488966549297754,0.9453645648148165,3d gaze,-12.558360228236785,-8.613183407972167,124.41979333250491,329370.5288225 329370.5313255 329370.53382899996 329370.5363325 329370.5388355 329370.5413385 329370.543842 329370.54634550004 329370.5488485 329370.5513515 329370.553855 329370.561365 329370.5688745 329370.5788875 329370.5863975 329370.588901 329370.5914045 329370.596411 329370.6014175 329370.6039205 329370.6064235 329370.60892699996 329370.6114305 17 | 80,329370.6940375,87.61450002202764,501,504,0.43642157783663305,0.626394584371041,1.4066920711562352,0.9799315854644333,3d gaze,-15.430161038768727,-16.429873254248818,124.4199976330284,329370.6940375 329370.69654100004 329370.6990445 329370.7015475 329370.704051 329370.70655450004 329370.7090575 329370.716567 329370.7190705 329370.72157349996 329370.724077 329370.7265805 329370.7290835 329370.7315865 329370.73409000004 329370.7365935 329370.7390965 329370.7415995 329370.74410300003 329370.7491095 329370.754116 329370.7566195 329370.75912249996 329370.7616255 329370.764129 329370.7666325 329370.76913549996 329370.77163850004 329370.774142 329370.7766455 329370.7791485 329370.78165200003 18 | 81,329370.816698,80.10449999710545,505,507,0.45800895897599114,0.6078435317320231,1.477030685356927,0.9991334948252591,3d gaze,-10.97000177270684,-13.998743086976255,122.22808154563788,329370.816698 329370.81920100003 329370.8217045 329370.8317175 329370.83422049996 329370.836724 329370.839227 329370.8417305 329370.84924 329370.851743 329370.8542465 329370.86175599997 329370.8642595 329370.8667625 329370.869266 329370.876776 329370.879279 329370.88178249996 329370.88428550004 329370.886789 329370.8968025 19 | 82,329370.904312,197.7574999909848,507,513,0.4733632419552844,0.5877847955924257,1.230902358334518,0.9997241684432122,3d gaze,-7.8105583961681635,-11.433039358777485,119.1149742292151,329370.904312 329370.9068155 329370.914325 329370.92183450004 329370.924338 329370.9268415 329370.934351 329370.9393575 329370.9418605 329370.944364 329370.94686749997 329370.951874 329370.954377 329370.95688049996 329370.95938350004 329370.9618865 329370.96439 329370.9668935 329370.96939650003 329370.9718995 329370.976906 329370.9794095 329370.981913 329370.98441649997 329370.9869195 329370.9969325 329371.0044425 329371.0144555 329371.02196549997 329371.0244685 329371.03197799996 329371.039488 329371.0419915 329371.04449450003 329371.049501 329371.0545075 329371.05951399996 329371.0620175 329371.0645205 329371.0670235 329371.06952699996 329371.07203050004 329371.0745335 329371.0770365 329371.07954 329371.084547 329371.08705 329371.0895535 329371.0920565 329371.09456 329371.09706349997 329371.0995665 329371.1020695 20 | 83,329371.1396185,82.60799996787682,514,517,0.5007450679537242,0.4921933755598194,1.465882311454262,0.9963515026750803,3d gaze,-2.689446009443835,-1.09639710904803,117.44809358701968,329371.1396185 329371.1421215 329371.14462499996 329371.1471285 329371.15463799995 329371.15714100003 329371.1596445 329371.16214749997 329371.164651 329371.1671545 329371.1696575 329371.17216049996 329371.174664 329371.1771675 329371.1796705 329371.182174 329371.18467750004 329371.1871805 329371.1896835 329371.192187 329371.19469050004 329371.1971935 329371.199697 329371.2022005 329371.2047035 329371.2072065 329371.20970999997 329371.2122135 329371.2147165 329371.2172195 329371.21972299996 329371.2222265 21 | 84,329371.3423825,80.1050000009127,520,523,0.48079971546146844,0.3931752861243644,1.4867904413117201,0.9928789881005088,3d gaze,-6.134125627994382,9.114650210424442,113.67830555196424,329371.3423825 329371.3498925 329371.352396 329371.3574025 329371.35990549996 329371.3624085 329371.36991849996 329371.372422 329371.374925 329371.3774285 329371.3799315 329371.38243500004 329371.387442 329371.389945 329371.39745499997 329371.399958 329371.4024615 329371.4049645 329371.4149775 329371.41748099995 329371.41998400004 329371.4224875 22 | 85,329371.4249905,80.10450005531311,523,525,0.46584561177826195,0.4067915073512875,1.471964624103112,0.9684970706351819,3d gaze,-8.92036704906943,7.851010340450591,115.58814650365038,329371.4249905 329371.4274935 329371.429997 329371.43500349997 329371.4375065 329371.44001 329371.4425135 329371.44501649996 329371.44751950004 329371.450023 329371.4550295 329371.45753250003 329371.460036 329371.4625395 329371.4650425 329371.4675455 329371.470049 329371.47255249997 329371.4750555 329371.477559 329371.4800625 329371.48256549996 329371.48506850004 329371.487572 329371.4900755 329371.4925785 329371.49508200004 329371.4975855 329371.5000885 329371.5025915 329371.50509500003 23 | 86,329371.6327615,145.18900000257418,529,533,0.3771364509892852,0.6395018791329649,1.2179953137288004,0.9769899068364757,3d gaze,-27.384416807774063,-18.177552808965668,124.23158976305342,329371.6327615 329371.63526450004 329371.637768 329371.640271 329371.6427745 329371.64527750004 329371.6477805 329371.650284 329371.6527875 329371.6552905 329371.6577935 329371.66029699997 329371.6628005 329371.6653035 329371.67030999996 329371.6728135 329371.6753165 329371.6778195 329371.680323 329371.68282650004 329371.6853295 329371.690336 329371.6928395 329371.695343 329371.69784649997 329371.7003495 329371.7028525 329371.705356 329371.70785949996 329371.71036250005 329371.7128655 329371.715369 329371.7178725 329371.72037550004 329371.7228785 329371.725382 329371.732892 329371.73539499997 329371.7378985 329371.7404015 329371.7504145 329371.752918 329371.755421 329371.75792450004 329371.7604275 329371.767937 329371.7704405 329371.77294349996 329371.775447 329371.7779505 24 | 87,329371.84303550003,127.66599998576567,535,539,0.6514316174768304,0.38745254608026297,1.3431612719367527,0.9977316070522306,3d gaze,27.278004907077122,11.07573157017153,127.22530681725809,329371.84303550003 329371.8455385 329371.84804149996 329371.850545 329371.8530485 329371.8555515 329371.85805449996 329371.86055800004 329371.8630615 329371.8655645 329371.8680675 329371.873074 329371.8755775 329371.8780805 329371.880584 329371.8830875 329371.8905975 329371.893101 329371.903114 329371.905617 329371.90812050004 329371.9106235 329371.918133 329371.9206365 329371.92313949997 329371.925643 329371.9281465 329371.9306495 329371.93315249996 329371.935656 329371.9406625 329371.9431655 329371.94566900004 329371.9481725 329371.9506755 329371.9531785 329371.955682 329371.9681985 329371.9707015 25 | 88,329371.9782115,80.10400005150586,539,542,0.6403056071922358,0.4113279526125217,1.368976135581906,0.996199103301297,3d gaze,24.73043395325111,8.165496025345426,126.23905118779118,329371.9782115 329371.9882245 329371.9957345 329372.003244 329372.0057475 329372.010754 329372.0132575 329372.0157605 329372.02076700004 329372.0232705 329372.0257735 329372.0282765 329372.03078000003 329372.0332835 329372.03578649997 329372.040793 329372.0432965 329372.04579949996 329372.04830250004 329372.050806 329372.0558125 329372.05831550003 26 | 89,329372.3386815,82.60749996406958,550,553,0.5062126375279985,0.519192537734462,1.3354482354070467,0.7744796847391647,3d gaze,-1.9912483499008786,-4.632827487542972,137.73512777990047,329372.3386815 329372.3411845 329372.34619099996 329372.3486945 329372.3612105 329372.366217 329372.3712235 329372.37372649997 329372.38624300004 329372.3887465 329372.39125 329372.393753 329372.39625650004 329372.3987595 329372.401263 329372.408773 329372.41127599997 329372.4162825 329372.42128899996 27 | 90,329372.428799,110.14350003097206,553,556,0.5071703096386371,0.5321953884011783,0.6680900701188867,0.7966226055165713,3d gaze,-1.779639841335642,-6.225129102998176,137.1601549031422,329372.428799 329372.431302 329372.43380550004 329372.4363085 329372.4388115 329372.4463215 329372.44882499997 329372.451328 329372.4738575 329372.4763605 329372.4838705 329372.4938835 329372.5013935 329372.5064 329372.50890350004 329372.5114065 329372.5139095 329372.516413 329372.5214195 329372.52392249997 329372.526426 329372.5289295 329372.5314325 329372.53393549996 329372.536439 329372.5389425 28 | 91,329372.56147149997,130.17000001855195,557,561,0.42588234671896436,0.3740343693546335,1.4971028193867335,0.8818088975363644,3d gaze,-17.200844053669897,12.065325024985118,122.5585572326399,329372.56147149997 329372.563975 329372.566478 329372.57398800005 329372.576491 329372.5789945 329372.5814975 329372.58400100004 329372.5865045 329372.591511 329372.59401450003 329372.5965175 329372.59902049997 329372.6065305 329372.60903399996 329372.6140405 329372.6240535 329372.6265565 329372.63156300003 329372.6340665 329372.63656949997 329372.6390725 329372.644079 329372.64658249996 329372.6490855 329372.651589 329372.6540925 329372.65659549995 329372.65909850004 329372.671615 329372.67411849997 329372.6766215 329372.679125 329372.681628 329372.68413149996 329372.689138 329372.6916415 29 | 92,329373.002046,80.10400005150586,570,572,0.417308178506565,0.3720023774483352,1.4969478716824702,0.873380101124053,3d gaze,-19.193455576767853,12.517338590803508,124.55102724561226,329373.002046 329373.009556 329373.012059 329373.0145625 329373.0170655 329373.0195685 329373.02207199996 329373.0270785 329373.0295815 329373.032085 329373.03458850004 329373.042098 329373.04460100003 329373.04960749997 329373.0596205 329373.06212400005 329373.0671305 329373.0696335 329373.07213700004 329373.0746405 329373.079647 329373.08215000003 30 | 93,329373.0921635,90.11699992697686,573,575,0.43273372250221415,0.39729481442262743,1.4740524540364321,0.9178356750301887,3d gaze,-16.177416590002103,9.630950191416558,125.18950867162847,329373.0921635 329373.0946665 329373.09716999996 329373.107183 329373.10968600004 329373.1121895 329373.1146925 329373.117196 329373.124706 329373.127209 329373.1297125 329373.1322155 329373.13471849996 329373.1422285 329373.1497385 329373.1597515 329373.16225449997 329373.167261 329373.1697645 329373.17226749996 329373.1747705 329373.179777 329373.18228049995 31 | 94,329373.184784,82.60750002227724,575,578,0.44037119786337703,0.41607380469077476,1.1121669321777965,0.7999873762930984,3d gaze,-14.902183257814746,7.602026172612202,127.35387141813437,329373.184784 329373.1872875 329373.1897905 329373.1922935 329373.19479700003 329373.1973005 329373.19980349997 329373.20481 329373.2073135 329373.20981649996 329373.21232 329373.2148235 329373.2173265 329373.2198295 329373.224836 329373.2273395 329373.2298425 329373.23234600003 329373.2348495 329373.242359 329373.2498685 329373.2598815 329373.262385 329373.2673915 32 | 95,329373.317457,212.77749998262152,579,586,0.49878496168985653,0.5282485513134947,1.4925625411817431,0.9016842769623672,3d gaze,-3.5186603095178244,-5.675141419086343,135.7617539429708,329373.317457 329373.31996 329373.32246349996 329373.3249665 329373.32747 329373.3299735 329373.33247649996 329373.33497950004 329373.3424895 329373.3499995 329373.36001249996 329373.3625155 329373.367522 329373.37002549996 329373.37252850004 329373.3750315 329373.380038 329373.38254150003 329373.385045 329373.3875485 329373.3900515 329373.392555 329373.3950585 329373.400065 329373.402568 329373.4050715 329373.40757449996 329373.41007750004 329373.412581 329373.4150845 329373.4175875 329373.42009050003 329373.422594 329373.4250975 329373.4276005 329373.4301035 329373.432607 329373.43511049997 329373.4376135 329373.44512299995 329373.4476265 329373.4501295 329373.452633 329373.4551365 329373.45763950003 329373.465149 329373.4676525 329373.4701555 329373.47265899996 329373.4751625 329373.4776655 329373.480169 329373.48267249996 329373.48517550004 329373.4876785 329373.490182 329373.4926855 329373.49518850003 329373.497692 329373.5001955 329373.5026985 329373.5052015 329373.507705 329373.51020849997 329373.5127115 329373.5152145 329373.517718 329373.52022149996 329373.52272450004 329373.5252275 329373.527731 329373.5302345 33 | 96,329373.53273750003,172.72499995306134,586,591,0.4894212160687572,0.5412391206626535,0.9466134833778558,0.992928013546492,3d gaze,-5.454450847033572,-7.225491255370926,134.8258539788778,329373.53273750003 329373.5352405 329373.537744 329373.545254 329373.54775699996 329373.5502605 329373.5527635 329373.5552665 329373.55777 329373.56528 329373.567783 329373.57028650003 329373.5727895 329373.57529249997 329373.577796 329373.5802995 329373.5828025 329373.58530599996 329373.5878095 329373.5903125 329373.592816 329373.59531949996 329373.59782250004 329373.6003255 329373.602829 329373.6053325 329373.60783550004 329373.6103385 329373.612842 329373.6153455 329373.6178485 329373.6203515 329373.62285499997 329373.6253585 329373.6278615 329373.6303645 329373.63286799996 329373.6353715 329373.6378745 329373.64538400003 329373.6478875 329373.65039049997 329373.652894 329373.6553975 329373.6579005 329373.662907 329373.6654105 329373.6679135 329373.6704165 329373.6779265 329373.68043 329373.6854365 329373.6954495 329373.69795299997 329373.700456 329373.7029595 329373.7054625 34 | 97,329374.0358935,210.2739999536425,601,607,0.4404178703527083,0.2769183515664347,0.9760154229330271,0.7542325866971403,3d gaze,-15.226444443719942,24.209519609548725,128.2558900908568,329374.0358935 329374.0409 329374.0459065 329374.053416 329374.05842250003 329374.08345499996 329374.0959715 329374.1034815 329374.1059845 329374.1134945 329374.115998 329374.118501 329374.1235075 329374.14103 329374.1435335 329374.1460365 329374.14853999997 329374.1560495 329374.15855299996 329374.1610565 329374.166063 329374.1785795 329374.2061155 329374.20861850004 329374.2161285 329374.2261415 329374.241161 329374.2461675 35 | 98,329374.2887225,155.2025000564754,608,613,0.41284613585276186,0.278410234551566,1.267796160138305,0.7234543518069084,3d gaze,-19.898549868826418,22.98277452541462,121.96227665326464,329374.2887225 329374.301239 329374.30874899996 329374.328775 329374.3337815 329374.3362845 329374.341291 329374.3437945 329374.34880100004 329374.35881400004 329374.361317 329374.3638205 329374.3663235 329374.406376 329374.4088795 329374.4264025 329374.43391200004 329374.4364155 329374.4389185 329374.443925 36 | 99,329374.4464285,142.6859999774024,613,617,0.4151435268343834,0.29337702373273605,0.5562513493101381,0.7404793031666519,3d gaze,-19.81724754210288,21.689918862722262,124.60373389327596,329374.4464285 329374.463951 329374.466454 329374.46895749995 329374.47146050003 329374.473964 329374.476467 329374.4789705 329374.48147400003 329374.488984 329374.4939905 329374.498997 329374.5140165 329374.51902300003 329374.5265325 329374.53404249996 329374.5415525 329374.54655900004 329374.5515655 329374.5715915 329374.5816045 329374.5891145 37 | 100,329374.691748,212.77750004082918,620,627,0.437284628676584,0.3067389365846124,0.5526212492492409,0.727725889169304,3d gaze,-16.04865261555315,20.935535861324503,130.29649478791188,329374.691748 329374.69425099995 329374.6992575 329374.701761 329374.70426449995 329374.7067675 329374.709271 329374.71177399997 329374.7142775 329374.7167805 329374.721787 329374.72429050005 329374.7267935 329374.73430350004 329374.736807 329374.7418135 329374.74682 329374.74932299997 329374.7518265 329374.756833 329374.75933599996 329374.7618395 329374.78687199997 329374.78937500005 329374.7918785 329374.79938850005 329374.80940150004 329374.816911 329374.8694795 329374.87198299996 329374.8794925 329374.881996 329374.8870025 329374.8895055 329374.892009 329374.9045255 38 | -------------------------------------------------------------------------------- /data/cover_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pupil-labs/pupil-tutorials/63053c53906d38aaada914f4a8d2a9b73a79932c/data/cover_image.png -------------------------------------------------------------------------------- /data/extracted_frames/.gitignore: -------------------------------------------------------------------------------- 1 | *.png 2 | -------------------------------------------------------------------------------- /recordings/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /requirements-all-tutorials.txt: -------------------------------------------------------------------------------- 1 | av 2 | jupyter 3 | numpy 4 | matplotlib 5 | msgpack 6 | opencv-python 7 | pandas 8 | Pillow 9 | scipy 10 | seaborn --------------------------------------------------------------------------------