{ "cells": [ { "cell_type": "markdown", "id": "955f8324", "metadata": {}, "source": [ "# Working with Local Dataset" ] }, { "cell_type": "markdown", "id": "41dfe059", "metadata": {}, "source": [ "In this tutorial, we will show how to use your own local dataset with the Dataset class. The Dataset class can help you to manage and process your eyetracking data." ] }, { "cell_type": "markdown", "id": "92ac248d", "metadata": {}, "source": [ "For demonstration purposes, we will use the raw data provided by the Toy dataset, a sample dataset that comes with pymovements." ] }, { "cell_type": "code", "execution_count": null, "id": "b1d8e6e8", "metadata": {}, "outputs": [], "source": [ "import pymovements as pm\n", "\n", "toy_dataset = pm.datasets.ToyDataset(\n", " root='data/',\n", " download=True,\n", " extract=True,\n", " remove_finished=True,\n", ")" ] }, { "cell_type": "markdown", "id": "405ebd53", "metadata": {}, "source": [ "## Define your Experiment\n", "\n", "To use the Dataset class, we first need to create an Experiment instance. This class represents the properties of the experiment, such as the screen dimensions and sampling rate." ] }, { "cell_type": "code", "execution_count": null, "id": "a89a38a7", "metadata": {}, "outputs": [], "source": [ "experiment = pm.gaze.Experiment(\n", " screen_width_px=1280,\n", " screen_height_px=1024,\n", " screen_width_cm=38,\n", " screen_height_cm=30.2,\n", " distance_cm=68,\n", " origin='lower left',\n", " sampling_rate=1000,\n", ")" ] }, { "cell_type": "markdown", "id": "ddbcf20e", "metadata": {}, "source": [ "## Parameters for File Parsing" ] }, { "cell_type": "markdown", "id": "cd6ab2fe", "metadata": {}, "source": [ "We also define a `filename_regex` which is a regular expression used to match and extract values from filenames of data files in the dataset. For example, `r'trial_(?P\\d+)_(?P\\d+).csv'` will match filenames that follow the pattern `trial_{text_id}_{page_id}.csv` and extract the values of `text_id` and `page_id` for each file." ] }, { "cell_type": "code", "execution_count": null, "id": "90a7d236", "metadata": {}, "outputs": [], "source": [ "filename_regex = r'trial_(?P\\d+)_(?P\\d+).csv'" ] }, { "cell_type": "markdown", "id": "d38ae134", "metadata": {}, "source": [ "Both values of `text_id` and `page_id` are numeric. We can use a map to define the casting of these values." ] }, { "cell_type": "code", "execution_count": null, "id": "24a626f4", "metadata": {}, "outputs": [], "source": [ "filename_regex_dtypes = {\n", " 'text_id': int,\n", " 'page_id': int,\n", "}" ] }, { "cell_type": "markdown", "id": "7e32b202", "metadata": {}, "source": [ "We can also adjust how the CSV files are read." ] }, { "cell_type": "markdown", "id": "e039de9b", "metadata": {}, "source": [ "The `column_map` dictionary maps the original column names in the CSV files to the desired column names. Here the original column names are 'timestamp', **'x'**, and **'y'**, and the desired column names are **'time'**, **'x_right_pix'**, and **'y_right_pix'**, respectively." ] }, { "cell_type": "code", "execution_count": null, "id": "19d897a3", "metadata": {}, "outputs": [], "source": [ "column_map = {\n", " 'timestamp': 'time',\n", " 'x': 'x_right_pix',\n", " 'y': 'y_right_pix',\n", "}" ] }, { "cell_type": "markdown", "id": "a1f91fdd", "metadata": {}, "source": [ "Here, we specify that the separator in the CSV files is a tab (**'\\t'**), and we provide the list of original column names and desired column names as the **'columns'** and **'new_columns'** parameters, respectively." ] }, { "cell_type": "code", "execution_count": null, "id": "14b40a9f", "metadata": {}, "outputs": [], "source": [ "read_csv_kwargs = {\n", " 'sep': '\\t',\n", " 'columns': list(column_map.keys()),\n", " 'new_columns': list(column_map.values()),\n", "}" ] }, { "cell_type": "markdown", "id": "2f1c04a7", "metadata": {}, "source": [ "## Define and load the Dataset" ] }, { "cell_type": "markdown", "id": "190ce9f6", "metadata": {}, "source": [ "Finaly we create a **Dataset** instance by passing in the root directory, Experiment instance, and other optional parameters such as the filename regular expression and custom CSV reading parameters. The `dataset_dirname`, `raw_dirname`, `preprocessed_dirname`, and `events_dirname` parameters define the names of the directories for the dataset, raw data, preprocessed data, and events data, respectively." ] }, { "cell_type": "code", "execution_count": null, "id": "22cb63cd", "metadata": {}, "outputs": [], "source": [ "# Define the path to the dataset directory\n", "dataset_dir = './data/ToyDataset/'\n", "\n", "# Set up the Dataset object\n", "dataset = pm.datasets.Dataset(\n", " root=dataset_dir,\n", " experiment=experiment,\n", " filename_regex=filename_regex,\n", " filename_regex_dtypes=filename_regex_dtypes,\n", " custom_read_kwargs=read_csv_kwargs,\n", " dataset_dirname='.',\n", " raw_dirname='raw',\n", " preprocessed_dirname='preprocessed',\n", " events_dirname='events',\n", ")" ] }, { "cell_type": "markdown", "id": "2ce1117c-b90c-44d9-8701-f12c01d47409", "metadata": {}, "source": [ "Now we can load the dataset. Here we select a subset including the first page of texts with ID 1 and 2." ] }, { "cell_type": "code", "execution_count": null, "id": "9bab0b02-6040-4927-8926-b5be44dc0a75", "metadata": {}, "outputs": [], "source": [ "subset = {\n", " 'text_id': [1, 2],\n", " 'page_id': 1,\n", "}\n", "\n", "dataset.load(subset=subset)" ] }, { "cell_type": "markdown", "id": "6b805c88-20b5-4e5b-8532-030bbd30d051", "metadata": {}, "source": [ "# Use the Dataset" ] }, { "cell_type": "markdown", "id": "d00d7e6c", "metadata": {}, "source": [ "Once we have created the Dataset instance, we can use its methods to preprocess and analyze data in our local dataset." ] }, { "cell_type": "code", "execution_count": null, "id": "9e09dfb0-fe97-4c55-bfec-665833d0fc37", "metadata": {}, "outputs": [], "source": [ "dataset.gaze[0].frame" ] }, { "cell_type": "markdown", "id": "0f1eb66d", "metadata": {}, "source": [ "Here we use the `pix2deg` method to convert the pixel coordinates to degrees of visual angle." ] }, { "cell_type": "code", "execution_count": null, "id": "08024785", "metadata": {}, "outputs": [], "source": [ "dataset.pix2deg()\n", "\n", "dataset.gaze[0].frame" ] }, { "cell_type": "markdown", "id": "b43cf3af", "metadata": {}, "source": [ "We can use the `pos2vel` method to calculate the velocity of the gaze position." ] }, { "cell_type": "code", "execution_count": null, "id": "1c9ed003-45ca-40a7-8a1d-d397babaf31c", "metadata": {}, "outputs": [], "source": [ "dataset.pos2vel(method='savitzky_golay', window_length=7, polyorder=2)\n", "\n", "dataset.gaze[0].frame" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.6" } }, "nbformat": 4, "nbformat_minor": 5 }