{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Interpolate data and concatenate streams\n", "\n", "Informative as it is, raw Neon data is not always easy to work with. Different data streams (e.g., gaze, eye states, IMU) are sampled at different rates, don't necessarily share a common start timestamp, and within each stream data might not have been sampled at a constant rate. This tutorial demonstrates how to deal with these issues by interpolating data streams and concatenating them into a single DataFrame.\n", "\n", "We will use the same ``boardView`` dataset as in the [previous tutorial](read_recording.ipynb)." ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "from pyneon import get_sample_data, NeonRecording\n", "\n", "import matplotlib.pyplot as plt\n", "\n", "recording_dir = (\n", " get_sample_data(\"boardView\")\n", " / \"Timeseries Data + Scene Video\"\n", " / \"boardview1-d4fd9a27\"\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We now access raw data from gaze, eye states, and IMU streams." ] }, { "cell_type": "code", "execution_count": 29, "metadata": {}, "outputs": [], "source": [ "recording = NeonRecording(recording_dir)\n", "gaze = recording.gaze\n", "eye_states = recording.eye_states\n", "imu = recording.imu" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Irregularly sampled data\n", "Data points from each stream are indexed by `timestamp [ns]`, which denotes the UTC time of the sample in nanoseconds. But are these samples equally spaced in time? Let's take a look at the first few samples of each stream, where, due to device boot-up, the sampling may be irregular." ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "data": { "image/png": "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+lxljCu1F6YszpHziePkamO4en0l+R5Syixfifb29lbt2rUvu75v37565plntHbtWq1Zs0aRkZFq1aqVJCknJ0eStGDBAlWrVs1hu8t9ONHX11ebNm1SSkqKlixZolGjRikxMVEbNmxQQEBAodvMnDlTw4YN0xtvvKHmzZvL19dXr732mtatW3fFueXk5Khx48b65JNPCqwLDg6WdPHK9JAhQ7Ro0SLNmjVL//73v7V06VI1a9aswDaenp7O+9Blq39e/PPg2osn3KVlq+2uNIarKqvHuiTn4ipzLMkxXL0+VxmjJM8/V5ljSR8nxig79bnKGK5eX3GN4WQ2Y4y5ereLEhISdPLkSc2dO/eK/e677z75+/tr7dq1euCBBzRixAhJUnZ2toKDgzV16lT16dPnmgo+deqUAgICNGvWLN19991q166dYmJi9Pbbb9v7PP7449qxY4e+/fZbe1tsbKyOHTumzZs3S5IefvhhZWRk6Ouvv7b3mTp1qv71r38pPT1dfn5+RaqnefPm+tvf/qa33nrrqn2zsrLk7++vzMzMIo8PAACA0lPUvGb5SnRubq5++eUXx0Hc3VW5cmX78oABA9SpUyfl5eWpX79+9nZfX18NGzZMTz75pPLz83X77bcrMzNT3333nfz8/Bz6XjJ//nzt27dPd9xxhypVqqRvvvlG+fn5iomJkSRFRERo3bp1Sk9Pt99+UadOHX388cdavHixIiMjNWPGDG3YsEGRkZH2cSMiIrR48WKlpqYqKChI/v7+6tWrl1577TV17dpVL7zwgqpXr64DBw5o9uzZevrpp3X+/HlNmTJFXbp0UVhYmFJTU7Vnzx717dvX6mEEAABAWWYs6Nevn9HFu7sdHjExMQ798vPzTXh4uPnf//3fAmPk5+ebN99808TExJjy5cub4OBgEx8fb1asWFHoPletWmVat25tKlWqZLy8vMwtt9xiZs2aZV+fmppqmjVrZry8vIwks3//fnP27FmTkJBg/P39TUBAgBk0aJB55plnTIMGDezbHT161MTFxRkfHx8jySxfvtwYY0xGRobp27evqVy5svH09DRRUVFm4MCBJjMz0/zyyy+mW7duJjQ01Hh4eJjw8HAzatQok5eXV6Tjl5mZaSSZzMzMIvUHAABA6SpqXrN0O0dR5eTkqFq1akpKStLdd99d3MOXWdzOAQAA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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# Take the first 0.5 seconds of gaze data\n", "gaze_begin = gaze.crop(0, 0.5, by=\"time\")\n", "# And the corresponding eye states and IMU data\n", "eye_states_begin = eye_states.restrict(gaze_begin)\n", "imu_begin = imu.restrict(gaze_begin)\n", "\n", "\n", "# Define a function to plot the timestamps of the gaze, eye states, and IMU data\n", "def plot_timestamps(gaze, eye_states, imu):\n", " _, ax = plt.subplots(figsize=(8, 2))\n", " ax.scatter(gaze.ts, np.ones_like(gaze.ts), s=5)\n", " ax.scatter(eye_states.ts, np.ones_like(eye_states.ts) * 2, s=5)\n", " ax.scatter(imu.ts, np.ones_like(imu.ts) * 3, s=5)\n", " ax.set_yticks([1, 2, 3])\n", " ax.set_yticklabels([\"Gaze\", \"Eye states\", \"IMU\"])\n", " ax.set_ylim(0.5, 3.5)\n", " ax.set_xlabel(\"Timestamp (ns)\")\n", " plt.show()\n", "\n", "\n", "plot_timestamps(gaze_begin, eye_states_begin, imu_begin)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As apparent from the figure above, in addition to the apparently later onset of IMU data, during the first 0.5 seconds of the recording the data suffers from dropouts and irregular sampling. While this is a common issue for the first few samples due to device boot-up, it could also happen at any time during the recording. For example, even in the middle of a recording (5 - 5.5 seconds), some irregular sampling might still be observed:" ] }, { "cell_type": "code", "execution_count": 31, "metadata": {}, "outputs": [ { "data": { "image/png": "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t09+fn723oKCgnT+/HklJycrKChI8fHxiouLU+fOnTVx4kQdO3Ys33rDhw9Xamqq/XX48OFr9l1kqjWTlHOH3PbfZYvri6KGM+Z09f6o7Rq1S+vxuHp/1HbtOW/m2q7enyvNWRpquwDLd6J9fHxUs2bNfLf36dNHw4YN09q1a7VmzRpFRUXpzjvvlCRlZGRIkhYuXKjKlSs77JffmxP9/Py0efNmrVixQkuXLtWIESOUkJCgDRs2KDAwMM995syZoyFDhujNN99Us2bN5Ofnp9dff13r1q276rFlZGSoYcOG+uijj3JtCwkJkXT5zvSgQYO0ePFizZ07V//617+0bNkyNW3aNNc+Xl5eznvT5Z3/uPzfQ2svf8HlLFtdXxQ1nDGnq/dHbdeoXVqPx9X7o7Zrz3kz13b1/lxpTlev7QJsxhhz7WGXxcfH68yZM5o/f/5Vx91///0KCAjQ2rVr9dBDD2n48OGSpPT0dIWEhGjatGnq3bv3dTV89uxZBQYGau7cubrnnnvUrl07xcTE6J133rGPeeqpp7Rz505999139nVt27bVyZMntWXLFknSY489pmPHjunrr7+2j5k2bZr++c9/KiUlRf7+/gXqp1mzZvrb3/6mt99++5pj09LSFBAQoNTU1ALXBwAAQMkpaF6zfCc6MzNTx48fdyzi4aEKFSrYl/v3769OnTopKytLffv2ta/38/PTkCFD9Mwzzyg7O1t33HGHUlNT9eOPP8rf399hbI4FCxZo//79uuuuu1S+fHl98803ys7OVkxMjCQpMjJS69atU0pKiv3xi1q1aunDDz/UkiVLFBUVpVmzZmnDhg2Kioqy142MjNSSJUuUlJSk4OBgBQQEqGfPnnr99dfVtWtXvfzyy6pSpYoOHjyoefPm6bnnntPFixc1depUdenSReHh4UpKStLevXvVp08fq6cRAAAApZmxoG/fvkaXn+52eMXExDiMy87ONhEREeb//u//ctXIzs42b731lomJiTFlypQxISEhJi4uzvzwww95zrlq1SrTsmVLU758eePt7W1uu+02M3fuXPv2pKQk07RpU+Pt7W0kmQMHDpjz58+b+Ph4ExAQYAIDA82AAQPMsGHDTL169ez7nThxwsTGxhpfX18jySxfvtwYY8yxY8dMnz59TIUKFYyXl5epXr26efTRR01qaqo5fvy46dat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mTPnmuf0r6ZOnapWrVrJ399fNptNZ86cyTVmz5496tq1qypUqCB/f3/dcccdWr58uaV5CNEAUELy+p/DX18JCQmaOHGiZs6c6dQ+S0uQHz16tLp27arIyMgiqde+fXuVKVNGH330UZHUQ9E7e/as6tWrp0mTJl3X/gcOHFDXrl31v//7v9qyZYuWLFmikydP6p577sl3n4SEBMXHx1+1pzvuuEPjxo0rcB/z5s3TsWPH7K/t27fL3d1d3bt3t4+Jjo7Wu+++q19++UWrV69WZGSk2rVrp99//12StHv3bmVnZ2vKlCnasWOHJkyYoPfff1/PP/+8w1xPP/20/v3vf+uNN97Q7t279dVXX6lx48b27StXrlRsbKy++eYbbdq0Sa1bt1bnzp31888/OxxjQc/7F198oZ9++knh4eEO648ePaq2bduqZs2aWrdunRYvXqwdO3bkeW4TExMdzo/Vn0fnzp1T+/btc52Lv+rUqZMuXbqk77//Xps2bVK9evXUqVMnHT9+vOATGQBAiTh27Jj99dZbbxl/f3+Hdenp6c5u0RhjTN++fU3Xrl2d3cZVnT171vj7+5u1a9cWad13333XNGrUqEhronhIMl988YXDuvPnz5t//OMfJjw83JQrV840btzYLF++3L79008/NR4eHiYrK8u+7quvvjI2m81cuHAhz3lGjhxp+vbte81+Dhw4YCSZn3/+2fKxTJgwwfj5+ZmMjIx8x6SmphpJ5ttvv813zGuvvWaioqLsyzt37jQeHh5m9+7dlvq59dZbzUsvvZTntrzOe45ff/3VVK5c2Wzfvt1ERESYCRMm2LdNmTLFVKxY0eHcb9u2zUgye/fuLVD9HPPnzzf169c3Xl5eJioqyiQkJJiLFy/mGrd8+XIjyZw+fdph/e+//24kmZUrV9rXpaWlGUlm2bJlV537r7gTDQAlpFKlSvZXQECAbDabwzpfX99cd4FbtWqlp556SoMHD1b58uUVGhqqadOm6ezZs3r44Yfl5+enmjVratGiRQ5zbd++XR06dJCvr69CQ0PVu3dvnTx50r79s88+U926deXt7a3g4GC1bdtWZ8+eVUJCgj744AN9+eWX9jvkK1askCT985//VHR0tMqVK6fq1avrxRdf1MWLF+01ExISdPvtt2vGjBmqVq2afH199cQTTygrK0uvvfaaKlWqpIoVKzr8VbJ0+Q795MmT1aFDB3l7e6t69er67LPPrnouv/nmG3l5ealp06b2dStWrJDNZtN3332nRo0aqVy5cmrevLmSkpLsY7Zu3arWrVvLz89P/v7+atiwoTZu3Gjf3rlzZ23cuFHJycnXvqBwOU8++aTWrl2rOXPmaNu2berevbvat2+vvXv3SpIaNmwoNzc3JSYmKisrS6mpqZo1a5batm2rMmXKOK3v6dOn64EHHpCPj0+e2y9cuKCpU6cqICBA9erVy7dOamqqgoKC7Mtff/21qlevrgULFigqKkqRkZHq37+/Tp06lW+N7OxspaenO9QpiOzsbPXu3VtDhw5VnTp1cm3PzMyUp6en3Nz+f/T09vaWJK1evdph7MCBA1WhQgU1btxYM2bM0OVsfdmqVavUp08fPf3009q5c6emTJmimTNn5vq5cjXBwcGKiYnRhx9+qLNnz+rSpUuaMmWKKlasqIYNGxb8oAsctwEARSYxMdEEBATkWn/lXeCWLVsaPz8/M2rUKLNnzx4zatQo4+7ubjp06GCmTp1q9uzZYwYMGGCCg4PN2bNnjTHGnD592oSEhJjhw4ebXbt2mc2bN5vY2FjTunVrY4wxR48eNR4eHmb8+PHmwIEDZtu2bWbSpEkmPT3dpKenmx49epj27dvb75BnZmYaY4wZNWqU+fHHH82BAwfMV199ZUJDQ824cePsvY4cOdL4+vqa++67z+zYscN89dVXxtPT08TFxZmnnnrK7N6928yYMcNIMj/99JN9P0kmODjYTJs2zSQlJZl//etfxt3d3ezcuTPf8zdo0CDTvn17h3U5d52aNGliVqxYYXbs2GHuvPNO07x5c/uYOnXqmF69epldu3aZPXv2mE8++cRs2bLFoU5oaKhJTEy8+gWE0+mKO5YHDx407u7u5siRIw7j2rRpY4YPH25fXrFihalYsaJxd3c3kkyzZs1y3an8q+K+E71u3Tojyaxbty7Xtq+//tr4+PgYm81mwsPDzfr16/Ots3fvXuPv72+mTp1qX/f3v//deHl5mSZNmpiVK1ea5cuXm9tvv93+syAv48aNM+XLlze//fZbntuvPO85xowZY2JjY012drYxxuS6E719+3bj4eFhXnvtNZOZmWlOnTpl7r33XiPJjBkzxj7u5ZdfNqtXrzabN282r776qvHy8jITJ060b2/Tpo3D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goKC1KxZM5UvX159+/bViBEj5O3trWnTpunAgQPWfoko8IMfAIAiY+WZ6KefftphTF7PGuovzykeOXLEhISEmPvuu8+sX7/e7Nu3zyxevNjEx8ebS5cumZ9++smMHj3abNiwwRw8eNB88sknxtPT03zzzTfGGGNGjx5tqlWrZnbv3m1+//13c+HCBfPll18aDw8P8/HHH5t9+/aZiRMnmqCgIIdjGDlypKlXr95VjyevY5JkKlSoYKZPn26SkpLMiBEjjJubm9mxY0e+52/btm3Gw8PDnDp1yr4ur+cff/75ZyPJHDhwwJw7d84MHDjQLF++3KSkpJjVq1ebGjVqmOeee86hhq+vb65nK+Eacq7xla+cN/5duHDBjBgxwkRGRpoyZcqYsLAwc/fdd5tt27bZa3z88cemfv36xsfHx4SEhJguXbqYXbt25Tvntd5YmJiYmGdPI0eOtI9p2bJlrhq7d+82kszSpUtz1fzzzz/N3XffbcLDw42np6cJCwszXbp0cXhjYX7zXhntjhw5Yu655x7j6+trQkNDTXx8vPnjjz8cervaOS3Iec9LXj+nevfubYKCgoynp6e57bbbzIcffuiwfdGiReb22283vr6+xsfHx9SrV8+8//77Du+pMMaYxYsXm+bNmxtvb2/j7+9vGjdu7PCGypEjR+bZ71/fMLxhwwbTrl07ExQUZPz8/EzTpk3tPwMLihANAE5QnCHaGGP27Nlj7r77bhMYGGi8vb1N7dq1zeDBg012drbZuXOniYuLMyEhIcbLy8tER0ebd955x77viRMnTGxsrPH19TWS7J+zO3ToUBMcHGx8fX3N/fffbyZMmFBkIXrSpEkmNjbWeHl5mcjISDN37tx8ztz/17hxY/P+++/bl68VojMzM80DDzxgqlatajw9PU14eLh58skn7W86NObym7z+/ve/X3NuALAZ85cP3wMAoITZbDZ98cUXlv9VsoULF2ro0KHavn17rmcbr8fJkycVExOjjRs35vtsOADk4JloAECp1LFjR+3du1dHjhxR1apVC10vJSVF7733HgEaQIFwJxoA4FTXeycaAJyJO9EAAKfiXg6A0qjwD5EBAAAANxlCNAAAAGARIRoAAACwiBANAAAAWESIBgAAACwiRAMAAAAWEaIBAAAAiwjRAAAAgEWEaAAAAMCi/wfigZkyahmYNgAAAABJRU5ErkJggg==", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "gaze_middle = gaze.crop(5, 5.5, by=\"time\")\n", "eye_states_middle = eye_states.restrict(gaze_middle)\n", "imu_middle = imu.restrict(gaze_middle)\n", "\n", "plot_timestamps(gaze_middle, eye_states_middle, imu_middle)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Some irregular sampling in the IMU data is observed in this segment of the recording as well. How frequent are these irregularities? Let's take a look at the distribution of the time differences between consecutive samples, and compare them to the expected time difference for a regular, nominal (as specified by Pupil Labs) sampling rate." ] }, { "cell_type": "code", "execution_count": 37, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Nominal sampling frequency of gaze: 200 Hz. Actual: 199.36 Hz\n", "Nominal sampling frequency of eye states: 200 Hz. Actual: 199.36 Hz\n", "Nominal sampling frequency of IMU: 110 Hz. Actual: 113.88 Hz\n" ] }, { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAnYAAAHVCAYAAAB8NLYkAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAABq/klEQVR4nO3deVxU9f4/8NfMsMvmyiIIikKu4AahmaAY4XLVyi1FtDIrMI2sq5Ui6g29FnozysIrlGmYmtTPSlMUKcNSkETFHXcWNRUYFJT5/P7oy1xHFplhFph5PR+Pech8zuec856Ph/HlWSVCCAEiIiIiavakhi6AiIiIiLSDwY6IiIjISDDYERERERkJBjsiIiIiI8FgR0RERGQkGOyIiIiIjASDHREREZGRYLAjIiIiMhIMdkRERERGgsGOiIiIyEgw2BERPSA/Px9RUVHw9vaGjY0NbGxs0K1bN0RGRuLIkSOGLo+IqF4SPiuWiOhv27dvx4QJE2BmZobJkyfD19cXUqkUJ06cwLfffosLFy4gPz8fHh4ehi6ViKhWDHZERADOnj0LX19fdOjQAWlpaXBxcVGZfv/+fXzyyScYO3Ys3N3dDVQlEVH9eCiWiAjAv//9b8jlciQlJdUIdQBgZmaG119/XRnqjhw5gmnTpqFTp06wsrKCs7MzXnjhBdy4cUM5z/nz5yGRSOp8Pej333/H008/DQcHB9jY2GDw4MHYv3+/bj80ERkd7rEjIgLQvn172NjY4PTp0w3q/+GHH+K7777DsGHD4OzsjGPHjuHzzz9Hz549ceDAAUgkEsjlcmzbtk1lvnv37uGNN96AhYUFiouLAQB79uxBWFgY+vbti+eeew5SqRRJSUk4ceIEfvnlF/j7+2v98xKRcWKwIyKTV1JSAgcHB4wZM6ZGELt16xbu37+vfN+iRQtYW1vjzp07sLa2VumbkpKCSZMmISMjA4MGDap1XZGRkfjss8+wa9cuBAcHQwgBHx8fdOrUCT/99JNyT96dO3fQvXt3dO7cGT///LOWPzERGSseiiUik1dSUgIAsLW1rTEtKCgIbdu2Vb4SEhIAQCXU3b17F9evX8fjjz8OAMjOzq51PV9++SU++eQT/Pvf/0ZwcDAAICcnB6dPn8bzzz+PGzdu4Pr167h+/TrkcjmGDh2KjIwMKBQKrX5eIjJeZoYugIjI0Ozs7AAAZWVlNaZ99tlnKC0tRVFREaZMmaJs/+uvvxAbG4uUlBTlIdVqt2/frrGcnJwcvPLKK5g0aRKio6OV7dWHfiMiIuqs7/bt22jZsqV6H4qITBKDHRGZPAcHB7i4uODo0aM1pgUEBAD4+0KIB40fPx6//fYb3nrrLfj5+cHW1hYKhQJPP/10jT1sN2/exLPPPgtvb2+sXbtWZVp13xUrVsDPz6/W+mrbk0hEVBsGOyIiACNGjMDatWvxxx9/PPJihZs3byItLQ2xsbFYuHChsr22Cy8UCgUmT56MW7duYffu3bCxsVGZ7uXlBQCwt7dHSEiIFj4JEZkynmNHRATg7bffho2NDV544QUUFRXVmP7gdWYymaxGGwCsWrWqxnyxsbHYuXMnvv76a3Ts2LHG9L59+8LLywsffPBBrYeCr127pu5HISITxj12REQAunTpgo0bN2LSpEnw8fFRPnlCCIH8/Hxs3LgRUqkUbm5usLe3x5NPPol///vfuHfvHtq3b4+ff/4Z+fn5KsvMzc3FkiVL8OSTT6K4uBhfffWVyvQpU6ZAKpVi7dq1CAsLQ/fu3TF9+nS0b98eV65cwd69e2Fvb4//9//+nz6HgoiaMd7uhIjoAWfPnsWHH36IXbt24fLly5BIJPDw8EBQUBBeeeUV+Pr6AgCuXLmCWbNmYe/evRBC4KmnnsJ//vMfuLq6IiYmBosWLUJ6erry6tfaPPj1m5OTgyVLlmDfvn0oKyuDs7MzAgICMHPmTAwZMkTnn5uIjAODHREREZGR4Dl2REREREaCwY6IiIjISDDYERERERkJBjsiIiIiI8FgR0RERGQkTPo+dgqFAlevXoWdnR0kEomhyyEiIiKqQQiB0tJSuLq6Qiqtf5+cSQe7q1evwt3d3dBlEBERET3SpUuX4ObmVm8fkw52dnZ2AP4eKHt7e92tSC4HXF3//vnqVaBFC92ti4iIiIxKSUkJ3N3dlbmlPiYd7KoPv9rb2+s22P3fcyX/b2UMdkRERKS2hpw2xosniIiIiIyESe+xM4SuC3bgjoVVndPPLxuhx2qIiIjImHCPHREREZGR4B47IiIiI6dQKFBZWWnoMqgO5ubmkD14Pn4jMNgREREZscrKSuTn50OhUBi6FKqHo6MjnJ2dG31fXQY7IiIiIyWEQEFBAWQyGdzd3R95c1vSPyEEysvLUVxcDABwcXFp1PIY7IiIiIzU/fv3UV5eDldXV9jY2Bi6HKqDtbU1AKC4uBjt2rVr1GFZRnciIiIjVVVVBQCwsLAwcCX0KNXB+969e41aDoMdERGRkePz0Js+bf0dMdgRERERGYlmH+xu3bqFfv36wc/PDz169EBiYqKhSyIiIiIyiGYf7Ozs7JCRkYGcnBz8/vvveP/993Hjxg1Dl0VERETNUHJyMhwdHbW6zPPnz0MikSAnJ0ery61Nsw92MplMecJhRUUFhBAQQhi4KiIiItLUtGnTIJFIsGzZMpX21NRUnZ8vOGHCBJw6dUqn69Algwe7jIwMjBo1Cq6urpBIJEhNTa3RJyEhAZ6enrCyskJAQAD++OMPlem3bt2Cr68v3Nzc8NZbb6FNmzZ6qp6IiIh0wcrKCsuXL8fNmzf1ul5ra2u0a9dOr+vUJo2CXXZ2NnJzc5Xvv/vuO4wZMwbvvPOO2o8skcvl8PX1RUJCQq3TN23ahOjoaMTExCA7Oxu+vr4IDQ1V3sgP+PtuzX/++Sfy8/OxceNGFBUV1bqsiooKlJSUqLyIiIhMhhCAXG6Yl5pH00JCQuDs7Iy4uLg6+2zduhXdu3eHpaUlPD098eGHH6pM9/T0xNKlSzF16lTY2trCw8MD33//Pa5du4bRo0fD1tYWvXr1wqFDh5TzPHwodtGiRfDz88P69evh6ekJBwcHTJw4EaWlpco+O3bswBNPPAFHR0e0bt0aI0eOxNmzZ9X6vNqiUbCbOXOmcjfluXPnMHHiRNjY2GDz5s14++231VpWWFgYli5dirFjx9Y6PT4+HjNmzMD06dPRrVs3rFmzBjY2Nli3bl2Nvk5OTvD19cUvv/xS67Li4uLg4OCgfLm7u6tVKxERUbNWXg7Y2hrmVV6uVqkymQzvv/8+Vq9ejcuXL9eYnpWVhfHjx2PixInIzc3FokWLsGDBAiQnJ6v0W7lyJQYOHIjDhw9jxIgRCA8Px9SpUzFlyhRkZ2fDy8sLU6dOrfc0rrNnzyI1NRXbt2/H9u3bsW/fPpXDxHK5HNHR0Th06BDS0tIglUoxduxYgzzGTaNgd+rUKfj5+QEANm/ejCeffBIbN25EcnIytm7dqrXiKisrkZWVhZCQEGWbVCpFSEgIMjMzAQBFRUXK1Hz79m1kZGTAx8en1uXNnz8ft2/fVr4uXbqktVqJiIhIu8aOHQs/Pz/ExMTUmBYfH4+hQ4diwYIF8Pb2xrRp0xAVFYUVK1ao9Bs+fDhmzpyJLl26YOHChSgpKUH//v0xbtw4eHt745///Cfy8vLqPNoHAAqFAsnJyejRowcGDRqE8PBwpKWlKac/++yzeOaZZ9C5c2f4+flh3bp1yM3NxfHjx7U3GA2k0SPFhBDKFLp7926MHDkSAODu7o7r169rrbjr16+jqqoKTk5OKu1OTk44ceIEAODChQt4+eWXlRdNzJo1Cz179qx1eZaWlrC0tNRafURERM2KjQ1QVma4dWtg+fLlGDJkCObOnavSnpeXh9GjR6u0DRw4EKtWrUJVVZXysVy9evVSTq/OEw/mhOq24uJiODs711qDp6cn7OzslO9dXFxUTgk7ffo0Fi5ciN9//x3Xr19XZqSLFy+iR48ean/mxtAo2PXr1w9Lly5FSEgI9u3bh08//RQAkJ+fXyOE6Zq/v79eLh8mIiJq9iQSoEULQ1ehlieffBKhoaGYP38+pk2bpvb85ubmyp+rr6itra2+w6YP9q+e58H+o0aNgoeHBxITE+Hq6gqFQoEePXqofd2BNmgU7FauXIkpU6YgNTUV7777Ljp37gwA2LJlCwYMGKC14tq0aQOZTFZj92hRUVGdqZqIiIiMy7Jly+Dn56dyqlXXrl2xf/9+lX779++Ht7e3cm+dPty4cQMnT55EYmIiBg0aBAD49ddf9bb+h2kU7Hx9fVWuiq22YsUKmJlptMhaWVhYoG/fvkhLS8OYMWMA/J2o09LSEBUVpbX1EBERUdPVs2dPTJ48GR999JGy7c0330T//v2xZMkSTJgwAZmZmfj444/xySef6LW2li1bonXr1vj888/h4uKCixcvYt68eXqt4UEaXTzRqVOnWp/ucPfuXXh7e6u1rLKyMuTk5CgPp+bn5yMnJwcXL14EAERHRyMxMRFffPEF8vLy8Oqrr0Iul2P69OmalE5ERETN0OLFi1UOf/bp0wfffPMNUlJS0KNHDyxcuBCLFy/W6HBtY0ilUqSkpCArKws9evTAG2+8UeMCDn2SCA0e0yCVSlFYWFjjBn5FRUVwd3dX65hyeno6goODa7RHREQoL1n++OOPsWLFChQWFsLPzw8fffQRAgIC1C27hpKSEjg4OOD27duwt7dv9PLqJJf/fak3gK5vbMEdC6s6u55fNkJ3dRARkUm5e/cu8vPz0bFjR1hZ1f1vDxlefX9X6uQVtY6bfv/998qfd+7cCQcHB+X7qqoqpKWloWPHjuosEkFBQY98BFhUVBQPvRIRERE9glrBrvo8N4lEgoiICJVp5ubmtd71mYiIiIj0Q61gV31su2PHjjh48CCfyUpERETUhGh0CWt+fr626yAiIiKiRtL43iRpaWlIS0tDcXFxjZv61fYcVyIiIjIMDa6TJD3T1nNlNQp2sbGxWLx4Mfr16wcXFxflXZuJiIio6TA3N4dEIsG1a9fQtm1b/nvdBAkhUFlZiWvXrkEqlcLCwqJRy9Mo2K1ZswbJyckIDw9v1MqJiIhId2QyGdzc3HD58mWcP3/e0OVQPWxsbNChQwdIpRrdYlhJo2BXWVmp1UeHERERkW7Y2tqiS5cuuHfvnqFLoTrIZDKYmZlpZY+qRsHupZdewsaNG7FgwYJGF0BERES6JZPJ9Pr8VDIcjYLd3bt38fnnn2P37t3o1asXzM3NVabHx8drpTgiIiIiajiNgt2RI0fg5+cHADh69KjKNJ6YSURERGQYGgW7vXv3arsOIiIiImqkxl16QURERERNhkZ77IKDg+s95Lpnzx6NCyIiIiIizWgU7KrPr6t279495OTk4OjRo4iIiNBGXURERESkJo2C3cqVK2ttX7RoEcrKyhpVEBERERFpRqvn2E2ZMoXPiSUiIiIyEK0Gu8zMTFhZWWlzkURERETUQBodin3mmWdU3gshUFBQgEOHDvFpFEREREQGolGwc3BwUHkvlUrh4+ODxYsX46mnntJKYURERESkHo2CXVJSkrbrICIiIqJG0ijYVcvKykJeXh4AoHv37ujdu7dWiiIiIiIi9WkU7IqLizFx4kSkp6fD0dERAHDr1i0EBwcjJSUFbdu21WaNRERERNQAGl0VO2vWLJSWluLYsWP466+/8Ndff+Ho0aMoKSnB66+/ru0aH2ns2LFo2bIlnnvuOb2vm4iIiKip0CjY7dixA5988gm6du2qbOvWrRsSEhLw008/aa24hpo9eza+/PJLva+XiIiIqCnRKNgpFAqYm5vXaDc3N4dCoWh0UeoKCgqCnZ2d3tdLRERE1JRoFOyGDBmC2bNn4+rVq8q2K1eu4I033sDQoUPVWlZGRgZGjRoFV1dXSCQSpKam1uiTkJAAT09PWFlZISAgAH/88YcmZRMREREZNY2C3ccff4ySkhJ4enrCy8sLXl5e6NixI0pKSrB69Wq1liWXy+Hr64uEhIRap2/atAnR0dGIiYlBdnY2fH19ERoaiuLiYrXrrqioQElJicqLiIiIyFhodFWsu7s7srOzsXv3bpw4cQIA0LVrV4SEhKi9rLCwMISFhdU5PT4+HjNmzMD06dMBAGvWrMEPP/yAdevWYd68eWqtKy4uDrGxsWrXSERERNQcqLXHbs+ePejWrRtKSkogkUgwbNgwzJo1C7NmzUL//v3RvXt3/PLLL1orrrKyEllZWSqBUSqVIiQkBJmZmWovb/78+bh9+7bydenSJa3VSkRERGRoau2xW7VqFWbMmAF7e/sa0xwcHDBz5kzEx8dj0KBBWinu+vXrqKqqgpOTk0q7k5OTck8hAISEhODPP/+EXC6Hm5sbNm/ejMDAwBrLs7S0hKWlpVZqI+3wnPdDg/ueXzZCh5UQERE1f2oFuz///BPLly+vc/pTTz2FDz74oNFFqWv37t16XycRERFRU6PWodiioqJab3NSzczMDNeuXWt0UdXatGkDmUyGoqKiGnU4OztrbT1ERERExkCtYNe+fXscPXq0zulHjhyBi4tLo4uqZmFhgb59+yItLU3ZplAokJaWVuuhViIiIiJTplawGz58OBYsWIC7d+/WmHbnzh3ExMRg5MiRahVQVlaGnJwc5OTkAADy8/ORk5ODixcvAgCio6ORmJiIL774Anl5eXj11Vchl8uVV8kSERER0d/UOsfuvffew7fffgtvb29ERUXBx8cHAHDixAkkJCSgqqoK7777rloFHDp0CMHBwcr30dHRAICIiAgkJydjwoQJuHbtGhYuXIjCwkL4+flhx44dNS6oICIiIjJ1agU7Jycn/Pbbb3j11Vcxf/58CCEAABKJBKGhoUhISFA7cAUFBSmXU5eoqChERUWptVwiIiIiU6P2DYo9PDzw448/4ubNmzhz5gyEEOjSpQtatmypi/qIiIiIqIE0evIEALRs2RL9+/fXZi1ERERE1AgaPSuWiIiIiJoeBjsiIiIiI8FgR0RERGQkGOyIiIiIjASDHREREZGRYLAjIiIiMhIMdkRERERGQuP72BEREREZM895PzSo3/llI3RcScNxjx0RERGRkWCwIyIiIjISJn0oVggBACgpKdHtiuRy5Y9VFeVQCEWdXXVeSxOjqChvcF9TGxsiIjKshv4bpet/n6qXX51b6iMRDellpC5fvgx3d3dDl0FERET0SJcuXYKbm1u9fUw62CkUCly9ehV2dnaQSCQ6XVdJSQnc3d1x6dIl2Nvb63RdzRHHp34cn7pxbOrH8akfx6duHJv66XN8hBAoLS2Fq6srpNL6z6Iz6UOxUqn0kclX2+zt7fkLUg+OT/04PnXj2NSP41M/jk/dODb109f4ODg4NKgfL54gIiIiMhIMdkRERERGgsFOTywtLRETEwNLS0tDl9IkcXzqx/GpG8emfhyf+nF86saxqV9THR+TvniCiIiIyJhwjx0RERGRkWCwIyIiIjISDHZERERERoLBjoiIiMhIMNhpUUJCAjw9PWFlZYWAgAD88ccfdfZNTk6GRCJReVlZWemxWv3KyMjAqFGj4OrqColEgtTU1EfOk56ejj59+sDS0hKdO3dGcnKyzus0BHXHJj09vca2I5FIUFhYqJ+C9SguLg79+/eHnZ0d2rVrhzFjxuDkyZOPnG/z5s147LHHYGVlhZ49e+LHH3/UQ7X6p8n4mNJ3z6effopevXopbyAbGBiIn376qd55TGXbUXdsTGm7qc2yZcsgkUgwZ86cevs1he2HwU5LNm3ahOjoaMTExCA7Oxu+vr4IDQ1FcXFxnfPY29ujoKBA+bpw4YIeK9YvuVwOX19fJCQkNKh/fn4+RowYgeDgYOTk5GDOnDl46aWXsHPnTh1Xqn/qjk21kydPqmw/7dq101GFhrNv3z5ERkbiwIED2LVrF+7du4ennnoKcrm8znl+++03TJo0CS+++CIOHz6MMWPGYMyYMTh69KgeK9cPTcYHMJ3vHjc3NyxbtgxZWVk4dOgQhgwZgtGjR+PYsWO19jelbUfdsQFMZ7t52MGDB/HZZ5+hV69e9fZrMtuPIK3w9/cXkZGRyvdVVVXC1dVVxMXF1do/KSlJODg46Km6pgWA2LZtW7193n77bdG9e3eVtgkTJojQ0FAdVmZ4DRmbvXv3CgDi5s2beqmpKSkuLhYAxL59++rsM378eDFixAiVtoCAADFz5kxdl2dwDRkfU/7uEUKIli1birVr19Y6zZS3HSHqHxtT3W5KS0tFly5dxK5du8TgwYPF7Nmz6+zbVLYf7rHTgsrKSmRlZSEkJETZJpVKERISgszMzDrnKysrg4eHB9zd3R/5PyVTk5mZqTKeABAaGlrveJoaPz8/uLi4YNiwYdi/f7+hy9GL27dvAwBatWpVZx9T3nYaMj6AaX73VFVVISUlBXK5HIGBgbX2MdVtpyFjA5jmdhMZGYkRI0bU2C5q01S2HwY7Lbh+/Tqqqqrg5OSk0u7k5FTneU8+Pj5Yt24dvvvuO3z11VdQKBQYMGAALl++rI+Sm7zCwsJax7OkpAR37twxUFVNg4uLC9asWYOtW7di69atcHd3R1BQELKzsw1dmk4pFArMmTMHAwcORI8ePersV9e2Y4znID6ooeNjat89ubm5sLW1haWlJV555RVs27YN3bp1q7WvqW076oyNqW03AJCSkoLs7GzExcU1qH9T2X7M9Lo2UgoMDFT5n9GAAQPQtWtXfPbZZ1iyZIkBK6OmzsfHBz4+Psr3AwYMwNmzZ7Fy5UqsX7/egJXpVmRkJI4ePYpff/3V0KU0SQ0dH1P77vHx8UFOTg5u376NLVu2ICIiAvv27aszwJgSdcbG1LabS5cuYfbs2di1a1ezu0iEwU4L2rRpA5lMhqKiIpX2oqIiODs7N2gZ5ubm6N27N86cOaOLEpsdZ2fnWsfT3t4e1tbWBqqq6fL39zfqwBMVFYXt27cjIyMDbm5u9fata9tp6O9ic6TO+DzM2L97LCws0LlzZwBA3759cfDgQfznP//BZ599VqOvqW076ozNw4x9u8nKykJxcTH69OmjbKuqqkJGRgY+/vhjVFRUQCaTqczTVLYfHorVAgsLC/Tt2xdpaWnKNoVCgbS0tHrPV3hQVVUVcnNz4eLioqsym5XAwECV8QSAXbt2NXg8TU1OTo5RbjtCCERFRWHbtm3Ys2cPOnbs+Mh5TGnb0WR8HmZq3z0KhQIVFRW1TjOlbac29Y3Nw4x9uxk6dChyc3ORk5OjfPXr1w+TJ09GTk5OjVAHNKHtR6+XahixlJQUYWlpKZKTk8Xx48fFyy+/LBwdHUVhYaEQQojw8HAxb948Zf/Y2Fixc+dOcfbsWZGVlSUmTpworKysxLFjxwz1EXSqtLRUHD58WBw+fFgAEPHx8eLw4cPiwoULQggh5s2bJ8LDw5X9z507J2xsbMRbb70l8vLyREJCgpDJZGLHjh2G+gg6o+7YrFy5UqSmporTp0+L3NxcMXv2bCGVSsXu3bsN9RF05tVXXxUODg4iPT1dFBQUKF/l5eXKPg//bu3fv1+YmZmJDz74QOTl5YmYmBhhbm4ucnNzDfERdEqT8TGl75558+aJffv2ifz8fHHkyBExb948IZFIxM8//yyEMO1tR92xMaXtpi4PXxXbVLcfBjstWr16tejQoYOwsLAQ/v7+4sCBA8ppgwcPFhEREcr3c+bMUfZ1cnISw4cPF9nZ2QaoWj+qb9Hx8Kt6TCIiIsTgwYNrzOPn5ycsLCxEp06dRFJSkt7r1gd1x2b58uXCy8tLWFlZiVatWomgoCCxZ88ewxSvY7WNCwCVbeHh3y0hhPjmm2+Et7e3sLCwEN27dxc//PCDfgvXE03Gx5S+e1544QXh4eEhLCwsRNu2bcXQoUOVwUUI09521B0bU9pu6vJwsGuq249ECCH0t3+QiIiIiHSF59gRERERGQkGOyIiIiIjwWBHREREZCQY7IiIiIiMBIMdERERkZFgsCMiIiIyEgx2REREREaCwY6IiIjISDDYERERETVCRkYGRo0aBVdXV0gkEqSmpqo1/6JFiyCRSGq8WrRooXYtDHZEREREjSCXy+Hr64uEhASN5p87dy4KCgpUXt26dcO4cePUXhaDHREREVEjhIWFYenSpRg7dmyt0ysqKjB37ly0b98eLVq0QEBAANLT05XTbW1t4ezsrHwVFRXh+PHjePHFF9WuhcGOiIiISIeioqKQmZmJlJQUHDlyBOPGjcPTTz+N06dP19p/7dq18Pb2xqBBg9ReF4MdERERkY5cvHgRSUlJ2Lx5MwYNGgQvLy/MnTsXTzzxBJKSkmr0v3v3LjZs2KDR3joAMGtswURERERUu9zcXFRVVcHb21ulvaKiAq1bt67Rf9u2bSgtLUVERIRG62OwIyIiItKRsrIyyGQyZGVlQSaTqUyztbWt0X/t2rUYOXIknJycNFofgx0RERGRjvTu3RtVVVUoLi5+5Dlz+fn52Lt3L77//nuN18dgR0RERNQIZWVlOHPmjPJ9fn4+cnJy0KpVK3h7e2Py5MmYOnUqPvzwQ/Tu3RvXrl1DWloaevXqhREjRijnW7duHVxcXBAWFqZxLRIhhGjUpyEiIiIyYenp6QgODq7RHhERgeTkZNy7dw9Lly7Fl19+iStXrqBNmzZ4/PHHERsbi549ewIAFAoFPDw8MHXqVPzrX//SuBYGOyIiIiIjwdudEBERERkJBjsiIiIiI8FgR0RERGQkGOyIiIiIjASDHREREZGRYLAjIiIiMhIMdkRERERGgsGOiIiIyEgw2BEREREZCQY7IiIiIiPBYEdERERkJBjsiIiIiIwEgx0RERGRkWCwIyIiIjISDHZERERERoLBjoiIiMhIMNgRERERGQkGOyIiIiIjwWBHRM1GcnIyJBJJna8DBw4YusQa3n//faSmpmo8//Hjx7Fo0SKcP39eazURkfEyM3QBRETqWrx4MTp27FijvXPnzgaopn7vv/8+nnvuOYwZM0aj+Y8fP47Y2FgEBQXB09NTq7URkfFhsCOiZicsLAz9+vUzdBlERE0OD8USkVERQsDT0xOjR4+uMe3u3btwcHDAzJkzlW0VFRWIiYlB586dYWlpCXd3d7z99tuoqKh45LpOnz6NZ599Fs7OzrCysoKbmxsmTpyI27dvAwAkEgnkcjm++OIL5eHiadOmAQAuXLiA1157DT4+PrC2tkbr1q0xbtw4lUOuycnJGDduHAAgODhYuYz09HRln59++gmDBg1CixYtYGdnhxEjRuDYsWMqdRYWFmL69Olwc3ODpaUlXFxcMHr0aB7eJTJC3GNHRM3O7du3cf36dZU2iUSC1q1bQyKRYMqUKfj3v/+Nv/76C61atVL2+X//7/+hpKQEU6ZMAQAoFAr84x//wK+//oqXX34ZXbt2RW5uLlauXIlTp07Ve25cZWUlQkNDUVFRgVmzZsHZ2RlXrlzB9u3bcevWLTg4OGD9+vV46aWX4O/vj5dffhkA4OXlBQA4ePAgfvvtN0ycOBFubm44f/48Pv30UwQFBeH48eOwsbHBk08+iddffx0fffQR3nnnHXTt2hUAlH+uX78eERERCA0NxfLly1FeXo5PP/0UTzzxBA4fPqw8dPvss8/i2LFjmDVrFjw9PVFcXIxdu3bh4sWLPLxLZGwEEVEzkZSUJADU+rK0tFT2O3nypAAgPv30U5X5//GPfwhPT0+hUCiEEEKsX79eSKVS8csvv6j0W7NmjQAg9u/fX2cthw8fFgDE5s2b6625RYsWIiIiokZ7eXl5jbbMzEwBQHz55ZfKts2bNwsAYu/evSp9S0tLhaOjo5gxY4ZKe2FhoXBwcFC237x5UwAQK1asqLdOIjIOPBRLRM1OQkICdu3apfL66aeflNO9vb0REBCADRs2KNv++usv/PTTT5g8eTIkEgkAYPPmzejatSsee+wxXL9+XfkaMmQIAGDv3r111uDg4AAA2LlzJ8rLy9X+DNbW1sqf7927hxs3bqBz585wdHREdnb2I+fftWsXbt26hUmTJqnULpPJEBAQoKzd2toaFhYWSE9Px82bN9Wuk4iaFx6KJaJmx9/f/5EXT0ydOhVRUVG4cOECPDw8sHnzZty7dw/h4eHKPqdPn0ZeXh7atm1b6zKKi4vrXH7Hjh0RHR2N+Ph4bNiwAYMGDcI//vEPTJkyRRn66nPnzh3ExcUhKSkJV65cgRBCOa36HL36nD59GgCUIfRh9vb2AABLS0ssX74cb775JpycnPD4449j5MiRmDp1KpydnR+5HiJqXhjsiMgoTZw4EW+88QY2bNiAd955B1999RX69esHHx8fZR+FQoGePXsiPj6+1mW4u7vXu44PP/wQ06ZNw3fffYeff/4Zr7/+OuLi4nDgwAG4ubnVO++sWbOQlJSEOXPmIDAwEA4ODpBIJJg4cSIUCsUjP191n/Xr19ca0MzM/vf1PmfOHIwaNQqpqanYuXMnFixYgLi4OOzZswe9e/d+5LqIqPlgsCMio9SqVSuMGDECGzZswOTJk7F//36sWrVKpY+Xlxf+/PNPDB06VHl4Vl09e/ZEz5498d577+G3337DwIEDsWbNGixduhQA6lzuli1bEBERgQ8//FDZdvfuXdy6dUulX13zV1+E0a5dO4SEhDyyTi8vL7z55pt48803cfr0afj5+eHDDz/EV1991ZCPSUTNBM+xIyKjFR4ejuPHj+Ott96CTCbDxIkTVaaPHz8eV65cQWJiYo1579y5A7lcXueyS0pKcP/+fZW2nj17QiqVqtwqpUWLFjXCGgDIZDKVw68AsHr1alRVVam0tWjRAgBqLCM0NBT29vZ4//33ce/evRrLv3btGgCgvLwcd+/eVZnm5eUFOzu7Bt3ShYiaF+6xI6Jm56effsKJEydqtA8YMACdOnVSvh8xYgRat26NzZs3IywsDO3atVPpHx4ejm+++QavvPIK9u7di4EDB6KqqgonTpzAN998g507d9Z5Lt+ePXsQFRWFcePGwdvbG/fv38f69eshk8nw7LPPKvv17dsXu3fvRnx8PFxdXdGxY0cEBARg5MiRWL9+PRwcHNCtWzdkZmZi9+7daN26tcp6/Pz8IJPJsHz5cty+fRuWlpYYMmQI2rVrh08//RTh4eHo06cPJk6ciLZt2+LixYv44YcfMHDgQHz88cc4deoUhg4divHjx6Nbt24wMzPDtm3bUFRUVCPoEpERMPRluUREDVXf7U4AiKSkpBrzvPbaawKA2LhxY63LrKysFMuXLxfdu3cXlpaWomXLlqJv374iNjZW3L59u85azp07J1544QXh5eUlrKysRKtWrURwcLDYvXu3Sr8TJ06IJ598UlhbWwsAyluf3Lx5U0yfPl20adNG2NraitDQUHHixAnh4eFR4/YoiYmJolOnTkImk9W49cnevXtFaGiocHBwEFZWVsLLy0tMmzZNHDp0SAghxPXr10VkZKR47LHHRIsWLYSDg4MICAgQ33zzzaMHnIiaHYkQDx0LICIyIm+88Qb++9//orCwEDY2NoYuh4hIp3iOHREZrbt37+Krr77Cs88+y1BHRCaB59gRkdEpLi7G7t27sWXLFty4cQOzZ882dElERHrBYEdERuf48eOYPHky2rVrh48++gh+fn6GLomISC94jh0RERGRkeA5dkRERERGwqQPxSoUCly9ehV2dnYa33WeiIiISJeEECgtLYWrqyuk0vr3yZl0sLt69eojnwVJRERE1BRcunTpkc+hNulgZ2dnB+DvgbK3t9fdiuRywNX175+vXgX+7xFBRERERI9SUlICd3d3ZW6pj0kHu+rDr/b29roNdjLZ/362t2ewIyIiIrU15LQxkw52htB1wQ7csbCqc/r5ZSP0WA0REREZE14VS0RERGQkGOyIiIiIjAQPxRIRERk5hUKByspKQ5dBdTA3N4fswfPxG4HBjoiIyIhVVlYiPz8fCoXC0KVQPRwdHeHs7Nzo++oy2BERERkpIQQKCgogk8ng7u7+yJvbkv4JIVBeXo7i4mIAgIuLS6OWx2BHRERkpO7fv4/y8nK4urrCxsbG0OVQHaytrQEAxcXFaNeuXaMOyzK6ExERGamqqioAgIWFhYEroUepDt737t1r1HIY7IiIiIwcn4fe9Gnr76jZB7tbt26hX79+8PPzQ48ePZCYmGjokoiIiIgMotkHOzs7O2RkZCAnJwe///473n//fdy4ccPQZREREVEzlJycDEdHR60u8/z585BIJMjJydHqcmvT7IOdTCZTHpeuqKiAEAJCCANXRURERJqaNm0aJBIJli1bptKempqq88PKEyZMwKlTp3S6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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "print(\n", " f\"Nominal sampling frequency of gaze: {gaze.sampling_freq_nominal} Hz. \"\n", " f\"Actual: {gaze.sampling_freq_effective:.2f} Hz\"\n", ")\n", "print(\n", " f\"Nominal sampling frequency of eye states: {eye_states.sampling_freq_nominal} Hz. \"\n", " f\"Actual: {eye_states.sampling_freq_effective:.2f} Hz\"\n", ")\n", "print(\n", " f\"Nominal sampling frequency of IMU: {imu.sampling_freq_nominal} Hz. \"\n", " f\"Actual: {imu.sampling_freq_effective:.2f} Hz\"\n", ")\n", "\n", "fig, axs = plt.subplots(3, 1, tight_layout=True)\n", "\n", "axs[0].hist(gaze.ts_diff, bins=50)\n", "axs[0].axvline(1e9 / gaze.sampling_freq_nominal, c=\"red\", label=\"Nominal\")\n", "axs[0].set_title(\"Gaze\")\n", "\n", "axs[1].hist(eye_states.ts_diff, bins=50)\n", "axs[1].axvline(1e9 / eye_states.sampling_freq_nominal, c=\"red\", label=\"Nominal\")\n", "axs[1].set_title(\"Eye states\")\n", "\n", "axs[2].hist(imu.ts_diff, bins=50)\n", "axs[2].axvline(1e9 / imu.sampling_freq_nominal, c=\"red\", label=\"Nominal\")\n", "axs[2].set_title(\"IMU\")\n", "axs[2].set_xlabel(\"Time difference [ns]\")\n", "\n", "for i in range(3):\n", " axs[i].set_yscale(\"log\")\n", " axs[i].set_ylabel(\"Counts\")\n", " axs[i].legend()\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For gaze and eye states data, the empirical distribution of time differences is close to the expected value (though with some integer multiples of the nominal sampling rate, which hints at possible eye video frame drops). For IMU data, the distribution is much wider." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Interpolating data streams\n", "\n", "Given the presence of irregular sampling, if you want to perform analyses that assume continuous data streams, interpolation is necessary. PyNeon uses the `scipy.interpolate.interp1d` [(API reference)](https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.interp1d.html) function to interpolate data streams. For instances of `NeonStream`, we can call `interpolate()` which returns a copy of the object with the data interpolated with the default parameters." ] }, { "cell_type": "code", "execution_count": 33, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Nominal sampling frequency of gaze: 200 Hz. Actual (after interpolation): 200.03 Hz\n", "Only one unique time difference: [5000000]\n", "The new gaze stream is uniformly sampled: True\n" ] } ], "source": [ "# Resample to the nominal sampling frequency\n", "gaze_resampled = gaze.interpolate()\n", "\n", "# Three ways you can check if the resampling was successful:\n", "# 1. Compare the effective sampling frequency to the nominal sampling frequency\n", "print(\n", " f\"Nominal sampling frequency of gaze: {gaze_resampled.sampling_freq_nominal} Hz. \"\n", " f\"Actual (after interpolation): {gaze_resampled.sampling_freq_effective:.2f} Hz\"\n", ")\n", "# 2. Check the number of unique time differences\n", "print(f\"Only one unique time difference: {np.unique(gaze_resampled.ts_diff)}\")\n", "# 3. Call the `is_uniformly_sampled` property (boolean)\n", "print(\n", " f\"The new gaze stream is uniformly sampled: {gaze_resampled.is_uniformly_sampled}\"\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In the above example, we resampled the gaze data with default parameters, which means that the resampled data will have the same start and timestamps as the original data, and the sampling rate is set to the nominal sampling frequency (200 Hz, as specified by Pupil Labs). Notice that resampling would not change the data type of the columns. For example, the `bool`-type `worn` column and the integer-type `fixation_id` column are preserved.\n", "nominal sampling rate (you can also customize by passing the `new_ts` argument).\n", "\n", "Alternatively, one can also resample the gaze data to any desired timestamps by specifying the `new_ts` parameter. This is especially helpful when synchronizing different data streams. For example, we can resample the gaze data (~200Hz) to the timestamps of the IMU data (~110Hz)." ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Original gaze data length: 6091\n", "Original IMU data length: 3459\n", "Gaze data length after resampling to IMU: 3459\n" ] } ], "source": [ "print(f\"Original gaze data length: {gaze.data.shape[0]}\")\n", "print(f\"Original IMU data length: {imu.data.shape[0]}\")\n", "gaze_resampled_to_imu = gaze.interpolate(new_ts=imu.ts)\n", "print(\n", " f\"Gaze data length after resampling to IMU: {gaze_resampled_to_imu.data.shape[0]}\"\n", ")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Concatenating different streams\n", "\n", "Based on the resampling method, it is then possible to concatenate different streams into a single DataFrame by resampling them to common timestamps. The method `concat_streams()` provides such functionality. It takes a list of stream names and resamples them to common timestamps, defined by the latest start and earliest end timestamps of the streams. The news ampling frequency can either be directly specified or taken from the lowest/highest sampling frequency of the streams.\n", "\n", "In the following example, we will concatenate the gaze, eye states, and IMU streams into a single DataFrame using the default parameters (e.g., using the lowest sampling frequency of the streams)." ] }, { "cell_type": "code", "execution_count": 35, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Concatenating streams:\n", "\tGaze\n", "\t3D eye states\n", "\tIMU\n", "Using lowest sampling rate: 110 Hz (['imu'])\n", "Using latest start timestamp: 1732621490607650343 (['imu'])\n", "Using earliest last timestamp: 1732621520979070343 (['gaze' '3d_eye_states'])\n", " gaze x [px] gaze y [px] worn fixation id blink id \\\n", "1732621490607650343 705.518843 554.990998 1 1 \n", "1732621490616741252 704.882466 553.793144 1 1 \n", "1732621490625832161 707.703787 556.712159 1 1 \n", "1732621490634923070 711.389879 553.846843 1 1 \n", "1732621490644013979 709.281775 555.543777 1 1 \n", "\n", " azimuth [deg] elevation [deg] pupil diameter left [mm] \\\n", "1732621490607650343 -7.085339 3.473196 3.346414 \n", "1732621490616741252 -7.126717 3.550038 3.363306 \n", "1732621490625832161 -6.944033 3.363048 3.368352 \n", "1732621490634923070 -6.707339 3.547815 3.365432 \n", "1732621490644013979 -6.842683 3.438366 3.374732 \n", "\n", " pupil diameter right [mm] eyeball center left x [mm] \\\n", "1732621490607650343 3.360563 -32.282935 \n", "1732621490616741252 3.359459 -32.249418 \n", "1732621490625832161 3.350918 -32.216781 \n", "1732621490634923070 3.361014 -32.249155 \n", "1732621490644013979 3.365781 -32.234159 \n", "\n", " ... acceleration x [g] acceleration y [g] \\\n", "1732621490607650343 ... -0.067383 -0.340820 \n", "1732621490616741252 ... -0.062619 -0.315917 \n", "1732621490625832161 ... -0.052682 -0.329993 \n", "1732621490634923070 ... -0.058795 -0.334090 \n", "1732621490644013979 ... -0.060815 -0.322199 \n", "\n", " acceleration z [g] roll [deg] pitch [deg] yaw [deg] \\\n", "1732621490607650343 0.932129 1.923968 -20.230545 132.920122 \n", "1732621490616741252 0.925714 1.923949 -20.227639 132.924402 \n", "1732621490625832161 0.924432 1.920479 -20.228228 132.927574 \n", "1732621490634923070 0.931812 1.916587 -20.228839 132.931756 \n", "1732621490644013979 0.925476 1.916104 -20.227092 132.937429 \n", "\n", " quaternion w quaternion x quaternion y quaternion z \n", "1732621490607650343 0.395828 -0.085287 -0.154390 0.901227 \n", "1732621490616741252 0.395796 -0.085271 -0.154370 0.901246 \n", "1732621490625832161 0.395766 -0.085242 -0.154389 0.901258 \n", "1732621490634923070 0.395728 -0.085207 -0.154411 0.901275 \n", "1732621490644013979 0.395683 -0.085190 -0.154403 0.901297 \n", "\n", "[5 rows x 34 columns]\n" ] } ], "source": [ "concat_stream = recording.concat_streams([\"gaze\", \"eye_states\", \"imu\"])\n", "print(concat_stream.data.head())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We show an exemplary sampling of eye, imu and concatenated data below. It can be seen that imu data has subsequent missing values which can in turn be interpolated" ] }, { "cell_type": "code", "execution_count": 36, "metadata": {}, "outputs": [ { "ename": "NameError", "evalue": "name 'time_to_ts' is not defined", "output_type": "error", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", "\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", "Cell \u001b[1;32mIn[36], line 3\u001b[0m\n\u001b[0;32m 1\u001b[0m start_time \u001b[38;5;241m=\u001b[39m \u001b[38;5;241m5\u001b[39m\n\u001b[0;32m 2\u001b[0m end_time \u001b[38;5;241m=\u001b[39m \u001b[38;5;241m5.3\u001b[39m\n\u001b[1;32m----> 3\u001b[0m start_ts \u001b[38;5;241m=\u001b[39m \u001b[43mtime_to_ts\u001b[49m(start_time, concat_stream)\n\u001b[0;32m 4\u001b[0m end_ts \u001b[38;5;241m=\u001b[39m time_to_ts(end_time, concat_stream)\n\u001b[0;32m 6\u001b[0m raw_gaze_data_slice \u001b[38;5;241m=\u001b[39m gaze\u001b[38;5;241m.\u001b[39mdata[\n\u001b[0;32m 7\u001b[0m (gaze\u001b[38;5;241m.\u001b[39mdata[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mtimestamp [ns]\u001b[39m\u001b[38;5;124m\"\u001b[39m] \u001b[38;5;241m>\u001b[39m\u001b[38;5;241m=\u001b[39m start_ts) \u001b[38;5;241m&\u001b[39m (gaze\u001b[38;5;241m.\u001b[39mdata[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mtimestamp [ns]\u001b[39m\u001b[38;5;124m\"\u001b[39m] \u001b[38;5;241m<\u001b[39m\u001b[38;5;241m=\u001b[39m end_ts)\n\u001b[0;32m 8\u001b[0m ]\n", "\u001b[1;31mNameError\u001b[0m: name 'time_to_ts' is not defined" ] } ], "source": [ "start_time = 5\n", "end_time = 5.3\n", "start_ts = time_to_ts(start_time, concat_stream)\n", "end_ts = time_to_ts(end_time, concat_stream)\n", "\n", "raw_gaze_data_slice = gaze.data[\n", " (gaze.data[\"timestamp [ns]\"] >= start_ts) & (gaze.data[\"timestamp [ns]\"] <= end_ts)\n", "]\n", "raw_eye_states_data_slice = eye_states.data[\n", " (eye_states.data[\"timestamp [ns]\"] > start_ts)\n", " & (eye_states.data[\"timestamp [ns]\"] <= end_ts)\n", "]\n", "raw_imu_data_slice = imu.data[\n", " (imu.data[\"timestamp [ns]\"] >= start_ts) & (imu.data[\"timestamp [ns]\"] <= end_ts)\n", "]\n", "concat_data_slice = concat_stream[\n", " (concat_stream[\"timestamp [ns]\"] >= start_ts)\n", " & (concat_stream[\"timestamp [ns]\"] <= end_ts)\n", "]\n", "\n", "# plot all data in the same scatter plot\n", "plt.figure(figsize=(15, 4))\n", "plt.scatter(\n", " raw_gaze_data_slice[\"timestamp [ns]\"],\n", " np.zeros_like(raw_gaze_data_slice[\"timestamp [ns]\"]) + 2,\n", " label=\"Raw gaze data\",\n", " color=\"red\",\n", ")\n", "plt.scatter(\n", " raw_eye_states_data_slice[\"timestamp [ns]\"],\n", " np.zeros_like(raw_eye_states_data_slice[\"timestamp [ns]\"]) + 1,\n", " label=\"Raw eye states data\",\n", " color=\"orange\",\n", ")\n", "plt.scatter(\n", " raw_imu_data_slice[\"timestamp [ns]\"],\n", " np.zeros_like(raw_imu_data_slice[\"timestamp [ns]\"]),\n", " label=\"Raw IMU data\",\n", " color=\"blue\",\n", ")\n", "plt.scatter(\n", " concat_data_slice[\"timestamp [ns]\"],\n", " np.zeros_like(concat_data_slice[\"timestamp [ns]\"]) - 1,\n", " label=\"Concatenated data\",\n", " color=\"green\",\n", ")\n", "# set x-ticks with higher frequency and add gridlines\n", "plt.xticks(concat_data_slice[\"timestamp [ns]\"], labels=None)\n", "plt.yticks([])\n", "plt.grid()\n", "plt.legend()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A linear interpolation allows us to estimate missing values. In the end, the concatenated dataframe combines all continuous data into one central location" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# plot imu data and interpolated data in same plot\n", "plt.figure(figsize=(16, 3))\n", "plt.scatter(\n", " raw_imu_data_slice[\"time [s]\"],\n", " raw_imu_data_slice[\"acceleration z [g]\"],\n", " label=\"Raw imu data\",\n", " color=\"blue\",\n", ")\n", "plt.plot(\n", " concat_data_slice[\"time [s]\"],\n", " concat_data_slice[\"acceleration z [g]\"],\n", " label=\"Interpolated imu data\",\n", " color=\"green\",\n", ")\n", "plt.legend()" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "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.12.6" } }, "nbformat": 4, "nbformat_minor": 2 }