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
5 changes: 5 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
New public widgets and shared-helper refactors need an issue or maintainer
discussion first. Bug fixes and features that stay inside one existing widget
can open a pull request directly. See
[pull request classes](https://github.com/electronmicroscopy/quantem.widget/blob/main/docs/maintainer/pull-requests.md).

### What problem does it solve?

<!--
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ new `rcN` heading when that rc is published to TestPyPI.

## Unreleased

- Maintainer docs split pull requests into discuss-first (new widgets,
cross-widget refactors) and incremental in-widget fixes, and add a
`widget-tutorials/` upload page for the public
[bobleesj/quantem-data](https://huggingface.co/datasets/bobleesj/quantem-data)
dataset. A copyable agent prompt opens that Hugging Face Community
pull request after `python -m check_meta` prints `ok`.
- Installation, Colab tutorial cells, and the verify snippet now install the
TestPyPI wheel and import `load` from `quantem.gpu.io`. `quantem
showdiffraction --demo` is documented as needing the public Fe3O4 hub folder,
Expand Down
13 changes: 13 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,19 @@ Use one small branch for one issue or documentation goal. Describe the user
problem before the implementation, and keep unrelated experiments or cleanup
out of the branch.

Adding a new widget, or a refactor that other widgets will import, starts with
an issue or a maintainer discussion. A bug fix or a feature that stays inside
one existing widget can go straight to a pull request. The two classes are in
the [pull request guide](docs/maintainer/pull-requests.md).

Tutorial fixtures for notebooks belong under `widget-tutorials/` in the public
[bobleesj/quantem-data](https://huggingface.co/datasets/bobleesj/quantem-data)
dataset. Upload and download commands are on that dataset card. A coding
agent can open the Hugging Face Community pull request with the prompt in
[Agent-assisted development](docs/agent-prompts.md#add-tutorial-data-hugging-face-pull-request).
The GitHub loader pull request is in
[Contribute tutorial data](docs/tutorials/contribute_data.md).

Once review begins, do not force-push. Add follow-up commits so GitHub preserves
inline comments and the reviewer can inspect only the changes since their last
visit. The project squash-merges completed work.
Expand Down
4 changes: 4 additions & 0 deletions docs/_toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ parts:
- caption: Tutorials
chapters:
- file: tutorials/download_data
- file: tutorials/contribute_data
title: Contribute tutorial data
- file: tutorials/show4dstem
sections:
- file: tutorials/show4dstem_single
Expand Down Expand Up @@ -88,6 +90,8 @@ parts:
- file: maintainer/index
title: Maintainer guide
sections:
- file: maintainer/pull-requests
title: Pull requests
- file: maintainer/docs-design
title: Docs design rules
- file: changelog
Expand Down
69 changes: 63 additions & 6 deletions docs/agent-prompts.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,15 @@ Prepare a focused quantem.widget pull request for:

<issue URL or concise goal>

First read AGENTS.md, CONTRIBUTING.md, the pull-request template, and any
instructions nearest the changed files. Inspect the worktree, branches, and
remotes; preserve unrelated user changes. Fetch the authoritative upstream
main branch before comparing or creating the feature branch. Follow the
repository's branch-naming rules; if none are present, use a short creation-date
prefix such as aug-8-show2d-contrast.
First read CONTRIBUTING.md, docs/maintainer/pull-requests.md, the
pull-request template, and any instructions nearest the changed files.
New public widgets and cross-widget refactors need an issue or maintainer
discussion first. In-widget bug fixes and features do not.

Inspect the worktree, branches, and remotes; preserve unrelated user changes.
Fetch the authoritative upstream main branch before you compare or create the
feature branch. Follow the repository's branch-naming rules; if none are
present, use a short creation-date prefix such as aug-8-show2d-contrast.

Keep one scientific or documentation goal in the PR. Stage named files only.
Exclude private data, machine-specific paths, notebook outputs, generated HTML,
Expand All @@ -122,3 +125,57 @@ Preserve my configured Git identity and do not add a Co-authored-by trailer.

When publication is approved, push to the contributor's fork and let the human
open the upstream PR unless they explicitly ask the agent to do that step.

## Add tutorial data (Hugging Face pull request)

Use this when a scientist has files that should become a public
`widget-tutorials/` fixture. The pull request is on Hugging Face, not
GitHub. Do not paste the Hugging Face token into this prompt.

```text
Add these files to the public Hugging Face dataset bobleesj/quantem-data
as a Community pull request.

Local folder:
<absolute path to a folder that already contains the data file(s) and will
get meta.json>

Target hub path:
widget-tutorials/<widget-or-shared>/<name>/<size>/

Permission (required; do not invent):
- I collected this data myself: <yes/no>
- permission.from: <name or list>
- permission.collectors: <name or list>
- permission.date: <YYYY-MM-DD>
- I have written permission from the collector: <yes, or "I collected it">

Read https://huggingface.co/datasets/bobleesj/quantem-data (dataset card).
Do not use quantem.widget.io.upload. Do not commit .npy or .emd into
electronmicroscopy/quantem.widget.

1. Confirm hf auth whoami prints a username. If it fails, stop and ask me
to create a Write token at huggingface.co/settings/tokens and either
run `hf auth login` (paste token, answer n to git credential) or
`export HF_TOKEN=...`. Do not run interactive hf auth login yourself.
Do not write the token into a file in any git repo.
2. Copy templates/meta.json. Fill name, source, date, sample, shape,
dtype, and permission from the files and from the permission lines
above. Read shape and dtype from the array or EMD. Omit sampling,
units, and optics if unknown. Do not invent a number.
3. Download check_meta/ from bobleesj/quantem-data (add --revision
refs/pr/N if that folder is not on main yet). Run
`python -m check_meta <folder>`. Stop if it is not ok.
4. Run:
hf upload bobleesj/quantem-data <folder> \
widget-tutorials/<widget-or-shared>/<name>/<size> \
--repo-type dataset --create-pr \
--commit-message "add <widget> <name> <size> tutorial data"
5. Give me the Community URL. Do not merge. Do not open a GitHub pull
request unless I also need a named loader in
quantem.widget.datasets (that GitHub PR waits until this HF PR
merges). A new widget is discuss-first.
```

See [Contribute tutorial data](tutorials/contribute_data.md) and
[Pull requests](maintainer/pull-requests.md).
17 changes: 13 additions & 4 deletions docs/api/datasets.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,13 @@ widget = Show1D.from_example("ducky", size="small")
widget
```

The public Hugging Face dataset is organized under `widget-tutorials/`. Reused
sources live once under `shared/`; widget-specific monitor runs or session
folders live under the widget name.
The public Hugging Face dataset
([bobleesj/quantem-data](https://huggingface.co/datasets/bobleesj/quantem-data))
is organized under `widget-tutorials/`. Reused sources live once under
`shared/`; widget-specific monitor runs or session folders live under the
widget name. Upload and download commands are on that dataset card. The
GitHub loader pull request is in
[Contribute tutorial data](../tutorials/contribute_data.md).

```text
widget-tutorials/{widget-or-shared}/{example}/{size}/...
Expand All @@ -66,10 +70,15 @@ widget-tutorials/show1d/ducky/small/show1d_monitor.jsonl
widget-tutorials/show1d/ducky/small/snapshots/*.npy
widget-tutorials/shared/gold-haadf/full/data.npy
widget-tutorials/show4dstem/gold-128-bin8/full/data.npy
widget-tutorials/showdiffraction/fe3o4-saed/small/data.npy
widget-tutorials/show4dstem/gold-512-bin4/full/data.npy
widget-tutorials/show4dstem/gold-512-bin8/full/data.npy
widget-tutorials/showfolder/gold-haadf-session/small/*.emd
```

`showdiffraction_fe3o4()` expects
`widget-tutorials/showdiffraction/fe3o4-saed/small/data.npy`. That folder is
not in the current hub snapshot.

This keeps widget tutorial payloads grouped together instead of placing many
example files at the top level of the shared dataset repository. `show2d_gold`
and `show3d_gold` intentionally share `widget-tutorials/shared/gold-haadf/full`
Expand Down
31 changes: 19 additions & 12 deletions docs/api/io.md
Original file line number Diff line number Diff line change
Expand Up @@ -570,33 +570,40 @@ owns it. Shut down that kernel from JupyterLab or stop the Python process.

The shared Hugging Face dataset repo
([bobleesj/quantem-data](https://huggingface.co/datasets/bobleesj/quantem-data),
MIT license) is the one place tutorial and reference data lives — its dataset
card intentionally holds no instructions and points back to this page. The
upload protocol is three steps:
MIT license) is the one place tutorial and reference data lives. Upload and
download commands, including Hugging Face pull requests, are on that dataset
card. This section is the `quantem.widget.io` helper reference for
maintainers who already have write access. The upload steps are:

1. **Install the hub extra and log in once.** Uploading needs a Hugging Face
account and a write token from
[huggingface.co/settings/tokens](https://huggingface.co/settings/tokens):

```bash
pip install "quantem.widget[hub]"
hf auth login # paste the write token
hf auth login # paste a Write token; answer n to git credential
```

Token steps for a Community pull request (no write access) are on the
dataset card. A Read token cannot open a PR. Ignore any hint to run
`git config --global credential.helper store`.

2. **Upload with the bucket + sidecar convention.** The repo has two trees:

- `widget-tutorials/<widget>/<dataset>/<size>/` — the baseline tutorial
bundles behind `quantem.widget.datasets` (sizes `small`/`medium`/
`large`/`full`). To contribute a tutorial bundle, pass
`folder="widget-tutorials/<widget>"` and `name="<dataset>/full"`.
`large`/`full`). Contributors add these with a Hugging Face pull
request, not `quantem.widget.io.upload`. See
[Contribute tutorial data](../tutorials/contribute_data.md).
Datasets shared by several widgets (the gold HAADF feeds both Show2D
and Show3D) live under `widget-tutorials/shared/`.
- `4dstem/` and `haadf/` — full-size originals for power users. A folder
of Arina `*_master.h5` files goes under `4dstem/`, a single image file
under `haadf/` (those are also the defaults for a directory vs a file).

Always pass `meta=` so downstream widgets get calibration — it is written
as a `meta.json` sidecar next to your data:
For `4dstem/` and `haadf/`, pass `meta=` so the helper writes a
`quantem_meta.json` sidecar. Tutorial loaders read `meta.json` from the
staged `widget-tutorials/` folder instead:

```python
from quantem.widget.io import upload
Expand All @@ -610,10 +617,10 @@ upload protocol is three steps:
)
```

No write access to the shared repo? Either open an issue on
[quantem.widget](https://github.com/electronmicroscopy/quantem.widget/issues) to get
added, or pass `repo="you/your-data"` to use your own HF dataset repo with
the same layout — every download helper accepts the same `repo=` override.
Write access to `bobleesj/quantem-data` is for maintainers. Contributors
open a Hugging Face pull request on the dataset card, then a GitHub pull
request for the named loader
([Contribute tutorial data](../tutorials/contribute_data.md)).

3. **Verify like a user would.** List, download to a fresh path, and open it
in the widget before announcing the dataset:
Expand Down
7 changes: 6 additions & 1 deletion docs/developer/widget-creation.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Creating a widget

This guide shows how to add a new interactive viewer or tool to `quantem.widget`. Instructions for agentic-driven development are on the [Agent-assisted development](../agent-prompts) page, and the workflow for setup, test, and PRs is in [CONTRIBUTING.md](https://github.com/electronmicroscopy/quantem.widget/blob/main/CONTRIBUTING.md).
This guide shows how to add a new interactive viewer or tool to `quantem.widget`. A new widget needs an issue or maintainer discussion first ([Pull requests](../maintainer/pull-requests.md)). Instructions for agentic-driven development are on the [Agent-assisted development](../agent-prompts) page, and the workflow for setup, test, and incremental PRs is in [CONTRIBUTING.md](https://github.com/electronmicroscopy/quantem.widget/blob/main/CONTRIBUTING.md).

Let's use `Ruler2D` as an example, a widget where the user places two endpoints on a 2D image and reads back a calibrated distance.

Expand Down Expand Up @@ -31,6 +31,11 @@ Always edit the file in `quantem.gpu`, never the generated copy.

## Before you start

A new public widget is a discuss-first change. Open an issue or confirm with a
maintainer that the widget belongs in this package before choosing a base class
or writing React code. Incremental fixes and features that stay inside one
existing widget skip this step. See [Pull requests](../maintainer/pull-requests.md).

Before choosing a base class or writing React code, define what the widget is supposed to do.

For `Ruler2D`, the example would be that it accepts one 2D image, stores coordinates as `(row, col)` in the original image, allows two endpoints to be placed or dragged, and reports their calibrated distance.
Expand Down
4 changes: 4 additions & 0 deletions docs/install.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ pip install -i https://test.pypi.org/simple/ \
"quantem.widget[hub]"
```

Widget tutorial fixtures live under `widget-tutorials/` on
[bobleesj/quantem-data](https://huggingface.co/datasets/bobleesj/quantem-data).
Upload and download commands are on that dataset card.

## Google Colab

Each tutorial notebook can open directly in Colab from the badge at the top of
Expand Down
11 changes: 9 additions & 2 deletions docs/intro.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,5 +130,12 @@ https://doi.org/10.1093/mam/ozag053.941.

- **Questions or bugs:** open an issue at
[github.com/electronmicroscopy/quantem.widget/issues](https://github.com/electronmicroscopy/quantem.widget/issues).
- **Maintained by** the Ophus group. Contributions and feedback are welcome via
pull request or issue.
- **New widgets and cross-widget refactors:** discuss first (issue or
maintainer). In-widget bug fixes can open a pull request directly. See
[Pull requests](maintainer/pull-requests.md) and
[CONTRIBUTING.md](https://github.com/electronmicroscopy/quantem.widget/blob/main/CONTRIBUTING.md).
- **Tutorial data:** public
[bobleesj/quantem-data](https://huggingface.co/datasets/bobleesj/quantem-data).
Upload and download commands are on that dataset card. The GitHub loader
pull request is in [Contribute tutorial data](tutorials/contribute_data.md).
- **Maintained by** the Ophus group.
6 changes: 3 additions & 3 deletions docs/maintainer/index.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Maintainer guide

Release process, automation, signoff protocols, UI standards, storyboards, and
performance notes for quantem.widget maintainers. Day-to-day users do not need
this section; start with the tutorials instead.
Release process, pull-request classes, automation, signoff protocols, UI
standards, storyboards, and performance notes for quantem.widget maintainers.
Day-to-day users do not need this section; start with the tutorials instead.

```{tableofcontents}
```
53 changes: 53 additions & 0 deletions docs/maintainer/pull-requests.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Pull requests

This package has two pull-request classes. The first needs a discussion before
code. The second can open a pull request directly.

Delivery style (one theme per PR, self-review as a draft, quote replies, keep
follow-up ideas in a new issue) follows the
[Billinge group pull-request practices](https://scikit-package.github.io/scikit-package/programming-guides/billinge-group-standards.html#pull-request-practices).
The class rule below is the extra gate for widgets: not every change needs an
issue first.

## Discuss first

Open an issue, or confirm with a maintainer, before writing the pull request
when the change:

- adds a new public widget
- extracts shared helpers or refactors code that other widgets import
- changes a public API, the comm protocol, or the tutorial-data contract

Those changes have side effects on other viewers, docs, release registration,
and review load. The discussion decides whether the widget or abstraction
belongs in this package, and what the smallest first pull request is.

A new widget then follows [Creating a widget](../developer/widget-creation.md).

## Incremental (no prior discussion)

Open a pull request when the change stays inside one existing widget:

- a bug fix
- a control or option used only by that widget
- docs or tests for that widget

Keep the branch to one problem. Use the
[pull-request template](https://github.com/electronmicroscopy/quantem.widget/blob/main/.github/PULL_REQUEST_TEMPLATE.md).

## Shared delivery rules

- One scientific or documentation goal per pull request.
- Branch names use a short date prefix such as `aug-19-show2d-contrast`.
- Once review starts, add follow-up commits. Do not force-push. The project
squash-merges completed work.
- Put reviewer actions and verification evidence in the three visible template
sections. Keep the hidden checklist out of the rendered description.

Tutorial fixtures for notebooks live in the public Hugging Face dataset
[bobleesj/quantem-data](https://huggingface.co/datasets/bobleesj/quantem-data)
under `widget-tutorials/`. Upload and download commands are on that dataset
card. A coding agent opens that Community pull request with
[Add tutorial data](../agent-prompts.md#add-tutorial-data-hugging-face-pull-request).
The GitHub loader pull request is in
[Contribute tutorial data](../tutorials/contribute_data.md).
20 changes: 20 additions & 0 deletions docs/tutorials/contribute_data.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Contribute tutorial data

How to add files, including the Hugging Face token
(`hf auth login`):
[bobleesj/quantem-data](https://huggingface.co/datasets/bobleesj/quantem-data).
A coding agent can open that Community pull request. Copy the prompt
[Add tutorial data](../agent-prompts.md#add-tutorial-data-hugging-face-pull-request).
The human creates the Write token and attests permission. The agent runs
`hf upload ... --create-pr` after `python -m check_meta` prints `ok`.

After that Hugging Face PR is merged, open a GitHub PR here only if a
notebook should load the fixture by name:

- helper in `src/quantem/widget/data/tutorials.py`
- list it on [Tutorial Datasets](../api/datasets.md)
- use it in the tutorial
- link the Hugging Face PR

A new widget is discuss-first. See [Pull requests](../maintainer/pull-requests.md).
Do not commit `.npy` or `.emd` here. Do not call `quantem.widget.io.upload`.
Loading