Fix Pyodide analysis pipeline (harvest #194: dataKey routing, MEMFS, MNE 1.x)#220
Open
jdpigeon wants to merge 4 commits into
Open
Fix Pyodide analysis pipeline (harvest #194: dataKey routing, MEMFS, MNE 1.x)#220jdpigeon wants to merge 4 commits into
jdpigeon wants to merge 4 commits into
Conversation
… PSD Harvests the still-valid fixes from the stale PR #194 (pyodide-fix) and re-applies them onto current main. #194 itself isn't mergeable — it was built on a superseded asset-serving base (HTTP server) that main replaced with the pyodide:// protocol, and it predates the buildMarkerRegistry marker-code fix (its loadEpochsEpic reverted to the broken 0-based event map). So this takes the logic, not the commits, and keeps buildMarkerRegistry intact. The pipeline crash (getEpochsInfoEpic: "Cannot read properties of undefined (reading 'map')") was because requestEpochsInfo/requestChannelInfo relied on worker.postMessage returning data — it returns undefined; results come back on the message channel. Fixes: - dataKey routing (parallel to plotKey): worker echoes dataKey + converts the PyProxy result to plain JS (structuredClone can't clone a PyProxy); pyodideMessageEpic routes epochsInfo -> SetEpochInfo, channelInfo -> SetChannelInfo. The two info epics + loadEpochsEpic are now fire-and-forget. - loadCleanedEpochs: stage .fif files in Pyodide MEMFS via new fs:readFileAsBytes IPC + writeEpochsToMemfs (WASM FS can't read host OS paths). - plotPSD: raw.plot_psd() -> raw.compute_psd().plot() (MNE 1.2+ removed plot_psd). - loadTopoEpic: call plotTopoMap, not plotTestPlot. - renderAnalyzeButton: show when epochsInfo.length > 0 (not only when drop >= 2). - eslint: ignore leftover src/renderer/utils/pyodide/** (pyodide.asm.js pegged the linter). Drops now-unused DEVICES/plotTestPlot/parseSingleQuoteJSON imports. Skipped from #194: the channel-index-0 fix (current loadERPEpic already handles 0 correctly post-Emotiv-removal), saveEpochs paren (already closed on main), and Prettier-only churn. Typecheck clean, lint completes, 29/29 tests pass. Needs in-app Pyodide verification (can't run WASM in CI/locally here). Also documents the lab.js 23.x datastore gotcha in learnings. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SNEh5EFg4dSpRrfJ2ae4vL
…locally load_data() reads the recorded CSVs from `js.csvArray` (the worker sets self.csvArray before running it), but the `js` module was never imported in that scope — a prior worker refactor dropped the global import that used to make it available. In Pyodide, `js` must be explicitly imported. Import it locally inside the `csv_strings is None` guard so the native-MNE tests, which pass csv_strings, never touch the Pyodide-only module. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SNEh5EFg4dSpRrfJ2ae4vL
raw_epochs.plot(..., events=None) raised "events must be an instance of bool or ndarray, got None" — MNE 1.x validates the events arg; False is the no-events-overlaid default. Also close the returned Figure so the worker's PyProxy→JS conversion doesn't try to structuredClone it back (DataCloneError); this clean plot isn't routed to the UI. Same MNE-1.x-API-tightening class as the plot_psd → compute_psd fix. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SNEh5EFg4dSpRrfJ2ae4vL
09aab1a to
b109fa5
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Background
Harvests the still-valid fixes from the stale #194 (pyodide-fix) and re-applies them onto current
main. #194 itself isn't mergeable: it was built on a superseded asset-serving base (HTTP server on :17173) thatmainreplaced with thepyodide://protocol, and it predates thebuildMarkerRegistrymarker-code fix (itsloadEpochsEpicreverted to the broken 0-based event map). So this takes the logic, not the commits, and keepsbuildMarkerRegistryintact. #194 can be closed once this lands.The bug
The Clean/analysis pipeline crashed with
getEpochsInfoEpic: Cannot read properties of undefined (reading 'map'). Root cause:requestEpochsInfo/requestChannelInforelied onworker.postMessagereturning data — nativepostMessagereturnsundefined; results actually come back on the message channel. Pre-existing, identical on the oldmain.Fixes
plotKey): the worker echoesdataKeyand converts the PyProxy result to plain JS (structuredClonecan't clone a PyProxy).pyodideMessageEpicroutesepochsInfo → SetEpochInfo,channelInfo → SetChannelInfo. The two info epics +loadEpochsEpicare now fire-and-forget.fs:readFileAsBytesIPC +writeEpochsToMemfsstage.fiffiles in Pyodide's WASM FS (it can't read host OS paths).raw.plot_psd()→raw.compute_psd().plot()(MNE 1.2+ removedplot_psd).plotTopoMap, notplotTestPlot.epochsInfo.length > 0(not only when the data looked bad,drop >= 2).src/renderer/utils/pyodide/**(pyodide.asm.jspegged the linter). Drops now-unusedDEVICES/plotTestPlot/parseSingleQuoteJSONimports.Kept
buildMarkerRegistryinloadEpochsEpic— #194 would have reverted it.Skipped from #194: channel-index-0 fix (current
loadERPEpicalready handles 0 post-Emotiv-removal),saveEpochsparen (already closed onmain), Prettier-only churn.Test plan
npm run typecheckcleannpm run lintcompletes (no hang — the pyodide ignore)npm test— 29/29 pass-cleaned-epo.fifsaved; Analyze → topo (SVG) + PSD render; channel selector incl. first channel renders ERP.🤖 Generated with Claude Code