Saving and Loading Event Data#
What you will learn in this tutorial:#
how to save your event data
how to load your event data
Preparations#
We import pymovements as the alias pm for convenience.
[1]:
import pymovements as pm
/home/docs/checkouts/readthedocs.org/user_builds/pymovements/envs/v0.19.0/lib/python3.9/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html
from .autonotebook import tqdm as notebook_tqdm
Let’s start by downloading our ToyDataset and loading in its data:
[2]:
dataset = pm.Dataset('ToyDataset', path='data/ToyDataset')
dataset.download()
dataset.load()
Using already downloaded and verified file: data/ToyDataset/downloads/pymovements-toy-dataset.zip
Extracting pymovements-toy-dataset.zip to data/ToyDataset/raw
100%|██████████| 20/20 [00:00<00:00, 38.55it/s]
[2]:
<pymovements.dataset.dataset.Dataset at 0x7f5d24633430>
Now let’s do some preprocessing:
[3]:
dataset.pix2deg()
dataset.pos2vel()
dataset.gaze[0]
100%|██████████| 20/20 [00:01<00:00, 17.66it/s]
100%|██████████| 20/20 [00:00<00:00, 35.76it/s]
[3]:
Experiment(sampling_rate=1000, screen=Screen(width_px=1280, height_px=1024, width_cm=38, height_cm=30.20, distance_cm=68, origin=upper left), eyetracker=None)
shape: (17_223, 8)
┌─────────┬───────────┬───────────┬─────────┬─────────┬───────────┬────────────────┬───────────────┐
│ time ┆ stimuli_x ┆ stimuli_y ┆ text_id ┆ page_id ┆ pixel ┆ position ┆ velocity │
│ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- │
│ i64 ┆ f64 ┆ f64 ┆ i64 ┆ i64 ┆ list[f64] ┆ list[f64] ┆ list[f64] │
╞═════════╪═══════════╪═══════════╪═════════╪═════════╪═══════════╪════════════════╪═══════════════╡
│ 1988145 ┆ -1.0 ┆ -1.0 ┆ 0 ┆ 1 ┆ [206.8, ┆ [-10.697598, ┆ [null, null] │
│ ┆ ┆ ┆ ┆ ┆ 152.4] ┆ -8.852399] ┆ │
│ 1988146 ┆ -1.0 ┆ -1.0 ┆ 0 ┆ 1 ┆ [206.9, ┆ [-10.695183, ┆ [null, null] │
│ ┆ ┆ ┆ ┆ ┆ 152.1] ┆ -8.859678] ┆ │
│ 1988147 ┆ -1.0 ┆ -1.0 ┆ 0 ┆ 1 ┆ [207.0, ┆ [-10.692768, ┆ [1.610194, │
│ ┆ ┆ ┆ ┆ ┆ 151.8] ┆ -8.866956] ┆ -5.256267] │
│ 1988148 ┆ -1.0 ┆ -1.0 ┆ 0 ┆ 1 ┆ [207.1, ┆ [-10.690352, ┆ [0.402548, │
│ ┆ ┆ ┆ ┆ ┆ 151.7] ┆ -8.869381] ┆ -4.447465] │
│ 1988149 ┆ -1.0 ┆ -1.0 ┆ 0 ┆ 1 ┆ [207.0, ┆ [-10.692768, ┆ [0.402561, │
│ ┆ ┆ ┆ ┆ ┆ 151.5] ┆ -8.874233] ┆ -3.234462] │
│ … ┆ … ┆ … ┆ … ┆ … ┆ … ┆ … ┆ … │
│ 2005363 ┆ -1.0 ┆ -1.0 ┆ 0 ┆ 1 ┆ [361.0, ┆ [-6.932438, ┆ [-63.266374, │
│ ┆ ┆ ┆ ┆ ┆ 415.4] ┆ -2.386672] ┆ -21.085616] │
│ 2005364 ┆ -1.0 ┆ -1.0 ┆ 0 ┆ 1 ┆ [358.0, ┆ [-7.006376, ┆ [-63.249652, │
│ ┆ ┆ ┆ ┆ ┆ 414.5] ┆ -2.408998] ┆ -19.431326] │
│ 2005365 ┆ -1.0 ┆ -1.0 ┆ 0 ┆ 1 ┆ [355.8, ┆ [-7.060582, ┆ [-60.359624, │
│ ┆ ┆ ┆ ┆ ┆ 413.8] ┆ -2.426362] ┆ -15.710061] │
│ 2005366 ┆ -1.0 ┆ -1.0 ┆ 0 ┆ 1 ┆ [353.1, ┆ [-7.12709, ┆ [null, null] │
│ ┆ ┆ ┆ ┆ ┆ 413.2] ┆ -2.441245] ┆ │
│ 2005367 ┆ -1.0 ┆ -1.0 ┆ 0 ┆ 1 ┆ [351.2, ┆ [-7.173881, ┆ [null, null] │
│ ┆ ┆ ┆ ┆ ┆ 412.9] ┆ -2.448686] ┆ │
└─────────┴───────────┴───────────┴─────────┴─────────┴───────────┴────────────────┴───────────────┘
Detect some events:
[4]:
dataset.detect_events('ivt')
dataset.events[0]
20it [00:00, 62.29it/s]
[4]:
shape: (73, 6)
┌─────────┬─────────┬──────────┬─────────┬─────────┬──────────┐
│ text_id ┆ page_id ┆ name ┆ onset ┆ offset ┆ duration │
│ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- │
│ i64 ┆ i64 ┆ str ┆ i64 ┆ i64 ┆ i64 │
╞═════════╪═════════╪══════════╪═════════╪═════════╪══════════╡
│ 0 ┆ 1 ┆ fixation ┆ 1988147 ┆ 1988322 ┆ 175 │
│ 0 ┆ 1 ┆ fixation ┆ 1988351 ┆ 1988546 ┆ 195 │
│ 0 ┆ 1 ┆ fixation ┆ 1988592 ┆ 1988736 ┆ 144 │
│ 0 ┆ 1 ┆ fixation ┆ 1988788 ┆ 1989013 ┆ 225 │
│ 0 ┆ 1 ┆ fixation ┆ 1989060 ┆ 1989170 ┆ 110 │
│ … ┆ … ┆ … ┆ … ┆ … ┆ … │
│ 0 ┆ 1 ┆ fixation ┆ 2004132 ┆ 2004331 ┆ 199 │
│ 0 ┆ 1 ┆ fixation ┆ 2004399 ┆ 2004687 ┆ 288 │
│ 0 ┆ 1 ┆ fixation ┆ 2004714 ┆ 2004878 ┆ 164 │
│ 0 ┆ 1 ┆ fixation ┆ 2004931 ┆ 2005109 ┆ 178 │
│ 0 ┆ 1 ┆ fixation ┆ 2005138 ┆ 2005287 ┆ 149 │
└─────────┴─────────┴──────────┴─────────┴─────────┴──────────┘
[5]:
dataset.detect_events('microsaccades')
dataset.events[0]
20it [00:00, 37.68it/s]
[5]:
shape: (215, 6)
┌─────────┬─────────┬──────────┬─────────┬─────────┬──────────┐
│ text_id ┆ page_id ┆ name ┆ onset ┆ offset ┆ duration │
│ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- │
│ i64 ┆ i64 ┆ str ┆ i64 ┆ i64 ┆ i64 │
╞═════════╪═════════╪══════════╪═════════╪═════════╪══════════╡
│ 0 ┆ 1 ┆ fixation ┆ 1988147 ┆ 1988322 ┆ 175 │
│ 0 ┆ 1 ┆ fixation ┆ 1988351 ┆ 1988546 ┆ 195 │
│ 0 ┆ 1 ┆ fixation ┆ 1988592 ┆ 1988736 ┆ 144 │
│ 0 ┆ 1 ┆ fixation ┆ 1988788 ┆ 1989013 ┆ 225 │
│ 0 ┆ 1 ┆ fixation ┆ 1989060 ┆ 1989170 ┆ 110 │
│ … ┆ … ┆ … ┆ … ┆ … ┆ … │
│ 0 ┆ 1 ┆ saccade ┆ 2005110 ┆ 2005126 ┆ 16 │
│ 0 ┆ 1 ┆ saccade ┆ 2005128 ┆ 2005138 ┆ 10 │
│ 0 ┆ 1 ┆ saccade ┆ 2005288 ┆ 2005345 ┆ 57 │
│ 0 ┆ 1 ┆ saccade ┆ 2005347 ┆ 2005356 ┆ 9 │
│ 0 ┆ 1 ┆ saccade ┆ 2005359 ┆ 2005365 ┆ 6 │
└─────────┴─────────┴──────────┴─────────┴─────────┴──────────┘
We now have event dataframes available with our detected event data.
Saving#
Saving your event data is as simple as:
[6]:
dataset.save_events()
100%|██████████| 20/20 [00:00<00:00, 2215.22it/s]
[6]:
<pymovements.dataset.dataset.Dataset at 0x7f5d24633430>
All of the event data is saved into this directory:
[7]:
dataset.paths.events
[7]:
PosixPath('data/ToyDataset/events')
Let’s confirm it by printing all the new files in this directory:
[8]:
print(list(dataset.paths.events.glob('*/*/*')))
[PosixPath('data/ToyDataset/events/aeye-lab-pymovements-toy-dataset-6cb5d66/data/trial_0_4.feather'), PosixPath('data/ToyDataset/events/aeye-lab-pymovements-toy-dataset-6cb5d66/data/trial_3_3.feather'), PosixPath('data/ToyDataset/events/aeye-lab-pymovements-toy-dataset-6cb5d66/data/trial_1_1.feather'), PosixPath('data/ToyDataset/events/aeye-lab-pymovements-toy-dataset-6cb5d66/data/trial_1_2.feather'), PosixPath('data/ToyDataset/events/aeye-lab-pymovements-toy-dataset-6cb5d66/data/trial_3_1.feather'), PosixPath('data/ToyDataset/events/aeye-lab-pymovements-toy-dataset-6cb5d66/data/trial_2_5.feather'), PosixPath('data/ToyDataset/events/aeye-lab-pymovements-toy-dataset-6cb5d66/data/trial_3_5.feather'), PosixPath('data/ToyDataset/events/aeye-lab-pymovements-toy-dataset-6cb5d66/data/trial_3_4.feather'), PosixPath('data/ToyDataset/events/aeye-lab-pymovements-toy-dataset-6cb5d66/data/trial_2_4.feather'), PosixPath('data/ToyDataset/events/aeye-lab-pymovements-toy-dataset-6cb5d66/data/trial_1_4.feather'), PosixPath('data/ToyDataset/events/aeye-lab-pymovements-toy-dataset-6cb5d66/data/trial_0_2.feather'), PosixPath('data/ToyDataset/events/aeye-lab-pymovements-toy-dataset-6cb5d66/data/trial_2_2.feather'), PosixPath('data/ToyDataset/events/aeye-lab-pymovements-toy-dataset-6cb5d66/data/trial_2_3.feather'), PosixPath('data/ToyDataset/events/aeye-lab-pymovements-toy-dataset-6cb5d66/data/trial_1_3.feather'), PosixPath('data/ToyDataset/events/aeye-lab-pymovements-toy-dataset-6cb5d66/data/trial_1_5.feather'), PosixPath('data/ToyDataset/events/aeye-lab-pymovements-toy-dataset-6cb5d66/data/trial_3_2.feather'), PosixPath('data/ToyDataset/events/aeye-lab-pymovements-toy-dataset-6cb5d66/data/trial_2_1.feather'), PosixPath('data/ToyDataset/events/aeye-lab-pymovements-toy-dataset-6cb5d66/data/trial_0_5.feather'), PosixPath('data/ToyDataset/events/aeye-lab-pymovements-toy-dataset-6cb5d66/data/trial_0_3.feather'), PosixPath('data/ToyDataset/events/aeye-lab-pymovements-toy-dataset-6cb5d66/data/trial_0_1.feather')]
All of the files have been saved into the Dataset.paths.events as feather files.
If we want to save the data into an alternative directory and also use a different file format like csv we can use the following:
[9]:
dataset.save_events(events_dirname='events_csv', extension='csv')
100%|██████████| 20/20 [00:00<00:00, 1946.45it/s]
[9]:
<pymovements.dataset.dataset.Dataset at 0x7f5d24633430>
Let’s confirm again by printing all the new files in this alternative directory:
[10]:
alternative_dirpath = dataset.path / 'events_csv'
print(list(alternative_dirpath.glob('*/*/*')))
[PosixPath('data/ToyDataset/events_csv/aeye-lab-pymovements-toy-dataset-6cb5d66/data/trial_1_5.csv'), PosixPath('data/ToyDataset/events_csv/aeye-lab-pymovements-toy-dataset-6cb5d66/data/trial_2_4.csv'), PosixPath('data/ToyDataset/events_csv/aeye-lab-pymovements-toy-dataset-6cb5d66/data/trial_0_5.csv'), PosixPath('data/ToyDataset/events_csv/aeye-lab-pymovements-toy-dataset-6cb5d66/data/trial_3_1.csv'), PosixPath('data/ToyDataset/events_csv/aeye-lab-pymovements-toy-dataset-6cb5d66/data/trial_1_3.csv'), PosixPath('data/ToyDataset/events_csv/aeye-lab-pymovements-toy-dataset-6cb5d66/data/trial_2_3.csv'), PosixPath('data/ToyDataset/events_csv/aeye-lab-pymovements-toy-dataset-6cb5d66/data/trial_2_1.csv'), PosixPath('data/ToyDataset/events_csv/aeye-lab-pymovements-toy-dataset-6cb5d66/data/trial_0_4.csv'), PosixPath('data/ToyDataset/events_csv/aeye-lab-pymovements-toy-dataset-6cb5d66/data/trial_0_2.csv'), PosixPath('data/ToyDataset/events_csv/aeye-lab-pymovements-toy-dataset-6cb5d66/data/trial_1_4.csv'), PosixPath('data/ToyDataset/events_csv/aeye-lab-pymovements-toy-dataset-6cb5d66/data/trial_0_1.csv'), PosixPath('data/ToyDataset/events_csv/aeye-lab-pymovements-toy-dataset-6cb5d66/data/trial_2_2.csv'), PosixPath('data/ToyDataset/events_csv/aeye-lab-pymovements-toy-dataset-6cb5d66/data/trial_2_5.csv'), PosixPath('data/ToyDataset/events_csv/aeye-lab-pymovements-toy-dataset-6cb5d66/data/trial_1_2.csv'), PosixPath('data/ToyDataset/events_csv/aeye-lab-pymovements-toy-dataset-6cb5d66/data/trial_3_2.csv'), PosixPath('data/ToyDataset/events_csv/aeye-lab-pymovements-toy-dataset-6cb5d66/data/trial_0_3.csv'), PosixPath('data/ToyDataset/events_csv/aeye-lab-pymovements-toy-dataset-6cb5d66/data/trial_3_3.csv'), PosixPath('data/ToyDataset/events_csv/aeye-lab-pymovements-toy-dataset-6cb5d66/data/trial_3_4.csv'), PosixPath('data/ToyDataset/events_csv/aeye-lab-pymovements-toy-dataset-6cb5d66/data/trial_1_1.csv'), PosixPath('data/ToyDataset/events_csv/aeye-lab-pymovements-toy-dataset-6cb5d66/data/trial_3_5.csv')]
Loading#
Now let’s imagine that this preprocessing and saving was done in another file and we only want to load the preprocessed data.
We simulate this by initializing a new dataset object. We don’t need to download any additional data.
[11]:
preprocessed_dataset = pm.Dataset('ToyDataset', path='data/ToyDataset')
The preprocessed data can now simply be loaded by setting preprocessed to True:
[12]:
preprocessed_dataset.load(events=True)
dataset.events[0]
100%|██████████| 20/20 [00:00<00:00, 39.70it/s]
100%|██████████| 20/20 [00:00<00:00, 1438.62it/s]
[12]:
shape: (215, 6)
┌─────────┬─────────┬──────────┬─────────┬─────────┬──────────┐
│ text_id ┆ page_id ┆ name ┆ onset ┆ offset ┆ duration │
│ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- │
│ i64 ┆ i64 ┆ str ┆ i64 ┆ i64 ┆ i64 │
╞═════════╪═════════╪══════════╪═════════╪═════════╪══════════╡
│ 0 ┆ 1 ┆ fixation ┆ 1988147 ┆ 1988322 ┆ 175 │
│ 0 ┆ 1 ┆ fixation ┆ 1988351 ┆ 1988546 ┆ 195 │
│ 0 ┆ 1 ┆ fixation ┆ 1988592 ┆ 1988736 ┆ 144 │
│ 0 ┆ 1 ┆ fixation ┆ 1988788 ┆ 1989013 ┆ 225 │
│ 0 ┆ 1 ┆ fixation ┆ 1989060 ┆ 1989170 ┆ 110 │
│ … ┆ … ┆ … ┆ … ┆ … ┆ … │
│ 0 ┆ 1 ┆ saccade ┆ 2005110 ┆ 2005126 ┆ 16 │
│ 0 ┆ 1 ┆ saccade ┆ 2005128 ┆ 2005138 ┆ 10 │
│ 0 ┆ 1 ┆ saccade ┆ 2005288 ┆ 2005345 ┆ 57 │
│ 0 ┆ 1 ┆ saccade ┆ 2005347 ┆ 2005356 ┆ 9 │
│ 0 ┆ 1 ┆ saccade ┆ 2005359 ┆ 2005365 ┆ 6 │
└─────────┴─────────┴──────────┴─────────┴─────────┴──────────┘
By default, the events directory and the feather extension will be chosen.
In case of alternative directory names or other file formats you can use the following:
[13]:
preprocessed_dataset.load(
events=True,
events_dirname='events_csv',
extension='csv',
)
dataset.events[0]
100%|██████████| 20/20 [00:00<00:00, 38.91it/s]
100%|██████████| 20/20 [00:00<00:00, 1137.87it/s]
[13]:
shape: (215, 6)
┌─────────┬─────────┬──────────┬─────────┬─────────┬──────────┐
│ text_id ┆ page_id ┆ name ┆ onset ┆ offset ┆ duration │
│ --- ┆ --- ┆ --- ┆ --- ┆ --- ┆ --- │
│ i64 ┆ i64 ┆ str ┆ i64 ┆ i64 ┆ i64 │
╞═════════╪═════════╪══════════╪═════════╪═════════╪══════════╡
│ 0 ┆ 1 ┆ fixation ┆ 1988147 ┆ 1988322 ┆ 175 │
│ 0 ┆ 1 ┆ fixation ┆ 1988351 ┆ 1988546 ┆ 195 │
│ 0 ┆ 1 ┆ fixation ┆ 1988592 ┆ 1988736 ┆ 144 │
│ 0 ┆ 1 ┆ fixation ┆ 1988788 ┆ 1989013 ┆ 225 │
│ 0 ┆ 1 ┆ fixation ┆ 1989060 ┆ 1989170 ┆ 110 │
│ … ┆ … ┆ … ┆ … ┆ … ┆ … │
│ 0 ┆ 1 ┆ saccade ┆ 2005110 ┆ 2005126 ┆ 16 │
│ 0 ┆ 1 ┆ saccade ┆ 2005128 ┆ 2005138 ┆ 10 │
│ 0 ┆ 1 ┆ saccade ┆ 2005288 ┆ 2005345 ┆ 57 │
│ 0 ┆ 1 ┆ saccade ┆ 2005347 ┆ 2005356 ┆ 9 │
│ 0 ┆ 1 ┆ saccade ┆ 2005359 ┆ 2005365 ┆ 6 │
└─────────┴─────────┴──────────┴─────────┴─────────┴──────────┘
What you have learned in this tutorial:#
saving your preprocesed data using
Dataset.save_preprocessed()load your preprocesed data using
Dataset.load(preprocessed=True)using custom directory names by specifying
preprocessed_dirnameusing other file formats than the default
featherformat by specifyingextension