// Generate the gallery's pulseq example sources from a demoSeq batch-test run. // Reads scripts/demo-results.json (written by test-demos.mjs), and for every // demo that ran cleanly AND has a CATALOG entry that isn't already curated, // writes an adapted .m into src/examples/pulseq/.m. Also writes // src/examples/generated-timings.ts with a rough run-time label per example. // // node scripts/test-demos.mjs && node scripts/gen-examples.mjs import fs from 'node:fs' import path from 'node:path' import { fileURLToPath } from 'node:url' import { adaptDemo } from './test-demos.mjs' import { CATALOG } from '../src/examples/catalog.ts' const here = path.dirname(fileURLToPath(import.meta.url)) const repoRoot = path.join(here, '..') const demoDir = process.env.PULSEQ_DEMO_DIR ?? path.resolve(repoRoot, '../../pulseq/matlab/demoSeq') const outDir = path.join(repoRoot, 'src', 'examples', 'pulseq') // Sequences hand-curated in src/examples/*.m — never auto-generate these. const CURATED = new Set(['fid', 'epi', 'gre']) function demoToId(file) { return file.replace(/^write_?/, '').replace(/\.m$/, '') } function approxLabel(ms) { const s = ms / 1000 if (s < 1.5) return '~1 s' if (s < 3) return '~2 s' if (s < 8) return `~${Math.round(s)} s` if (s < 45) return `~${Math.round(s / 5) * 5} s` return '~1 min+' } const results = JSON.parse(fs.readFileSync(path.join(here, 'demo-results.json'), 'utf8')) fs.rmSync(outDir, { recursive: true, force: true }) fs.mkdirSync(outDir, { recursive: true }) // Timings for the curated examples (measured separately; gre has autoLabel off) const timings = { fid: '~1 s', epi: '~2 s', gre: '~5 s' } const written = [] for (const r of results) { const ok = r.ok && r.seqFiles?.length > 0 && r.seqFiles.every((s) => s.parseOk) if (!ok) continue const id = demoToId(r.demo) if (CURATED.has(id) || !(id in CATALOG)) continue const src = adaptDemo(fs.readFileSync(path.join(demoDir, r.demo), 'utf8')) fs.writeFileSync(path.join(outDir, `${id}.m`), src) timings[id] = approxLabel(r.elapsedMs) written.push(id) } const tsBody = '// AUTO-GENERATED by scripts/gen-examples.mjs — do not edit.\n' + '// Rough in-browser run-time labels per example id.\n' + 'export const TIMINGS: Record = ' + JSON.stringify(timings, null, 2) + '\n' fs.writeFileSync(path.join(repoRoot, 'src', 'examples', 'generated-timings.ts'), tsBody) console.log(`generated ${written.length} example sources:`, written.join(', ')) console.log('timings ->', JSON.stringify(timings))