diff --git a/src/pymovements/dataset/dataset_files.py b/src/pymovements/dataset/dataset_files.py index dfc4c40eb..1553fddb9 100644 --- a/src/pymovements/dataset/dataset_files.py +++ b/src/pymovements/dataset/dataset_files.py @@ -377,7 +377,7 @@ def load_gaze_file( column_schema_overrides=definition.filename_format_schema_overrides['gaze'], ) elif filepath.suffix == '.asc': - gaze_df = from_asc( + gaze_df, _ = from_asc( filepath, experiment=definition.experiment, add_columns=add_columns, diff --git a/src/pymovements/gaze/io.py b/src/pymovements/gaze/io.py index 722477491..18868e3dd 100644 --- a/src/pymovements/gaze/io.py +++ b/src/pymovements/gaze/io.py @@ -271,21 +271,25 @@ def from_csv( def from_asc( file: str | Path, *, - patterns: str | list | None = 'eyelink', + patterns: str | list[dict[str, Any] | str] | None = 'eyelink', + metadata_patterns: list[dict[str, Any] | str] | None = None, schema: dict[str, Any] | None = None, experiment: Experiment | None = None, add_columns: dict[str, str] | None = None, - column_schema_overrides: dict[str, type] | None = None, -) -> GazeDataFrame: + column_schema_overrides: dict[str, Any] | None = None, +) -> tuple[GazeDataFrame, dict[str, Any]]: """Initialize a :py:class:`pymovements.gaze.gaze_dataframe.GazeDataFrame`. Parameters ---------- file: str | Path Path of IPC/feather file. - patterns: str | list | None - list of patterns to match for additional columns or a key identifier of eye tracker specific + patterns: str | list[dict[str, Any] | str] | None + List of patterns to match for additional columns or a key identifier of eye tracker specific default patterns. Supported values are: eyelink. (default: 'eyelink') + metadata_patterns: list[dict[str, Any] | str] | None + List of patterns to match for extracting metadata from custom logged messages. + (default: None) schema: dict[str, Any] | None Dictionary to optionally specify types of columns parsed by patterns. (default: None) experiment: Experiment | None @@ -293,14 +297,14 @@ def from_asc( add_columns: dict[str, str] | None Dictionary containing columns to add to loaded data frame. (default: None) - column_schema_overrides: dict[str, type] | None + column_schema_overrides: dict[str, Any] | None Dictionary containing types for columns. (default: None) Returns ------- - GazeDataFrame - The gaze data frame read from the asc file. + tuple[GazeDataFrame, dict[str, Any]] + The gaze data frame and a metadata dictionary read from the asc file. Examples -------- @@ -308,7 +312,7 @@ def from_asc( We can then load the data into a ``GazeDataFrame``: >>> from pymovements.gaze.io import from_asc - >>> gaze = from_asc(file='tests/files/eyelink_monocular_example.asc', patterns='eyelink') + >>> gaze, metadata = from_asc(file='tests/files/eyelink_monocular_example.asc') >>> gaze.frame shape: (16, 3) ┌─────────┬───────┬────────────────┐ @@ -328,7 +332,8 @@ def from_asc( │ 2339290 ┆ 618.0 ┆ [637.6, 531.4] │ │ 2339291 ┆ 618.0 ┆ [637.3, 531.2] │ └─────────┴───────┴────────────────┘ - + >>> metadata['sampling_rate'] + 1000.0 """ if isinstance(patterns, str): if patterns == 'eyelink': @@ -338,7 +343,9 @@ def from_asc( raise ValueError(f"unknown pattern key '{patterns}'. Supported keys are: eyelink") # Read data. - gaze_data, _ = parse_eyelink(file, patterns=patterns, schema=schema) + gaze_data, metadata = parse_eyelink( + file, patterns=patterns, schema=schema, metadata_patterns=metadata_patterns, + ) if add_columns is not None: gaze_data = gaze_data.with_columns([ @@ -361,7 +368,7 @@ def from_asc( time_unit='ms', pixel_columns=['x_pix', 'y_pix'], ) - return gaze_df + return gaze_df, metadata def from_ipc( diff --git a/src/pymovements/utils/parsing.py b/src/pymovements/utils/parsing.py index a2e12f43b..849cb8641 100755 --- a/src/pymovements/utils/parsing.py +++ b/src/pymovements/utils/parsing.py @@ -40,58 +40,58 @@ ) EYELINK_META_REGEXES = [ - {'pattern': r'\*\*\s+VERSION:\s+(?P.*)\s+'}, - { - 'pattern': r'\*\*\s+DATE:\s+(?P[A-Z,a-z]+)\s+(?P[A-Z,a-z]+)' - r'\s+(?P\d\d?)\s+(?P