{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "Pupil Core camera synchronisation\n", "=================================\n", "\n", "We used this protocol to investigate how well Pupil Capture synchronises the clocks of the Eye and World cameras on a Pupil Core headset. See [here](06b_pupil_core_timing_analysis.ipynb) for a detailed explanation and analysis showing how this is dependant on operating system and camera settings.\n" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "STLAB device setup complete...\n", "\"1s_near_IR_pulse.dsf\" saved in the current working directory.\n", "video file loaded...\n", "> Waiting for a light to stamp...\n", "> Waiting for a light to stamp...\n", "> Waiting for a light to stamp...\n", "playing video file...\n", "> Light stamped on frame.eye.0 at 346194.799512\n", "> Light stamped on frame.world at 346194.774064\n", "> Light stamped on frame.eye.1 at 346194.805085\n", "> Waiting for a light to stamp...\n", "> Waiting for a light to stamp...\n", "> Waiting for a light to stamp...\n", "playing video file...\n", "> Light stamped on frame.eye.0 at 346201.864576\n", "> Light stamped on frame.eye.1 at 346201.870149\n", "> Light stamped on frame.world at 346201.846864\n", "> Waiting for a light to stamp...\n", "> Waiting for a light to stamp...\n", "> Waiting for a light to stamp...\n", "playing video file...\n", "> Light stamped on frame.world at 346208.919664\n", "> Light stamped on frame.eye.0 at 346208.945881\n", "> Light stamped on frame.eye.1 at 346208.951454\n" ] }, { "data": { "text/plain": [ "'OK'" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "from time import sleep\n", "\n", "from pyplr.stlab import SpectraTuneLab, pulse_protocol\n", "from pyplr.pupil import PupilCore\n", "\n", "# Set up pupil\n", "p = PupilCore()\n", "\n", "# Annotations / notifications can crash Capture if they are sent too\n", "# close together so we will wait and send them at the end of the script\n", "p.annotation_capture_plugin(should='stop')\n", "sleep(.02)\n", "\n", "# Setup stlab and make spectrum with near-IR\n", "d = SpectraTuneLab(password='****************')\n", "spec = [0, 0, 0, 0, 0, 0, 0, 4095, 0, 0]\n", "pulse_protocol(spec, 1000, '1s_near_IR_pulse')\n", "d.load_video_file('1s_near_IR_pulse.dsf')\n", "\n", "# light_stamper params\n", "threshold = 10\n", "timeout = 6.\n", "\n", "# Make annotations for each camera\n", "world_annotation = p.new_annotation('LIGHT_ON_WORLD')\n", "eye_0_annotation = p.new_annotation('LIGHT_ON_EYE_0')\n", "eye_1_annotation = p.new_annotation('LIGHT_ON_EYE_1')\n", "\n", "# Dict for the light_stamper timestamps\n", "results = {'world': [],\n", " 'eye_0': [],\n", " 'eye_1': []}\n", "\n", "# Start recording and wait a while\n", "p.command('R pupil_core_camera_sync_tests')\n", "sleep(5.)\n", "\n", "# Begin testing protocol\n", "for i in range(3):\n", " # Start light_stampers\n", " lst_world = p.light_stamper(\n", " world_annotation,\n", " threshold, \n", " timeout,\n", " topic='frame.world')\n", " lst_eye_0 = p.light_stamper(\n", " eye_0_annotation, \n", " threshold, \n", " timeout,\n", " topic='frame.eye.0')\n", " lst_eye_1 = p.light_stamper(\n", " eye_1_annotation, \n", " threshold, \n", " timeout, \n", " topic='frame.eye.1')\n", " \n", " # Wait 100 ms then flash light\n", " sleep(1.)\n", " d.play_video_file()\n", " sleep(timeout)\n", " \n", " # Add timestamps to results dictionary\n", " results['world'].append(lst_world.result())\n", " results['eye_0'].append(lst_eye_0.result())\n", " results['eye_1'].append(lst_eye_1.result())\n", "\n", "# Start Annotation Capture plugin\n", "p.annotation_capture_plugin(should='start')\n", "sleep(.02)\n", "\n", "# Send the annotations with 20 ms spacing\n", "for k in results.keys():\n", " for ts in [val[1] for val in results[k]]:\n", " annotation = p.new_annotation('light_on_{}'.format(k))\n", " annotation['timestamp'] = ts\n", " p.send_annotation(annotation)\n", " sleep(0.02)\n", " \n", "# Wait for 5 s and stop recording\n", "sleep(5.) \n", "p.command('r')\n" ] } ], "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.7.7" } }, "nbformat": 4, "nbformat_minor": 4 }