Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ on:

permissions:
contents: write
id-token: write

jobs:
build:
Expand Down Expand Up @@ -71,10 +72,59 @@ jobs:
```
Requires MATLAB R2022a+. See [DEPLOY.md](matlab/DEPLOY.md) for details.

**Python:** Install from PyPI:
```bash
pip install seqeyes-python
```

## Changes

See [commits since last release](https://github.com/${{ github.repository }}/compare/${{ github.event.before }}...${{ github.ref_name }}).
files: |
seqeyes-web.vsix
seqeyes-*.mltbx
python/dist/*
generate_release_notes: true

python-build:
name: Build Python package
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
cache: pip
cache-dependency-path: python/pyproject.toml

- name: Install build tools
run: |
python -m pip install --upgrade pip
pip install build

- name: Build wheel and sdist
run: cd python && python -m build

- name: Upload Python artifacts
uses: actions/upload-artifact@v4
with:
name: seqeyes-python-dist
path: python/dist/*

publish-pypi:
name: Publish to PyPI
needs: python-build
runs-on: ubuntu-latest
if: startsWith(github.ref, 'refs/tags/v')
steps:
- name: Download Python artifacts
uses: actions/download-artifact@v4
with:
name: seqeyes-python-dist
path: dist/

- name: Publish to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
45 changes: 45 additions & 0 deletions .github/workflows/python-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: Python Package Tests

on:
pull_request:
branches: [main, master]
push:
branches: [main, master, 'feature/**', 'fix/**']
workflow_dispatch:

jobs:
test:
name: Python ${{ matrix.python-version }}
runs-on: ubuntu-latest
timeout-minutes: 15
strategy:
fail-fast: false
matrix:
python-version: ['3.10', '3.11', '3.12']

steps:
- name: Checkout
uses: actions/checkout@v5

- name: Setup Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: pip
cache-dependency-path: python/pyproject.toml

- name: Install package with test dependencies
run: |
python -m pip install --upgrade pip
pip install -e "./python[test,pypulseq]"

- name: Run tests
run: python -m pytest python/tests/ -v

- name: Upload test results
uses: actions/upload-artifact@v5
if: ${{ !cancelled() }}
with:
name: python-test-results-py${{ matrix.python-version }}
path: python/.pytest_results/
retention-days: 14
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@ dist/
*.mltbx
*.asc
.vscode-test/
.vscode/
test-results/
playwright-report/
performance-results/
matlab/pulseq-bundle.js
.DS_Store
__pycache__/
.pytest_cache/
30 changes: 0 additions & 30 deletions .vscode/launch.json

This file was deleted.

24 changes: 0 additions & 24 deletions .vscode/tasks.json

This file was deleted.

35 changes: 35 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,41 @@ open('spiral_inout.seq') % or double‑click in Current Folder

All the same features as the browser & VS Code versions — 7 channels, k‑space viewer, themes, tooltips — rendered inside a native MATLAB figure. Requires R2022a+.

## 🐍 Python Package

Interactive Pulseq sequence viewer for Jupyter notebooks and Python scripts — a drop‑in replacement for `pypulseq.Sequence.plot()`. Renders directly in notebook cell output or opens in your default browser.

### Install

```bash
pip install seqeyes-python
```

For pypulseq integration:

```bash
pip install seqeyes-python[pypulseq]
```

### Usage

```python
import seqeyes

# Enable SeqEyes (once per session) — seq.plot() is now interactive
seqeyes.set(theme="dark", time_disp="ms")

# Build your sequence with pypulseq as usual
seq.plot() # interactive viewer in Jupyter
seq.plot(show_blocks=True) # per‑call overrides
seq.plot(time_range=(0, 0.05)) # zoom to first 50 ms

# Restore matplotlib at any time
seqeyes.reset()
```

All the same features as the other versions — interactive waveforms, k‑space viewer, themes, tooltips — rendered directly in Jupyter or your browser. Requires Python ≥ 3.9.

## Features

- **Custom editor for `.seq` files** — opens automatically on double‑click
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "seqeyes-web",
"displayName": "SeqEyes",
"description": "Visualize Pulseq MRI sequences inside VS Code — inspect sequence diagrams, k-space trajectorieswith interactive user interface.",
"version": "0.1.17",
"version": "0.2.0",
"publisher": "SeqEyesDeveloper",
"license": "MIT",
"icon": "images/logo.png",
Expand Down
94 changes: 94 additions & 0 deletions python/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# SeqEyes — Interactive Pulseq MRI Sequence Viewer for Python

**SeqEyes** is a lightweight Python package that provides interactive
visualization of Pulseq (.seq) MRI sequences in Jupyter notebooks.
It works as a drop‑in replacement for `pypulseq.Sequence.plot()`,
rendering an interactive viewer directly in Jupyter notebook cell
output — just like Plotly.

## Features

- 🎛️ **Interactive waveform viewer** — zoom, pan, per‑channel amplitude zoom
- 📍 **Tooltip** with block details (RF amplitude, gradient strength, ADC params)
- 🗺️ **3D k‑space trajectory viewer** — rotate, zoom, depth‑sorted rendering
- 🎨 **8 colour themes** — system, light, dark, dracula, nord, and more
- 📏 **Unit conversion** — time (s / ms / µs), gradient (Hz/m / mT/m / G/cm)
- 📐 **Minimap** with TR/TE overlay and viewport indicator
- 💾 **Export to standalone HTML** — shareable, no Python needed
- 🔌 **Drop‑in pypulseq integration** — `seq.plot()` just works

## Installation

```bash
pip install seqeyes-python
```

For pypulseq integration:
```bash
pip install seqeyes-python[pypulseq]
```

## Quick Start

```python
import seqeyes

# Enable SeqEyes (once per session) — seq.plot() is now interactive
seqeyes.set(theme="dark", time_disp="ms")

# Build your sequence with pypulseq as usual
seq.plot() # interactive viewer in Jupyter
seq.plot(show_blocks=True) # per‑call overrides
seq.plot(time_range=(0, 0.05)) # zoom to first 50 ms

# Restore matplotlib at any time
seqeyes.reset()
```

In a plain `.py` script (no Jupyter), `seq.plot()` opens the viewer
in a desktop pop‑up window (requires `pywebview`) or falls back to
your default browser.

### Using without pypulseq

```python
from seqeyes import SeqEyesViewer

with open('my_sequence.seq') as f:
viewer = SeqEyesViewer(f.read(), theme="dark")

viewer # renders inline in Jupyter
```

## API Reference

| Function | Description |
|---|---|
| `seqeyes.set(**kwargs)` | Enable SeqEyes and set global defaults (`theme`, `show_blocks`, `time_disp`, `grad_disp`, `time_range`) |
| `seqeyes.reset()` | Restore matplotlib `seq.plot()` and clear all defaults |
| `SeqEyesViewer(seq_text, ...)` | Low‑level viewer for raw `.seq` content (no pypulseq needed) |

## Viewer Controls

| Action | How |
|---|---|
| Zoom | Scroll wheel |
| Pan | Click + drag |
| Amplitude zoom (per channel) | Ctrl + scroll wheel |
| Tooltip | Hover over waveform |
| Toggle channels | Click legend labels |
| K‑Space viewer | Click "K‑Space" button |
| Rotate k‑space | Click + drag in panel |
| Minimap navigation | Click on minimap strip |
| Open another file | 📂 Open button |

## Requirements

- Python ≥ 3.9
- numpy ≥ 1.21
- pypulseq ≥ 1.4 (optional, for `seq.plot()` integration)
- pywebview ≥ 5 (optional, for native desktop pop‑up windows)

## License

MIT
Loading
Loading