diff --git a/.gitignore b/.gitignore index dbe68211..f6d92366 100644 --- a/.gitignore +++ b/.gitignore @@ -3,8 +3,6 @@ .coveragerc .notes/* !.notes/.gitkeep -!.notes/eeglab-migration-gap-audit.md -!.notes/implementation-notes.html # Python # Byte-compiled / optimized / DLL files diff --git a/.notes/eeglab-final-epic-closeout.md b/.notes/eeglab-final-epic-closeout.md deleted file mode 100644 index b2b2c353..00000000 --- a/.notes/eeglab-final-epic-closeout.md +++ /dev/null @@ -1,180 +0,0 @@ -# EEGPrep Final Standalone Epic Closeout Evidence - -Date: 2026-06-07 -Phase issue: #165 -Epic issue: #157 -Branch: `phase/165-final-integration-release-hardening` -Base: `origin/feature/eeglab-full-standalone-completion` -Final epic PR target after this phase: `origin/develop` - -Phase 8 closes the phase stack on the epic branch. It prepares evidence for the -future epic PR to `develop`, but does not open that final PR. - -## Phase Issues and PRs - -| Phase | Issue | PR | Scope | Result | -| --- | --- | --- | --- | --- | -| 1 | #158 | #166 | Final standalone audit matrix, validator, runtime contract, docs architecture | Merged | -| 2 | #159 | #171 | clean_rawdata and FIRFilt bundled-plugin completion | Merged | -| 3 | #160 | #169 | DIPFIT and source-localization standalone parity | Merged | -| 4 | #161 | #170 | STUDY PAC, LIMO-compatible design, and advanced statistics boundaries | Merged | -| 5 | #162 | #168 | Large-dataset `.fdt`, memmap, and `storedisk` semantics | Merged | -| 6 | #163 | #167 | ICLabel, viewprops, and component diagnostic parity | Merged | -| 7 | #164 | #172 | Standalone Sphinx manual, tutorials, API pages, and help resources | Merged | -| 8 | #165 | This branch | Integration, QA, release hardening, and evidence | In review | - -## Feature Summary - -The merged epic branch now covers the remaining standalone EEGLAB parity areas -identified after the core parity PR: - -- A machine-readable final parity matrix and validator for bundled plugins, - object/storage semantics, optional-toolbox boundaries, and documentation. -- clean_rawdata standard ASR, calibration-time Riemannian ASR support, explicit - full-Riemannian limitation, artifact diagnostics, and FIRFilt helper/dialog - parity. -- DIPFIT standalone spherical settings, grid search, nonlinear fitting, - multifit, leadfield, dipplot, coordinate transforms, and explicit source - backend limits. -- STUDY PAC compute/cache/read/plot workflows, LIMO-compatible design-matrix - export, neighbor/interpolation helpers, and explicit source-statistics - boundaries. -- Python-native large-dataset save/load, `.fdt` sidecars, memory maps, - `storedisk` offload/retrieve behavior, and GUI/console session synchronization. -- ICLabel default-network runtime behavior, label statistics, viewprops-style - diagnostics, and explicit alternate-network boundaries. -- EEGPrep-owned Sphinx user manual, migration notes, GUI plus console tutorials, - BIDS workflow docs, bundled plugin docs, generated API pages, and packaged - help resources. - -## Matrix Closeout - -`docs/parity/eeglab_final_parity_matrix.json` now validates against the full -final-epic reference surface: - -- 31 grouped rows cover 180 final-epic EEGLAB reference paths. -- Status counts: 21 `implemented`, 3 `consolidated`, 2 `optional_dependency`, - 2 `partial`, 2 `stale_skip`, and 1 `matlab_runtime_skip`. -- There are no remaining `port` or `docs_gap` rows. -- The two `partial` rows are intentional backend boundaries, not forgotten work: - DIPFIT MRI/BEM/LORETA/FieldTrip source workflows and STUDY-level - FieldTrip/source-statistics workflows. - -Phase 8 reclassified the six Phase 7 documentation rows from `docs_gap` to -`implemented` after verifying that the completed Sphinx manual covers console -history migration, event/indexing tutorials, STUDY workflows, source/DIPFIT -boundaries, time-frequency/visual workflow notes, and BIDS tutorials. - -## Phase 8 Findings Fixed - -- The final matrix still had six Phase 7 documentation rows marked `docs_gap` - after PR #172 merged. Phase 8 reclassified those rows to `implemented` and - added regression coverage that no final closeout row remains `port` or - `docs_gap`. -- The MATLAB-enabled parity run exposed an inconsistent synthetic HDF5 fixture: - `xmin=-1`, `pnts=1000`, `srate=500`, and `xmax=1.0`. EEGLAB/EEGPrep timing - semantics make the final point `0.998`, so Phase 8 corrected the fixture and - assertion in `tests/test_pop_loadset_h5.py`. -- OC autoreview found that the time-frequency/movie documentation row needed - explicit user-guide coverage. Phase 8 added supported time-frequency and ERP - image wrapper guidance to `docs/source/user_guide/preprocessing_pipeline.rst` - and the EEG movie boundary to `docs/source/user_guide/visual_parity.rst`. -- The first MATLAB parity attempt found a truncated ignored - `sample_data/EmotionValence.set` download. Phase 8 refreshed that local - fixture to the S3-reported 203,941,008 bytes before rerunning the suite. - -## Runtime Independence - -Runtime package code must not read, import from, or shell out to -`src/eegprep/eeglab`. The vendored tree remains a development and parity-test -oracle only. - -Phase 8 verified this with `tests/test_runtime_eeglab_independence.py` and a -source scan for direct `src/eegprep/eeglab`, `eegprep.eeglab`, importlib -resource, or package-root path-join dependencies. Development validators and -visual parity tools may read the vendored reference tree. - -## Public API, Help, Package Data, and Menu Inventory - -Phase 8 kept the public API/menu/help/package evidence in tested surfaces: - -- `tests/test_package_exports.py` covers lazy public exports. -- `tests/test_public_api_examples.py` covers documented API examples and - package-data declarations. -- `tests/test_guifunc_pophelp_chansel.py` covers packaged Markdown help - resources, `pophelp`, and implemented menu help targets. -- `tests/test_menu_placeholder_inventory.py` covers menu placeholder metadata. -- `tests/test_gui_main_window.py` covers main-window menu/help/session wiring. - -## Visual Parity Attachment Inventory - -Visual artifacts are attached to phase PR comments rather than committed: - -- PR #167, ICLabel/viewprops: `iclabel_pop_prop_extended_dashboard`, - `pop_icflag_dialog`, `pop_iclabel_dialog`, and `pop_viewprops_dialog` - side-by-side images. -- PR #169, DIPFIT: `pop_dipfit_settings`, `pop_dipfit_gridsearch`, - `pop_dipfit_nonlinear`, `pop_dipplot`, `pop_multifit`, `pop_leadfield`, - `pop_dipfit_loreta`, and `pop_dipfit_headmodel` evidence. -- PR #171, FIRFilt: `pop_kaiserbeta_dialog`, `pop_firwsord_dialog`, - `pop_firpmord_dialog`, `pop_xfirws_dialog`, and refreshed - `pop_firpmord_dialog_review_fix` evidence. -- PRs #166, #168, #170, and #172 did not add new GUI dialog layouts requiring - fresh visual attachments. - -## GUI Agent Mixed Workflow QA - -Computer Use inspected the live `eegprep-gui --window-menu-bar` window and -confirmed the visible startup state: File and Help enabled, dataset-dependent -Edit/Tools/Plot/Study/Datasets menus disabled, and the EEGLAB-style startup -instructions visible. Computer Use click actions against the Python-hosted -Qt app were rejected by the tool as inactive immediately after state capture, -so Phase 8 continued the requested flow QA with Qt-driven actions against the -real main window. - -The mixed workflow QA script exercised startup menus, Help menu opening, -packaged `pophelp` dispatch, dataset storage and GUI refresh, GUI dataset -retrieve followed by console namespace inspection, and a bare console -`pop_reref(EEG, [])` call followed by GUI refresh. - -## Accepted Non-Goals - -These are explicit final-epic boundaries rather than Phase 8 omissions: - -- Full Manopt-backed Riemannian ASR processing remains an optional dependency - decision; standard ASR and calibration-time Riemannian behavior are supported. -- DIPFIT MRI-derived BEM headmodel creation, AFNI atlas clipping, LORETA source - analysis, and FieldTrip source-statistics workflows remain explicit backend - limits. -- Full LIMO model fitting, result computation, and browsing remain external - backend workflows; EEGPrep owns design-matrix preparation. -- ICLabel `lite` and `beta` network artifacts remain explicit MATLAB/Octave - engine paths until EEGPrep packages tested standalone assets. -- MATLAB object overloads, developer tests, command-window shims, and third-party - plugin ecosystems remain consolidated, skipped, or extension-owned rather than - one-for-one runtime ports. - -## Verification Log - -Phase 8 verification is run from this branch. Results are updated before the -phase PR is opened. - -| Command | Result | -| --- | --- | -| `uv sync --group dev --extra gui --extra console --extra docs --extra torch` | Passed | -| `uv pip install /Applications/MATLAB_R2026a.app/extern/engines/python` | Passed: installed local `matlabengine==26.1` for MATLAB parity verification | -| `uv run --no-sync python -m tools.eeglab_final_parity_matrix --json` | Passed: `ok: true`, 31 rows, 180 expected paths | -| `uv run --no-sync pytest tests/test_eeglab_final_parity_matrix.py tests/test_pop_loadset_h5.py::TestPopLoadsetH5::test_basic_h5_loading --tb=short` | Passed: 13 passed | -| `uv run --no-sync pytest tests/test_runtime_eeglab_independence.py tests/test_guifunc_pophelp_chansel.py tests/test_public_api_examples.py tests/test_package_exports.py tests/test_menu_placeholder_inventory.py` | Passed: 37 passed | -| `uv run --no-sync pytest tests/test_gui_main_window.py` | Passed: 69 passed | -| `uv run --no-sync pytest tests/test_console_workspace.py` | Passed: 86 passed | -| `uv run --no-sync ruff check .` | Passed | -| `uv run --no-sync ruff format --check .` | Passed | -| `uv run --no-sync ty check` | Passed | -| `uv run --no-sync sphinx-build -b html docs/source docs/_build/html` | Passed | -| `uv run --no-sync pytest tests/test_visual_parity.py` | Passed: 26 passed | -| `EEGPREP_SKIP_MATLAB=1 uv run --no-sync pytest -m "not slow" --tb=short` | Passed: 1873 passed, 209 skipped, 12 deselected | -| `uv run --no-sync pytest -m "matlab or octave" --tb=short` | Passed: 342 passed, 21 skipped, 1818 deselected | -| GUI Agent mixed workflow QA script | Passed: startup/menu/help, GUI retrieve to console sync, console bare `pop_reref` to GUI refresh | -| `.agents/skills/oc-autoreview-adapted/scripts/autoreview --mode local --codex-bin /tmp/codex-fast-autoreview` | Passed clean after fixing accepted docs findings | -| `./pre-commit.py --fix` | Passed on the staged Phase 8 files | diff --git a/.notes/eeglab-final-parity-audit.md b/.notes/eeglab-final-parity-audit.md deleted file mode 100644 index b0635c77..00000000 --- a/.notes/eeglab-final-parity-audit.md +++ /dev/null @@ -1,168 +0,0 @@ -# EEGPrep Final Standalone Parity Audit - -Audit date: 2026-06-07 -Epic: #157 -Phase issue: #158 -Machine-readable contract: `docs/parity/eeglab_final_parity_matrix.json` -Validator: `uv run --no-sync python -m tools.eeglab_final_parity_matrix --json` - -## Purpose - -This audit expands the completed core parity matrix into the final standalone -product-completion surface for EEGPrep. It covers the remaining non-stale -workflows that are not fully represented by -`docs/parity/eeglab_core_parity_matrix.json`: - -- bundled plugin depth for `clean_rawdata`, `firfilt`, `ICLabel`/viewprops, and - `dipfit`; -- MATLAB object/storage folders `@eegobj`, `@memmapdata`, and `@mmo`; -- optional-toolbox workflows such as LIMO, PAC, FieldTrip-style STUDY helpers, - Riemannian ASR, and DIPFIT fitting; -- EEGLAB tutorial/doc surfaces that should become EEGPrep-owned Sphinx docs. - -This phase does not port feature behavior. It defines the rows, status values, -phase ownership, optional-dependency rules, documentation architecture, and -validator behavior that later phase agents must use. - -## Status Taxonomy - -Rows in the final matrix use these statuses: - -- `implemented`: EEGPrep has the standalone behavior; the responsible phase - owns verification, docs, and final evidence. -- `partial`: EEGPrep has part of the behavior, but important options, GUI - paths, diagnostics, numerical parity, or docs still need phase work. -- `port`: a useful workflow is not implemented yet and should be ported or - redesigned as native Python/Qt behavior. -- `consolidated`: EEGPrep intentionally covers the behavior through a different - Python helper or public contract instead of a same-name file. -- `stale_skip`: a MATLAB demo, test, packaging helper, or obsolete alias is not - a user workflow. These rows require the full stale-policy object with every - field set to `false`. -- `matlab_runtime_skip`: MATLAB path, command-window, GUI shim, or toolbox - activation behavior that must not exist in installed EEGPrep runtime code. -- `optional_dependency`: a real scientific workflow needs a substantial backend - decision. The row must name the dependency, fallback behavior, user-facing - message, and phase contract. -- `external_plugin`: behavior belongs to an external plugin ecosystem and - should use EEGPrep extension contracts rather than core package code. -- `docs_gap`: a documentation/tutorial surface that Phase 7 must write after - feature phases define final behavior. - -All non-skip rows must name a responsible phase and the matching phase issue. -Skip rows must have `responsible_phase: "none"` and `phase_issue: null`. - -## Phase Ownership - -- Phase 2 / #159 owns `clean_rawdata` and FIRFilt rows, including standard ASR, - Riemannian ASR optional-backend decisions, `vis_artifacts`, FIR order - calculators, boundary helpers, reports, and frequency-response plotting. -- Phase 3 / #160 owns DIPFIT settings, fitting, FieldTrip/source-localization - boundaries, atlas and coordinate transforms, leadfield/LORETA workflows, and - dipole plotting evidence. -- Phase 4 / #161 owns optional LIMO/PAC/STUDY statistics behavior and - FieldTrip-style STUDY neighbor/interpolation/source workflows. It must - coordinate with Phase 3 for source-localization assumptions. -- Phase 5 / #162 owns Python-native large-dataset storage, `storedisk`, - `option_memmapdata`, and the product decision for `@memmapdata`/`@mmo` - semantics. It should not port MATLAB overloads one-for-one. -- Phase 6 / #163 owns ICLabel, label statistics, viewprops, component-property - diagnostics, alternate runtime/network decisions, and visual evidence. -- Phase 7 / #164 owns the EEGLAB-style Sphinx docs architecture and all - `docs_gap` tutorial rows. It should merge after feature phases describe - actual completed behavior rather than intentions. -- Phase 8 / #165 owns final integration, release hardening, docs build, - non-slow tests, MATLAB parity where available, visual parity suite, GUI Agent - mixed-flow QA, and evidence rollup. - -## Phase 2 Completion Update - -Phase 2 / #159 moved the useful `clean_rawdata` and FIRFilt rows from intent to -verified standalone behavior. Standard clean_rawdata/ASR remains implemented as -native Python, `vis_artifacts` diagnostics are packaged and wired through -`pop_clean_rawdata`, and FIRFilt now exposes EEGLAB-named helper functions, -order dialogs, boundary-aware filtering helpers, reports, and frequency-response -plotting without any runtime dependency on the vendored EEGLAB tree. - -Full Riemannian ASR processing remains an `optional_dependency` row by design. -EEGPrep supports the calibration-time Riemannian estimate through -`useriemannian='calib'`, but it does not vendor Manopt or fake full -Riemannian processing. Explicit full-processing requests must fail with a clear -limitation until a tested Python manifold-optimization backend is selected. - -## Optional-Dependency Rules - -EEGPrep should prefer standalone Python behavior for core preprocessing, data -structures, GUI/console state, saved-file behavior, and bundled plugin workflows -that can be tested without external scientific toolboxes. - -Use `optional_dependency` only when the workflow requires a substantial backend -that can be installed, versioned, tested, and documented. These rows must not -produce fake outputs. Until a backend is selected, user-facing functions should -raise clear limitations that name the missing backend and point to EEGPrep docs. - -Use `external_plugin` for broad third-party ecosystems that do not belong in -core EEGPrep. Those workflows should be built through the extension API, -catalog/trust model, packaged help, tests, and docs. - -## Documentation Architecture - -Phase 7 should reorganize and expand Sphinx docs into an EEGLAB-style manual -with EEGPrep-specific behavior: - -1. Installation and optional dependencies. -2. Concepts guide: EEG structures, events, epochs, channel locations, ICA, - STUDY, history, `EEG`, `ALLEEG`, `CURRENTSET`, and indexing boundaries. -3. GUI tutorials and menu workflows. -4. Command line, `eegprep-console`, `LASTCOM`, `ALLCOM`, and script replay. -5. Preprocessing, filtering, cleaning, and artifact diagnostics. -6. ICA, ICLabel, rejection, and visual diagnostics. -7. STUDY, statistics, PAC, source localization, and optional backend limits. -8. Bundled plugins and external extensions. -9. API reference. -10. EEGLAB migration notes mapping familiar MATLAB workflows to EEGPrep GUI, - Python, and console workflows. -11. Developer parity contracts, matrix maintenance, visual evidence, and the - standalone runtime boundary. - -The current docs already have useful pages under `docs/source/user_guide/`, -`docs/source/api/`, and `docs/source/examples/`. Phase 7 should reorganize and -extend those pages rather than generating API dumps or copying EEGLAB prose. - -## Runtime Contract - -The installed `eegprep` package must not read, import from, or shell out to -`src/eegprep/eeglab`. That checkout is a development oracle for audits, parity -tests, and tooling only. Runtime help text, options, sample resources, and docs -must be EEGPrep-owned packaged resources. - -This phase adds `tests/test_runtime_eeglab_independence.py` to scan package -Python files for vendored-reference dependency patterns. Tooling under `tools/` -may read the vendored EEGLAB tree because validation is a development task. - -## Validator Contract - -`tools.eeglab_final_parity_matrix` discovers 180 final-epic EEGLAB reference -paths from the vendored checkout: - -- plugin paths from the four bundled plugin roots, excluding MatConvNet and - Manopt third-party library internals/examples/tests; -- object/storage MATLAB class folder files; -- EEGLAB tutorial scripts and Live Scripts. - -Rows may group several source paths into one workflow, but each discovered -reference path must appear exactly once. Missing paths, duplicated paths, -missing optional-dependency contracts, stale-skip policy mistakes, missing docs -architecture sections, and inconsistent phase ownership fail validation. - -The existing core command remains separate and must still pass: - -```bash -uv run --no-sync python -m tools.eeglab_parity_matrix --json -``` - -The final epic command is: - -```bash -uv run --no-sync python -m tools.eeglab_final_parity_matrix --json -``` diff --git a/.notes/eeglab-migration-gap-audit.md b/.notes/eeglab-migration-gap-audit.md deleted file mode 100644 index 4599399a..00000000 --- a/.notes/eeglab-migration-gap-audit.md +++ /dev/null @@ -1,241 +0,0 @@ -# EEGPrep Remaining EEGLAB Migration Gap Audit - -Audit date: 2026-06-07 -Branch audited: `feature/eeglab-core-parity-completion` / PR #152 -Primary reference: `docs/parity/eeglab_core_parity_matrix.json` - -## Summary - -This file is the current committed audit of what still remains after the -remaining-core-parity epic. It supersedes the earlier pre-epic audit that listed -items 1-7 as open work. - -PR #152 completes or explicitly classifies the first seven migration categories: - -1. Long-tail helper coverage -2. Missing or legacy `pop_*` entry points -3. Unsupported options in implemented user-facing functions -4. STUDY and group-level depth -5. Statistics package -6. Time-frequency internals -7. File-format and channel-location long tail - -The machine-readable matrix now covers all in-scope EEGLAB functions for those -categories: - -- `uv run --no-sync python -m tools.eeglab_parity_matrix --json` -- 608 rows cover 608 expected in-scope EEGLAB functions. -- Status counts: 238 `implemented`, 99 `consolidated`, 104 `stale_skip`, - 121 `matlab_runtime_skip`, and 46 `external_dependency_skip`. -- There are no remaining `port`, `partial`, or unclassified rows for the - categories covered by PR #152. - -## Completed In PR #152 - -The epic converted the original gap audit into an enforceable parity matrix and -then closed the useful core gaps through phase PRs: - -- Phase 1: parity matrix, staleness triage, and standalone runtime contracts. -- Phase 2: file-format and channel-location long-tail helpers. -- Phase 3: EEGLAB-style statistics helpers. -- Phase 4: time-frequency internals and legacy time-frequency entry points. -- Phase 5: unsupported options in already user-facing functions. -- Phase 6: deeper STUDY/group-level helpers. -- Phase 7: remaining audit-approved helpers and `pop_*` wrappers. -- Phase 8: closeout docs, help resources, QA, and matrix validation. - -The follow-up issues for time-warped `newtimef`, exact `correct_mc` random-symbol -distribution fitting, PAC classification, and STUDY long-tail helper depth are -also resolved in the same PR stack. - -## What Still Remains - -The remaining items are no longer generic “missing same-name files.” They are -explicitly outside the current core parity scope, intentionally skipped because -they are stale/MATLAB-only, or dependent on external runtimes/toolboxes. Future -work should start from these product areas, not from a blind same-name port. - -### 1. MATLAB Runtime And Figure-Helper Skips - -Many EEGLAB files are MATLAB command-window, path, deployed-app, figure-editing, -or low-level GUI compatibility helpers. EEGPrep should not port these -one-for-one unless a real EEGPrep user workflow needs them. - -Examples include: - -- `abouteeglab`, `eeg_cache`, `eeg_eval`, `eeg_global`, `eeglab_execmenu`, - `eeglab_new`, and `eeglab_options` -- EEGLAB help menu wrappers such as `eeg_helpadmin`, `eeg_helpgui`, - `eeg_helppop`, `eeg_helpstudy`, and `eeg_helptimefreq` -- MATLAB dialog or path wrappers such as `questdlg2`, `warndlg2`, - `uigetfile2`, `uiputfile2`, and `removepath` -- MATLAB plotting utilities such as `axcopy`, `copyaxis`, `plotcurve`, - `plotdata`, `ploterp`, `plotmesh`, `plotsphere`, `textsc`, and `sbplot` - -Recommended handling: keep these rows classified in the parity matrix. Port only -when a concrete EEGPrep GUI/API path requires the behavior, and implement it as -native Python/Qt behavior rather than a MATLAB-runtime imitation. - -### 2. External Dependency And Toolbox-Backed Workflows - -Some EEGLAB functions depend on external toolboxes, MATLAB-specific runtimes, or -large plugin ecosystems. These are intentionally not silently faked in EEGPrep. - -Examples include: - -- LIMO workflows: `pop_limo`, `pop_limoresults`, `std_limo`, - `std_limodesign`, `std_limoresults`, and `std_readfilelimo` -- FieldTrip/neighbour/DIPFIT-dependent STUDY helpers such as - `std_prepare_neighbors`, `std_interp`, `std_dipplot`, and - `std_dipoleclusters` -- Legacy ICA backends such as `binica`, `jader`, `sobi`, `acsobiro`, - `fastif`, and old `runica_ml*` variants -- Direct legacy BIOSIG/EGI import wrappers where a supported modern import path - already exists or an external backend is required -- PAC compute/plot/cache helpers such as `pac`, `pac_cont`, `std_pac`, - `std_pacplot`, and `std_readpac` - -Recommended handling: create separate product epics only when EEGPrep can offer -a tested standalone implementation or a clearly documented optional dependency. -Do not add placeholder math or fake cache files just to match names. - -### 3. MATLAB Object And Memory-Mapped Infrastructure - -EEGLAB has MATLAB class-style folders that are not one-for-one Python concepts: - -- `functions/@eegobj` -- `functions/@memmapdata` -- `functions/@mmo` - -This matters for full MATLAB `storedisk` and memory-mapped dataset behavior. -EEGPrep currently uses explicit Python `EEGPrepSession`, `ALLEEG`, and dataset -storage semantics instead. - -Recommended handling: treat this as a future storage/performance design epic, -not a MATLAB class port. If EEGPrep needs large-dataset lazy loading, design a -Python-native data backend with tests for GUI/console synchronization, -`pop_newset`, save/load behavior, and STUDY workflows. - -### 4. Bundled Plugin Depth - -The bundled in-repo plugin surfaces are represented, but not all plugin internals -are complete one-for-one ports. - -Remaining plugin-depth areas: - -- `clean_rawdata`: exact Riemannian ASR processing parity, full - `vis_artifacts` behavior, and Manopt-backed MATLAB helper depth. -- `firfilt`: lower-level helper coverage such as detailed reports, inverse - order helpers, minimum-phase helpers, frequency-response plotting, and order - calculator dialogs. -- `ICLabel` / viewprops: Phase #163 closes the standalone default-network, - `eeg_icalabelstat`, and native Qt/Python diagnostic-browser surface. The - EEGLAB `lite`/`beta` network artifacts remain explicit MATLAB/Octave - passthrough choices rather than silently emulated standalone assets. -- `DIPFIT`: lower-level grid/nonlinear/reject/dipplot helpers, manual/batch - dialogs, atlas conversion helpers, and private transform utilities. - -Recommended handling: split these into plugin-specific epics. Each plugin should -define what “standalone EEGPrep parity” means, which external assets are allowed, -and which EEGLAB MATLAB internals should stay unported. - -### 5. External Plugin Ecosystem - -EEGPrep now has extension infrastructure, but the broad EEGLAB external plugin -ecosystem is not part of core EEGPrep. - -Examples: - -- ERPLAB -- LIMO as a full external statistics workflow -- SIFT -- NFT -- MFF/importer plugin ecosystems -- Lab-specific processing plugins - -Recommended handling: external plugin work should use EEGPrep’s extension -contracts, catalog/trust model, documentation, and extension-development skill. -Do not merge third-party plugin behavior into core EEGPrep unless it becomes a -maintained bundled plugin with tests, docs, packaging, and GUI/console support. - -### 6. Docs, Tutorials, And User Education - -EEGPrep has EEGPrep-owned help resources and user-facing docs for the new epic -work, but EEGLAB’s full tutorial corpus is larger than the ported docs. - -Remaining useful docs work: - -- End-to-end tutorials comparable to EEGLAB’s practical workflows. -- More task-oriented examples for STUDY, EEGBrowser, extension authoring, file - I/O, time-frequency, and statistics. -- User-facing migration notes for EEGLAB users moving MATLAB commands to - EEGPrep Python/console workflows. -- Curated visual parity evidence index for major GUI surfaces. - -Recommended handling: keep help Markdown next to user-facing `pop_*` features, -but plan tutorials as product documentation rather than generated API dumps. - -### 7. Ongoing Parity Matrix Maintenance - -The parity matrix is now the source of truth for the first seven audit -categories. Future feature work should update it whenever an EEGLAB-facing -function is added, consolidated, or intentionally skipped. - -Required behavior: - -- `tools/eeglab_parity_matrix.py` must stay green. -- Runtime package code must not depend on `src/eegprep/eeglab`. -- New GUI features need visual parity evidence. -- New console/API features need replayable history and `eegprep-console` - synchronization tests where relevant. -- New numerical behavior should have MATLAB parity tests when deterministic and - feasible. - -## Not Recommended - -Avoid these patterns in future migration work: - -- Blind one-file-to-one-file ports of stale MATLAB helpers. -- Fake implementations that return plausible shapes but do not perform the - EEGLAB workflow. -- Runtime fallbacks that read the vendored EEGLAB checkout. -- Adding external-toolbox behavior without an explicit optional dependency, - install docs, tests, and clear user-facing failure mode. -- Implementing old MATLAB GUI shims when the right EEGPrep answer is a native - Qt or Python API surface. - -## Next Planning Step - -Epic #157 now turns the remaining product areas above into a scoped issue tree. -Its Phase 1 contract lives in: - -- `.notes/eeglab-final-parity-audit.md` -- `docs/parity/eeglab_final_parity_matrix.json` -- `tools/eeglab_final_parity_matrix.py` - -The final matrix assigns concrete phase ownership for bundled plugin depth, -object/storage semantics, optional-toolbox workflows, and docs/tutorial gaps. -Future phase agents should update that matrix instead of reclassifying product -scope from this prose audit. - -Before the final epic started, the strongest candidates were: - -1. Bundled plugin depth, split by plugin family. -2. Large-dataset storage and memory mapping semantics. -3. External dependency workflows such as LIMO or advanced DIPFIT. -4. User documentation/tutorial parity for completed core workflows. - -Before changing core parity rows, run: - -```bash -uv run --no-sync python -m tools.eeglab_parity_matrix --json -``` - -Before changing final epic rows, run: - -```bash -uv run --no-sync python -m tools.eeglab_final_parity_matrix --json -``` - -Then decide whether the work changes the existing matrix rows or belongs to a -new matrix/category outside PR #152’s original scope. diff --git a/.notes/implementation-notes.html b/.notes/implementation-notes.html deleted file mode 100644 index d1bb62e1..00000000 --- a/.notes/implementation-notes.html +++ /dev/null @@ -1,725 +0,0 @@ - - -
- -Issue #213 closes the final Fable 5 architecture closeout phase for - statistics and ICLabel/viewprops ownership. The branch keeps public call - signatures, return values, command strings, GUI labels, and Matplotlib - dashboard layout behavior stable while moving implementations into focused - owner modules.
-functions/statistics/_core.py into the existing same-name
- public modules such as fdr.py, statcond.py,
- surrogdistrib.py, and the anova*_cell.py and
- ttest*_cell.py helpers. _core.py is now only a
- compatibility re-export shell; shared array/grid helpers and two-way ANOVA
- data containers live in _shared.py.plugins/ICLabel/pop_prop_extended.py into pop/dialog
- glue, _prop_numerics.py for classifier, DIPFIT, PVAF, spectra,
- and dashboard data assembly, and _prop_browser.py for the
- Matplotlib property-browser rendering and rejection controls.pop_prop_extended module as a facade that
- re-exports the existing helper names used by tests and by
- pop_viewprops, so users do not need to change imports.| Remaining item | Disposition | Rationale |
|---|---|---|
pop_load_frombids.py raw-reader and montage
- ownership | Fixed in PR #216 / issue #212 | BIDS raw loading
- and montage inference moved into EEG-BIDS helper modules while
- pop_load_frombids stayed orchestration/history glue. |
functions/statistics/_core.py mega-module | Fixed - in issue #213 | Implementations now live in same-name statistics
- modules, with _shared.py holding only shared helpers. |
plugins/ICLabel/pop_prop_extended.py mixed
- ownership | Fixed in issue #213 | Pop/history/dialog glue, - numerics/data assembly, and Matplotlib browser rendering now have - separate owner modules. |
functions/guifunc/qt.py stateless renderer namespace | Fixed - in PR #216 / issue #212 | Qt renderer helpers were split into - module-level helpers while preserving call-site compatibility and dialog - behavior. |
pop_clust finite-outlier robust k-means dispatch | Fixed - in PR #217 / issue #210 | STUDY clustering behavior was consolidated - in the STUDY/time-frequency/statistics phase with dedicated tests. |
pop_chanplot, measure-field maps, cached measure
- axes, range masks, default plot targets, _trial_rows, factor
- matching, and std_clustplot history construction | Fixed - in PR #217 / issue #210 | STUDY measure/cache helper ownership was - consolidated as one phase because those paths share STUDY data contracts. |
| Time-frequency numeric-vector parsing, bootstrap/FDR helpers, - threshold-vector helpers, and empirical p-value convention audit | Fixed - or explicitly documented in PR #214 / issue #208 and PR #217 / issue - #210 | Shared parsing moved to lower-level helpers in Phase 1; - time-frequency and statistics behavior consolidation landed in Phase 3 - where numerical behavior could be tested together. |
Divergent is_on(), empty-value, Python literal,
- chanloc serialization, topographic channel selection, boundary-event
- detection, and ConsoleEegh history mutation copies | Fixed - in PR #214 / issue #208 | Shared low-level contracts were centralized - before later phases consumed them. |
| Rejection-family browser plumbing, epoched rejection scaffolds, - component activation access, ICA finalization, and clean_rawdata - channel-removal masks | Fixed in PR #215 / issue #209 | These - scientific rejection/ICA/cleaning helpers were consolidated in the phase - that could test visual rejection state and numerical side effects - together. |
| CLI transform/pipeline duplication, JSON detection, stale - per-module harness contracts, extension catalog split, entry-point - helpers, active-record predicate, and bundled-plugin metadata | Fixed - in PR #218 / issue #211 | CLI and extension ownership was - consolidated in one agent-facing architecture phase. |
| FIR helper ownership and FIR GUI band-edge/shape duplication | Fixed - in PR #216 / issue #212 | plugins/firfilt now owns FIR
- design helpers, and clean_rawdata imports downward from firfilt. |
| GUI extension pop-result STUDY return handling from #197/#205 | Non-goal - for #213 | The earlier tracker identified this as behavior-changing
- because GUI extension pop_* functions returning STUDY state
- would expand observable session behavior. No #213 work touched extension
- GUI result semantics; this remains outside a mechanical closeout split
- unless a future behavior issue requests it. |
| All other #197 findings not named above | Superseded by epic - #207 phase split | #197 and #205 were closed as superseded by the - replacement architecture closeout epic. PRs #214, #215, #217, #218, #216, - and this #213 branch are the final accounting set for those remaining - findings. |
_core.py
- compatibility re-exports, and existing statistical behavior.pop_prop_extended facade, classifier/DIPFIT/PVAF data assembly,
- dashboard rendering, navigation, rejection controls, packaged help, and
- pop_viewprops delegation.Issue #212 closes the Phase 5 architecture ownership work for BIDS - import helpers, Qt dialog rendering helpers, and FIR design helpers while - preserving standalone EEGPrep runtime behavior.
-pop_load_frombids as the BIDS orchestration,
- metadata, event, history, and report wrapper, and moved raw EEG file
- loading plus packaged montage inference into plugins/EEG_BIDS
- helper modules.plugins/firfilt
- so clean_rawdata imports shared filter design behavior from the plugin
- that owns FIR filtering semantics.QtDialogRenderer._helper aliases for
- existing callers and tests.Issue #164 turns the final-epic documentation into a coherent standalone
- EEGPrep manual modeled after EEGLAB's learning path but written for Python,
- the Qt GUI, eegprep-console, and EEGPrep-owned packaged
- resources.
sample_data
- files where possible, and used explicit return_com=True
- examples to teach history replay.pop_* API index plus missing
- packaged help topics for pop_chansel,
- pop_load_frombids, and pop_loadset_h5.Issue #163 closes the Phase 6 final-epic ICLabel/viewprops rows by adding - standalone label statistics, making alternate network support explicit, and - documenting the native EEGPrep diagnostic workflow.
-eeg_icalabelstat as an EEGPrep-owned public
- helper that preserves EEGLAB threshold-count console output while returning
- structured Python statistics for reports and tests.netICL.mat. EEGLAB lite and beta
- network artifacts are allowed only through MATLAB/Octave engines that have
- those ICLabel files, and standalone requests raise a clear
- NotImplementedError.pop_viewprops
- and pop_prop_extended surfaces as the maintained standalone
- parity path instead of porting MATLAB figure helper internals one for one.pop_iclabel, pop_icflag,
- eeg_icalabelstat, pop_viewprops, and
- pop_prop_extended as one component-review workflow.pop_icflag Cancel
- path, pop_icflag OK/default-threshold path, and
- pop_viewprops component dialog OK path; returned commands and
- rejection vectors matched expectations.Issue #158 establishes the Phase 1 contract for epic #157. It adds an - enforceable final-epic matrix for bundled plugin depth, MATLAB object/storage - semantics, optional-toolbox workflows, and EEGLAB-style docs architecture - without porting feature behavior.
-docs/parity/eeglab_final_parity_matrix.json as a
- second matrix instead of changing the completed core matrix, so
- uv run --no-sync python -m tools.eeglab_parity_matrix --json
- remains the PR #152 core validator.source_paths and requires every discovered final-epic
- EEGLAB path to be covered exactly once..notes/eeglab-final-parity-audit.md so Phase 7 can write user
- docs after Phases 2-6 define final behavior.src/eegprep/eeglab dependency patterns.AMICA_BINARY, package bin/, and system
- PATH.optional_dependency for LIMO, PAC,
- Riemannian ASR, FieldTrip-style STUDY/source workflows, and DIPFIT fitting
- instead of pretending those computations are available without a tested
- backend.partial
- and consolidated rows, because the final epic still needs each
- owner to provide verification, docs, or explicit limitation evidence.Issue #147 implements the Ramberg-Schmeiser/random-symbol fitting stack
- needed by correct_mc while keeping EEGPrep runtime code independent
- of the vendored EEGLAB checkout.
rsfit, rsadjust, rsget,
- rspdfsolv, and rspfunc as standalone numerical
- helpers under functions/timefreqfunc, matching the EEGLAB
- Ramberg-Schmeiser moment and quantile formulas with SciPy optimization and
- beta/gamma functions already available in the project.correct_mc so neighboring-bin channel correlations
- are tested with rsfit(correlations, 0), which is the EEGLAB
- decision path for the returned p-value array and ncorrect
- threshold.correctfit as a standalone gamma-parameter correction
- helper because it belongs to the same EEGLAB distribution-fit stack, but did
- not add a new bootstat(distfit='on') API in this issue.correct_mc input handling, output shape,
- and time-frequency workflow remain intact; only the temporary t-test
- p-value estimator was replaced with the EEGLAB RS fit.NaN p-values
- inside correct_mc instead of crashing the whole helper, matching
- the existing EEGPrep behavior for non-estimable cells while the public
- rsfit helper still fails clearly on invalid distributions.rsadjust preserves EEGLAB's C - 2AB + 2A^3
- sign convention for lambda2. This differs from the
- standardized third-moment numerator in rspdfsolv, but changing
- it would break exact parity with functions/timefreqfunc/rsadjust.m.bootstat remains EEGPrep's callable bootstrap helper. Its
- broader EEGLAB distfit/vals/correctp
- behavior changes the bootstrap API surface and is intentionally left out of
- this correct_mc-scoped follow-up.correctfit behavior, and correct_mc delegation to
- rsfit.rsfit, rsadjust, rsget,
- rspdfsolv, and rspfunc outputs when MATLAB Engine
- and the EEGLAB reference checkout are available.Follow-up #149 closes the non-PAC Phase 6 STUDY helper rows that remained - after the core STUDY implementation. The branch implements the standalone - selection and trialinfo helpers that EEGPrep workflows can use directly, and - classifies the remaining plotting, precompute, MATLAB-runtime, or - external-toolbox rows with row-level rationale in the parity matrix.
-src/eegprep/eeglab.consolidated with the owning EEGPrep path and focused test notes.matlab_runtime_skip.external_dependency_skip.Phase 8 reviews the integrated Phases 1-7 surface for closeout evidence - rather than adding another feature area. The branch remains scoped to matrix, - docs/help, QA evidence, and concrete integration defects.
-port and partial rows only named generic follow-up work in test_notes. The closeout now requires actionable rows to cite a concrete issue, and rows point to #146, #147, #148, or #149.pop_* wrappers, but Phase 6's public STUDY helpers pop_addindepvar and pop_listfactors were missing packaged help resources. Phase 8 adds those help topics and a focused packaged-help regression check.pop_newtimef and pop_newcrossf is present in PR review comments rather than committed files; Phase 8 keeps that as evidence documentation because closeout did not change those dialogs.port/partial rows were not force-ported during closeout. They represent follow-up issues whose own scopes require parity-first design, fixtures, or GUI evidence. Closing Phase 8 by naming those issues is safer than adding incomplete analysis math or one-for-one MATLAB GUI internals.src/eegprep continues to avoid importing from, reading from, or shelling out to src/eegprep/eeglab.uv run --no-sync python -m tools.eeglab_parity_matrix: parity matrix OK, 608 rows cover 608 in-scope EEGLAB functions.uv run --no-sync ruff check ., uv run --no-sync ruff format --check ., and uv run --no-sync ty check: passed after syncing optional GUI/torch extras needed by the type checker.EEGPREP_SKIP_MATLAB=1 uv run --no-sync pytest -m "not slow": passed with 1746 tests passing, 233 skipped, and 11 deselected../pre-commit.py --changed-from origin/feature/eeglab-core-parity-completion: passed for the Phase 8 changed-file set.EEGPrepSession state across load, bare pop_select, and bare pop_reref calls.pop_listfactors display-only options as a non-GUI EEGLAB compatibility regression. Phase 8 fixed that by accepting splitreg, contrast, and interaction as non-GUI no-ops, then reran autoreview clean against origin/feature/eeglab-core-parity-completion.follow_up_issue URLs as canonical matrix follow-up evidence and by adding direct channel-cache coverage for the hardened subject-filter error.Phase 7 closes the remaining audit-approved helper and wrapper gaps that - were still actionable after Phases 2-6, while classifying obsolete or - toolbox-dependent MATLAB surfaces explicitly in the parity matrix.
-pop_averef, pop_compareerps, pop_findmatchingcomps, pop_fusechanrej, pop_icathresh, pop_rejchanspec, and pop_topochansel. Each wrapper either delegates to an existing modern EEGPrep path or implements the thin compatibility behavior directly with replayable command history.pop_* wrapper. No runtime code reads from the vendored EEGLAB checkout.pop_topochansel reuses the existing EEGPrep channel selector for GUI fallback, so visual parity captures were not applicable.newtimef marker and cycle GUI workflows.correct_mc random-symbol distribution fitting.pop_averef, spectral channel rejection, topographic channel selection, ICA helper math, and rejection helper outputs.port or partial rows without either an implementation/classification or a concrete follow-up issue.Phase 5 closes option-level gaps in existing user-facing functions while - keeping EEGPrep standalone and explicit about MATLAB-only or toolbox-dependent - behavior.
-pop_export expressions, filename-backed pop_epoch data, pop_editset file assignments, pop_comperp display/significance toggles, pop_erpimage event sorting, and headplot_setup preview/original-location options.pop_eegfilt FFT filtering, MATLAB/text pop_runscript, unsupported pop_runica algorithms, FieldTrip-style coregister methods, and full Riemannian ASR processing.pop_export accepts a restricted numeric expression language instead of arbitrary Python evaluation. This covers common scale/log/clip transforms without exposing broad runtime objects through command history.clean_artifacts(Distance='Riemannian') uses the supported calibration-time Riemannian ASR estimate. Full Riemannian ASR processing remains unported and raises a clear error when requested directly.pop_envtopo remains a one-dataset wrapper because multi-dataset component envelopes need a deliberate group workflow rather than a silent merge of dataset-specific ICA maps.pop_export keywords are accepted, missing pop_editset paths fail as missing files, dataformat applies to numeric ICA imports, pop_comperp standard-deviation traces use EEGLAB's dataset-axis spread, and unknown ASR distance names are rejected.EEGPREP_SKIP_MATLAB=1 where needed.Phase 6 deepens standalone STUDY workflows without adding runtime dependencies - on the vendored EEGLAB tree or pretending external LIMO behavior is available.
-pacdata cache exists.NotImplementedError limitations because EEGPrep does not ship an external LIMO toolbox equivalent.STUDY caches. Runtime code does not read from EEGLAB's reference checkout.std_addvarlevel stores EEGLAB-like level values of one or two; the previous numeric level list is preserved as levelindex for deterministic downstream use.std_apcluster is a deterministic standalone affinity-propagation implementation for EEGPrep workflows, not a dependency on EEGLAB's MATLAB apcluster helper.pacdata.src/eegprep/functions/sigprocfunc: readlocs, writelocs, convertlocs, chancenter, floatread, floatwrite, snapread, and EGI location lookup.src/eegprep/functions/popfunc for pop_readlocs, pop_writelocs, pop_chancenter, pop_chancoresp, pop_loadbci, and pop_snapread.pop_chanedit so GUI and command workflows share one implementation.readchans, elecind, omitchans, and channel-correspondence return values.pop_chancoresp implements the workflow-supporting label and fiducial pairing behavior without recreating EEGLAB's full interactive listbox editor.cart2all and fills derived fields without avoidable spherical round-trip drift.floatread and floatwrite are implemented for EEGLAB-style binary helper coverage, while high-level EEG file export remains owned by existing pop_writeeeg paths.pop_readlocs, pop_writelocs, pop_chancenter, and pop_chancoresp; this phase intentionally shipped API and console behavior first.pop_chanedit, pop_comperp, pop_editset, pop_eegfilt, pop_envtopo, pop_epoch, pop_erpimage, pop_newcrossf, pop_newtimef, and pop_runica.pop_editset which is one pixel narrower in the capture.pop_editset disabled channel/ICA file controls visible because they mirror EEGLAB's field inventory and make future parity paths discoverable without pretending those assignments are currently enabled..visual-parity/ for PR attachment/review evidence and are not committed as package files..fdt column-major channel/time ordering for filename-backed pop_epoch and pop_editset workflows.return_com=True history support for pop_addindepvar and pop_listfactors so new public STUDY pop helpers remain usable from the mixed GUI/console workspace.bootstat basevect handling with EEGLAB's 1-based user-facing indices, kept empty MATLAB parity arguments as numeric [], and accepted NumPy vector selections in channel-location read/write helpers.pac.m, pac_cont.m, std_pac.m, std_pacplot.m, and std_readpac.m were inspected from sccn/eeglab develop because the local vendored EEGLAB tree in this worktree is empty.latphase branches explicit.std_readpac remains a deterministic standalone cache reader for explicit EEGPrep-owned pacdata, pactimes, and pacfreqs fields and supports time/frequency range slicing and malformed-cache validation.timewarp, angtimewarp, and tf_cycle_calc as standalone Python helpers under functions/timefreqfunc; runtime code does not read from src/eegprep/eeglab.newtimef accepts matrix-form timewarp latencies in milliseconds, optional timewarpms reference latencies, and EEGLAB-facing 1-based timewarpidx marker indices.pop_newtimef GUI keeps EEGLAB's visible control inventory and routes time-warp options through the existing optional arguments field; explicit time-warp controls were not added because EEGLAB does not expose them in this dialog.tf cycle calc button now opens a nested EEGPrep dialog matching EEGLAB's cycle calculator controls and writes calculated frequency/cycle vectors back to the parent dialog.timewarp is supported. EEGLAB's comments mention cell-form historical variants, but current EEGLAB raises for cell-form timewarp, so EEGPrep rejects non-matrix input clearly.tf_cycle_calc returns a dataclass with named arrays instead of MATLAB multiple outputs; the cycles and widths table match EEGLAB numerically.pop_newtimef time-warp history, console history recording, and dialog inventory.timewarp, angtimewarp, and tf_cycle_calc is included behind the existing MATLAB skip behavior.pop_* helper dialogs.useriemannian='calib' keeps the calibration-time Riemannian estimate, while full Manopt-backed processing raises a clear limitation instead of silently emulating MATLAB behavior.vis_artifacts and vis_artifacts_diagnostics as EEGPrep-owned diagnostic surfaces and wired the pop_clean_rawdata visual checkbox to those packaged helpers.src/eegprep/eeglab.EEG.dipfit.model entries.pop_dipfit_gridsearch, pop_dipfit_nonlinear, pop_multifit, pop_dipfit_batch, pop_dipfit_manual, pop_leadfield, dipfit_reject, dipplot/pop_dipplot, headcoordinates, electroderealign, mni2tal, and sph2spm.eegprep-console workflows can replay the new DIPFIT operations.load_afni_atlas reads user-supplied AFNI/NIfTI volumes only when nibabel is installed and raises a clear limitation otherwise.pop_leadfield supports explicit source-point arrays and simple files with source positions; FieldTrip-style source model files that need external readers remain unsupported.pac with EEGPrep's existing timefreq backend. It returns complex PAC values for epoched data and interpolates amplitude/phase decompositions onto a shared overlapping time grid when their wavelet windows differ.pac_cont with SciPy bandpass filtering and Hilbert transforms for continuous modulation, PLV, correlation, and linear-regression PAC methods.std_pac as the STUDY cache writer for channel PAC. STUDY caches store real PAC magnitude under STUDY.changrp[*].pacdata because plotting and std_readpac use real frequency/time arrays, while lower-level pac retains complex values.std_pacplot through std_readpac so command-line and plotted range filtering share one cache contract.std_limodesign as the feasible standalone LIMO-compatible layer: categorical matrices, continuous matrices, interactions, split regressors, description output, and optional text exports.pop_limo, std_limo, std_limoresults, pop_limoresults, and std_readfilelimo as explicit external-toolbox limitations. EEGPrep still does not create placeholder LIMO result files.std_prepare_neighbors with a standalone distance-based channel-neighbor list and LIMO-compatible adjacency matrix. It does not call FieldTrip at runtime.std_interp for STUDY channel-location unions using the existing EEGPrep channel interpolation backend. It preserves each dataset's existing channels when adding requested missing channels.std_dipplot and std_dipoleclusters limitation wrappers for STUDY-level source workflows that need Phase 3 DIPFIT/source contracts.std_pac STUDY caches require a single freqphase value, matching the practical EEGLAB STUDY PAC cache shape. Use low-level pac directly for full amplitude-by-phase-frequency grids.latphase histogram mode raise explicit NotImplementedError messages until they have a tested standalone backend.pac, pac_cont, std_pac, std_readpac, std_pacplot, std_limodesign, std_prepare_neighbors, std_interp, and source/LIMO limitation paths.This phase implements EEGPrep-owned storage behavior for issue #162 without
- adding runtime dependencies on the vendored EEGLAB tree or porting MATLAB
- @memmapdata/@mmo overloads one-for-one.
MemmapData, a NumPy-compatible handle over EEGLAB-style
- .fdt sidecars. It preserves channel-major EEG shapes and uses the
- EEGLAB channel-fast float32 file layout for continuous and epoched data.OffloadedData for option_storedisk. It records
- the saved .set path and shape metadata, but raises on sample access
- until the dataset is retrieved through eeg_retrieve or
- EEGPrepSession.retrieve.eeg_store,
- eeg_retrieve, and EEGPrepSession mutation points.pop_saveset now accepts savemode="twofiles" and
- honors EEG_OPTIONS["option_savetwofiles"]. pop_loadset
- honors EEG_OPTIONS["option_memmapdata"] for sidecar-backed data.option_storedisk.
- This intentionally fails with a clear save-first error instead of pretending
- data was unloaded..set data still loads into memory; memory mapping is
- only honest for datasets with a separate .fdt sidecar.pop_loadset channel-only and loadmode="info"
- paths are explicit non-implemented paths in Phase 5. Full dataset loading,
- storedisk retrieval, save/load, STUDY resave, and GUI/console synchronization
- are covered.icaact are not given a separate lazy
- storage layer in this phase.eeg_retrieve, refusing unsaved eviction,
- pop_newset new-dataset behavior, STUDY resave, and mixed
- session/console synchronization.@memmapdata and
- @mmo to point at the Python-native storage backend and tests.src/eegprep/cli/commands/transforms.py
- with argparse registration so the shared dispatcher can mount resample,
- rereference, filter, clean, epoch,
- and ica without importing GUI entry points.pop_loadset, runs the existing
- pop_* or plugin pop wrapper with return_com=True, appends
- the returned history to the saved dataset, and writes a manifest next to the
- output unless --manifest is supplied.--output unless --overwrite is
- explicit. JSON mode redirects incidental processing stdout to stderr before
- emitting the final JSON response.python -m eegprep.cli.commands.transforms harness for focused
- subprocess tests, while the public entry point is the top-level
- eegprep dispatcher.eegprep.cli.transforms helper was removed so
- future work has one transform command implementation to maintain.eegprep command as the headless agent/batch
- interface while leaving eegprep-gui and
- eegprep-console unchanged for human interactive use.eegprep-cli skill under
- resources/skills and exposed it through
- eegprep skills get eegprep-cli, so agents can load usage rules
- without scraping Sphinx docs.pop_* and plugin functions; it
- does not duplicate preprocessing math. This keeps parity behavior aligned
- with GUI and console workflows.eegprep-console.eegprep eeglab compare.pop_runica itself synchronous for scripts, tests, CLI,
- and console calls. The background worker is owned by the Qt menu action
- layer because only the GUI needs to keep repainting while the computation
- runs.pop_runica GUI option collection from ICA execution
- so the options dialog always opens on the main Qt thread and only the pure
- computation runs in the worker.EEGPrepSession is updated
- only from the success callback.eegprep dispatcher the canonical owner of
- JSON error envelopes, including nested command parse failures such as
- eegprep qc report --json.pop_* invocation behavior.eegprep.extension_catalog_validation
- while eegprep.extension_catalog remains the manager-facing runtime
- catalog module.eegprep.extensions
- so the registry, validator, and plugin menu use the same metadata rules.