CI Docs Health Release Drafter
A desktop application for annotating Deep Brain Stimulation (DBS) programming sessions. Built for clinicians and researchers working with DBS systems.
Publisher: Wyss Center for Bio and Neuroengineering (contact: lucia.poma@wysscenter.ch)
You can find installation files for Windows (.msi), MacOS (.dmg) and Linux (.deb) under the GitHub Releases. However, note that the files are unsigned, so that a warning might pop up during installation. To proceed with installation, you must accept the risk and continue. In some cases, for example where your organization has strict settings, this might not be possible. In this case, try the install via PowerShell below.
In an open PowerShell window:
irm https://raw.githubusercontent.com/Brain-Modulation-Lab/DBSAnnotator/main/scripts/install.ps1 | iexFrom cmd.exe (or if execution policy blocks scripts):
powershell -ExecutionPolicy Bypass -NoProfile -Command "irm https://raw.githubusercontent.com/Brain-Modulation-Lab/DBSAnnotator/main/scripts/install.ps1 | iex"curl -LsSf https://raw.githubusercontent.com/Brain-Modulation-Lab/DBSAnnotator/main/scripts/install.sh | shwget -qO- https://raw.githubusercontent.com/Brain-Modulation-Lab/DBSAnnotator/main/scripts/install.sh | shThe application guides you through a DBS programming session in three steps:
- Initial Setup — Select output file, electrode model, initial stimulation parameters, and baseline clinical scales
- Session Scales — Choose which scales to track during the session (Mood, Anxiety, Energy, etc.)
- Active Recording — Adjust stimulation parameters in real-time, record scale values at each timepoint, add notes, and export a clinical report
There is also a Free Annotations mode for quick timestamped text annotations without the full stimulation workflow.
- Electrode visualization with interactive contact selection (supports directional leads)
- Clinical scale presets for OCD, MDD, PD, ET
- BIDS-compliant file naming (sub-XX_ses-YYYYMMDD_task-programming_run-XX_events.tsv)
- Export to Word with electrode configuration images, clinical notes, and session data tables
- Dark/Light theme toggle
- Timestamps aligned with Medtronic Percept data (Eastern Time)
Data is saved as TSV. The canonical schema is documented in
[docs/output_format.rst](docs/output_format.rst) and auto-generated from the
code-level constants in dbs_annotator.config to prevent drift.
We welcome contributions! Please see the Contributing Guide for detailed guidelines on:
- Bug reports and feature requests
- Code contributions and pull requests
- Development setup and testing
- Community guidelines
- Fork the repository
- Create a feature branch
- Make your changes following PEP 8
- Add tests for new functionality
- Submit a pull request
- Python 3.12+ (see
requires-pythoninpyproject.toml) - uv (recommended) or pip
cd DBSAnnotator
# With uv (recommended)
uv sync
# Install git hooks (pre-commit runs with pre-commit-uv from dev dependencies)
uv run pre-commit install
# Or with pip
pip install -e .python -m dbs_annotator
# or, once the project is installed, the console script
dbs-annotatorDBSAnnotator/
├── src/dbs_annotator/ # Application source code
│ ├── models/ # Data models (session, scales, stimulation, electrode)
│ ├── views/ # Qt views (step0-3, annotations, wizard window)
│ ├── controllers/ # Business logic (wizard controller)
│ ├── ui/ # Reusable UI widgets and dialogs
│ ├── utils/ # Utilities (export, themes, responsive, resources)
│ ├── config.py # App configuration and constants
│ └── config_electrode_models.py # Electrode model definitions
├── styles/ # QSS theme files (Briefcase + dev; see resource_path)
├── icons/ # Application icons (e.g. logosimple/ bundle)
├── scripts/ # Utility scripts
└── pyproject.toml # Project configuration and dependencies
Architecture follows the Model-View-Controller (MVC) pattern.
Briefcase turns this repo into platform-native bundles and installers. The GUI stack is PySide6 (Qt); the packaged entrypoint is python -m dbs_annotator via src/dbs_annotator/__main__.py.
Install tooling (once per machine):
- Windows: WiX Toolset is required only if you build MSI installers (
briefcase package windowsdefaults to MSI). For CI and quick artifacts, use ZIP packaging instead (no WiX):briefcase package windows -p zip. - macOS: Xcode Command Line Tools (
xcode-select --install). For DMG output, Briefcase pullsdmgbuildvia dependencies.
Typical local flow:
uv sync --locked --dev --group build
uv export --locked --format requirements.txt --no-dev --no-hashes --no-emit-project --no-emit-workspace --output-file constraints-briefcase.txt
# First-time / after config changes — pick platform + format (examples):
uv run briefcase create macOS app
uv run briefcase build macOS app
uv run briefcase package macOS -p dmg
uv run briefcase create windows app
uv run briefcase build windows app
uv run briefcase package windows -p zip # avoids WiX; omit -p (MSI) when WiX is installedmacOS builds on Apple Silicon produce arm64 artifacts when universal_build = false is set under [tool.briefcase.app.dbs_annotator.macOS] in pyproject.toml.
Windows Briefcase quirks: keep [tool.briefcase].version in sync with dbs_annotator.__version__ (Briefcase does not use Hatch’s dynamic [project] version). Bump both in one step with uv run python scripts/release_prepare.py <version> (or --bump …). If briefcase build fails at “Setting stub app details” / RCEdit with “Unable to commit changes”, exclude the repo or build\ from real-time antivirus scanning and retry (see Briefcase issue #1530).
The Windows stub binary is named **DBSAnnotator.exe** (from [tool.briefcase.app.dbs_annotator].formal_name). After changing that field, run **briefcase create windows app** again (or delete build\dbs_annotator\windows) before **briefcase build**.
Icons for the stub, MSI/ZIP, and Qt (QApplication / window chrome) live under **icons/logosimple/: **logosimple.ico**, **logosimple.png**, plus **logosimple-{16,32,64,128,256,512}.png** for Linux system (BeeWare copies them into the Freedesktop hicolor tree; all six are listed in the upstream briefcase-linux-system-template). **logosimple.icns is for macOS (build with iconutil on a Mac; see scripts/build_app_icons.py). Configure with icon = "icons/logosimple/logosimple" in pyproject.toml. The repo-root **icons/** tree is a Briefcase **sources** entry and is shipped next to the app package; runtime lookup uses resource_path() (package dir, then src/icons, then repo-root icons/).
Inventory (for packaging):
| Area | Notes |
|---|---|
| App type | Qt GUI (console_app is false by default). |
| Heavy deps | PySide6, matplotlib, pandas, python-docx, docx2pdf (Windows: pywin32; macOS: appscript via docx2pdf). |
| Data files | JSON presets under src/dbs_annotator/config/; QSS and SVG under repo-root **styles/** (also a Briefcase **sources** entry); app icons under **icons/logosimple/** (Briefcase + Qt). |
| macOS entitlements | Add an entitlements plist only if you enable the Hardened Runtime and need extra capabilities (network is usually fine without custom entitlements). |
Signing is not wired in CI by default; release engineers use local or protected-runner secrets.
macOS (Developer ID + notarization):
- Sign the
.app(and DMG/PKG if applicable) with your Developer ID Application identity. - Submit with
xcrun notarytool(App Store Connect API key) and staple the ticket withxcrun stapler staple. - Apple’s overview: Developer ID, Packaging Mac software for distribution.
Windows (Authenticode):
- Sign the installer and/or binaries with signtool and your code-signing certificate (EV certificates accumulate SmartScreen reputation faster than OV-only setups).
- Briefcase documents Windows signing flags (
--cert-store,--timestamp-url, etc.) in the Windows platform reference.
GitHub Actions secrets (when you automate signing):
| Secret | Purpose |
|---|---|
WINDOWS_SIGN_PFX_BASE64 |
Base64-encoded PFX certificate used by signtool in release.yml |
WINDOWS_SIGN_PFX_PASSWORD |
Password for the PFX above |
APPLE_IDENTITY |
Developer ID identity name for codesign |
APPLE_API_ISSUER |
App Store Connect issuer for notarytool |
APPLE_API_KEY_ID |
App Store Connect key id for notarytool |
APPLE_API_KEY |
Contents of the .p8 key file (stored as secret text) |
Test release workflow before tagging:
- Open Actions and run
CD - Create GitHub Releasemanually (workflow_dispatch). - Set
publish_release=falseto build and upload artifacts without creating a release. - Optionally set
sign_artifacts=trueto validate signing gates; leave itfalseif secrets are not configured yet.
pytestThis project uses uv for dependency locking, security auditing, and update automation.
- Audit vulnerabilities locally:
uv audit - Upgrade all locked dependencies:
uv lock --upgrade - Upgrade one dependency:
uv lock --upgrade-package <package> - Re-sync after lock changes:
uv sync --locked --dev --group build
To reduce supply-chain risk from very new releases, dependency resolution is configured with:
pyproject.toml->[tool.uv] exclude-newer = "1 week"
In CI/automation:
CI - Lint and Type Checkrunsuv auditon each push/PR.- Dependabot updates the
uv.lockecosystem weekly with a 7-day cooldown before opening update PRs.
MIT License — see LICENSE for details.
Wyss Center for Bio and Neuroengineering — lucia.poma@wysscenter.ch