Skip to content

Commit c74a9b0

Browse files
committed
FIX: doctests and flakes
1 parent aabcf18 commit c74a9b0

File tree

1 file changed

+194
-0
lines changed

1 file changed

+194
-0
lines changed

src/eyelinkio/edf/read.py

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,184 @@ class EDF(dict):
6868
----------
6969
fname : str
7070
The name of the EDF file.
71+
72+
Attributes
73+
----------
74+
info : dict
75+
A :class:`dict` containing information about the EDF file, with keys:
76+
77+
filename: str
78+
The name of the file.
79+
meas_date : datetime
80+
The date and time that the data was recorded. This datetime is
81+
timezone-naive, as the timezone is not stored in the EDF file.
82+
version : str
83+
The EyeLink tracker version that was used to record the data.
84+
For example, ``"EYELINK II 1"``, or
85+
``"EYELINK REVISION 2.10 (Jun 13 2002)"``. This is extracted from
86+
the EDF file preamble, and corresponds to the line beginning with
87+
``"** VERSION:`` in an ASCII (``.asc``) converted file.
88+
edfapi_version : str
89+
The version of the EDF API that was used to read the data from the
90+
EDF file. This is extracted from the EDF file preamble, and corresponds
91+
to the line beginning with ``"** CONVERTED FROM"`` in an ASCII (``.asc``)
92+
converted file.
93+
For example, ``"4.2.1197.0 MacOS X standalone Sep 27 2024"``.
94+
camera : str
95+
The camera type that was used to record the data. This is extracted
96+
from the EDF file preamble, and corresponds to the line beginning with
97+
``"** CAMERA:`` in an ASCII (``.asc``) converted file. Below are a few
98+
possible values (non-exhaustive):
99+
100+
- ``"EYELINK II CL v5.15 Jan 24 2018"``
101+
- ``"Eyelink GL Version 1.2 Sensor=AJ7"``
102+
- ``"EyeLink CL Version 1.4 Sensor=BG5"``
103+
- ``"EyeLink CL-OL BASE Version 1.0 Sensor=AH7"``
104+
- ``"EyeLink CL-OL HEAD Version 1.0 Sensor=BGC"``
105+
106+
serial : str
107+
The serial number of the EyeLink tracker that was used to record the
108+
data, usually in the form of ``"CLG-XXXX"``. This is extracted from the
109+
EDF file preamble, and corresponds to the line beginning with
110+
``"** SERIAL NUMBER:`` in an ASCII (``.asc``) converted file.
111+
camera_config : str
112+
The camera configuration that was used to record the data, for example,
113+
``"ACA32140.SCD"``. This is extracted from the EDF file preamble, and
114+
corresponds to the line beginning with ``"** CAMERA_CONFIG:`` in an ASCII
115+
(``.asc``) converted file.
116+
sfreq : float
117+
The sampling frequency of the data, in Hz.
118+
ps_units :
119+
The unit used to measure pupil size. This will be either ``"PUPIL_AREA"``,
120+
or ``"PUPIL_DIAMETER"``, depending on whether pupil size was measured
121+
as the total number of pixels within the detected pupil boundary (area), or
122+
the diameter of the circle fitted to the pupil boundary (diameter).
123+
eye : str
124+
The eye that was recorded. This will be either ``"LEFT_EYE"``,
125+
``"RIGHT_EYE"``, or ``"BINOCULAR"`` if both eyes were recorded.
126+
sample_fields : list of str
127+
A list describing the data types and units of the extracted samples from the
128+
EDF file. Currently this will be:
129+
``["xpos", "ypos", "ps"]`` for a monocular file, which corresponds to
130+
x and y eyegaze coordinates in screen-pixels, and the pupil size.
131+
For a binocular file, this will include separate fields for each eye:
132+
``["xpos_left", "ypos_left", ... "xpos_right", "ypos_right", "ps_right"]``.
133+
134+
In the future, options may be added to extract additional data types,
135+
such as head position or eye velocity. There may also be options to extract
136+
eyegaze data in different coordinate frames, such as
137+
head-referenced-eye-angle (HREF), or raw pupil position.
138+
screen_coords : list of int
139+
The screen resolution in pixels of the monitor used in the eye-tracking
140+
experiment, in the form ``[width, height]``, for example, ``[1920, 1080]``.
141+
calibrations : list of dict
142+
A list of dictionaries, each containing information about a calibration
143+
that was performed during the experiment. Each dictionary has the following
144+
keys:
145+
146+
- ``onset``: The time (in seconds) at which the calibration started.
147+
- ``eye``: The eye that was calibrated, e.g. ``"left"`` or ``"right"``.
148+
- ``model``: The calibration model used, for example, ``"HV5"``.
149+
- ``validation``:
150+
A structured :class:`numpy.ndarray` with 5 columns and
151+
``n`` rows, where n is the number of validation points. For example,
152+
an HV5 calibration has 5 validation points and thus 5 rows.
153+
Each row contains the following fields:
154+
155+
- ``point_x``: The x position of the validation point on the screen,
156+
in pixels.
157+
- ``point_y``: The y position of the validation point on the screen,
158+
in pixels.
159+
- ``offset``: The offset between the validation point and the gaze
160+
position, in pixels.
161+
- ``diff_x``: The difference between the x position of the gaze and
162+
the validation point, in pixels.
163+
- ``diff_y``: The difference between the y position of the gaze and
164+
the validation point, in pixels.
165+
discrete : dict
166+
A dictionary containing ocular and stimulus events from the EDF file, with keys:
167+
168+
- ``saccades``:
169+
A structured :class:`numpy.ndarray` containing saccade
170+
events with the following fields:
171+
172+
- ``eye``: The eye that was recorded, either ``"left"`` or ``"right"``.
173+
- ``stime``: The time (in seconds) at which the saccade started.
174+
- ``etime``: The time (in seconds) at which the saccade ended.
175+
- ``sxp``: The x position of the saccade start, in pixels.
176+
- ``syp``: The y position of the saccade start, in pixels.
177+
- ``exp``: The x position of the saccade end, in pixels.
178+
- ``eyp``: The y position of the saccade end, in pixels.
179+
- ``pv``: The average velocity of the saccade, in pixels per second.
180+
181+
- ``fixations``:
182+
A structured :class:`numpy.ndarray` containing fixation
183+
events with the following fields:
184+
185+
- ``eye``: The eye that was recorded, either ``"left"`` or ``"right"``.
186+
- ``stime``: The time (in seconds) at which the fixation started.
187+
- ``etime``: The time (in seconds) at which the fixation ended.
188+
- ``axp``: The x position of the fixation, in pixels.
189+
- ``ayp``: The y position of the fixation, in pixels.
190+
191+
- ``blinks``:
192+
a structured :class:`numpy.ndarray` containing blink events
193+
with the following fields:
194+
195+
- ``eye``: The eye that was recorded, either ``"left"`` or ``"right"``.
196+
- ``stime``: The time (in seconds) at which the blink started.
197+
- ``etime``: The time (in seconds) at which the blink ended.
198+
199+
- ``messages``:
200+
a structured :class:`numpy.ndarray` containing stimulus
201+
presentation events, with the following fields:
202+
203+
- ``stime``: The time (in seconds) at which the message was sent.
204+
- ``msg``: The message that was sent, as a byte string.
205+
206+
- ``buttons``:
207+
A structured :class:`numpy.ndarray` containing button press
208+
events, with the following fields:
209+
210+
- ``stime``: The time (in seconds) at which the button was pressed.
211+
- ``buttons``: The button that was pressed, as a bitmask.
212+
213+
- ``inputs``:
214+
A structured :class:`numpy.ndarray` containing input events,
215+
with the following fields:
216+
217+
- ``stime``: The time (in seconds) at which the input was received.
218+
- ``input``: The input that was received, as a bitmask.
219+
220+
For example, this can be used to track the ground-truth stimulus
221+
presentation times using a photodiode, by sending a pulse to the
222+
Eyelink tracker's input port.
223+
224+
- ``starts``:
225+
A structured :class:`numpy.ndarray` containing start events,
226+
which indicate the start of a recording period, with the following
227+
fields:
228+
229+
- ``stime``: The time in seconds that the recording period started.
230+
231+
- ``ends``:
232+
A structured :class:`numpy.ndarray` containing end events, which
233+
indicate the end of a recording period, with the following fields:
234+
235+
- ``stime``: The time in seconds that the recording period ended.
236+
237+
Examples
238+
--------
239+
>>> import eyelinkio
240+
>>> fname = eyelinkio.utils._get_test_fnames()[0]
241+
>>> edf = eyelinkio.read_edf(fname)
242+
>>> keys = edf.keys() # ['info', 'discrete', 'times', 'samples']
243+
>>> edf['info']['eye']
244+
'LEFT_EYE'
245+
>>> first_saccade = edf['discrete']['saccades'][0] # first saccade
246+
>>> edf['discrete']['saccades']['stime'][:3] # First 3 saccades start times
247+
array([0.077, 0.226, 0.391])
248+
>>> messages = edf['discrete']['messages']['msg'] # stimulus presentation messages
71249
"""
72250

73251
def __init__(self, fname):
@@ -103,6 +281,13 @@ def to_pandas(self):
103281
df_samples : dict of DataFrame
104282
A dictionary of :class:`~pandas.DataFrame`'s, containing the samples,
105283
blinks, saccades, fixations, messages, and calibrations.
284+
285+
Examples
286+
--------
287+
>>> import eyelinkio
288+
>>> fname = eyelinkio.utils._get_test_fnames()[0]
289+
>>> edf = eyelinkio.read_edf(fname)
290+
>>> dfs = edf.to_pandas()
106291
"""
107292
from ..utils import to_pandas
108293
return to_pandas(self)
@@ -116,6 +301,15 @@ def to_mne(self):
116301
An instance of Raw.
117302
calibrations : list of Calibration
118303
A list of Calibration objects.
304+
305+
Examples
306+
--------
307+
>>> import eyelinkio
308+
>>> import mne
309+
>>> mne.set_log_level("WARNING")
310+
>>> fname = eyelinkio.utils._get_test_fnames()[0]
311+
>>> edf = eyelinkio.read_edf(fname)
312+
>>> raw, cals = edf.to_mne()
119313
"""
120314
from ..utils import to_mne
121315
return to_mne(self)

0 commit comments

Comments
 (0)