Skip to content

feat: Add plate_row/col to PositionBase#269

Merged
tlambert03 merged 21 commits into
pymmcore-plus:mainfrom
tlambert03:only-plate-row-col
Mar 30, 2026
Merged

feat: Add plate_row/col to PositionBase#269
tlambert03 merged 21 commits into
pymmcore-plus:mainfrom
tlambert03:only-plate-row-col

Conversation

@tlambert03
Copy link
Copy Markdown
Member

this is a subset of #268

It pulls out the addition of plate_row/plate_col to PositionBase accepting only int | None (not strings), and doesn't do anything with naming for now... continuing to leave that concern to the downstream/application level

This also, renames Position row/col to grid_row/grid_col (with deprecated backwards compatible accessors) and removes the "excluded from serialization" flag that they used to have (i can't remember why I did that, but it was probably aesthetic and not well principled)

ieivanov and others added 20 commits March 24, 2026 12:56
Add serialized int fields to PositionBase for annotating which well a
position belongs to, enabling HCS zarr output from plain stage positions
without requiring WellPlatePlan. Also populate these fields in
WellPlatePlan.all_well_positions and selected_well_positions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add serialized int fields to PositionBase for annotating which well a
position belongs to, enabling HCS zarr output from plain stage positions
without requiring WellPlatePlan. Also populate these fields in
WellPlatePlan.all_well_positions and selected_well_positions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add a `name_pattern` field to `_GridPlan` that controls how grid
positions are named. Supports {row}, {col}, {idx} format variables.
Default is "{idx:04d}" (preserves backward compat). Names are now
generated in useq-schema so downstream consumers don't need to
override them.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- If name is None but plate_row/plate_col are set, auto-generate
  a well name using existing _index_to_row_name (e.g., 0,0 -> "A1")
- When iterating with a grid plan, compose pos_name as
  "{position_name}_{grid_name}" for plate positions (e.g., "A1_0000")
- Explicit names are never overwritten

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When plate_row and plate_col are set, the position name is always
derived from them (e.g., plate_row=0, plate_col=0 -> "A1"). Providing
an explicit name that doesn't match raises ValueError. This ensures
the position name and zarr well path are always coupled.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
plate_row accepts 0-based int (0 -> "A") or str ("A").
plate_col accepts 0-based int (0 -> "1") or str ("1").
The well name is derived accordingly and validated against
any explicit name provided.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…pos_name

26 new tests covering:
- Name auto-generation from int and str plate_row/plate_col
- Mismatched name validation (ValueError)
- JSON and YAML serialization round-trips
- Propagation through Position.__add__
- WellPlatePlan setting plate_row/plate_col on positions
- Grid name_pattern (default, custom, serialization)
- Composite MDAEvent.pos_name for plate positions with grid

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When plate_row and plate_col are both int (standard well-plate indices),
the name is strictly derived (e.g., 0,0 -> "A1") and mismatches raise
ValueError. When either is a str (custom naming like "fish0",
"neuromast0"), any explicit name is accepted, allowing free-form
naming for non-standard plate layouts.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Use inline isinstance checks instead of a variable so mypy can
narrow int|str to int within the branch.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@codecov
Copy link
Copy Markdown

codecov Bot commented Mar 30, 2026

Codecov Report

❌ Patch coverage is 84.61538% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 93.62%. Comparing base (867e9a1) to head (1f30ea4).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
src/useq/_position.py 84.00% 4 Missing ⚠️

❌ Your patch status has failed because the patch coverage (84.61%) is below the target coverage (85.00%). You can increase the patch coverage or adjust the target coverage.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #269      +/-   ##
==========================================
- Coverage   93.69%   93.62%   -0.07%     
==========================================
  Files          33       33              
  Lines        2568     2590      +22     
==========================================
+ Hits         2406     2425      +19     
- Misses        162      165       +3     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@tlambert03 tlambert03 merged commit 2462136 into pymmcore-plus:main Mar 30, 2026
20 of 21 checks passed
@tlambert03 tlambert03 deleted the only-plate-row-col branch March 30, 2026 13:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants