fix: assign fov names for plate positions with grid_plan#136
Conversation
When stage_positions have plate_row/plate_col but no explicit name, generate fov-indexed names consistent with WellPlatePlan: - With grid: fov0, fov1, ... per grid point within each well - Without grid: fov0 (single FOV per well) - Explicit names are always preserved Closes pymmcore-plus#131 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #136 +/- ##
==========================================
- Coverage 97.63% 97.52% -0.11%
==========================================
Files 21 21
Lines 2534 2630 +96
==========================================
+ Hits 2474 2565 +91
- Misses 60 65 +5 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Extract _grid_position_name helper that centralizes all position naming:
- Explicit user name (with RandomPoints suffix when needed)
- fov{index} for plate positions
- str(position_index) fallback
_pos_with_grid_point now only handles coordinate merging.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
_grid_position_name now checks pos.plate_row/plate_col directly instead of taking a pre-computed has_plate flag. Same for the no-grid branch in _build_stage_positions_plan. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Use _grid_position_name for both grid-expanded and standalone positions, eliminating duplicated naming logic. Update docstring with full parameter docs and examples. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
@tlambert03 I think I'm happy with this PR. To clarify again in my own words, this PR fixes the bug described in #131 and organizes the naming logic for positions with grid in P.S. Not sure why that test fails, it's not related to the work in this PR I think |
|
But to me honest, the issue is still complicated and a bit confusing to me. For example, useq.WellPlatePlan names positions generates position names like I still think it would be cleanest if naming logic lives in useq - once a name is set by the user or assigned based on some logic, it should not be changed. This is what I has started in pymmcore-plus/useq-schema#268, but maybe that went a little too far. Let me know what you think here. One clean option may be to remove auto-naming from useq, and handle that in pymmcore-plus and ome-writers as these may have different naming requirements. For example, in pymmcore-plus we may chose to set event.pos_name to |
|
thanks for this! I think my main question here would be how you intend to use this name. Would you be "depending" on the specifics of the name format to, for example, parse the name to extract grid information? Or is the goal here just to give a name that is better than we currently have, for visual/human consumption, but not as an implicit API contract? if it's the former – if we're establishing a naming format that downstream code could parse to recover indices, then I would be a bit worried. I don't think name should be load bearing for things like grid position. That said, I don't mind just populating it to something better-than-nothing as a visual aid. if you do need the index programmatically, and if the coordinateTransform added in #134 is insufficient (and indeed it doesn't store actual grid indices), then maybe we should discuss establishing a new field in the metadata somewhere? |
|
Sorry, I think I took the discussion off-course. I think we should merge this PR - it fixes a bug in the writer, which is currently preventing us from acquiring data with the latest codebase, and adheres to the current naming standards. I'll open a separate issue where we can discuss Position naming more broadly. |
|
ok, I'm happy to merge this, but I want to be clear on why: In other words, if you ever find yourself parsing position names written by ome-writers to get at things like |
|
Thanks! Just opened pymmcore-plus/useq-schema#272. I absolutely agree with you that our code shouldn't bake in metadata in the position names. I also think that if the user choses to assign a position name that carries information to them, we should allow for that. I think you'd agree with me on that. In pymmcore-plus/useq-schema#272 I explain how that's currently not the case. I also think that if the user doesn't provide a position name and we need to pick one - for display in logs / UI or when writing data to disk, it helpful (not required) if we pick something meaningful. In pymmcore-plus/useq-schema#272 I explain how it's currently hard for us to monitor acquisition progress from logs as the position names don't carry through. It would be nice to get something like "Imaging position A1_0000" for example. Both of these use cases are largely separate from our discussion in #134. I am with you that we shouldn't encourage users to parse position names. |
100%, that's the only thing I want names to be. I know we are, in places, assigning position names when they are not previously user-assigned. my main thing is that I want to resist the urge to go any deeper in that pattern (i.e. i want us to, in general, avoid doing anything with position names except for simply passing through whatever the user names them). I know we're not strictly doing that just yet, I'm just trying to make sure we don't go deeper in the wrong direction. And yes, I agree that, in the absence of a user name, a better-than-nothing string is preferred! I'll have a look at the related useq-issues soon, thanks! |
Summary
stage_positionshaveplate_row/plate_colbut no explicitname, generate fov-indexed names consistent withWellPlatePlanconventionfov0,fov1, ... per wellfov0in its well_grid_position_namehelper;_pos_with_grid_pointnow only handles coordinate mergingCloses #131
Supersedes #135
What this does NOT change
"0","1", etc.)rp_g0000,rp_p0000_g0001, etc.)fov0,fov1, etc.)Test plan
plate_positions_with_global_grid— plate + grid, no names →fov0/fov1per wellplate_positions_no_grid— plate without grid, no names →fov0per wellplate_positions_with_explicit_names— user names preserved🤖 Generated with Claude Code