Changes to the Markups Module

Several updates to the Markups module and the addition of a Markups toolbar were added in commit: ENH: Improve control point state management and add markups toolbar · Slicer/Slicer@09d12ae · GitHub and are available in the latest preview version.

The motivation for these changes was to add support for unplaced or missing control points. These states make it possible to create landmark templates for efficient placing of pre-named points, which is a common feature in other landmarking software. The position status can now be accessed and changed in the control points table of the Markups menu. Additionally, the number of control points in any markup node can now be locked, preventing the addition of new points and the deletion of named points.

While making these updates, we found that the current system of adding new points via the mouse mode menu made it difficult to tell which markup was being edited. To resolve this, a Markups toolbar was added to display/select the active markup node and provide access to several node properties without opening the Markups module.

In the Markups toolbar, the “Create new node and initiate placement” and the “Continue placement” functions have been explicitly separated, to prevent confusion about whether a new node would be created on entering placement mode. The “Place” button in the mouse mode toolbar is now replaced with a button that toggles the Markups toolbar (where new nodes can be created), when there are no active nodes that can accept more points in the scene.

Placement of annotation nodes is not included in the Markups toolbar. Previously, the placement of markups or annotation type nodes was not well distinguished, which was especially problematic as the Annotation nodes are a legacy type that are planned to be phased out. Creation of Annotation type nodes has been moved to the Annotation module to avoid confusion and so they will only be placed intentionally. A shortcut to the Annotation module has been added to the Markups toolbar to prompt the user and reduce the number of clicks needed to place a node.

The issues and fixes related to these changes are being tracked here, so please update with any feedback.

I made a short video demonstrating the new functionality of the Markups module and toolbar and related changes to creating legacy Annotations.

Many thanks to @lassoan, @muratmaga, @jamesobutler, @ezgimercan and others who helped and advised on these updates.


I’ve added a tutorial showing how the new options to create unplaced control points and lock the number of points in a node can be used to make templates for landmarking.

I have had trouble easily understanding the position status options in the markups control points context menu.

  • “Set position missing for highlighted fiducial(s)” → It is actually functioning as a toggle that Sets or Unsets the position missing. I see it toggling between different states in the last column of the table. Can it instead only do the action stated? “Unset position” for instance does not act as a toggle for unsetting/restoring position. It only unsets.

  • Upon quick reading “Unset position…” and “Set position…” based on their sentence structure they initially appear to be the opposites of each other however they are not. The latter is “Set position missing” which is an unrelated “Set” action. What do you think about the following rewording and reordering:

    • Restore position of highlighted fiducial(s)
    • Unset position of highlighted fiducial(s) ← or “Clear position…”
    • Edit position of highlighted fiducial(s)
    • Skip position of highlighted fiducial(s) ← Formerly “Set position missing…”

The above order also matches the order when cycling through the position status states in the last column of the table. Restore/complete → unset → edit → skip

“Unset” also sounds a bit technical compared to maybe “Clear”. Maybe Clear/Restore just seems like more natural pairs than Unset/Restore?

1 Like

These look good to me.

1 Like

Thank you @jamesobutler, I like your naming suggestions, too. The recommended order is better, too, but I think we should start with the Edit action (Edit, Skip, Restore, Clear), because Edit and Skip are the most commonly needed right-click menu actions (Restore is rarely needed and Clear is available by a single click on the state icon).

1 Like

Sure, I’m fine with it starting with edit as the top entry. So you agree with “Clear” instead of “Unset”? If so, I think that will be good to make it a bit less technical sounding.

I agree that “Clear position” sounds better than “Unset position”. Since the “clear” word is not used in markups for anything else, it should not be a problem to have a slight mismatch between the source code and GUI; and a bit less obvious match between set/unset operation names.

PR issued for this naming and reordering

The ‘Persistent’ option is no longer available.


Or I may have missed in the ‘Markups properties’ module.

This was very convenient when placing multiple fiducial points. Now we have to click on the fiducial icon in the toolbar every time.

Is it a deprecated function? If yes, is it definitively removed ? Or is it restorable for fiducial placement ?

Thank you.

It is there. It is now called “place multiple points” as persistence wasn’t a very clear term.

Ah, and there’s much more in the complete toolbar. Mine was truncated to the right.

When the markups toolbar is positioned in a second row, it shows up completely.

Thanks for the quick reply.

Yes, I think the length of the toolbar is one of @jamesobutler’s concerns.

In dark mode it is hard to see the toolbar expansion button. This button indicates that only a part of the toolbar is visible and when the button is clicked then the hidden part is displayed. We should adjust the color theme to make the button clearly visible.

The toolbar could be made somewhat smaller (at the cost of requiring more clicks to access functions on it), but the idea is that users would move it to a second toolbar row. I think we initialize the Sequence toolbar to be in the second row and probably we should do the same for this toolbar, too.

Thanks Sara and the team! This one feature I’ve been waiting for a very long time…

I’ve been using the updated module for a while now. I’ve integrated it into our workflow and it changed my landmarking experience a lot. I am mostly using it to mark a list of anatomical points on lots of skull CTs. I’ve created a “template” markups file with empty points and fill that out for every sample. It is much more efficient compared to my old method (of keeping a PDF file open for the order of points and naming them using Python scripts before saving).

I haven’t used it for other markup node types (curves, angles etc) yet but I am looking forward to. We have a couple projects starting that will use curves to mark regions, so this tool will definitely come handy.

One other thing, I am having trouble finding the function call for adding “undefined” points to a node through Python. And for some reason, my Slicer instance crashes when I try to autocomplete [fiducial node].logic.Add … methods. I’ve just started using preview version (just for this update) so I need to investigate if it’s because of these updates or something else.

There is room for improvement in terms of GUI but I am super happy with the functionality (also kinda suck at picking function/button names and designing icons).

1 Like

As a workaround, you can add points at an arbitrary location and then unset their location.

F = slicer.mrmlScene.AddNewNodeByClass('vtkMRMLFiducialNode')
tempLocation = vtk.vtkVector3d(0,0,0)
newControlPointIndex = F.AddControlPointWorld(tempLocation, 'my-landmark-label')
F.UnsetNthControlPointPosition( newControlPointIndex )

to add a single control point with an unset location, or
if you want to add several and then unset them all.


I was searching under SetNthControlPoint… group. Thanks, Mike!

1 Like

Thanks for your feedback @ezgimercan. Could you send a few lines of code to replicate the Slicer crash?

a = loadMarkups(<your markup file .mrk.json>)

then click tab and select a function. When I hit enter, it freezes and crashes.

This is the last line of log file:
[DEBUG][Qt] 11.10.2021 15:45:21 [] (unknown:0) - Python console user input: a=loadMarkups("/home/emerc1/XXX.mrk.json")

Version 2021-10-10, Linux, + SlicerMorph

Thanks @ezgimercan! It’s not replicating on my Mac, but I’ll give it a try on Linux.

I’m not sure if it is related, but I ran into something like this crash a while back Reproducible Slicer crash on attempted tab completion, on Nightly 2020-01-08 . Unfortunately, it wasn’t really sorted out at the time, and it went away in a more recent preview release, so I don’t think it was pursued any further.