diff --git a/DeToX/Base.py b/DeToX/Base.py
index abefc60..ee59b43 100644
--- a/DeToX/Base.py
+++ b/DeToX/Base.py
@@ -157,11 +157,27 @@ def set_eyetracking_settings(self, desired_fps=None, desired_illumination_mode=N
Notes
-----
- Settings cannot be changed during active recording. If an ongoing recording
- is detected, a non-blocking warning is issued and the function exits safely.
+ is detected, a non-blocking warning is issued and the function exits safely.
- When `use_gui=True`, a PsychoPy dialog window appears. It must be closed
- manually before the program continues.
+ manually before the program continues.
- After successfully applying new settings, the internal attributes `self.fps`
- and `self.illum_mode` are updated to reflect the current device configuration.
+ and `self.illum_mode` are updated to reflect the current device configuration.
+
+ Examples
+ --------
+ ```python
+ # Set frequency to 120 Hz programmatically
+ ET_controller.set_eyetracking_settings(desired_fps=120)
+
+ # Set illumination mode to 'Bright'
+ ET_controller.set_eyetracking_settings(desired_illumination_mode='Bright')
+
+ # Set both frequency and illumination mode
+ ET_controller.set_eyetracking_settings(desired_fps=120, desired_illumination_mode='Bright')
+
+ # Use GUI to select settings interactively
+ ET_controller.set_eyetracking_settings(use_gui=True)
+ ```
"""
# Pre-condition Check
@@ -279,15 +295,32 @@ def show_status(self, decision_key="space", video_help=True):
Examples
--------
- >>> # Use built-in video
- >>> tracker.show_status()
-
- >>> # No video
- >>> tracker.show_status(video_help=False)
-
- >>> # Custom video
- >>> my_video = visual.MovieStim(win, 'custom.mp4', size=0.5, pos=(0, -0.2))
- >>> tracker.show_status(video_help=my_video)
+ ```python
+ # Basic usage with built-in video
+ ET_controller.show_status()
+
+ # No background video
+ ET_controller.show_status(video_help=False)
+
+ # Custom exit key
+ ET_controller.show_status(decision_key='return')
+
+ # Use custom video
+ from psychopy import visual
+ my_video = visual.MovieStim(
+ win,
+ 'instructions.mp4',
+ size=(0.8, 0.6),
+ pos=(0, -0.1)
+ )
+ ET_controller.show_status(video_help=my_video)
+
+ # Complete workflow: position participant before calibration
+ ET_controller.show_status() # Position participant
+ success = ET_controller.calibrate(5) # Run calibration
+ if success:
+ ET_controller.start_recording('data.h5') # Start recording
+ ```
"""
# --- 1. Instruction Display ---
@@ -447,12 +480,12 @@ def show_status(self, decision_key="space", video_help=True):
def calibrate(self,
- calibration_points,
- infant_stims=None,
- shuffle=True,
- audio=True,
- anim_type='zoom',
- visualization_style='circles'
+ calibration_points=5,
+ infant_stims=True,
+ shuffle=True,
+ audio=True,
+ anim_type='zoom',
+ visualization_style='circles'
):
"""
Run infant-friendly calibration procedure.
@@ -471,62 +504,114 @@ def calibrate(self,
- 9: Comprehensive 9-point pattern (3×3 grid).
- list: Custom points in normalized coordinates [-1, 1].
Example: [(-0.4, 0.4), (0.4, 0.4), (0.0, 0.0)]
- infant_stims : list of str or True, optional
+ infant_stims : list of str or None, optional
Paths to engaging image files for calibration targets (e.g., colorful
- characters, animated objects). If True (default), uses built-in stimuli
+ characters, animated objects). If None (default), uses built-in stimuli
from the package. If fewer stimuli than calibration points are provided,
stimuli are automatically repeated in sequence to cover all points
- (e.g., 3 stimuli for 7 points becomes [s1, s2, s3, s1, s2, s3, s1]).
+ (e.g., 3 stimuli for 7 points becomes `[s1, s2, s3, s1, s2, s3, s1]`).
+ Defaults to `None`, which resolves to `True`.
+
+
+
+
+
+
+
+ This is the first item's accordion body. It is shown by default, until the collapse plugin adds the appropriate classes that we use to style each element. These classes control the overall appearance, as well as the showing and hiding via CSS transitions. You can modify any of this with custom CSS or overriding our default variables. It's also worth noting that just about any HTML can go within the .accordion-body, though the transition does limit overflow.
+
+
+
+
+
+
+
+
+
+ This is the second item's accordion body. It is hidden by default, until the collapse plugin adds the appropriate classes that we use to style each element. These classes control the overall appearance, as well as the showing and hiding via CSS transitions. You can modify any of this with custom CSS or overriding our default variables. It's also worth noting that just about any HTML can go within the .accordion-body, though the transition does limit overflow.
+
+
+
+
+
+
+
+
+
+ This is the third item's accordion body. It is hidden by default, until the collapse plugin adds the appropriate classes that we use to style each element. These classes control the overall appearance, as well as the showing and hiding via CSS transitions. You can modify any of this with custom CSS or overriding our default variables. It's also worth noting that just about any HTML can go within the .accordion-body, though the transition does limit overflow.
+
+
+
+
shuffle : bool, optional
- Whether to randomize stimulus presentation order. When True (default),
+ Whether to randomize stimulus presentation order. When `True` (default),
stimuli are shuffled after any necessary repetition and before assignment
- to calibration points. Set to False if you want deterministic
- stimulus-to-point mapping or specific stimulus ordering. Default True.
+ to calibration points. Set to `False` if you want deterministic
+ stimulus-to-point mapping or specific stimulus ordering. Default is `True`.
+
audio : bool or psychopy.sound.Sound or None, optional
- Controls attention-getting audio during calibration:
- - True: Uses built-in calibration sound (default). Sound loops
- continuously while stimulus is selected.
- - False or None: No audio feedback.
- - psychopy.sound.Sound: Uses your pre-loaded custom sound object.
- You are responsible for setting the sound parameters (e.g.,
- loops=-1 for continuous looping).
- The audio provides auditory feedback when the experimenter selects
- a calibration point by pressing a number key.
- Default True.
+ Controls attention-getting audio during calibration.
+ If `True` (default), uses the built-in calibration sound, which loops
+ continuously while a stimulus is selected.
+ If `False` or `None`, no audio feedback is played.
+ If a `psychopy.sound.Sound` object is provided, it will be used as the
+ audio source; you are responsible for configuring it (e.g., setting
+ `loops=-1` for continuous looping).
+ The audio provides feedback when the experimenter selects a calibration
+ point by pressing a number key. Default is `True`.
+
anim_type : {'zoom', 'trill'}, optional
- Animation style for the calibration stimuli:
- - 'zoom': Smooth size oscillation (default)
- - 'trill': Rapid rotation with pauses
- visualization_style : {'lines', 'circles'}, optional
- How to display calibration results:
- - 'lines': Draw lines from targets to gaze samples
- - 'circles': Draw small filled circles at gaze sample positions
- Default 'circles'.
+ Animation style for the calibration stimuli.
+ `'zoom'` applies a smooth size oscillation (default).
+ `'trill'` uses rapid rotation with pauses.
+ Default is `'zoom'`.
+
+ visualization_style : {'circles','lines'}, optional
+ How to display calibration results.
+ `'lines'` draws lines from targets to gaze samples.
+ `'circles'` draws small filled circles at gaze sample positions.
Returns
-------
bool
- True if calibration completed successfully and was accepted by the user,
- False if calibration was aborted or failed.
+ `True` if calibration completed successfully and was accepted by the user,
+ `False` if calibration was aborted or failed.
Examples
--------
- >>> # Standard 5-point calibration with default audio
- >>> controller.calibrate(5)
-
- >>> # Calibration without audio
- >>> controller.calibrate(5, audio=False)
-
- >>> # Custom audio
- >>> from psychopy import sound
- >>> my_sound = sound.Sound('custom_beep.wav', loops=-1)
- >>> controller.calibrate(5, audio=my_sound)
-
- >>> # 9-point calibration with custom stimuli and trill animation
- >>> controller.calibrate(9, infant_stims=['stim1.png', 'stim2.png'],
- ... anim_type='trill')
- """
+ Standard 5-point calibration with default audio:
+
+ ```python
+ ET_controller.calibrate(5)
+ ```
+
+ Calibration without audio:
+ ```python
+ ET_controller.calibrate(5, audio=False)
+ ```
+
+ Custom audio:
+
+ ```python
+ from psychopy import sound
+ # Load custom sound and set to loop indefinitely
+ my_sound = sound.Sound('custom_beep.wav', loops=-1)
+ ET_controller.calibrate(5, audio=my_sound)
+ ```
+
+ 9-point calibration with custom stimuli and trill animation:
+
+ ```python
+ ET_controller.calibrate(9, infant_stims=['stim1.png', 'stim2.png'], anim_type='trill')
+ ```
+ """
# --- Visualization Style Validation ---
valid_styles = ['lines', 'circles']
if visualization_style not in valid_styles:
@@ -669,6 +754,16 @@ def save_calibration(self, filename=None, use_gui=False):
-----
- In simulation mode, saving is skipped and a warning is issued.
- If `use_gui` is True and the dialog is cancelled, returns False.
+
+ Examples
+ --------
+ ```python
+ # Save with default timestamped name
+ ET_controller.save_calibration()
+
+ ### Save with specified filename
+ ET_controller.save_calibration('subject_01_calib.dat')
+ ```
"""
# --- Simulation guard ---
if self.simulate:
@@ -751,6 +846,7 @@ def load_calibration(self, filename=None, use_gui=False):
use_gui : bool, optional
If `True`, a graphical file-open dialog is displayed for the user to
select the calibration file. Defaults to `False`.
+
Returns
-------
bool
@@ -764,6 +860,32 @@ def load_calibration(self, filename=None, use_gui=False):
If the method is called while the ETracker is in simulation mode.
ValueError
If `use_gui` is `False` and `filename` is not provided.
+
+ Examples
+ --------
+ ```python
+ # Load calibration from specific file
+ success = ET_controller.load_calibration('subject_01_calib.dat')
+ if success:
+ ET_controller.start_recording('subject_01_data.h5')
+
+ # Use GUI to select file
+ success = ET_controller.load_calibration(use_gui=True)
+
+ # Multi-session workflow
+ # Session 1: Calibrate and save
+ ET_controller.calibrate(5)
+ ET_controller.save_calibration('participant_123.dat')
+ ET_controller.start_recording('session_1.h5')
+ # ... run experiment ...
+ ET_controller.stop_recording()
+
+ # Session 2: Load previous calibration
+ ET_controller.load_calibration('participant_123.dat')
+ ET_controller.start_recording('session_2.h5')
+ # ... run experiment ...
+ ET_controller.stop_recording()
+ ```
"""
# --- Pre-condition Check: Ensure not in simulation mode ---
# Calibration can only be applied to a physical eye tracker.
@@ -862,11 +984,13 @@ def start_recording(self, filename=None, raw_format=False):
Examples
--------
- # Standard format (simplified columns)
- tracker.start_recording('data.h5')
+ ```python
+ ### Standard format (simplified columns)
+ ET_controller.start_recording('data.h5')
- # Raw format (all Tobii SDK columns preserved)
- tracker.start_recording('data_raw.h5', raw_format=True)
+ ### Raw format (all Tobii SDK columns preserved)
+ ET_controller.start_recording('data_raw.h5', raw_format=True)
+ ```
"""
# --- State validation ---
# Check current recording status and handle conflicts
@@ -1007,9 +1131,11 @@ def record_event(self, label):
Examples
--------
- tracker.record_event('trial_1_start')
- # ... present stimulus ...
- tracker.record_event('stimulus_offset')
+ ```python
+ ET_controller.record_event('trial_1_start')
+ # present stimulus
+ ET_controller.record_event('stimulus_offset')
+ ```
"""
# --- State validation ---
# Ensure recording is active before logging events
@@ -1044,6 +1170,61 @@ def save_data(self):
Uses thread-safe buffer swapping to minimize lock time, then processes
and saves data in CSV or HDF5 format. Events are merged with gaze data
based on timestamp proximity.
+
+ This method is typically called automatically by `stop_recording()`, but
+ can be called manually during recording to periodically save data and
+ clear buffers. This is useful for long experiments to avoid memory buildup
+ and ensure data is saved even if the program crashes.
+
+ Notes
+ -----
+ - Automatically called by `stop_recording()`
+ - Safe to call during active recording
+ - Clears buffers after saving
+ - Events are matched to nearest gaze sample by timestamp
+
+ Examples
+ --------
+ ```python
+ # Automatic saving (most common)
+ ET_controller.start_recording('data.h5')
+ # ... run experiment ...
+ ET_controller.stop_recording() # Automatically calls save_data()
+
+ # Manual periodic saves for long experiments
+ ET_controller.start_recording('long_experiment.h5')
+
+ for trial in range(100):
+ ET_controller.record_event(f'trial_{trial}_start')
+ # ... present stimuli ...
+ ET_controller.record_event(f'trial_{trial}_end')
+
+ # Save data every 10 trials to prevent memory buildup
+ if (trial + 1) % 10 == 0:
+ ET_controller.save_data() # Saves and clears buffers
+
+ ET_controller.stop_recording()
+
+ # Save data at natural break points
+ ET_controller.start_recording('session.h5')
+
+ # Block 1
+ for trial in range(20):
+ # ... run trial ...
+ pass
+ ET_controller.save_data() # Save after block 1
+
+ # Short break
+ core.wait(30)
+
+ # Block 2
+ for trial in range(20):
+ # ... run trial ...
+ pass
+ ET_controller.save_data() # Save after block 2
+
+ ET_controller.stop_recording()
+ ```
"""
# --- Performance monitoring ---
start_saving = core.getTime()
@@ -1109,6 +1290,78 @@ def save_data(self):
def gaze_contingent(self, N=5):
"""
Initialize real-time gaze buffer for contingent applications.
+
+ Creates a rolling buffer that stores the most recent N gaze samples,
+ enabling real-time gaze-contingent paradigms. Must be called before
+ using `get_gaze_position()` for real-time gaze tracking.
+
+ The buffer automatically maintains the N most recent samples, discarding
+ older data. This provides a stable estimate of current gaze position by
+ aggregating across multiple samples.
+
+ Parameters
+ ----------
+ N : int, optional
+ Number of recent gaze samples to store in the rolling buffer.
+ Larger values provide smoother estimates but increase latency.
+ Typical values: 3-10 samples. Default 5.
+
+ Raises
+ ------
+ TypeError
+ If N is not an integer.
+
+ Notes
+ -----
+ - Call this method ONCE before your experimental loop
+ - Buffer size trades off stability vs. latency:
+ * Smaller N (3-5): Lower latency, more noise
+ * Larger N (8-10): Smoother tracking, higher latency
+ - For 120 Hz eye tracker with N=5: ~42ms latency
+ - For 60 Hz eye tracker with N=5: ~83ms latency
+
+ Examples
+ --------
+ ```python
+ # Basic real-time gaze tracking
+ ET_controller.gaze_contingent(N=5) # Initialize buffer
+ ET_controller.start_recording('data.h5')
+
+ # Create gaze-contingent stimulus
+ circle = visual.Circle(win, radius=0.05, fillColor='red')
+
+ for frame in range(600): # 10 seconds at 60 fps
+ gaze_pos = ET_controller.get_gaze_position()
+ circle.pos = gaze_pos
+ circle.draw()
+ win.flip()
+
+ ET_controller.stop_recording()
+
+ # Adjust buffer size for your needs
+ ET_controller.gaze_contingent(N=3) # Low latency, more jitter
+ ET_controller.gaze_contingent(N=10) # Smooth, higher latency
+
+ # Gaze-contingent window paradigm
+ ET_controller.gaze_contingent(N=5)
+ ET_controller.start_recording('gaze_window.h5')
+
+ stimulus = visual.ImageStim(win, 'image.png')
+ window = visual.Circle(win, radius=0.1, fillColor=None, lineColor='white')
+
+ for trial in range(20):
+ stimulus.draw()
+
+ for frame in range(120): # 2 seconds
+ gaze_pos = ET_controller.get_gaze_position()
+ window.pos = gaze_pos
+ window.draw()
+ win.flip()
+
+ ET_controller.record_event(f'trial_{trial}_end')
+
+ ET_controller.stop_recording()
+ ```
"""
# --- Input validation ---
if not isinstance(N, int):
@@ -1161,21 +1414,23 @@ def get_gaze_position(self, fallback_offscreen=True, method="median"):
Examples
--------
- >>> # Basic usage (median aggregation)
- >>> pos = tracker.get_gaze_position()
- >>> if pos is not None:
- ... circle.pos = pos
-
- >>> # Use mean for smoother tracking
- >>> pos = tracker.get_gaze_position(method="mean")
-
- >>> # Lowest latency (last sample only)
- >>> pos = tracker.get_gaze_position(method="last")
-
- >>> # Return None instead of offscreen position
- >>> pos = tracker.get_gaze_position(fallback_offscreen=False)
- >>> if pos is None:
- ... print("No valid gaze data")
+ ```python
+ # Basic usage (median aggregation)
+ pos = ET_controller.get_gaze_position()
+ if pos is not None:
+ circle.pos = pos
+
+ # Use mean for smoother tracking
+ pos = ET_controller.get_gaze_position(method="mean")
+
+ # Lowest latency (last sample only)
+ pos = ET_controller.get_gaze_position(method="last")
+
+ # Return None instead of offscreen position
+ pos = ET_controller.get_gaze_position(fallback_offscreen=False)
+ if pos is None:
+ print("No valid gaze data")
+ ```
"""
# --- Buffer validation ---
if self.gaze_contingent_buffer is None:
@@ -1746,7 +2001,7 @@ def _simulate_user_position_guide(self):
# Record events during experiment
controller.record_event('trial_1_start')
- # Run trial 1...
+ # Run trial 1
controller.record_event('trial_1_end')
controller.save_data() # Save and clear buffer after trial 1
diff --git a/DeToX/Calibration.py b/DeToX/Calibration.py
index 30ca762..ecc5ce8 100644
--- a/DeToX/Calibration.py
+++ b/DeToX/Calibration.py
@@ -392,13 +392,6 @@ def _fade_sound(self, sound, fade_duration=0.5, steps=10):
-----
The sound is automatically stopped after the fade completes, and volume
is reset to 1.0 (maximum) so it's ready for the next playback at full volume.
-
- Examples
- --------
- >>> # Fade out calibration audio when point is collected
- >>> self._fade_sound(self.audio, fade_duration=0.5)
- >>> # Next play() will start at full volume
- >>> self.audio.play()
"""
# --- Fade-out Loop ---
# Gradually decrease volume from current level to 0
diff --git a/Documentation/Vignettes/Calibration.qmd b/Documentation/Vignettes/Calibration.qmd
index 5745c3c..0971c4f 100644
--- a/Documentation/Vignettes/Calibration.qmd
+++ b/Documentation/Vignettes/Calibration.qmd
@@ -128,7 +128,13 @@ Let's break down what's happening here:
**`shuffle=True`**: Randomizes which image appears at each calibration point. This prevents habituation and keeps participants engaged throughout the procedure.
+<<<<<<< HEAD
+**`audio=True`**: Plays an attention-getting sound along with the visual stimulus to help capture and maintain the participant's focus.
+
+**`anim_type='zoom'`**: Makes the stimuli gently pulse in size to attract attention. You can also use `'trill'` for a rotating animation.
+=======
**`audio=True`**: Plays an attention-getting sound along with the visual stimulus to help capture and maintain the participant's focus. **`anim_type='zoom'`**: Makes the stimuli gently pulse in size to attract attention. You can also use `'trill'` for a rotating animation.
+>>>>>>> origin/main
**`visualization_style='circles'`**: Displays the calibration results using dots at each point. You can also choose `'lines'` to show lines connecting the target to where the gaze landed.
diff --git a/Documentation/Vignettes/Installation.qmd b/Documentation/Vignettes/Installation.qmd
index 721bf2d..9b5fb8d 100644
--- a/Documentation/Vignettes/Installation.qmd
+++ b/Documentation/Vignettes/Installation.qmd
@@ -9,14 +9,6 @@ So you're interested in using DeToX? Awesome! Let's get you set up quickly.
DeToX is designed as a lightweight wrapper around **PsychoPy** and **tobii_research**. Here's the good news: `tobii_research` usually comes bundled with PsychoPy, which means the only real hurdle is installing PsychoPy itself. And yes, PsychoPy *can* be a bit tricky to install due to its many dependencies—but don't worry, we'll walk you through it. Once PsychoPy is up and running, adding DeToX is a breeze.
-::: callout-note
-## Eye Tracker Drivers Required {fig-align="right" width="49" height="33"}
-
-Before DeToX can communicate with your Tobii eye tracker, you need to ensure the correct drivers are installed on your computer. The easiest way to do this is by downloading and installing the [Tobii Pro Eye Tracker Manager](https://www.tobii.com/products/software/applications-and-developer-kits/tobii-pro-eye-tracker-manager)—a free software provided by Tobii that allows you to installs the necessary drivers for your device.
-
-As a bonus, the Eye Tracker Manager also includes a built-in calibration tool (designed for adult self-paced calibration), which can be useful for testing that your hardware is working properly before running DeToX.
-:::
-
## Installing PsychoPy
Since PsychoPy is the main challenge, let's tackle that first. You have **two main options**:
diff --git a/Documentation/_quarto.yml b/Documentation/_quarto.yml
index b6107c8..597e02c 100644
--- a/Documentation/_quarto.yml
+++ b/Documentation/_quarto.yml
@@ -86,7 +86,7 @@ website:
format:
html:
theme:
- - pulse
+ - sandstone
- styles.scss # your custom SCSS file
toc: true
toc-expand: 4
@@ -123,15 +123,22 @@ filters:
quartodoc:
- style: pkgdown
title: Reference
package: DeToX
+
+ style: pkgdown
+ parser: numpy
+ renderer:
+ style: markdown
+ table_style: table
+ render_interlinks: true
+
dir: api
sidebar: api/_sidebar.yml
sections:
- title: Main Eye-tracker Class
- desc: >
+ desc: |
The central class of the DeToX package, responsible for connecting to
and managing the Tobii eye tracker. This class must be instantiated
before any other functionality can be used. It provides access to
@@ -141,7 +148,7 @@ quartodoc:
- ETracker
- subtitle: Control the Recording
- desc: >
+ desc: |
Functions for starting, stopping, and managing the capture of eye-tracking
data. These methods allow you to initiate and terminate recordings,
mark events of interest, and save collected data to disk.
@@ -152,7 +159,7 @@ quartodoc:
- ETracker.save_data
- subtitle: Calibration
- desc: >
+ desc: |
Methods for running and managing eye tracker calibration. These include
displaying calibration status, initiating calibration routines, and
saving or loading calibration settings to ensure accurate gaze data.
@@ -163,7 +170,7 @@ quartodoc:
- ETracker.load_calibration
- subtitle: Gaze Contingent
- desc: >
+ desc: |
Tools for running gaze-contingent experiments, where visual presentation
adapts dynamically to a participants gaze position. Includes functionality
for live gaze-contingent control and methods to compute average gaze
@@ -173,7 +180,7 @@ quartodoc:
- ETracker.get_gaze_position
- title: Internal Calibration
- desc: >
+ desc: |
Classes for running eye-tracker calibration. These get called internally by the ETracker class, and are reported here only for completeness.
They are comprise of a base calibration class that set the common interface, and the specific implementations for Tobii and Mouse calibration.
contents:
@@ -182,7 +189,7 @@ quartodoc:
- MouseCalibrationSession
- title: Coordinate Conversion
- desc: >
+ desc: |
A collection of utility functions designed to help the conversion of the data from different formats.
These are called internally by the ETracker class, but can be used independently if needed.
contents:
@@ -195,7 +202,7 @@ quartodoc:
- get_psychopy_pos_from_trackbox
- title: Utilities
- desc: >
+ desc: |
A set of utility classes and functions for presenting stimuli
and formatted text. These are called internally by the ETracker class.
contents:
@@ -203,7 +210,7 @@ quartodoc:
- InfantStimuli
- title: Configuration Settings
- desc: >
+ desc: |
Configuration classes and module-level instances for customizing the
behavior and appearance of the DeToX eye-tracking system. These settings
control animation parameters, colors, UI element sizes, and data formats.
diff --git a/Documentation/api/BaseCalibrationSession.qmd b/Documentation/api/BaseCalibrationSession.qmd
index 3e464c3..a08e7ac 100644
--- a/Documentation/api/BaseCalibrationSession.qmd
+++ b/Documentation/api/BaseCalibrationSession.qmd
@@ -7,6 +7,7 @@ BaseCalibrationSession(
audio=None,
anim_type='zoom',
visualization_style='lines',
+ visualization_style='lines',
)
```
@@ -43,15 +44,15 @@ simulation modes support 2-9 calibration points.
#### Parameters {.doc-section .doc-section-parameters}
-| Name | Type | Description | Default |
-|--------------------|--------|----------------------------------------------------|------------|
-| calibration_points | list | List of calibration point coordinates to validate. | _required_ |
+| Name | Type | Description | Default |
+|--------------------|----------------|----------------------------------------------------|------------|
+| calibration_points | [list](`list`) | List of calibration point coordinates to validate. | _required_ |
#### Raises {.doc-section .doc-section-raises}
-| Name | Type | Description |
-|--------|------------|-------------------------------------------------------|
-| | ValueError | If number of points is less than 2 or greater than 9. |
+| Name | Type | Description |
+|--------|----------------------------|-------------------------------------------------------|
+| | [ValueError](`ValueError`) | If number of points is less than 2 or greater than 9. |
### show_message_and_wait { #DeToX.BaseCalibrationSession.show_message_and_wait }
@@ -67,8 +68,14 @@ then pauses execution until any key is pressed.
#### Parameters {.doc-section .doc-section-parameters}
-| Name | Type | Description | Default |
-|--------|--------|-------------------------------------------------------------------|--------------|
-| body | str | The main message text to display. | _required_ |
-| title | str | Title for the message box. Default empty string. | `''` |
-| pos | tuple | Position of the message box center on screen. Default (0, -0.15). | `(0, -0.15)` |
\ No newline at end of file
+| Name | Type | Description | Default |
+|--------|--------|------------------------------------------------------------------------------------------------------------------------|--------------|
+| body | str | The main message text to display. Will be formatted with box-drawing characters via NicePrint. | _required_ |
+| title | str | Title for the message box. Appears at the top of the formatted box. Default empty string. | `''` |
+| pos | tuple | Position of the message box center on screen in window units. Default (0, -0.15) places message slightly below center. | `(0, -0.15)` |
+
+#### Returns {.doc-section .doc-section-returns}
+
+| Name | Type | Description |
+|--------|--------|---------------|
+| | None | |
\ No newline at end of file
diff --git a/Documentation/api/ETSettings.AnimationSettings.qmd b/Documentation/api/ETSettings.AnimationSettings.qmd
index ad4d916..84db081 100644
--- a/Documentation/api/ETSettings.AnimationSettings.qmd
+++ b/Documentation/api/ETSettings.AnimationSettings.qmd
@@ -22,17 +22,17 @@ in height units (percentage of screen height).
## Attributes {.doc-section .doc-section-attributes}
-| Name | Type | Description |
-|-----------------------|--------|--------------------------------------------------------------------------------------------------------------------------------------------|
-| focus_time | float | Wait time in seconds before collecting calibration data at each point. Allows participant to fixate on the target. Default is 0.5 seconds. |
-| zoom_speed | float | Speed multiplier for the zoom animation. Higher values make the size oscillation faster. Default is 6.0. |
-| max_zoom_size | float | Maximum size for zoom animation as percentage of screen height. Default is 0.11 (11% of screen height). |
-| min_zoom_size | float | Minimum size for zoom animation as percentage of screen height. Default is 0.05 (5% of screen height). |
-| trill_size | float | Fixed size for trill animation as percentage of screen height. Default is 0.075 (7.5% of screen height). |
-| trill_rotation_range | float | Maximum rotation angle in degrees for trill animation. Default is 20 degrees. |
-| trill_cycle_duration | float | Total cycle time for trill animation in seconds (active + pause). Default is 1.5 seconds. |
-| trill_active_duration | float | Duration of active trill rotation in seconds, within each cycle. Default is 1.1 seconds (leaves 0.4s pause). |
-| trill_frequency | float | Number of back-and-forth rotation oscillations per second during active trill phase. Default is 3.0 oscillations/second. |
+| Name | Type | Description |
+|-----------------------|------------------|--------------------------------------------------------------------------------------------------------------------------------------------|
+| focus_time | [float](`float`) | Wait time in seconds before collecting calibration data at each point. Allows participant to fixate on the target. Default is 0.5 seconds. |
+| zoom_speed | [float](`float`) | Speed multiplier for the zoom animation. Higher values make the size oscillation faster. Default is 6.0. |
+| max_zoom_size | [float](`float`) | Maximum size for zoom animation as percentage of screen height. Default is 0.11 (11% of screen height). |
+| min_zoom_size | [float](`float`) | Minimum size for zoom animation as percentage of screen height. Default is 0.05 (5% of screen height). |
+| trill_size | [float](`float`) | Fixed size for trill animation as percentage of screen height. Default is 0.075 (7.5% of screen height). |
+| trill_rotation_range | [float](`float`) | Maximum rotation angle in degrees for trill animation. Default is 20 degrees. |
+| trill_cycle_duration | [float](`float`) | Total cycle time for trill animation in seconds (active + pause). Default is 1.5 seconds. |
+| trill_active_duration | [float](`float`) | Duration of active trill rotation in seconds, within each cycle. Default is 1.1 seconds (leaves 0.4s pause). |
+| trill_frequency | [float](`float`) | Number of back-and-forth rotation oscillations per second during active trill phase. Default is 3.0 oscillations/second. |
## Examples {.doc-section .doc-section-examples}
diff --git a/Documentation/api/ETSettings.CalibrationPatterns.qmd b/Documentation/api/ETSettings.CalibrationPatterns.qmd
index ee8dd4e..e69de29 100644
--- a/Documentation/api/ETSettings.CalibrationPatterns.qmd
+++ b/Documentation/api/ETSettings.CalibrationPatterns.qmd
@@ -1,37 +0,0 @@
-# ETSettings.CalibrationPatterns { #DeToX.ETSettings.CalibrationPatterns }
-
-```python
-ETSettings.CalibrationPatterns(
- points_5=(lambda: [(0.0, 0.0), (-0.8, 0.8), (0.8, 0.8), (-0.8, -0.8), (0.8, -0.8)])(),
- points_9=(lambda: [(-0.8, 0.8), (0.0, 0.8), (0.8, 0.8), (-0.8, 0.0), (0.0, 0.0), (0.8, 0.0), (-0.8, -0.8), (0.0, -0.8), (0.8, -0.8)])(),
- num_samples_mouse=5,
-)
-```
-
-Standard calibration point patterns in normalized coordinates.
-
-Defines commonly used calibration patterns in normalized units where
-the screen ranges from -1 to +1 in both dimensions. These universal
-coordinates work across different screen sizes, aspect ratios, and
-PsychoPy unit systems.
-
-Convert to window-specific coordinates at runtime using the
-norm_to_window_units() function from the Coords module.
-
-## Attributes {.doc-section .doc-section-attributes}
-
-| Name | Type | Description |
-|-------------------|---------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| points_5 | list of tuple | 5-point calibration pattern (4 corners + center). Standard for quick calibrations with good coverage. Pattern: corners at 0.4 from edges to avoid screen boundaries. |
-| points_9 | list of tuple | 9-point calibration pattern (33 grid). Standard for comprehensive calibrations requiring high accuracy. Pattern: 3 rows 3 columns with 0.4 positioning. |
-| num_samples_mouse | int | Number of mouse position samples to collect per calibration point in simulation mode. Default 5. |
-
-## Examples {.doc-section .doc-section-examples}
-
-```python
->>> from DeToX import ETSettings as cfg
->>> from DeToX.Coords import norm_to_window_units
->>>
->>> # Change number of mouse samples collected per point
->>> cfg.calibration.num_samples_mouse = 10
-```
\ No newline at end of file
diff --git a/Documentation/api/ETSettings.UIElementSizes.qmd b/Documentation/api/ETSettings.UIElementSizes.qmd
index c20fe8c..4b9da04 100644
--- a/Documentation/api/ETSettings.UIElementSizes.qmd
+++ b/Documentation/api/ETSettings.UIElementSizes.qmd
@@ -27,6 +27,23 @@ PsychoPy window configuration.
## Attributes {.doc-section .doc-section-attributes}
+<<<<<<< HEAD
+| Name | Type | Description |
+|---------------------|------------------|---------------------------------------------------------------------------------------------------------------------|
+| highlight | [float](`float`) | Radius of circles highlighting selected calibration points for retry. Default is 0.02 (2% of screen height). |
+| line_width | [float](`float`) | Thickness of lines drawn in calibration visualizations. Default is 0.003 (0.3% of screen height). |
+| marker | [float](`float`) | Size of markers indicating data collection points. Default is 0.02 (2% of screen height). |
+| border | [float](`float`) | Thickness of the red calibration mode border around the screen. Default is 0.005 (0.5% of screen height). |
+| plot_line | [float](`float`) | Width of lines in calibration result plots connecting targets to samples. Default is 0.002 (0.2% of screen height). |
+| text | [float](`float`) | Base text height (deprecated - use specific text sizes below). Default is 0.025 (2.5% of screen height). |
+| target_circle | [float](`float`) | Radius of target circles drawn in calibration result visualizations. Default is 0.012 (1.2% of screen height). |
+| target_circle_width | [float](`float`) | Line width for target circle outlines in result visualizations. Default is 0.003 (0.3% of screen height). |
+| sample_marker | [float](`float`) | Radius of sample markers in circle visualization style. Default is 0.005 (0.5% of screen height). |
+| instruction_text | [float](`float`) | Text height for instruction displays during calibration. Default is 0.019 (1.9% of screen height). |
+| message_text | [float](`float`) | Text height for general message displays. Default is 0.016 (1.6% of screen height). |
+| title_text | [float](`float`) | Text height for title text in message boxes. Default is 0.018 (1.8% of screen height). |
+| legend_text | [float](`float`) | Text height for legend labels showing eye color coding. Default is 0.015 (1.5% of screen height). |
+=======
| Name | Type | Description |
|---------------------|--------|---------------------------------------------------------------------------------------------------------------------|
| highlight | float | Radius of circles highlighting selected calibration points for retry. Default is 0.02 (2% of screen height). |
@@ -42,6 +59,7 @@ PsychoPy window configuration.
| message_text | float | Text height for general message displays. Default is 0.016 (1.6% of screen height). |
| title_text | float | Text height for title text in message boxes. Default is 0.018 (1.8% of screen height). |
| legend_text | float | Text height for legend labels showing eye color coding. Default is 0.015 (1.5% of screen height). |
+>>>>>>> origin/main
## Notes {.doc-section .doc-section-notes}
diff --git a/Documentation/api/ETracker.calibrate.qmd b/Documentation/api/ETracker.calibrate.qmd
index ec84dce..66241b7 100644
--- a/Documentation/api/ETracker.calibrate.qmd
+++ b/Documentation/api/ETracker.calibrate.qmd
@@ -2,8 +2,13 @@
```python
ETracker.calibrate(
+<<<<<<< HEAD
+ calibration_points=5,
+ infant_stims=True,
+=======
calibration_points,
infant_stims=None,
+>>>>>>> origin/main
shuffle=True,
audio=True,
anim_type='zoom',
@@ -21,6 +26,50 @@ mode (real eye tracker vs. mouse simulation).
## Parameters {.doc-section .doc-section-parameters}
+<<<<<<< HEAD
+| Name | Type | Description | Default |
+|---------------------|------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------|
+| calibration_points | int or list of tuple | Calibration pattern specification. \ Use `5` for the standard 5-point pattern (4 corners + center; default). \ Use `9` for a comprehensive 9-point pattern (3*3 grid). Alternatively, provide a list of custom points in normalized coordinates in the range [-1, 1], for example: `[(-0.4, 0.4), (0.4, 0.4), (0.0, 0.0)]`. | `5` |
+| infant_stims | list of str or True | Paths to engaging image files for calibration targets (e.g., colorful characters, animated objects). If `True` (default), uses built-in stimuli from the package. If fewer stimuli than calibration points are provided, stimuli are automatically repeated in sequence to cover all points (e.g., 3 stimuli for 7 points becomes `[s1, s2, s3, s1, s2, s3, s1]`). Defaults to `None`, which resolves to `True`. | `True` |
+| shuffle | [bool](`bool`) | Whether to randomize stimulus presentation order. When `True` (default), stimuli are shuffled after any necessary repetition and before assignment to calibration points. Set to `False` if you want deterministic stimulus-to-point mapping or specific stimulus ordering. Default is `True`. | `True` |
+| audio | [bool](`bool`) or [psychopy](`psychopy`).[sound](`psychopy.sound`).[Sound](`psychopy.sound.Sound`) or None | Controls attention-getting audio during calibration. If `True` (default), uses the built-in calibration sound, which loops continuously while a stimulus is selected. If `False` or `None`, no audio feedback is played. If a `psychopy.sound.Sound` object is provided, it will be used as the audio source; you are responsible for configuring it (e.g., setting `loops=-1` for continuous looping). The audio provides feedback when the experimenter selects a calibration point by pressing a number key. Default is `True`. | `True` |
+| anim_type | ([zoom](`zoom`), [trill](`trill`)) | Animation style for the calibration stimuli. `'zoom'` applies a smooth size oscillation (default). `'trill'` uses rapid rotation with pauses. Default is `'zoom'`. | `'zoom'` |
+| visualization_style | ([circles](`circles`), [lines](`lines`)) | How to display calibration results. `'lines'` draws lines from targets to gaze samples. `'circles'` draws small filled circles at gaze sample positions. | `'circles','lines'` |
+
+## Returns {.doc-section .doc-section-returns}
+
+| Name | Type | Description |
+|--------|----------------|---------------------------------------------------------------------------------------------------------------------------|
+| | [bool](`bool`) | `True` if calibration completed successfully and was accepted by the user, `False` if calibration was aborted or failed. |
+
+## Examples {.doc-section .doc-section-examples}
+
+Standard 5-point calibration with default audio:
+
+```python
+ET_controller.calibrate(5)
+```
+
+Calibration without audio:
+
+```python
+ET_controller.calibrate(5, audio=False)
+```
+
+Custom audio:
+
+```python
+from psychopy import sound
+# Load custom sound and set to loop indefinitely
+my_sound = sound.Sound('custom_beep.wav', loops=-1)
+ET_controller.calibrate(5, audio=my_sound)
+```
+
+9-point calibration with custom stimuli and trill animation:
+
+```python
+ET_controller.calibrate(9, infant_stims=['stim1.png', 'stim2.png'], anim_type='trill')
+=======
| Name | Type | Description | Default |
|---------------------|--------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------|
| calibration_points | int or list of tuple | Calibration pattern specification: - 5: Standard 5-point pattern (4 corners + center). Default. - 9: Comprehensive 9-point pattern (33 grid). - list: Custom points in normalized coordinates [-1, 1]. Example: [(-0.4, 0.4), (0.4, 0.4), (0.0, 0.0)] | _required_ |
@@ -59,4 +108,5 @@ mode (real eye tracker vs. mouse simulation).
>>> # 9-point calibration with custom stimuli and trill animation
>>> controller.calibrate(9, infant_stims=['stim1.png', 'stim2.png'],
... anim_type='trill')
+>>>>>>> origin/main
```
\ No newline at end of file
diff --git a/Documentation/api/ETracker.gaze_contingent.qmd b/Documentation/api/ETracker.gaze_contingent.qmd
index 56c97f6..ee40448 100644
--- a/Documentation/api/ETracker.gaze_contingent.qmd
+++ b/Documentation/api/ETracker.gaze_contingent.qmd
@@ -4,4 +4,76 @@
ETracker.gaze_contingent(N=5)
```
-Initialize real-time gaze buffer for contingent applications.
\ No newline at end of file
+Initialize real-time gaze buffer for contingent applications.
+
+Creates a rolling buffer that stores the most recent N gaze samples,
+enabling real-time gaze-contingent paradigms. Must be called before
+using `get_gaze_position()` for real-time gaze tracking.
+
+The buffer automatically maintains the N most recent samples, discarding
+older data. This provides a stable estimate of current gaze position by
+aggregating across multiple samples.
+
+## Parameters {.doc-section .doc-section-parameters}
+
+| Name | Type | Description | Default |
+|--------|--------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------|
+| N | [int](`int`) | Number of recent gaze samples to store in the rolling buffer. Larger values provide smoother estimates but increase latency. Typical values: 3-10 samples. Default 5. | `5` |
+
+## Raises {.doc-section .doc-section-raises}
+
+| Name | Type | Description |
+|--------|--------------------------|-------------------------|
+| | [TypeError](`TypeError`) | If N is not an integer. |
+
+## Notes {.doc-section .doc-section-notes}
+
+- Call this method ONCE before your experimental loop
+- Buffer size trades off stability vs. latency:
+* Smaller N (3-5): Lower latency, more noise
+* Larger N (8-10): Smoother tracking, higher latency
+- For 120 Hz eye tracker with N=5: ~42ms latency
+- For 60 Hz eye tracker with N=5: ~83ms latency
+
+## Examples {.doc-section .doc-section-examples}
+
+```python
+# Basic real-time gaze tracking
+ET_controller.gaze_contingent(N=5) # Initialize buffer
+ET_controller.start_recording('data.h5')
+
+# Create gaze-contingent stimulus
+circle = visual.Circle(win, radius=0.05, fillColor='red')
+
+for frame in range(600): # 10 seconds at 60 fps
+ gaze_pos = ET_controller.get_gaze_position()
+ circle.pos = gaze_pos
+ circle.draw()
+ win.flip()
+
+ET_controller.stop_recording()
+
+# Adjust buffer size for your needs
+ET_controller.gaze_contingent(N=3) # Low latency, more jitter
+ET_controller.gaze_contingent(N=10) # Smooth, higher latency
+
+# Gaze-contingent window paradigm
+ET_controller.gaze_contingent(N=5)
+ET_controller.start_recording('gaze_window.h5')
+
+stimulus = visual.ImageStim(win, 'image.png')
+window = visual.Circle(win, radius=0.1, fillColor=None, lineColor='white')
+
+for trial in range(20):
+ stimulus.draw()
+
+ for frame in range(120): # 2 seconds
+ gaze_pos = ET_controller.get_gaze_position()
+ window.pos = gaze_pos
+ window.draw()
+ win.flip()
+
+ ET_controller.record_event(f'trial_{trial}_end')
+
+ET_controller.stop_recording()
+```
\ No newline at end of file
diff --git a/Documentation/api/ETracker.get_gaze_position.qmd b/Documentation/api/ETracker.get_gaze_position.qmd
index 36f8158..9e2e965 100644
--- a/Documentation/api/ETracker.get_gaze_position.qmd
+++ b/Documentation/api/ETracker.get_gaze_position.qmd
@@ -11,45 +11,39 @@ real-time gaze estimate. Handles missing or invalid data gracefully.
## Parameters {.doc-section .doc-section-parameters}
-| Name | Type | Description | Default |
-|--------------------|--------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------|
-| fallback_offscreen | bool | If True (default), returns an offscreen position (3x screen dimensions) when no valid gaze data is available. If False, returns None. | `True` |
-| method | str | Aggregation method for combining samples and eyes. - "median" (default): Robust to outliers, good for noisy data - "mean": Smoother but sensitive to outliers - "last": Lowest latency, uses only most recent sample | `'median'` |
+| Name | Type | Description | Default |
+|--------------------|----------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------|
+| fallback_offscreen | [bool](`bool`) | If True (default), returns an offscreen position (3x screen dimensions) when no valid gaze data is available. If False, returns None. | `True` |
+| method | [str](`str`) | Aggregation method for combining samples and eyes. - "median" (default): Robust to outliers, good for noisy data - "mean": Smoother but sensitive to outliers - "last": Lowest latency, uses only most recent sample | `'median'` |
## Returns {.doc-section .doc-section-returns}
-| Name | Type | Description |
-|--------|---------------|-----------------------------------------------------------------------------------------------------------------------------|
-| | tuple or None | Gaze position (x, y) in PsychoPy coordinates (current window units), or None if no valid data and fallback_offscreen=False. |
+| Name | Type | Description |
+|--------|--------------------------|-----------------------------------------------------------------------------------------------------------------------------|
+| | [tuple](`tuple`) or None | Gaze position (x, y) in PsychoPy coordinates (current window units), or None if no valid data and fallback_offscreen=False. |
## Raises {.doc-section .doc-section-raises}
-| Name | Type | Description |
-|--------|--------------|---------------------------------------------------------------|
-| | RuntimeError | If gaze_contingent() was not called to initialize the buffer. |
+| Name | Type | Description |
+|--------|--------------------------------|---------------------------------------------------------------|
+| | [RuntimeError](`RuntimeError`) | If gaze_contingent() was not called to initialize the buffer. |
## Examples {.doc-section .doc-section-examples}
```python
->>> # Basic usage (median aggregation)
->>> pos = tracker.get_gaze_position()
->>> if pos is not None:
-... circle.pos = pos
-```
+# Basic usage (median aggregation)
+pos = ET_controller.get_gaze_position()
+if pos is not None:
+ circle.pos = pos
-```python
->>> # Use mean for smoother tracking
->>> pos = tracker.get_gaze_position(method="mean")
-```
+# Use mean for smoother tracking
+pos = ET_controller.get_gaze_position(method="mean")
-```python
->>> # Lowest latency (last sample only)
->>> pos = tracker.get_gaze_position(method="last")
-```
+# Lowest latency (last sample only)
+pos = ET_controller.get_gaze_position(method="last")
-```python
->>> # Return None instead of offscreen position
->>> pos = tracker.get_gaze_position(fallback_offscreen=False)
->>> if pos is None:
-... print("No valid gaze data")
+# Return None instead of offscreen position
+pos = ET_controller.get_gaze_position(fallback_offscreen=False)
+if pos is None:
+ print("No valid gaze data")
```
\ No newline at end of file
diff --git a/Documentation/api/ETracker.load_calibration.qmd b/Documentation/api/ETracker.load_calibration.qmd
index 8b8c007..eec8065 100644
--- a/Documentation/api/ETracker.load_calibration.qmd
+++ b/Documentation/api/ETracker.load_calibration.qmd
@@ -14,20 +14,46 @@ available when connected to a physical eye tracker.
## Parameters {.doc-section .doc-section-parameters}
-| Name | Type | Description | Default |
-|----------|--------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------|
-| filename | str | The path to the calibration data file (e.g., "subject_01_calib.dat"). If `use_gui` is `True`, this path is used as the default suggestion in the file dialog. If `use_gui` is `False`, this parameter is required. | `None` |
-| use_gui | bool | If `True`, a graphical file-open dialog is displayed for the user to select the calibration file. Defaults to `False`. | `False` |
+| Name | Type | Description | Default |
+|----------|----------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------|
+| filename | [str](`str`) | The path to the calibration data file (e.g., "subject_01_calib.dat"). If `use_gui` is `True`, this path is used as the default suggestion in the file dialog. If `use_gui` is `False`, this parameter is required. | `None` |
+| use_gui | [bool](`bool`) | If `True`, a graphical file-open dialog is displayed for the user to select the calibration file. Defaults to `False`. | `False` |
## Returns {.doc-section .doc-section-returns}
-| Name | Type | Description |
-|--------|--------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| | bool | Returns `True` if the calibration was successfully loaded and applied, and `False` otherwise (e.g., user cancelled the dialog, file not found, or data was invalid). |
+| Name | Type | Description |
+|--------|----------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| | [bool](`bool`) | Returns `True` if the calibration was successfully loaded and applied, and `False` otherwise (e.g., user cancelled the dialog, file not found, or data was invalid). |
## Raises {.doc-section .doc-section-raises}
-| Name | Type | Description |
-|--------|--------------|-------------------------------------------------------------------|
-| | RuntimeError | If the method is called while the ETracker is in simulation mode. |
-| | ValueError | If `use_gui` is `False` and `filename` is not provided. |
\ No newline at end of file
+| Name | Type | Description |
+|--------|--------------------------------|-------------------------------------------------------------------|
+| | [RuntimeError](`RuntimeError`) | If the method is called while the ETracker is in simulation mode. |
+| | [ValueError](`ValueError`) | If `use_gui` is `False` and `filename` is not provided. |
+
+## Examples {.doc-section .doc-section-examples}
+
+```python
+# Load calibration from specific file
+success = ET_controller.load_calibration('subject_01_calib.dat')
+if success:
+ ET_controller.start_recording('subject_01_data.h5')
+
+# Use GUI to select file
+success = ET_controller.load_calibration(use_gui=True)
+
+# Multi-session workflow
+# Session 1: Calibrate and save
+ET_controller.calibrate(5)
+ET_controller.save_calibration('participant_123.dat')
+ET_controller.start_recording('session_1.h5')
+# ... run experiment ...
+ET_controller.stop_recording()
+
+# Session 2: Load previous calibration
+ET_controller.load_calibration('participant_123.dat')
+ET_controller.start_recording('session_2.h5')
+# ... run experiment ...
+ET_controller.stop_recording()
+```
\ No newline at end of file
diff --git a/Documentation/api/ETracker.qmd b/Documentation/api/ETracker.qmd
index ca5fd65..98207f1 100644
--- a/Documentation/api/ETracker.qmd
+++ b/Documentation/api/ETracker.qmd
@@ -38,8 +38,13 @@ This class is intended to be the first object you instantiate in your experiment
```python
ETracker.calibrate(
+<<<<<<< HEAD
+ calibration_points=5,
+ infant_stims=True,
+=======
calibration_points,
infant_stims=None,
+>>>>>>> origin/main
shuffle=True,
audio=True,
anim_type='zoom',
@@ -57,6 +62,50 @@ mode (real eye tracker vs. mouse simulation).
#### Parameters {.doc-section .doc-section-parameters}
+<<<<<<< HEAD
+| Name | Type | Description | Default |
+|---------------------|------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------|
+| calibration_points | int or list of tuple | Calibration pattern specification. \ Use `5` for the standard 5-point pattern (4 corners + center; default). \ Use `9` for a comprehensive 9-point pattern (3*3 grid). Alternatively, provide a list of custom points in normalized coordinates in the range [-1, 1], for example: `[(-0.4, 0.4), (0.4, 0.4), (0.0, 0.0)]`. | `5` |
+| infant_stims | list of str or True | Paths to engaging image files for calibration targets (e.g., colorful characters, animated objects). If `True` (default), uses built-in stimuli from the package. If fewer stimuli than calibration points are provided, stimuli are automatically repeated in sequence to cover all points (e.g., 3 stimuli for 7 points becomes `[s1, s2, s3, s1, s2, s3, s1]`). Defaults to `None`, which resolves to `True`. | `True` |
+| shuffle | [bool](`bool`) | Whether to randomize stimulus presentation order. When `True` (default), stimuli are shuffled after any necessary repetition and before assignment to calibration points. Set to `False` if you want deterministic stimulus-to-point mapping or specific stimulus ordering. Default is `True`. | `True` |
+| audio | [bool](`bool`) or [psychopy](`psychopy`).[sound](`psychopy.sound`).[Sound](`psychopy.sound.Sound`) or None | Controls attention-getting audio during calibration. If `True` (default), uses the built-in calibration sound, which loops continuously while a stimulus is selected. If `False` or `None`, no audio feedback is played. If a `psychopy.sound.Sound` object is provided, it will be used as the audio source; you are responsible for configuring it (e.g., setting `loops=-1` for continuous looping). The audio provides feedback when the experimenter selects a calibration point by pressing a number key. Default is `True`. | `True` |
+| anim_type | ([zoom](`zoom`), [trill](`trill`)) | Animation style for the calibration stimuli. `'zoom'` applies a smooth size oscillation (default). `'trill'` uses rapid rotation with pauses. Default is `'zoom'`. | `'zoom'` |
+| visualization_style | ([circles](`circles`), [lines](`lines`)) | How to display calibration results. `'lines'` draws lines from targets to gaze samples. `'circles'` draws small filled circles at gaze sample positions. | `'circles','lines'` |
+
+#### Returns {.doc-section .doc-section-returns}
+
+| Name | Type | Description |
+|--------|----------------|---------------------------------------------------------------------------------------------------------------------------|
+| | [bool](`bool`) | `True` if calibration completed successfully and was accepted by the user, `False` if calibration was aborted or failed. |
+
+#### Examples {.doc-section .doc-section-examples}
+
+Standard 5-point calibration with default audio:
+
+```python
+ET_controller.calibrate(5)
+```
+
+Calibration without audio:
+
+```python
+ET_controller.calibrate(5, audio=False)
+```
+
+Custom audio:
+
+```python
+from psychopy import sound
+# Load custom sound and set to loop indefinitely
+my_sound = sound.Sound('custom_beep.wav', loops=-1)
+ET_controller.calibrate(5, audio=my_sound)
+```
+
+9-point calibration with custom stimuli and trill animation:
+
+```python
+ET_controller.calibrate(9, infant_stims=['stim1.png', 'stim2.png'], anim_type='trill')
+=======
| Name | Type | Description | Default |
|---------------------|--------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------|
| calibration_points | int or list of tuple | Calibration pattern specification: - 5: Standard 5-point pattern (4 corners + center). Default. - 9: Comprehensive 9-point pattern (33 grid). - list: Custom points in normalized coordinates [-1, 1]. Example: [(-0.4, 0.4), (0.4, 0.4), (0.0, 0.0)] | _required_ |
@@ -95,6 +144,7 @@ mode (real eye tracker vs. mouse simulation).
>>> # 9-point calibration with custom stimuli and trill animation
>>> controller.calibrate(9, infant_stims=['stim1.png', 'stim2.png'],
... anim_type='trill')
+>>>>>>> origin/main
```
### gaze_contingent { #DeToX.ETracker.gaze_contingent }
@@ -105,6 +155,78 @@ ETracker.gaze_contingent(N=5)
Initialize real-time gaze buffer for contingent applications.
+Creates a rolling buffer that stores the most recent N gaze samples,
+enabling real-time gaze-contingent paradigms. Must be called before
+using `get_gaze_position()` for real-time gaze tracking.
+
+The buffer automatically maintains the N most recent samples, discarding
+older data. This provides a stable estimate of current gaze position by
+aggregating across multiple samples.
+
+#### Parameters {.doc-section .doc-section-parameters}
+
+| Name | Type | Description | Default |
+|--------|--------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------|
+| N | [int](`int`) | Number of recent gaze samples to store in the rolling buffer. Larger values provide smoother estimates but increase latency. Typical values: 3-10 samples. Default 5. | `5` |
+
+#### Raises {.doc-section .doc-section-raises}
+
+| Name | Type | Description |
+|--------|--------------------------|-------------------------|
+| | [TypeError](`TypeError`) | If N is not an integer. |
+
+#### Notes {.doc-section .doc-section-notes}
+
+- Call this method ONCE before your experimental loop
+- Buffer size trades off stability vs. latency:
+* Smaller N (3-5): Lower latency, more noise
+* Larger N (8-10): Smoother tracking, higher latency
+- For 120 Hz eye tracker with N=5: ~42ms latency
+- For 60 Hz eye tracker with N=5: ~83ms latency
+
+#### Examples {.doc-section .doc-section-examples}
+
+```python
+# Basic real-time gaze tracking
+ET_controller.gaze_contingent(N=5) # Initialize buffer
+ET_controller.start_recording('data.h5')
+
+# Create gaze-contingent stimulus
+circle = visual.Circle(win, radius=0.05, fillColor='red')
+
+for frame in range(600): # 10 seconds at 60 fps
+ gaze_pos = ET_controller.get_gaze_position()
+ circle.pos = gaze_pos
+ circle.draw()
+ win.flip()
+
+ET_controller.stop_recording()
+
+# Adjust buffer size for your needs
+ET_controller.gaze_contingent(N=3) # Low latency, more jitter
+ET_controller.gaze_contingent(N=10) # Smooth, higher latency
+
+# Gaze-contingent window paradigm
+ET_controller.gaze_contingent(N=5)
+ET_controller.start_recording('gaze_window.h5')
+
+stimulus = visual.ImageStim(win, 'image.png')
+window = visual.Circle(win, radius=0.1, fillColor=None, lineColor='white')
+
+for trial in range(20):
+ stimulus.draw()
+
+ for frame in range(120): # 2 seconds
+ gaze_pos = ET_controller.get_gaze_position()
+ window.pos = gaze_pos
+ window.draw()
+ win.flip()
+
+ ET_controller.record_event(f'trial_{trial}_end')
+
+ET_controller.stop_recording()
+```
+
### get_gaze_position { #DeToX.ETracker.get_gaze_position }
```python
@@ -118,47 +240,41 @@ real-time gaze estimate. Handles missing or invalid data gracefully.
#### Parameters {.doc-section .doc-section-parameters}
-| Name | Type | Description | Default |
-|--------------------|--------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------|
-| fallback_offscreen | bool | If True (default), returns an offscreen position (3x screen dimensions) when no valid gaze data is available. If False, returns None. | `True` |
-| method | str | Aggregation method for combining samples and eyes. - "median" (default): Robust to outliers, good for noisy data - "mean": Smoother but sensitive to outliers - "last": Lowest latency, uses only most recent sample | `'median'` |
+| Name | Type | Description | Default |
+|--------------------|----------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------|
+| fallback_offscreen | [bool](`bool`) | If True (default), returns an offscreen position (3x screen dimensions) when no valid gaze data is available. If False, returns None. | `True` |
+| method | [str](`str`) | Aggregation method for combining samples and eyes. - "median" (default): Robust to outliers, good for noisy data - "mean": Smoother but sensitive to outliers - "last": Lowest latency, uses only most recent sample | `'median'` |
#### Returns {.doc-section .doc-section-returns}
-| Name | Type | Description |
-|--------|---------------|-----------------------------------------------------------------------------------------------------------------------------|
-| | tuple or None | Gaze position (x, y) in PsychoPy coordinates (current window units), or None if no valid data and fallback_offscreen=False. |
+| Name | Type | Description |
+|--------|--------------------------|-----------------------------------------------------------------------------------------------------------------------------|
+| | [tuple](`tuple`) or None | Gaze position (x, y) in PsychoPy coordinates (current window units), or None if no valid data and fallback_offscreen=False. |
#### Raises {.doc-section .doc-section-raises}
-| Name | Type | Description |
-|--------|--------------|---------------------------------------------------------------|
-| | RuntimeError | If gaze_contingent() was not called to initialize the buffer. |
+| Name | Type | Description |
+|--------|--------------------------------|---------------------------------------------------------------|
+| | [RuntimeError](`RuntimeError`) | If gaze_contingent() was not called to initialize the buffer. |
#### Examples {.doc-section .doc-section-examples}
```python
->>> # Basic usage (median aggregation)
->>> pos = tracker.get_gaze_position()
->>> if pos is not None:
-... circle.pos = pos
-```
+# Basic usage (median aggregation)
+pos = ET_controller.get_gaze_position()
+if pos is not None:
+ circle.pos = pos
-```python
->>> # Use mean for smoother tracking
->>> pos = tracker.get_gaze_position(method="mean")
-```
+# Use mean for smoother tracking
+pos = ET_controller.get_gaze_position(method="mean")
-```python
->>> # Lowest latency (last sample only)
->>> pos = tracker.get_gaze_position(method="last")
-```
+# Lowest latency (last sample only)
+pos = ET_controller.get_gaze_position(method="last")
-```python
->>> # Return None instead of offscreen position
->>> pos = tracker.get_gaze_position(fallback_offscreen=False)
->>> if pos is None:
-... print("No valid gaze data")
+# Return None instead of offscreen position
+pos = ET_controller.get_gaze_position(fallback_offscreen=False)
+if pos is None:
+ print("No valid gaze data")
```
### load_calibration { #DeToX.ETracker.load_calibration }
@@ -177,23 +293,49 @@ available when connected to a physical eye tracker.
#### Parameters {.doc-section .doc-section-parameters}
-| Name | Type | Description | Default |
-|----------|--------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------|
-| filename | str | The path to the calibration data file (e.g., "subject_01_calib.dat"). If `use_gui` is `True`, this path is used as the default suggestion in the file dialog. If `use_gui` is `False`, this parameter is required. | `None` |
-| use_gui | bool | If `True`, a graphical file-open dialog is displayed for the user to select the calibration file. Defaults to `False`. | `False` |
+| Name | Type | Description | Default |
+|----------|----------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------|
+| filename | [str](`str`) | The path to the calibration data file (e.g., "subject_01_calib.dat"). If `use_gui` is `True`, this path is used as the default suggestion in the file dialog. If `use_gui` is `False`, this parameter is required. | `None` |
+| use_gui | [bool](`bool`) | If `True`, a graphical file-open dialog is displayed for the user to select the calibration file. Defaults to `False`. | `False` |
#### Returns {.doc-section .doc-section-returns}
-| Name | Type | Description |
-|--------|--------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| | bool | Returns `True` if the calibration was successfully loaded and applied, and `False` otherwise (e.g., user cancelled the dialog, file not found, or data was invalid). |
+| Name | Type | Description |
+|--------|----------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| | [bool](`bool`) | Returns `True` if the calibration was successfully loaded and applied, and `False` otherwise (e.g., user cancelled the dialog, file not found, or data was invalid). |
#### Raises {.doc-section .doc-section-raises}
-| Name | Type | Description |
-|--------|--------------|-------------------------------------------------------------------|
-| | RuntimeError | If the method is called while the ETracker is in simulation mode. |
-| | ValueError | If `use_gui` is `False` and `filename` is not provided. |
+| Name | Type | Description |
+|--------|--------------------------------|-------------------------------------------------------------------|
+| | [RuntimeError](`RuntimeError`) | If the method is called while the ETracker is in simulation mode. |
+| | [ValueError](`ValueError`) | If `use_gui` is `False` and `filename` is not provided. |
+
+#### Examples {.doc-section .doc-section-examples}
+
+```python
+# Load calibration from specific file
+success = ET_controller.load_calibration('subject_01_calib.dat')
+if success:
+ ET_controller.start_recording('subject_01_data.h5')
+
+# Use GUI to select file
+success = ET_controller.load_calibration(use_gui=True)
+
+# Multi-session workflow
+# Session 1: Calibrate and save
+ET_controller.calibrate(5)
+ET_controller.save_calibration('participant_123.dat')
+ET_controller.start_recording('session_1.h5')
+# ... run experiment ...
+ET_controller.stop_recording()
+
+# Session 2: Load previous calibration
+ET_controller.load_calibration('participant_123.dat')
+ET_controller.start_recording('session_2.h5')
+# ... run experiment ...
+ET_controller.stop_recording()
+```
### record_event { #DeToX.ETracker.record_event }
@@ -209,21 +351,23 @@ simulation vs. real eye tracker modes.
#### Parameters {.doc-section .doc-section-parameters}
-| Name | Type | Description | Default |
-|--------|--------|--------------------------------------------------------------------------|------------|
-| label | str | Descriptive label for the event (e.g., 'trial_start', 'stimulus_onset'). | _required_ |
+| Name | Type | Description | Default |
+|--------|--------------|--------------------------------------------------------------------------|------------|
+| label | [str](`str`) | Descriptive label for the event (e.g., 'trial_start', 'stimulus_onset'). | _required_ |
#### Raises {.doc-section .doc-section-raises}
-| Name | Type | Description |
-|--------|----------------|-----------------------------------------|
-| | RuntimeWarning | If called when recording is not active. |
+| Name | Type | Description |
+|--------|------------------------------------|-----------------------------------------|
+| | [RuntimeWarning](`RuntimeWarning`) | If called when recording is not active. |
#### Examples {.doc-section .doc-section-examples}
-tracker.record_event('trial_1_start')
-# ... present stimulus ...
-tracker.record_event('stimulus_offset')
+```python
+ET_controller.record_event('trial_1_start')
+# present stimulus
+ET_controller.record_event('stimulus_offset')
+```
### save_calibration { #DeToX.ETracker.save_calibration }
@@ -239,22 +383,32 @@ and saves it as a binary file. This can be reloaded later with
#### Parameters {.doc-section .doc-section-parameters}
-| Name | Type | Description | Default |
-|----------|-------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------|
-| filename | str \| None | Desired output path. If None and `use_gui` is False, a timestamped default name is used (e.g., 'YYYY-mm-dd_HH-MM-SS_calibration.dat'). If provided without an extension, '.dat' is appended. If an extension is already present, it is left unchanged. | `None` |
-| use_gui | bool | If True, opens a file-save dialog (Psychopy) where the user chooses the path. The suggested name respects the logic above. Default False. | `False` |
+| Name | Type | Description | Default |
+|----------|----------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------|
+| filename | [str](`str`) \| None | Desired output path. If None and `use_gui` is False, a timestamped default name is used (e.g., 'YYYY-mm-dd_HH-MM-SS_calibration.dat'). If provided without an extension, '.dat' is appended. If an extension is already present, it is left unchanged. | `None` |
+| use_gui | [bool](`bool`) | If True, opens a file-save dialog (Psychopy) where the user chooses the path. The suggested name respects the logic above. Default False. | `False` |
#### Returns {.doc-section .doc-section-returns}
-| Name | Type | Description |
-|--------|--------|-----------------------------------------------------------------------------------------------------|
-| | bool | True if saved successfully; False if cancelled, no data available, in simulation mode, or on error. |
+| Name | Type | Description |
+|--------|----------------|-----------------------------------------------------------------------------------------------------|
+| | [bool](`bool`) | True if saved successfully; False if cancelled, no data available, in simulation mode, or on error. |
#### Notes {.doc-section .doc-section-notes}
- In simulation mode, saving is skipped and a warning is issued.
- If `use_gui` is True and the dialog is cancelled, returns False.
+#### Examples {.doc-section .doc-section-examples}
+
+```python
+# Save with default timestamped name
+ET_controller.save_calibration()
+
+### Save with specified filename
+ET_controller.save_calibration('subject_01_calib.dat')
+```
+
### save_data { #DeToX.ETracker.save_data }
```python
@@ -267,6 +421,61 @@ Uses thread-safe buffer swapping to minimize lock time, then processes
and saves data in CSV or HDF5 format. Events are merged with gaze data
based on timestamp proximity.
+This method is typically called automatically by `stop_recording()`, but
+can be called manually during recording to periodically save data and
+clear buffers. This is useful for long experiments to avoid memory buildup
+and ensure data is saved even if the program crashes.
+
+#### Notes {.doc-section .doc-section-notes}
+
+- Automatically called by `stop_recording()`
+- Safe to call during active recording
+- Clears buffers after saving
+- Events are matched to nearest gaze sample by timestamp
+
+#### Examples {.doc-section .doc-section-examples}
+
+```python
+# Automatic saving (most common)
+ET_controller.start_recording('data.h5')
+# ... run experiment ...
+ET_controller.stop_recording() # Automatically calls save_data()
+
+# Manual periodic saves for long experiments
+ET_controller.start_recording('long_experiment.h5')
+
+for trial in range(100):
+ ET_controller.record_event(f'trial_{trial}_start')
+ # ... present stimuli ...
+ ET_controller.record_event(f'trial_{trial}_end')
+
+ # Save data every 10 trials to prevent memory buildup
+ if (trial + 1) % 10 == 0:
+ ET_controller.save_data() # Saves and clears buffers
+
+ET_controller.stop_recording()
+
+# Save data at natural break points
+ET_controller.start_recording('session.h5')
+
+# Block 1
+for trial in range(20):
+ # ... run trial ...
+ pass
+ET_controller.save_data() # Save after block 1
+
+# Short break
+core.wait(30)
+
+# Block 2
+for trial in range(20):
+ # ... run trial ...
+ pass
+ET_controller.save_data() # Save after block 2
+
+ET_controller.stop_recording()
+```
+
### set_eyetracking_settings { #DeToX.ETracker.set_eyetracking_settings }
```python
@@ -285,27 +494,43 @@ configuration changes are only made when the device is idle and connected.
#### Parameters {.doc-section .doc-section-parameters}
-| Name | Type | Description | Default |
-|---------------------------|--------|------------------------------------------------------------------------------------------------------------------|-----------|
-| desired_fps | int | Desired sampling frequency in Hz (e.g., 60, 120, 300). If None, the current frequency is retained. | `None` |
-| desired_illumination_mode | str | Desired illumination mode (e.g., 'Auto', 'Bright', 'Dark'). If None, the current illumination mode is retained. | `None` |
-| use_gui | bool | If True, opens a PsychoPy GUI dialog that allows users to select settings interactively. Defaults to False. | `False` |
+| Name | Type | Description | Default |
+|---------------------------|----------------|------------------------------------------------------------------------------------------------------------------|-----------|
+| desired_fps | [int](`int`) | Desired sampling frequency in Hz (e.g., 60, 120, 300). If None, the current frequency is retained. | `None` |
+| desired_illumination_mode | [str](`str`) | Desired illumination mode (e.g., 'Auto', 'Bright', 'Dark'). If None, the current illumination mode is retained. | `None` |
+| use_gui | [bool](`bool`) | If True, opens a PsychoPy GUI dialog that allows users to select settings interactively. Defaults to False. | `False` |
#### Raises {.doc-section .doc-section-raises}
-| Name | Type | Description |
-|--------|--------------|-------------------------------------------------------------------------------------------|
-| | RuntimeError | If no physical eye tracker is connected or if the function is called in simulation mode. |
-| | ValueError | If the specified FPS or illumination mode is not supported by the connected device. |
+| Name | Type | Description |
+|--------|--------------------------------|-------------------------------------------------------------------------------------------|
+| | [RuntimeError](`RuntimeError`) | If no physical eye tracker is connected or if the function is called in simulation mode. |
+| | [ValueError](`ValueError`) | If the specified FPS or illumination mode is not supported by the connected device. |
#### Notes {.doc-section .doc-section-notes}
- Settings cannot be changed during active recording. If an ongoing recording
- is detected, a non-blocking warning is issued and the function exits safely.
+is detected, a non-blocking warning is issued and the function exits safely.
- When `use_gui=True`, a PsychoPy dialog window appears. It must be closed
- manually before the program continues.
+manually before the program continues.
- After successfully applying new settings, the internal attributes `self.fps`
- and `self.illum_mode` are updated to reflect the current device configuration.
+and `self.illum_mode` are updated to reflect the current device configuration.
+
+#### Examples {.doc-section .doc-section-examples}
+
+```python
+# Set frequency to 120 Hz programmatically
+ET_controller.set_eyetracking_settings(desired_fps=120)
+
+# Set illumination mode to 'Bright'
+ET_controller.set_eyetracking_settings(desired_illumination_mode='Bright')
+
+# Set both frequency and illumination mode
+ET_controller.set_eyetracking_settings(desired_fps=120, desired_illumination_mode='Bright')
+
+# Use GUI to select settings interactively
+ET_controller.set_eyetracking_settings(use_gui=True)
+```
### show_status { #DeToX.ETracker.show_status }
@@ -325,10 +550,17 @@ or provide your own custom MovieStim object.
#### Parameters {.doc-section .doc-section-parameters}
+<<<<<<< HEAD
+| Name | Type | Description | Default |
+|--------------|----------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------|
+| decision_key | [str](`str`) | Key to press to exit visualization. Default 'space'. | `'space'` |
+| video_help | [bool](`bool`) or [visual](`psychopy.visual`).[MovieStim](`psychopy.visual.MovieStim`) | Controls background video display: - True: Uses built-in instructional video (default) - False: No video displayed - visual.MovieStim: Uses your pre-loaded custom video. You are responsible for scaling (size) and positioning (pos) the MovieStim to fit your desired layout. Default True. | `True` |
+=======
| Name | Type | Description | Default |
|--------------|--------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------|
| decision_key | str | Key to press to exit visualization. Default 'space'. | `'space'` |
| video_help | bool or visual.MovieStim | Controls background video display: - True: Uses built-in instructional video (default) - False: No video displayed - visual.MovieStim: Uses your pre-loaded custom video. You are responsible for scaling (size) and positioning (pos) the MovieStim to fit your desired layout. Default True. | `True` |
+>>>>>>> origin/main
#### Notes {.doc-section .doc-section-notes}
@@ -341,6 +573,32 @@ height units and positioned at (0, -0.08) to avoid covering the track box.
#### Examples {.doc-section .doc-section-examples}
```python
+<<<<<<< HEAD
+# Basic usage with built-in video
+ET_controller.show_status()
+
+# No background video
+ET_controller.show_status(video_help=False)
+
+# Custom exit key
+ET_controller.show_status(decision_key='return')
+
+# Use custom video
+from psychopy import visual
+my_video = visual.MovieStim(
+ win,
+ 'instructions.mp4',
+ size=(0.8, 0.6),
+ pos=(0, -0.1)
+)
+ET_controller.show_status(video_help=my_video)
+
+# Complete workflow: position participant before calibration
+ET_controller.show_status() # Position participant
+success = ET_controller.calibrate(5) # Run calibration
+if success:
+ ET_controller.start_recording('data.h5') # Start recording
+=======
>>> # Use built-in video
>>> tracker.show_status()
```
@@ -354,6 +612,7 @@ height units and positioned at (0, -0.08) to avoid covering the track box.
>>> # Custom video
>>> my_video = visual.MovieStim(win, 'custom.mp4', size=0.5, pos=(0, -0.2))
>>> tracker.show_status(video_help=my_video)
+>>>>>>> origin/main
```
### start_recording { #DeToX.ETracker.start_recording }
@@ -370,18 +629,20 @@ Creates HDF5 or CSV files based on filename extension.
#### Parameters {.doc-section .doc-section-parameters}
-| Name | Type | Description | Default |
-|------------|--------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------|
-| filename | str | Output filename for gaze data. If None, generates timestamp-based name. File extension determines format (.h5/.hdf5 for HDF5, .csv for CSV, defaults to .h5). | `None` |
-| raw_format | bool | If True, preserves all original Tobii SDK column names and data. If False (default), uses simplified column names and subset of columns. Raw format is useful for advanced analysis requiring full metadata. | `False` |
+| Name | Type | Description | Default |
+|------------|----------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------|
+| filename | [str](`str`) | Output filename for gaze data. If None, generates timestamp-based name. File extension determines format (.h5/.hdf5 for HDF5, .csv for CSV, defaults to .h5). | `None` |
+| raw_format | [bool](`bool`) | If True, preserves all original Tobii SDK column names and data. If False (default), uses simplified column names and subset of columns. Raw format is useful for advanced analysis requiring full metadata. | `False` |
#### Examples {.doc-section .doc-section-examples}
-# Standard format (simplified columns)
-tracker.start_recording('data.h5')
+```python
+### Standard format (simplified columns)
+ET_controller.start_recording('data.h5')
-# Raw format (all Tobii SDK columns preserved)
-tracker.start_recording('data_raw.h5', raw_format=True)
+### Raw format (all Tobii SDK columns preserved)
+ET_controller.start_recording('data_raw.h5', raw_format=True)
+```
### stop_recording { #DeToX.ETracker.stop_recording }
@@ -397,9 +658,9 @@ simulation and real eye tracker modes appropriately.
#### Raises {.doc-section .doc-section-raises}
-| Name | Type | Description |
-|--------|-------------|---------------------------------------|
-| | UserWarning | If recording is not currently active. |
+| Name | Type | Description |
+|--------|------------------------------|---------------------------------------|
+| | [UserWarning](`UserWarning`) | If recording is not currently active. |
#### Notes {.doc-section .doc-section-notes}
diff --git a/Documentation/api/ETracker.record_event.qmd b/Documentation/api/ETracker.record_event.qmd
index 7504642..088944e 100644
--- a/Documentation/api/ETracker.record_event.qmd
+++ b/Documentation/api/ETracker.record_event.qmd
@@ -12,18 +12,20 @@ simulation vs. real eye tracker modes.
## Parameters {.doc-section .doc-section-parameters}
-| Name | Type | Description | Default |
-|--------|--------|--------------------------------------------------------------------------|------------|
-| label | str | Descriptive label for the event (e.g., 'trial_start', 'stimulus_onset'). | _required_ |
+| Name | Type | Description | Default |
+|--------|--------------|--------------------------------------------------------------------------|------------|
+| label | [str](`str`) | Descriptive label for the event (e.g., 'trial_start', 'stimulus_onset'). | _required_ |
## Raises {.doc-section .doc-section-raises}
-| Name | Type | Description |
-|--------|----------------|-----------------------------------------|
-| | RuntimeWarning | If called when recording is not active. |
+| Name | Type | Description |
+|--------|------------------------------------|-----------------------------------------|
+| | [RuntimeWarning](`RuntimeWarning`) | If called when recording is not active. |
## Examples {.doc-section .doc-section-examples}
-tracker.record_event('trial_1_start')
-# ... present stimulus ...
-tracker.record_event('stimulus_offset')
\ No newline at end of file
+```python
+ET_controller.record_event('trial_1_start')
+# present stimulus
+ET_controller.record_event('stimulus_offset')
+```
\ No newline at end of file
diff --git a/Documentation/api/ETracker.save_calibration.qmd b/Documentation/api/ETracker.save_calibration.qmd
index 303e26e..f795075 100644
--- a/Documentation/api/ETracker.save_calibration.qmd
+++ b/Documentation/api/ETracker.save_calibration.qmd
@@ -12,18 +12,28 @@ and saves it as a binary file. This can be reloaded later with
## Parameters {.doc-section .doc-section-parameters}
-| Name | Type | Description | Default |
-|----------|-------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------|
-| filename | str \| None | Desired output path. If None and `use_gui` is False, a timestamped default name is used (e.g., 'YYYY-mm-dd_HH-MM-SS_calibration.dat'). If provided without an extension, '.dat' is appended. If an extension is already present, it is left unchanged. | `None` |
-| use_gui | bool | If True, opens a file-save dialog (Psychopy) where the user chooses the path. The suggested name respects the logic above. Default False. | `False` |
+| Name | Type | Description | Default |
+|----------|----------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------|
+| filename | [str](`str`) \| None | Desired output path. If None and `use_gui` is False, a timestamped default name is used (e.g., 'YYYY-mm-dd_HH-MM-SS_calibration.dat'). If provided without an extension, '.dat' is appended. If an extension is already present, it is left unchanged. | `None` |
+| use_gui | [bool](`bool`) | If True, opens a file-save dialog (Psychopy) where the user chooses the path. The suggested name respects the logic above. Default False. | `False` |
## Returns {.doc-section .doc-section-returns}
-| Name | Type | Description |
-|--------|--------|-----------------------------------------------------------------------------------------------------|
-| | bool | True if saved successfully; False if cancelled, no data available, in simulation mode, or on error. |
+| Name | Type | Description |
+|--------|----------------|-----------------------------------------------------------------------------------------------------|
+| | [bool](`bool`) | True if saved successfully; False if cancelled, no data available, in simulation mode, or on error. |
## Notes {.doc-section .doc-section-notes}
- In simulation mode, saving is skipped and a warning is issued.
-- If `use_gui` is True and the dialog is cancelled, returns False.
\ No newline at end of file
+- If `use_gui` is True and the dialog is cancelled, returns False.
+
+## Examples {.doc-section .doc-section-examples}
+
+```python
+# Save with default timestamped name
+ET_controller.save_calibration()
+
+### Save with specified filename
+ET_controller.save_calibration('subject_01_calib.dat')
+```
\ No newline at end of file
diff --git a/Documentation/api/ETracker.save_data.qmd b/Documentation/api/ETracker.save_data.qmd
index 0860773..cffcbda 100644
--- a/Documentation/api/ETracker.save_data.qmd
+++ b/Documentation/api/ETracker.save_data.qmd
@@ -8,4 +8,59 @@ Save buffered gaze and event data to file with optimized processing.
Uses thread-safe buffer swapping to minimize lock time, then processes
and saves data in CSV or HDF5 format. Events are merged with gaze data
-based on timestamp proximity.
\ No newline at end of file
+based on timestamp proximity.
+
+This method is typically called automatically by `stop_recording()`, but
+can be called manually during recording to periodically save data and
+clear buffers. This is useful for long experiments to avoid memory buildup
+and ensure data is saved even if the program crashes.
+
+## Notes {.doc-section .doc-section-notes}
+
+- Automatically called by `stop_recording()`
+- Safe to call during active recording
+- Clears buffers after saving
+- Events are matched to nearest gaze sample by timestamp
+
+## Examples {.doc-section .doc-section-examples}
+
+```python
+# Automatic saving (most common)
+ET_controller.start_recording('data.h5')
+# ... run experiment ...
+ET_controller.stop_recording() # Automatically calls save_data()
+
+# Manual periodic saves for long experiments
+ET_controller.start_recording('long_experiment.h5')
+
+for trial in range(100):
+ ET_controller.record_event(f'trial_{trial}_start')
+ # ... present stimuli ...
+ ET_controller.record_event(f'trial_{trial}_end')
+
+ # Save data every 10 trials to prevent memory buildup
+ if (trial + 1) % 10 == 0:
+ ET_controller.save_data() # Saves and clears buffers
+
+ET_controller.stop_recording()
+
+# Save data at natural break points
+ET_controller.start_recording('session.h5')
+
+# Block 1
+for trial in range(20):
+ # ... run trial ...
+ pass
+ET_controller.save_data() # Save after block 1
+
+# Short break
+core.wait(30)
+
+# Block 2
+for trial in range(20):
+ # ... run trial ...
+ pass
+ET_controller.save_data() # Save after block 2
+
+ET_controller.stop_recording()
+```
\ No newline at end of file
diff --git a/Documentation/api/ETracker.show_status.qmd b/Documentation/api/ETracker.show_status.qmd
index cae414d..e1ae767 100644
--- a/Documentation/api/ETracker.show_status.qmd
+++ b/Documentation/api/ETracker.show_status.qmd
@@ -16,10 +16,17 @@ or provide your own custom MovieStim object.
## Parameters {.doc-section .doc-section-parameters}
+<<<<<<< HEAD
+| Name | Type | Description | Default |
+|--------------|----------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------|
+| decision_key | [str](`str`) | Key to press to exit visualization. Default 'space'. | `'space'` |
+| video_help | [bool](`bool`) or [visual](`psychopy.visual`).[MovieStim](`psychopy.visual.MovieStim`) | Controls background video display: - True: Uses built-in instructional video (default) - False: No video displayed - visual.MovieStim: Uses your pre-loaded custom video. You are responsible for scaling (size) and positioning (pos) the MovieStim to fit your desired layout. Default True. | `True` |
+=======
| Name | Type | Description | Default |
|--------------|--------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------|
| decision_key | str | Key to press to exit visualization. Default 'space'. | `'space'` |
| video_help | bool or visual.MovieStim | Controls background video display: - True: Uses built-in instructional video (default) - False: No video displayed - visual.MovieStim: Uses your pre-loaded custom video. You are responsible for scaling (size) and positioning (pos) the MovieStim to fit your desired layout. Default True. | `True` |
+>>>>>>> origin/main
## Notes {.doc-section .doc-section-notes}
@@ -32,6 +39,32 @@ height units and positioned at (0, -0.08) to avoid covering the track box.
## Examples {.doc-section .doc-section-examples}
```python
+<<<<<<< HEAD
+# Basic usage with built-in video
+ET_controller.show_status()
+
+# No background video
+ET_controller.show_status(video_help=False)
+
+# Custom exit key
+ET_controller.show_status(decision_key='return')
+
+# Use custom video
+from psychopy import visual
+my_video = visual.MovieStim(
+ win,
+ 'instructions.mp4',
+ size=(0.8, 0.6),
+ pos=(0, -0.1)
+)
+ET_controller.show_status(video_help=my_video)
+
+# Complete workflow: position participant before calibration
+ET_controller.show_status() # Position participant
+success = ET_controller.calibrate(5) # Run calibration
+if success:
+ ET_controller.start_recording('data.h5') # Start recording
+=======
>>> # Use built-in video
>>> tracker.show_status()
```
@@ -45,4 +78,5 @@ height units and positioned at (0, -0.08) to avoid covering the track box.
>>> # Custom video
>>> my_video = visual.MovieStim(win, 'custom.mp4', size=0.5, pos=(0, -0.2))
>>> tracker.show_status(video_help=my_video)
+>>>>>>> origin/main
```
\ No newline at end of file
diff --git a/Documentation/api/ETracker.start_recording.qmd b/Documentation/api/ETracker.start_recording.qmd
index bb38b0c..5ac1563 100644
--- a/Documentation/api/ETracker.start_recording.qmd
+++ b/Documentation/api/ETracker.start_recording.qmd
@@ -12,15 +12,17 @@ Creates HDF5 or CSV files based on filename extension.
## Parameters {.doc-section .doc-section-parameters}
-| Name | Type | Description | Default |
-|------------|--------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------|
-| filename | str | Output filename for gaze data. If None, generates timestamp-based name. File extension determines format (.h5/.hdf5 for HDF5, .csv for CSV, defaults to .h5). | `None` |
-| raw_format | bool | If True, preserves all original Tobii SDK column names and data. If False (default), uses simplified column names and subset of columns. Raw format is useful for advanced analysis requiring full metadata. | `False` |
+| Name | Type | Description | Default |
+|------------|----------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------|
+| filename | [str](`str`) | Output filename for gaze data. If None, generates timestamp-based name. File extension determines format (.h5/.hdf5 for HDF5, .csv for CSV, defaults to .h5). | `None` |
+| raw_format | [bool](`bool`) | If True, preserves all original Tobii SDK column names and data. If False (default), uses simplified column names and subset of columns. Raw format is useful for advanced analysis requiring full metadata. | `False` |
## Examples {.doc-section .doc-section-examples}
-# Standard format (simplified columns)
-tracker.start_recording('data.h5')
+```python
+### Standard format (simplified columns)
+ET_controller.start_recording('data.h5')
-# Raw format (all Tobii SDK columns preserved)
-tracker.start_recording('data_raw.h5', raw_format=True)
\ No newline at end of file
+### Raw format (all Tobii SDK columns preserved)
+ET_controller.start_recording('data_raw.h5', raw_format=True)
+```
\ No newline at end of file
diff --git a/Documentation/api/ETracker.stop_recording.qmd b/Documentation/api/ETracker.stop_recording.qmd
index d22ecca..b89cc6b 100644
--- a/Documentation/api/ETracker.stop_recording.qmd
+++ b/Documentation/api/ETracker.stop_recording.qmd
@@ -12,9 +12,9 @@ simulation and real eye tracker modes appropriately.
## Raises {.doc-section .doc-section-raises}
-| Name | Type | Description |
-|--------|-------------|---------------------------------------|
-| | UserWarning | If recording is not currently active. |
+| Name | Type | Description |
+|--------|------------------------------|---------------------------------------|
+| | [UserWarning](`UserWarning`) | If recording is not currently active. |
## Notes {.doc-section .doc-section-notes}
diff --git a/Documentation/api/InfantStimuli.qmd b/Documentation/api/InfantStimuli.qmd
index a04ca7d..a96cea2 100644
--- a/Documentation/api/InfantStimuli.qmd
+++ b/Documentation/api/InfantStimuli.qmd
@@ -25,12 +25,12 @@ Key features include:
## Attributes {.doc-section .doc-section-attributes}
-| Name | Type | Description |
-|---------------|------------------------|--------------------------------------------------------|
-| win | psychopy.visual.Window | The PsychoPy window used for rendering. |
-| stims | dict | Dictionary mapping indices to ImageStim objects. |
-| stim_size | dict | Dictionary mapping indices to original stimulus sizes. |
-| present_order | list | List defining the presentation sequence of stimuli. |
+| Name | Type | Description |
+|---------------|---------------------------------------------------------------------------------------|--------------------------------------------------------|
+| win | [psychopy](`psychopy`).[visual](`psychopy.visual`).[Window](`psychopy.visual.Window`) | The PsychoPy window used for rendering. |
+| stims | [dict](`dict`) | Dictionary mapping indices to ImageStim objects. |
+| stim_size | [dict](`dict`) | Dictionary mapping indices to original stimulus sizes. |
+| present_order | [list](`list`) | List defining the presentation sequence of stimuli. |
## Methods
@@ -53,15 +53,15 @@ of available stimuli, enabling circular access patterns.
#### Parameters {.doc-section .doc-section-parameters}
-| Name | Type | Description | Default |
-|--------|--------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------|------------|
-| idx | int | The index of the stimulus in the presentation order. Can be any non-negative integer; values beyond the stimulus count will wrap around using modulo operation. | _required_ |
+| Name | Type | Description | Default |
+|--------|--------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------|------------|
+| idx | [int](`int`) | The index of the stimulus in the presentation order. Can be any non-negative integer; values beyond the stimulus count will wrap around using modulo operation. | _required_ |
#### Returns {.doc-section .doc-section-returns}
-| Name | Type | Description |
-|--------|---------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| | psychopy.visual.ImageStim | The stimulus corresponding to the given index in the presentation order. The returned stimulus is ready for positioning, animation, and drawing operations. |
+| Name | Type | Description |
+|--------|---------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| | [psychopy](`psychopy`).[visual](`psychopy.visual`).[ImageStim](`psychopy.visual.ImageStim`) | The stimulus corresponding to the given index in the presentation order. The returned stimulus is ready for positioning, animation, and drawing operations. |
#### Examples {.doc-section .doc-section-examples}
@@ -85,15 +85,15 @@ the base size before applying scaling transformations.
#### Parameters {.doc-section .doc-section-parameters}
-| Name | Type | Description | Default |
-|--------|--------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------|------------|
-| idx | int | The index of the stimulus in the presentation order. Can be any non-negative integer; values beyond the stimulus count will wrap around using modulo operation. | _required_ |
+| Name | Type | Description | Default |
+|--------|--------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------|------------|
+| idx | [int](`int`) | The index of the stimulus in the presentation order. Can be any non-negative integer; values beyond the stimulus count will wrap around using modulo operation. | _required_ |
#### Returns {.doc-section .doc-section-returns}
-| Name | Type | Description |
-|--------|--------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| | tuple | The original size of the stimulus as (width, height) in the units specified during stimulus creation. These values represent the stimulus dimensions before any scaling or animation effects. |
+| Name | Type | Description |
+|--------|------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| | [tuple](`tuple`) | The original size of the stimulus as (width, height) in the units specified during stimulus creation. These values represent the stimulus dimensions before any scaling or animation effects. |
#### Notes {.doc-section .doc-section-notes}
diff --git a/Documentation/api/MouseCalibrationSession.qmd b/Documentation/api/MouseCalibrationSession.qmd
index b5b3234..d2d1f98 100644
--- a/Documentation/api/MouseCalibrationSession.qmd
+++ b/Documentation/api/MouseCalibrationSession.qmd
@@ -50,6 +50,6 @@ calibration to ensure consistency across modes.
#### Returns {.doc-section .doc-section-returns}
-| Name | Type | Description |
-|--------|--------|-------------------------------------------------------------------------------------------------------------------|
-| | bool | True if calibration finished successfully and was accepted by user, False if the user exits early via escape key. |
\ No newline at end of file
+| Name | Type | Description |
+|--------|----------------|-------------------------------------------------------------------------------------------------------------------|
+| | [bool](`bool`) | True if calibration finished successfully and was accepted by user, False if the user exits early via escape key. |
\ No newline at end of file
diff --git a/Documentation/api/NicePrint.qmd b/Documentation/api/NicePrint.qmd
index 856e66b..e5835ee 100644
--- a/Documentation/api/NicePrint.qmd
+++ b/Documentation/api/NicePrint.qmd
@@ -18,14 +18,22 @@ environments.
## Parameters {.doc-section .doc-section-parameters}
+<<<<<<< HEAD
+| Name | Type | Description | Default |
+|---------|----------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------|
+| body | [str](`str`) | The string to print inside the box. Can contain multiple lines separated by newline characters. Each line will be padded to align within the box. | _required_ |
+| title | [str](`str`) | A title to print on the top border of the box. The title will be centered within the top border. If empty string or not provided, the top border will be solid. Default empty string. | `''` |
+| verbose | [bool](`bool`) | If True, the formatted box will be printed to the console. Default is True. | `True` |
+=======
| Name | Type | Description | Default |
|---------|--------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------|
| body | str | The string to print inside the box. Can contain multiple lines separated by newline characters. Each line will be padded to align within the box. | _required_ |
| title | str | A title to print on the top border of the box. The title will be centered within the top border. If empty string or not provided, the top border will be solid. Default empty string. | `''` |
| verbose | bool | If True, the formatted box will be printed to the console. Default is True. | `True` |
+>>>>>>> origin/main
## Returns {.doc-section .doc-section-returns}
-| Name | Type | Description |
-|--------|--------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| | str | The formatted text with box characters, ready for display in console or use with PsychoPy TextStim objects. Includes all box-drawing characters and proper spacing. |
\ No newline at end of file
+| Name | Type | Description |
+|--------|--------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| | [str](`str`) | The formatted text with box characters, ready for display in console or use with PsychoPy TextStim objects. Includes all box-drawing characters and proper spacing. |
\ No newline at end of file
diff --git a/Documentation/api/TobiiCalibrationSession.qmd b/Documentation/api/TobiiCalibrationSession.qmd
index 109667c..f435800 100644
--- a/Documentation/api/TobiiCalibrationSession.qmd
+++ b/Documentation/api/TobiiCalibrationSession.qmd
@@ -50,6 +50,6 @@ any subset of points until satisfied.
#### Returns {.doc-section .doc-section-returns}
-| Name | Type | Description |
-|--------|--------|--------------------------------------------------------------------------------------------------------------------------------|
-| | bool | True if calibration was successful and accepted by user, False if aborted via escape key or if calibration computation failed. |
\ No newline at end of file
+| Name | Type | Description |
+|--------|----------------|--------------------------------------------------------------------------------------------------------------------------------|
+| | [bool](`bool`) | True if calibration was successful and accepted by user, False if aborted via escape key or if calibration computation failed. |
\ No newline at end of file
diff --git a/Documentation/api/convert_height_to_units.qmd b/Documentation/api/convert_height_to_units.qmd
index b49281e..396b820 100644
--- a/Documentation/api/convert_height_to_units.qmd
+++ b/Documentation/api/convert_height_to_units.qmd
@@ -17,16 +17,16 @@ elements appear at the intended size on screen.
## Parameters {.doc-section .doc-section-parameters}
-| Name | Type | Description | Default |
-|--------------|------------------------|-----------------------------------------------------------------------------------------------------------------------------------------|------------|
-| win | psychopy.visual.Window | The PsychoPy window which provides information about units and size. The window's current unit system determines the conversion method. | _required_ |
-| height_value | float | Size in height units (fraction of screen height). For example, 0.1 represents 10% of the screen height. | _required_ |
+| Name | Type | Description | Default |
+|--------------|---------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------|------------|
+| win | [psychopy](`psychopy`).[visual](`psychopy.visual`).[Window](`psychopy.visual.Window`) | The PsychoPy window which provides information about units and size. The window's current unit system determines the conversion method. | _required_ |
+| height_value | [float](`float`) | Size in height units (fraction of screen height). For example, 0.1 represents 10% of the screen height. | _required_ |
## Returns {.doc-section .doc-section-returns}
-| Name | Type | Description |
-|--------|--------|-------------------------------------------------------------------------------------------------------------------------------------------|
-| | float | Size converted to current window units. The returned value maintains the same visual size on screen as the original height specification. |
+| Name | Type | Description |
+|--------|------------------|-------------------------------------------------------------------------------------------------------------------------------------------|
+| | [float](`float`) | Size converted to current window units. The returned value maintains the same visual size on screen as the original height specification. |
## Notes {.doc-section .doc-section-notes}
diff --git a/Documentation/api/get_psychopy_pos.qmd b/Documentation/api/get_psychopy_pos.qmd
index af88791..777474a 100644
--- a/Documentation/api/get_psychopy_pos.qmd
+++ b/Documentation/api/get_psychopy_pos.qmd
@@ -16,23 +16,23 @@ stimuli and for accurate visualization of eye tracking results.
## Parameters {.doc-section .doc-section-parameters}
-| Name | Type | Description | Default |
-|--------|------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------|
-| win | psychopy.visual.Window | The PsychoPy window which provides information about units and size. Window properties determine the target coordinate system. | _required_ |
-| p | tuple or array - like | The Tobii ADCS coordinates to convert. Can be: - Single coordinate: (x, y) tuple - Multiple coordinates: (N, 2) array where N is number of samples Values should be in range [0, 1] where (0, 0) is top-left and (1, 1) is bottom-right. | _required_ |
-| units | str | The target units for the PsychoPy coordinates. If None, uses the window's default units. Supported: 'norm', 'height', 'pix', 'cm', 'deg', 'degFlat', 'degFlatPos'. | `None` |
+| Name | Type | Description | Default |
+|--------|---------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------|
+| win | [psychopy](`psychopy`).[visual](`psychopy.visual`).[Window](`psychopy.visual.Window`) | The PsychoPy window which provides information about units and size. Window properties determine the target coordinate system. | _required_ |
+| p | [tuple](`tuple`) or [array](`array`) - [like](`like`) | The Tobii ADCS coordinates to convert. Can be: - Single coordinate: (x, y) tuple - Multiple coordinates: (N, 2) array where N is number of samples Values should be in range [0, 1] where (0, 0) is top-left and (1, 1) is bottom-right. | _required_ |
+| units | [str](`str`) | The target units for the PsychoPy coordinates. If None, uses the window's default units. Supported: 'norm', 'height', 'pix', 'cm', 'deg', 'degFlat', 'degFlatPos'. | `None` |
## Returns {.doc-section .doc-section-returns}
-| Name | Type | Description |
-|--------|------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| | tuple or ndarray | The converted PsychoPy coordinates in the specified unit system. - Single input: returns (x, y) tuple - Array input: returns (N, 2) array Origin is at screen center for most unit systems. |
+| Name | Type | Description |
+|--------|------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| | [tuple](`tuple`) or [ndarray](`ndarray`) | The converted PsychoPy coordinates in the specified unit system. - Single input: returns (x, y) tuple - Array input: returns (N, 2) array Origin is at screen center for most unit systems. |
## Raises {.doc-section .doc-section-raises}
-| Name | Type | Description |
-|--------|------------|------------------------------------------------------|
-| | ValueError | If the provided units are not supported by PsychoPy. |
+| Name | Type | Description |
+|--------|----------------------------|------------------------------------------------------|
+| | [ValueError](`ValueError`) | If the provided units are not supported by PsychoPy. |
## Examples {.doc-section .doc-section-examples}
diff --git a/Documentation/api/get_psychopy_pos_from_trackbox.qmd b/Documentation/api/get_psychopy_pos_from_trackbox.qmd
index 5ccb29d..1d4cc3c 100644
--- a/Documentation/api/get_psychopy_pos_from_trackbox.qmd
+++ b/Documentation/api/get_psychopy_pos_from_trackbox.qmd
@@ -18,23 +18,23 @@ because TBCS uses the tracker's perspective, not the user's.
## Parameters {.doc-section .doc-section-parameters}
-| Name | Type | Description | Default |
-|--------|------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------|
-| win | psychopy.visual.Window | The PsychoPy window which provides information about units and size. Window properties determine the target coordinate system. | _required_ |
-| p | tuple | The Tobii TBCS coordinates to convert as (x, y). Values are in range [0, 1] representing position within the track box from the tracker's perspective. | _required_ |
-| units | str | The target units for the PsychoPy coordinates. If None, uses the window's default units. Supported: 'norm', 'height', 'pix', 'cm', 'deg', 'degFlat', 'degFlatPos'. | `None` |
+| Name | Type | Description | Default |
+|--------|---------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------|
+| win | [psychopy](`psychopy`).[visual](`psychopy.visual`).[Window](`psychopy.visual.Window`) | The PsychoPy window which provides information about units and size. Window properties determine the target coordinate system. | _required_ |
+| p | [tuple](`tuple`) | The Tobii TBCS coordinates to convert as (x, y). Values are in range [0, 1] representing position within the track box from the tracker's perspective. | _required_ |
+| units | [str](`str`) | The target units for the PsychoPy coordinates. If None, uses the window's default units. Supported: 'norm', 'height', 'pix', 'cm', 'deg', 'degFlat', 'degFlatPos'. | `None` |
## Returns {.doc-section .doc-section-returns}
-| Name | Type | Description |
-|--------|--------|--------------------------------------------------------------------------------------------------------------------------------|
-| | tuple | The converted PsychoPy coordinates in the specified unit system. Suitable for positioning visual feedback about user position. |
+| Name | Type | Description |
+|--------|------------------|--------------------------------------------------------------------------------------------------------------------------------|
+| | [tuple](`tuple`) | The converted PsychoPy coordinates in the specified unit system. Suitable for positioning visual feedback about user position. |
## Raises {.doc-section .doc-section-raises}
-| Name | Type | Description |
-|--------|------------|------------------------------------------|
-| | ValueError | If the provided units are not supported. |
+| Name | Type | Description |
+|--------|----------------------------|------------------------------------------|
+| | [ValueError](`ValueError`) | If the provided units are not supported. |
## Notes {.doc-section .doc-section-notes}
diff --git a/Documentation/api/get_tobii_pos.qmd b/Documentation/api/get_tobii_pos.qmd
index a2dfd22..be54c92 100644
--- a/Documentation/api/get_tobii_pos.qmd
+++ b/Documentation/api/get_tobii_pos.qmd
@@ -17,23 +17,23 @@ hardware-independent coordinate system for eye tracking data.
## Parameters {.doc-section .doc-section-parameters}
-| Name | Type | Description | Default |
-|--------|------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------|
-| win | psychopy.visual.Window | The PsychoPy window which provides information about units and size. Window properties determine the source coordinate system. | _required_ |
-| p | tuple | The PsychoPy coordinates to convert as (x, y) in specified units. | _required_ |
-| units | str | The units of the input PsychoPy coordinates. If None, uses the window's default units. Supported: 'norm', 'height', 'pix', 'cm', 'deg', 'degFlat', 'degFlatPos'. | `None` |
+| Name | Type | Description | Default |
+|--------|---------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------|
+| win | [psychopy](`psychopy`).[visual](`psychopy.visual`).[Window](`psychopy.visual.Window`) | The PsychoPy window which provides information about units and size. Window properties determine the source coordinate system. | _required_ |
+| p | [tuple](`tuple`) | The PsychoPy coordinates to convert as (x, y) in specified units. | _required_ |
+| units | [str](`str`) | The units of the input PsychoPy coordinates. If None, uses the window's default units. Supported: 'norm', 'height', 'pix', 'cm', 'deg', 'degFlat', 'degFlatPos'. | `None` |
## Returns {.doc-section .doc-section-returns}
-| Name | Type | Description |
-|--------|--------|-----------------------------------------------------------------------------------------------------------------------------------|
-| | tuple | The converted Tobii ADCS coordinates as (x, y) where both values are in range [0, 1]. (0, 0) is top-left, (1, 1) is bottom-right. |
+| Name | Type | Description |
+|--------|------------------|-----------------------------------------------------------------------------------------------------------------------------------|
+| | [tuple](`tuple`) | The converted Tobii ADCS coordinates as (x, y) where both values are in range [0, 1]. (0, 0) is top-left, (1, 1) is bottom-right. |
## Raises {.doc-section .doc-section-raises}
-| Name | Type | Description |
-|--------|------------|------------------------------------------|
-| | ValueError | If the provided units are not supported. |
+| Name | Type | Description |
+|--------|----------------------------|------------------------------------------|
+| | [ValueError](`ValueError`) | If the provided units are not supported. |
## Notes {.doc-section .doc-section-notes}
diff --git a/Documentation/api/index.qmd b/Documentation/api/index.qmd
index 69303ec..d638491 100644
--- a/Documentation/api/index.qmd
+++ b/Documentation/api/index.qmd
@@ -2,7 +2,11 @@
## Main Eye-tracker Class
-The central class of the DeToX package, responsible for connecting to and managing the Tobii eye tracker. This class must be instantiated before any other functionality can be used. It provides access to calibration, recording control, and gaze-contingent presentation methods. Below are the main methods and properties of this class:
+The central class of the DeToX package, responsible for connecting to
+and managing the Tobii eye tracker. This class must be instantiated
+before any other functionality can be used. It provides access to
+calibration, recording control, and gaze-contingent presentation methods.
+Below are the main methods and properties of this class:
| | |
@@ -11,7 +15,9 @@ The central class of the DeToX package, responsible for connecting to and manag
### Control the Recording
-Functions for starting, stopping, and managing the capture of eye-tracking data. These methods allow you to initiate and terminate recordings, mark events of interest, and save collected data to disk.
+Functions for starting, stopping, and managing the capture of eye-tracking
+data. These methods allow you to initiate and terminate recordings,
+mark events of interest, and save collected data to disk.
| | |
@@ -23,7 +29,9 @@ Functions for starting, stopping, and managing the capture of eye-tracking data
### Calibration
-Methods for running and managing eye tracker calibration. These include displaying calibration status, initiating calibration routines, and saving or loading calibration settings to ensure accurate gaze data.
+Methods for running and managing eye tracker calibration. These include
+displaying calibration status, initiating calibration routines, and
+saving or loading calibration settings to ensure accurate gaze data.
| | |
@@ -35,7 +43,10 @@ Methods for running and managing eye tracker calibration. These include display
### Gaze Contingent
-Tools for running gaze-contingent experiments, where visual presentation adapts dynamically to a participants gaze position. Includes functionality for live gaze-contingent control and methods to compute average gaze positions for experimental logic.
+Tools for running gaze-contingent experiments, where visual presentation
+adapts dynamically to a participants gaze position. Includes functionality
+for live gaze-contingent control and methods to compute average gaze
+positions for experimental logic.
| | |
@@ -45,7 +56,8 @@ Tools for running gaze-contingent experiments, where visual presentation adapts
## Internal Calibration
-Classes for running eye-tracker calibration. These get called internally by the ETracker class, and are reported here only for completeness. They are comprise of a base calibration class that set the common interface, and the specific implementations for Tobii and Mouse calibration.
+Classes for running eye-tracker calibration. These get called internally by the ETracker class, and are reported here only for completeness.
+They are comprise of a base calibration class that set the common interface, and the specific implementations for Tobii and Mouse calibration.
| | |
@@ -56,7 +68,8 @@ Classes for running eye-tracker calibration. These get called internally by the
## Coordinate Conversion
-A collection of utility functions designed to help the conversion of the data from different formats. These are called internally by the ETracker class, but can be used independently if needed.
+A collection of utility functions designed to help the conversion of the data from different formats.
+These are called internally by the ETracker class, but can be used independently if needed.
| | |
@@ -71,7 +84,8 @@ A collection of utility functions designed to help the conversion of the data fr
## Utilities
-A set of utility classes and functions for presenting stimuli and formatted text. These are called internally by the ETracker class.
+A set of utility classes and functions for presenting stimuli
+and formatted text. These are called internally by the ETracker class.
| | |
@@ -81,7 +95,12 @@ A set of utility classes and functions for presenting stimuli and formatted text
## Configuration Settings
-Configuration classes and module-level instances for customizing the behavior and appearance of the DeToX eye-tracking system. These settings control animation parameters, colors, UI element sizes, and data formats. Note: These settings should generally not be changed unless you have specific requirements. However, they can be modified through the module-level instances (e.g., ETSettings.animation) for easy configuration of your experiments.
+Configuration classes and module-level instances for customizing the
+behavior and appearance of the DeToX eye-tracking system. These settings
+control animation parameters, colors, UI element sizes, and data formats.
+Note: These settings should generally not be changed unless you have specific
+requirements. However, they can be modified through the module-level instances
+(e.g., ETSettings.animation) for easy configuration of your experiments.
| | |
diff --git a/Documentation/api/pix2tobii.qmd b/Documentation/api/pix2tobii.qmd
index 47b1dd5..2020625 100644
--- a/Documentation/api/pix2tobii.qmd
+++ b/Documentation/api/pix2tobii.qmd
@@ -13,16 +13,16 @@ coordinate conversion functions.
## Parameters {.doc-section .doc-section-parameters}
-| Name | Type | Description | Default |
-|--------|------------------------|-----------------------------------------------------------------------------------------------------------------------------|------------|
-| win | psychopy.visual.Window | The PsychoPy window which provides screen dimensions for normalization. | _required_ |
-| p | tuple | The PsychoPy pixel coordinates to convert as (x, y). Origin is at screen center, x increases rightward, y increases upward. | _required_ |
+| Name | Type | Description | Default |
+|--------|---------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------|------------|
+| win | [psychopy](`psychopy`).[visual](`psychopy.visual`).[Window](`psychopy.visual.Window`) | The PsychoPy window which provides screen dimensions for normalization. | _required_ |
+| p | [tuple](`tuple`) | The PsychoPy pixel coordinates to convert as (x, y). Origin is at screen center, x increases rightward, y increases upward. | _required_ |
## Returns {.doc-section .doc-section-returns}
-| Name | Type | Description |
-|--------|--------|----------------------------------------------------------------------------------------------------------------------------------|
-| | tuple | The converted Tobii ADCS coordinates as (x, y) in range [0, 1]. Origin is top-left, x increases rightward, y increases downward. |
+| Name | Type | Description |
+|--------|------------------|----------------------------------------------------------------------------------------------------------------------------------|
+| | [tuple](`tuple`) | The converted Tobii ADCS coordinates as (x, y) in range [0, 1]. Origin is top-left, x increases rightward, y increases downward. |
## Notes {.doc-section .doc-section-notes}
diff --git a/Documentation/api/psychopy_to_pixels.qmd b/Documentation/api/psychopy_to_pixels.qmd
index ca95d5f..89a756c 100644
--- a/Documentation/api/psychopy_to_pixels.qmd
+++ b/Documentation/api/psychopy_to_pixels.qmd
@@ -15,16 +15,16 @@ to a top-left origin system used by image libraries like PIL.
## Parameters {.doc-section .doc-section-parameters}
-| Name | Type | Description | Default |
-|--------|------------------------|-----------------------------------------------------------------------------------------------------------------------------------|------------|
-| win | psychopy.visual.Window | The PsychoPy window which provides information about units and size. Window units and dimensions determine the conversion method. | _required_ |
-| pos | tuple | The PsychoPy coordinates to convert as (x, y) in current window units. | _required_ |
+| Name | Type | Description | Default |
+|--------|---------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------|------------|
+| win | [psychopy](`psychopy`).[visual](`psychopy.visual`).[Window](`psychopy.visual.Window`) | The PsychoPy window which provides information about units and size. Window units and dimensions determine the conversion method. | _required_ |
+| pos | [tuple](`tuple`) | The PsychoPy coordinates to convert as (x, y) in current window units. | _required_ |
## Returns {.doc-section .doc-section-returns}
-| Name | Type | Description |
-|--------|--------|-----------------------------------------------------------------------------------------------------------------------------------|
-| | tuple | The converted pixel coordinates as (int, int) with origin at top-left. Values are rounded to nearest integer for pixel alignment. |
+| Name | Type | Description |
+|--------|------------------|-----------------------------------------------------------------------------------------------------------------------------------|
+| | [tuple](`tuple`) | The converted pixel coordinates as (int, int) with origin at top-left. Values are rounded to nearest integer for pixel alignment. |
## Notes {.doc-section .doc-section-notes}
diff --git a/Documentation/api/tobii2pix.qmd b/Documentation/api/tobii2pix.qmd
index 56a1f21..641c4e7 100644
--- a/Documentation/api/tobii2pix.qmd
+++ b/Documentation/api/tobii2pix.qmd
@@ -12,16 +12,16 @@ and is essential for displaying gaze data in PsychoPy windows.
## Parameters {.doc-section .doc-section-parameters}
-| Name | Type | Description | Default |
-|--------|------------------------|-----------------------------------------------------------------------------------------------------------------------------------|------------|
-| win | psychopy.visual.Window | The PsychoPy window which provides screen dimensions for scaling. | _required_ |
-| p | tuple | The Tobii ADCS coordinates to convert as (x, y) in range [0, 1]. Origin is top-left, x increases rightward, y increases downward. | _required_ |
+| Name | Type | Description | Default |
+|--------|---------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------|------------|
+| win | [psychopy](`psychopy`).[visual](`psychopy.visual`).[Window](`psychopy.visual.Window`) | The PsychoPy window which provides screen dimensions for scaling. | _required_ |
+| p | [tuple](`tuple`) | The Tobii ADCS coordinates to convert as (x, y) in range [0, 1]. Origin is top-left, x increases rightward, y increases downward. | _required_ |
## Returns {.doc-section .doc-section-returns}
-| Name | Type | Description |
-|--------|--------|---------------------------------------------------------------------------------------------------------------------------------------------|
-| | tuple | The converted PsychoPy pixel coordinates as (x, y) with origin at screen center. Values are rounded to nearest integer for pixel alignment. |
+| Name | Type | Description |
+|--------|------------------|---------------------------------------------------------------------------------------------------------------------------------------------|
+| | [tuple](`tuple`) | The converted PsychoPy pixel coordinates as (x, y) with origin at screen center. Values are rounded to nearest integer for pixel alignment. |
## Notes {.doc-section .doc-section-notes}
diff --git a/Documentation/index.qmd b/Documentation/index.qmd
index 0cea863..75369bc 100644
--- a/Documentation/index.qmd
+++ b/Documentation/index.qmd
@@ -28,20 +28,51 @@ While this repository provided solid solutions for integrating Tobii eye tracker
## Simplicity
-While the eye-tracking landscape offers many excellent tools—from [PsychoPy](https://psychopy.org/hardware/eyeTracking.html)'s built-in Tobii integration to comprehensive packages like [Titta](https://github.com/marcus-nystrom/Titta)—DeToX carves out its own niche through thoughtful simplicity. We've prioritized clarity and ease-of-use without sacrificing the flexibility researchers need. When your codebase is straightforward and well-documented, it becomes a platform for innovation rather than an obstacle to overcome.
+While the eye-tracking landscape offers many exc llent tools—from [PsychoPy](https://psychopy.org/hardware/eyeTracking.html)'s built-in Tobii integration to comprehensive packages like [Titta](https://github.com/marcus-nystrom/Titta)—DeToX carves out its own niche through thoughtful simplicity. We've prioritized clarity and ease-of-use without sacrificing the flexibility researchers need. When your codebase is straightforward and well-documented, it becomes a platform for innovation rather than an obstacle to overcome.
## Documentation
We believe that good software is only as valuable as its documentation. Too often, researchers encounter powerful packages that become frustrating to use due to unclear or incomplete documentation. When you're left wondering what a function does or how to modify basic settings, the package becomes more of a hindrance than a help. A package should empower users, not confuse them. That's why we've prioritized creating clear, comprehensive documentation with practical examples and step-by-step tutorials. Our goal is documentation that helps you understand not just **what** to do, but **why**—so you can confidently adapt the code to your specific experimental needs.
-
### Vignettes
+
Our vignettes offer hands-on explanations of DeToX's settings and features through practical examples. Each vignette focuses on specific functionality, walking you through the implementation details and configuration options you'll need to effectively integrate these features into your research workflow.
### Tutorial
While vignettes dive deep into individual features, our tutorial take a different approach - it demonstrate a complete working experiment from start to finish. Rather than explaining every parameter in detail it shows you how all the pieces fit together in real research scenarios.
+
+
+
+
# Questions?
While we tried to have a thotoug documentation with lots of examples you may have question or suggestions.
diff --git a/Documentation/resources/ETManager.jpg b/Documentation/resources/ETManager.jpg
new file mode 100644
index 0000000..7f8e2be
Binary files /dev/null and b/Documentation/resources/ETManager.jpg differ
diff --git a/Documentation/resources/Logosvg.png b/Documentation/resources/Logosvg.png
index 921b3d7..33f6a31 100644
Binary files a/Documentation/resources/Logosvg.png and b/Documentation/resources/Logosvg.png differ
diff --git a/Documentation/resources/Logosvg.svg b/Documentation/resources/Logosvg.svg
index 62e6235..0ba7ec5 100644
--- a/Documentation/resources/Logosvg.svg
+++ b/Documentation/resources/Logosvg.svg
@@ -29,13 +29,21 @@
inkscape:document-units="mm"
inkscape:zoom="1.7675"
inkscape:cx="64.780764"
+<<<<<<< HEAD
+ inkscape:cy="206.22348"
+=======
inkscape:cy="206.78925"
+>>>>>>> origin/main
inkscape:window-width="1920"
inkscape:window-height="1009"
inkscape:window-x="-8"
inkscape:window-y="-8"
inkscape:window-maximized="1"
+<<<<<<< HEAD
+ inkscape:current-layer="layer6" />>>>>>> origin/main
id="defs1">>>>>>> origin/main
sodipodi:nodetypes="cscsc" /> svg {
+>>>>>>> origin/main
/*------------------------------------*/
/* 🚫 Hide Keywords Section */
/*------------------------------------*/
@@ -58,42 +66,79 @@ body main > header div.keywords {
-/*------------------------------------*/
-/* 💻 Code Block and Output Styling */
-/*------------------------------------*/
-
-// Inline Code Styling
-p code:not(.sourceCode),
-li code:not(.sourceCode),
-td code:not(.sourceCode) {
- background-color: var(--bs-code-bg);
- color: var(--bs-code-color);
- padding: .2em;
- border-radius: 3px;
-}
-
-// Code Output Block Styling
-.cell-output.cell-output-stdout {
- background-color: #f0f2f4;
- color: #2d2d2d;
- padding: 1px 4px;
- margin-bottom: 5px;
- border-left: 2px solid #A9C3C6;
- border-radius: 1px;
- overflow: auto;
+ul.mt-1 > li > .sidebar-item-container > a > .menu-text {
+ font-weight: bold !important;
}
+/*------------------------------------*/
+/* Card and accordion */
+/*------------------------------------*/
-// Preformatted Text Styling
-pre {
- border: none;
- background: transparent;
- padding: 0;
+// Card styling
+.card {
+ background-color: #2e5576;
+ border-radius: 8px;
+ margin: 20px;
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.3);
+ padding: 0;
+ overflow: hidden;
+
+ // Style headings directly in card (for header)
+ > h1, > h2, > h3, > h4, > h5, > h6 {
+ background-color: #1c3952;
+ padding: 15px 20px;
+ margin: 0;
+ border-bottom: 2px solid #ffffff;
+ color: #ffffff;
+ }
+
+ // Width variants (optional)
+ &.w-30 { max-width: 30rem; }
+ &.w-40 { max-width: 40rem; }
+ &.w-50 { max-width: 50rem; }
+ &.w-60 { max-width: 60rem; }
}
-pre code {
- border: none;
- background: transparent;
- padding: 0;
- color: inherit;
-}
+// Accordion styling
+.accordion {
+ padding: 15px;
+
+ details {
+ color: #ffffff;
+ background-color: #1c3952;
+ margin-bottom: 10px;
+ border-radius: 4px;
+ font-size: .8em;
+ filter: drop-shadow(5px 5px 0px #0A0A0A);
+
+ &:hover {
+ filter: drop-shadow(5px 5px 4px #0A0A0A);
+ }
+
+ &:last-child {
+ margin-bottom: 0;
+ }
+
+ > summary {
+ color: #ffffff;
+ padding: 10px 15px;
+ font-size: 1em;
+ cursor: pointer;
+ border-radius: 4px;
+
+ &:hover {
+ background-color: rgba(255, 255, 255, 0.1);
+ }
+ }
+
+ // Add padding when details is open to create space for text
+ &[open] {
+ padding: 0 15px 15px 15px; // Add horizontal and bottom padding
+ }
+
+ // Target all text content inside details
+ p, div, span, code, strong, em {
+ color: #ffffff !important;
+ }
+ }
+}
\ No newline at end of file
diff --git a/docs/Vignettes/Calibration.html b/docs/Vignettes/Calibration.html
index 0364605..bb12298 100644
--- a/docs/Vignettes/Calibration.html
+++ b/docs/Vignettes/Calibration.html
@@ -66,6 +66,10 @@
+<<<<<<< HEAD
+
+=======
+>>>>>>> origin/main
@@ -138,7 +142,11 @@
+<<<<<<< HEAD
+
+=======
+>>>>>>> origin/main
@@ -146,7 +154,11 @@
calibration_points=5: Uses a standard 5-point calibration pattern (corners plus center). This is the default and works well for most studies. You can also choose 9 points for higher precision, or pass a custom list of coordinates in height units for specialized configurations.
shuffle=True: Randomizes which image appears at each calibration point. This prevents habituation and keeps participants engaged throughout the procedure.
+<<<<<<< HEAD
+
audio=True: Plays an attention-getting sound along with the visual stimulus to help capture and maintain the participant’s focus.
+
anim_type='zoom': Makes the stimuli gently pulse in size to attract attention. You can also use 'trill' for a rotating animation.
+=======
audio=True: Plays an attention-getting sound along with the visual stimulus to help capture and maintain the participant’s focus. anim_type='zoom': Makes the stimuli gently pulse in size to attract attention. You can also use 'trill' for a rotating animation.
+>>>>>>> origin/main
visualization_style='circles': Displays the calibration results using dots at each point. You can also choose 'lines' to show lines connecting the target to where the gaze landed.
---title: "Calibration"description-meta:: "Learn how to use DeToX to perform calibration to ensure the best data quality"
@@ -1111,6 +1190,144 @@
Loading Calibration**`shuffle=True`**: Randomizes which image appears at each calibration point. This prevents habituation and keeps participants engaged throughout the procedure.
+<<<<<<< HEAD
+**`audio=True`**: Plays an attention-getting sound along with the visual stimulus to help capture and maintain the participant's focus.
+
+**`anim_type='zoom'`**: Makes the stimuli gently pulse in size to attract attention. You can also use `'trill'` for a rotating animation.
+
+**`visualization_style='circles'`**: Displays the calibration results using dots at each point. You can also choose `'lines'` to show lines connecting the target to where the gaze landed.
+
+::: Advanced
+### Customizing Calibration Parameters
+
+Beyond the basic configuration, you can customize several aspects of the calibration procedure to match your experimental needs:
+
+**`infant_stims`**: By default (`infant_stims=True`), DeToX uses a set of engaging animal cartoons included with the package. These work well for most infant studies, but you can provide a list of file paths to your own images if you prefer custom stimuli that better match your study's theme or participant age group.
+
+**`audio`**: By default (`audio=True`), an attention-getting sound included with DeToX plays automatically when stimuli appear. Set this to `None` to disable audio entirely, or pass your own pre-loaded `psychopy.sound.Sound` object to use custom sounds that fit your experimental context.
+
+**`calibration_points`**: By default uses a 5-point pattern (corners plus center). You can specify `9` for higher precision, or pass a custom list of coordinates in height units for specialized configurations tailored to your stimulus regions.
+:::
+
+### The Calibration Process
+
+#### Step 1: Instructions
+
+First, you'll see instructions explaining the controls:
+
+``` markdown
+┌──────────────────── Calibration Setup ─────────────────────┐
+│Mouse-Based Calibration Setup: │
+│ │
+│ - Press number keys (1-5) to select calibration points │
+│ - Move your mouse to the animated stimulus │
+│ - Press SPACE to collect samples at the selected point │
+│ - Press ENTER to finish collecting and see results │
+│ - Press ESCAPE to exit calibration │
+│ │
+│ Any key will start calibration immediately! │
+└────────────────────────────────────────────────────────────┘
+```
+
+these instructions will tell you how to control the calibration using your keyboard.
+
+Press any key when you're ready to begin.
+
+#### Data Collection
+
+The calibration screen appears with a thin red border indicating you're in calibration mode. Press a number key (1-5) to display an animated stimulus at the corresponding calibration point. The participant should look at the stimulus while it animates. When you're confident they're fixating on the target, press **SPACE** to collect gaze samples. The system waits briefly (0.25 seconds) to ensure stable fixation, then records the eye tracking data for that point. Repeat this process for all calibration points. You don't need to go in order.
+
+#### Step 3: Review Results
+
+Once you've collected data for all points (or whenever you're satisfied), press **ENTER** to compute and visualize the calibration results. You'll see a display showing the calibration targets and dots (or lines if you selected them in the `visualization_style`) to where the gaze samples actually landed.
+
+At this stage, you have several options:
+
+``` markdown
+┌────────────── Calibration Results ───────────────┐
+│Review calibration results above. │
+│ │
+│ - Press ENTER to accept calibration │
+│ - Press Numbers → SPACE to retry some points │
+│ - Press ESCAPE to restart calibration │
+│ │
+└──────────────────────────────────────────────────┘
+```
+
+**Accept the calibration**: If the results look good across all points, press **SPACE** to accept and move forward with your experiment.
+
+**Retry specific points**: Notice one or two points with poor accuracy? Press the number keys corresponding to those points—they'll highlight in yellow to confirm your selection. You can select multiple points if needed. Once you've marked all points for retry, press **SPACE** again to recollect data for just those points. This targeted approach is especially valuable with infants and children, where you might get excellent data at most points but struggle with one or two locations.
+
+**Start over**: If the overall quality is poor or you want a fresh start, press **ESCAPE** to discard all data and restart the entire calibration procedure from the beginning.
+
+::: callout-important
+### Simulation Mode
+
+When running with `simulate=True`, the calibration procedure uses mouse position instead of real eye tracker data. Press number keys to display stimuli at calibration points, move your mouse to each target location, and press SPACE to "collect" samples. This allows you to test your entire experiment workflow without needing physical eye tracking hardware.
+:::
+
+### Calibration Complete!
+
+Congratulations! You've successfully positioned your participant and completed the calibration procedure using DeToX. With accurate calibration in place, you're now ready to present your experimental stimuli and collect high-quality eye tracking data.
+
+Here's a video demonstrating the entire calibration workflow from start to finish:
+
+```{=html}
+<div style="padding:56.25% 0 0 0;position:relative;"><iframe src="https://player.vimeo.com/video/1139719474?badge=0&autopause=0&player_id=0&app_id=58479" frameborder="0" allow="autoplay; fullscreen; picture-in-picture; clipboard-write; encrypted-media; web-share" referrerpolicy="strict-origin-when-cross-origin" style="position:absolute;top:0;left:0;width:100%;height:100%;" title="Calibration procedure using DeToX"></iframe></div><script src="https://player.vimeo.com/api/player.js"></script>
+```
+
+## Save and Load calibration
+
+While we recommend performing calibration at the start of each session to ensure optimal accuracy, DeToX also allows you to save and load calibration data for convenience. In our opinion, this should only be used in special circumstances where there is a headrest and little to no chance of movement between sessions. However, if you need to save and reuse calibration data, here's how:
+
+### Saving Calibration
+
+After completing a successful calibration, you can save the calibration data to a file:
+
+``` python
+# Save with custom filename
+ET_controller.save_calibration(filename="S01_calibration.dat")
+```
+
+``` markdown
+┌────── Calibration Saved ─────┐
+│Calibration data saved to: │
+│S01_calibration.dat │
+└──────────────────────────────┘
+```
+
+The calibration data is saved as a binary file (`.dat` format) that can be reloaded in future sessions. If you don't specify a filename, DeToX automatically generates a timestamped name like `2024-01-15_14-30-00_calibration.dat`.
+
+you can also choose to use a GUI file dialog to select the save location:
+
+``` python
+# Save with GUI file dialog
+ET.save_calibration(use_gui=True)
+```
+
+### Loading Calibration
+
+To reuse a previously saved calibration in a new session:
+
+``` python
+# Load from specific file
+ET.load_calibration(filename="S01_calibration.dat")
+```
+
+``` markdown
+┌───── Calibration Loaded ──────┐
+│Calibration data loaded from: │
+│S01_calibration.dat │
+└───────────────────────────────┘
+```
+
+or again, use a GUI file dialog to select the file:
+
+``` python
+# Load with GUI file dialog
+ET.load_calibration(use_gui=True)
+```
+=======
**`audio=True`**: Plays an attention-getting sound along with the visual stimulus to help capture and maintain the participant's focus. **`anim_type='zoom'`**: Makes the stimuli gently pulse in size to attract attention. You can also use `'trill'` for a rotating animation.**`visualization_style='circles'`**: Displays the calibration results using dots at each point. You can also choose `'lines'` to show lines connecting the target to where the gaze landed.
@@ -1245,6 +1462,7 @@
Loading Calibration# Load with GUI file dialogET.load_calibration(use_gui=True)```
+>>>>>>> origin/main
DeToX is designed as a lightweight wrapper around **PsychoPy** and **tobii_research**. Here's the good news: `tobii_research` usually comes bundled with PsychoPy, which means the only real hurdle is installing PsychoPy itself. And yes, PsychoPy *can* be a bit tricky to install due to its many dependencies—but don't worry, we'll walk you through it. Once PsychoPy is up and running, adding DeToX is a breeze.::: callout-note
+<<<<<<< HEAD
+## Eye Tracker Drivers Required {fig-align="right" width="49" height="33"}
+=======
## Eye Tracker Drivers Required {fig-align="right" width="49" height="33"}
+>>>>>>> origin/main
Before DeToX can communicate with your Tobii eye tracker, you need to ensure the correct drivers are installed on your computer. The easiest way to do this is by downloading and installing the [Tobii Pro Eye Tracker Manager](https://www.tobii.com/products/software/applications-and-developer-kits/tobii-pro-eye-tracker-manager)—a free software provided by Tobii that allows you to installs the necessary drivers for your device.
diff --git a/docs/api/BaseCalibrationSession.html b/docs/api/BaseCalibrationSession.html
index 7e869f0..6a0b2f1 100644
--- a/docs/api/BaseCalibrationSession.html
+++ b/docs/api/BaseCalibrationSession.html
@@ -146,7 +146,7 @@
Position of the message box center on screen. Default (0, -0.15).
(0, -0.15)
@@ -1162,15 +1166,15 @@
#### Parameters {.doc-section .doc-section-parameters}
-| Name | Type | Description | Default |
-|--------------------|--------|----------------------------------------------------|------------|
-| calibration_points | list | List of calibration point coordinates to validate. | _required_ |
+| Name | Type | Description | Default |
+|--------------------|----------------|----------------------------------------------------|------------|
+| calibration_points | [list](`list`) | List of calibration point coordinates to validate. | _required_ |#### Raises {.doc-section .doc-section-raises}
-| Name | Type | Description |
-|--------|------------|-------------------------------------------------------|
-| | ValueError | If number of points is less than 2 or greater than 9. |
+| Name | Type | Description |
+|--------|----------------------------|-------------------------------------------------------|
+| | [ValueError](`ValueError`) | If number of points is less than 2 or greater than 9. |### show_message_and_wait { #DeToX.BaseCalibrationSession.show_message_and_wait }
@@ -1186,11 +1190,19 @@
#### Parameters {.doc-section .doc-section-parameters}
+<<<<<<< HEAD
+| Name | Type | Description | Default |
+|--------|------------------|-------------------------------------------------------------------|--------------|
+| body | [str](`str`) | The main message text to display. | _required_ |
+| title | [str](`str`) | Title for the message box. Default empty string. | `''` |
+| pos | [tuple](`tuple`) | Position of the message box center on screen. Default (0, -0.15). | `(0, -0.15)` |
+=======
| Name | Type | Description | Default ||--------|--------|-------------------------------------------------------------------|--------------|| body | str | The main message text to display. | _required_ || title | str | Title for the message box. Default empty string. | `''` || pos | tuple | Position of the message box center on screen. Default (0, -0.15). | `(0, -0.15)` |
+>>>>>>> origin/main