-
Notifications
You must be signed in to change notification settings - Fork 4
New epochs class and marker mapping #14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Refactored the Epochs class to use a dictionary of epochs indexed by epoch index, added properties for empty epochs, and improved overlap checking and warnings. Updated the to_numpy method to support flexible sampling rates and interpolation, and improved baseline correction error handling. Modified plot_epochs and its helpers to work with the new Epochs API, and updated the pupil_size_and_epoching tutorial to use the new sample data and API.
Expanded and clarified docstrings for epoching functions and the Epochs class, including detailed parameter and return value descriptions. Refactored Dataset to automatically handle native data without requiring a 'custom' flag, and improved section construction for native recordings. Updated tutorials to use consistent event naming and native data examples. Minor bugfixes and doc improvements in export and utility modules.
|
@JGHartel Currently the baseline correction method is not updated yet. What do you think would be the best API/code for it? For operability with other methods such as |
JGHartel
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Overall, I welcome the suggested changes. In particular, the rename towards epoch_info and the unified access to epochs data as epoch.epochs, rather than the previous mixed access, is appreciated. Still, I would like to invite some discussions on the assumed datatypes, e.g. epochs.epochs and epochs.annotate being a dictionary. This would especially futureproof the development, if dataset level operations should be introduced
pyneon/epochs.py
Outdated
| # Create epochs | ||
| self.epochs, self.data = _create_epochs(source, times_df) | ||
| @cached_property | ||
| def epochs(self) -> dict[int, Stream | Events | None]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
flagging this in case we ever want to support multi-recording functionality. It would be good to have a Unique ID for each event, so that one can easily concat these dicts between recordings. Alternatively, we could then construct an implicit multiindex (recording, epoch_number), which would require a custom concat function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems a bit of an advanced user case and also in principle should apply to other classes (e.g. streams and events). My evaluation would be it would require another PR if we see value in supporting multi-recording concatenation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR introduces a major refactoring of the Epochs class to make it more intuitive and easier to use. The key changes include moving away from nested DataFrames to a dictionary-based structure, renaming methods for clarity, and introducing lazy computation of epochs using cached properties.
Changes:
- Refactored
Epochsclass to useepochs_dict(cached property returning a dictionary) instead of nested DataFrames - Renamed
event_timestoepochs_infoandevents_to_times_dftoevents_to_epochs_infofor better comprehension - Changed
Eventsclass to use event IDs as DataFrame index instead of separate columns - Added new
filter_by_namemethod to Events class and updatedfilter_by_durationbehavior - Added PLR sample dataset support with Figshare hosting
- Consolidated CI workflows (removed separate tests.yml, integrated into main.yml)
Reviewed changes
Copilot reviewed 19 out of 22 changed files in this pull request and generated 17 comments.
Show a summary per file
| File | Description |
|---|---|
| pyneon/epochs.py | Major refactoring of Epochs class with new dictionary-based structure, cached properties, and helper functions renamed |
| pyneon/events.py | Modified to use event IDs as index, added filter_by_name method, updated filter_by_duration |
| pyneon/stream.py | Added stub for detect_events_from_derivative method, updated docstrings with reusable doc snippets |
| pyneon/vis/vis.py | Updated plot_epochs to work with new epochs_dict structure |
| pyneon/dataset.py | Made sections.csv optional, improved error handling for missing recordings |
| pyneon/utils/doc_decorators.py | Added reusable documentation snippets for common return types and parameters |
| pyneon/utils/sample_data.py | Added PLR dataset URL and test |
| tests/conftest.py | Added simple_events fixture for testing Events functionality |
| tests/test_events.py | Added (empty) test stub for crop functionality |
| tests/test_streams.py | Added tests for interpolation and concatenation methods |
| .github/workflows/main.yml | Consolidated CI workflows, added test job dependencies |
| source/tutorials/*.ipynb | Updated tutorial notebooks to use new API names |
| README.md | Added information about sample datasets on Figshare |
Comments suppressed due to low confidence (1)
pyneon/epochs.py:223
- The properties
columnsanddtypes(lines 216-223) referenceself.datawhich no longer exists in the newEpochsclass structure. These properties need to be updated or removed.
@property
def columns(self) -> pd.Index:
return self.data.columns[:-3]
@property
def dtypes(self) -> pd.Series:
"""The data types of the epoched data."""
return self.data.dtypes[:-3]
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Standardized AprilTag detection output to use flat columns (e.g., 'frame id', 'tag id', 'corner 0 x [px]') instead of nested arrays. Updated all related code, docstrings, and type definitions to match the new format, and revised downstream usages in pose estimation, homography computation, visualization, and tutorials. This improves data interoperability and simplifies downstream processing.
Replaces all AprilTag-specific detection code and APIs with a unified marker detection interface supporting both AprilTag and ArUco markers. Renames functions and parameters (e.g., detect_apriltags → detect_markers), updates documentation, and introduces a utility for mapping marker names to OpenCV dictionaries. Updates all usages, docstrings, and tutorial code to reflect the new marker-agnostic approach.
Changed 'tag id' data type from Int32 to str in variables.py for consistency. Fixed marker detection logic in detect_marker.py to handle None values for all_ids. Updated pyproject.toml to require opencv-python>=4.7. Minor update to surface_mapping.ipynb output.
Renamed 'detect_marker.py' to 'marker_mapping.py' and 'mapping.py' to 'scanpath.py' for improved clarity in the video module structure. Updated the surface_mapping.ipynb tutorial output to reflect new error messages and improved performance, including a change from a KeyError to a TypeCheckError in homography upsampling.
Moved estimate_camera_pose to a new file (estimate_pose.py) and updated imports across the video module to reflect this change. Renamed internal methods in recording.py for clarity. Fixed type hints and docstrings in scanpath.py. Minor formatting and docstring improvements in marker_mapping.py and video.py. Updated surface_mapping tutorial for improved readability.
Standardizes terminology from 'tag' to 'marker' across the codebase, including function arguments, variable names, and documentation. Updates marker detection to use 'marker_family' instead of 'marker_name', and refactors related utility functions and docstrings. Improves random/sequential frame access for marker detection, updates homography and camera pose estimation interfaces, and revises tutorial notebook code and comments for consistency.
Replaces generic corner indices with named corners (top left, top right, bottom right, bottom left) throughout marker detection, pose estimation, and homography mapping. Updates related docstrings, plotting utilities, and adds a new plot_detected_markers method to Video and visualization modules. This improves code clarity and consistency for marker handling.
Standardizes marker detection and layout columns, adds marker family and name fields, and updates related functions and visualizations to use the new schema. Introduces a new plot_marker_layout visualization and updates the surface mapping tutorial for improved clarity and consistency.
Standardizes all references from 'frame id' to 'frame index' across the codebase, including function arguments, DataFrame columns, and documentation. Updates marker detection to support multiple marker families, refines homography output to use flattened matrix columns, and improves interpolation with a max_gap_ms parameter. Also adds a new example script (pg.py) and updates the surface mapping tutorial to match the new API.
Replaced outdated sample data keys and URLs in sample_data.py, updated the default sample in the main block, and removed 'labels.csv' from expected cloud files. Enhanced the cloud-format tutorial notebook with clearer explanations, updated directory structure, and improved code and output to use the new 'simple' sample dataset. Added 'seedir' to documentation dependencies in pyproject.toml.
Introduces an optional detector_parameters argument to marker detection functions in pyneon, allowing custom cv2.aruco.DetectorParameters to be passed for all marker families. Updates docstrings and documentation to reflect this new parameter, improves code formatting, and fixes minor typos in docstrings. Also updates sample data utility to support format selection and makes minor tutorial and import order adjustments.
Refactored the find_homographies function to accept explicit parameters for method, ransacReprojThreshold, maxIters, and confidence instead of a settings dictionary. Updated docstrings and documentation decorators to reflect the new parameters and improve clarity. Adjusted Recording.find_homographies to match the new API and updated its documentation accordingly.
Expanded and clarified docstrings for marker mapping, homography, and stream manipulation functions. Updated documentation to include pyneon.find_homographies in the public API and Sphinx docs. Improved tutorial on interpolation and concatenation to cover cropping, restriction, and stream alignment. Minor docstring formatting and consistency improvements throughout.
…ting Replaced repeated docstring sections with shared snippets via %(...)s formatting for axis and show parameters, marker layout, and return values. Added plot_marker_layout to visualization API and implemented its plotting logic, including marker image orientation handling and name overlay. Updated surface mapping tutorial to demonstrate marker layout plotting.
Epochs
Developers and users have found the old
Epochsclass quite unintuitive and operationally hard to use (e.g., nested DataFrame). This PR aims to reorganize the class.Current features:
event_timesis renamed toepochs_infofor easier comprehensionEpochsinstance will not compute the epochs or annotated data automatically.epochsis now a cached property in the form of a dictionary. Keys are indices ofepochs_infoand values areStream/Eventsinstances.annotate_epochs.Marker mapping
Per suggestions, this PR also aims to expand the marker mapping from AprilTags to also ArUco markers (using OpenCV's aruco module). This direct interface also allows us to get rid of the optional dependency of
pupil-apriltags. API and documentations are improved along the way.