Skip to content

Target Selection: persist changes on save; lock fiducials outside Edit; restore timeline footer #641

Description

@peterhollender

Three bugs from smoke-testing SlicerOpenLIFU#640.

Bug 1: New target not persisted on Save

Root cause: mutating a nested field of the SlicerOpenLIFUPlanningSession parameter pack (planning_session.session.planning_session.targets = ...) does not automatically re-serialize the outer pack. The SlicerOpenLIFUPlanningSessionWrapper gets deserialized-on-read but never re-serialized-on-mutation.

The legacy OpenLIFUDataLogic.update_underlying_openlifu_session handles this by explicitly reassigning the outer field back to the parameter node after mutation:

parameter_node.loaded_session = session  # remember to write the updated session into the parameter node

My new OpenLIFUTargetSelectionLogic does not do the equivalent, so target additions / moves / renames vanish from the openlifu Session by the time save_loaded_session reads it, even though target_nodes (which uses a different serializer path) persists correctly.

Fix:

  • After every mutation, capture the wrapper, mutate the openlifu object, write the wrapper back to the pack, and then reassign the pack to the app state:

    wrapper = planning_session.session
    wrapper.planning_session.targets = new_target_points
    planning_session.session = wrapper
    get_app_state().loaded_planning_session = planning_session
  • Extract this into a _persist_planning_session_changes(planning_session) helper so every mutation goes through it and the pattern is documented in one place.

Bug 2: Placement + edit flow leaves fiducial draggable

Newly-placed target fiducials come out of slicer.mrmlScene.AddNewNodeByClass("vtkMRMLMarkupsFiducialNode") unlocked (Slicer default), so they stay draggable in 3D even after Add Target completes. And the Edit button on the page currently only toggles cell editability -- it doesn't lock / unlock fiducials at all.

Desired workflow (per user):

  1. Click Add Target → PLACE mode.
  2. Click in slice view (or type R / A / S values in the row cells) → target placed, page enters Edit mode focused on the new target.
  3. User drags the fiducial in slice / 3D views OR edits R / A / S cells to fine-tune.
  4. Click Done to commit (exits edit mode, all fiducials re-locked).

Editing an existing target: same, minus the placement step. User selects the row and clicks Edit.

Fix:

  • When entering edit mode: unlock the currently-selected fiducial (or if none selected, all stay locked). Lock all other targets.
  • On selection change while in edit mode: unlock the newly-selected, re-lock the previously-selected.
  • When exiting edit mode: lock all target fiducials.
  • After add_target_from_scene: rebuild the table, select the new row, toggle the Edit button ON. Edit button becomes "Done".
  • Table editTriggers follows the mode: NoEditTriggers when off, DoubleClicked | EditKeyPressed | AnyKeyPressed when on.

Optional (deferred): tint the focused fiducial's selected color to yellow while it's the edit-focus, restore its palette color on unfocus. Legacy Pre-Planning did this via a SlicerOpenLIFU.OriginalSelectedColor node attribute. Nice UX cue but not required.

Bug 3: Timeline footer not visible for the new workflow

PAGE_DEFS in host/page_registry.py currently has every page with on_timeline=False, so the timeline strip is hidden everywhere. As the workflow-timeline pages come online (Target Selection first, Virtual Fit / Solution Generator next), they should register on the timeline so the user can see progression and click circles to jump between reachable steps.

Fix:

  • Set OpenLIFUTargetSelection to on_timeline=True. Home / Data Manager / Session Overviews stay off-timeline (they're hubs / entry points, not linear workflow steps).
  • Verify the footer's timeline strip renders correctly with one item. The Next button hides itself (one-item timelines have no next step) -- this is expected and correct until Virtual Fit lands.
  • When Virtual Fit is added, it will also register on the timeline and the Next button becomes useful.

Acceptance

  1. Load a Planning Session → Overview → click Edit Targets… → Target Selection opens. Footer shows the timeline strip with a single "Target Selection" step highlighted.
  2. Click Add Target → click in a slice view → target is placed and locked in 3D (not draggable). Table row appears. Edit button is now labelled Done (edit mode entered). The new row's fiducial is now UNLOCKED and can be dragged.
  3. Drag the fiducial in the 2D or 3D view → R / A / S cells in the row update to match.
  4. Edit an R / A / S cell → fiducial moves to match.
  5. Click Done → edit mode exits, fiducial re-locks (can no longer be dragged). Button label returns to Edit.
  6. Select an existing target row, click Edit → same behaviour: that row's fiducial unlocks, others stay locked. Click Done → re-locks.
  7. Save via toolbar → target appears on disk in subjects/{subject_id}/planning_sessions/{ps_id}/{ps_id}.planning.json inside the openlifu Session's targets list.
  8. Data Manager and Planning Session Overview show the updated target count after save.

Relates to SlicerOpenLIFU#640, SlicerOpenLIFU#636, SlicerOpenLIFU#631.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions