TypeError: Function takes 2 positional arguments but 3 were given

I have been modifying a code to measure angle between Markup lines. It worked just fine in Slicer’s Python terminal. However, as soon as i moved on to create a module the following error pops up:

TypeError: ShowAngle() takes 2 positional arguments but 3 were given.

When i run the module on slicer it gives the angle correctly however, when i start moving the markup line to observe the angle changing i get the previous error.
I am assuming the error is in addObserver function but i am not quite sure about it,

I am using QT Designer for GUI, i am posting a snap shot of the main function.

image (5)
image
image (6)

Thank you so much,

Callback functions of VTK observers are required to take 2 arguments (caller and eventId). If the callback function is a member of a class then it requires an additional self argument as first argument, so you need a total of 3 arguments.

Note that in current Slicer versions you can use “angle” markup to measure a simple angle.

1 Like

Thank you so much Dr. Lasso for your quick reply,
May i ask about the ruler Markup? It seems that it is only visible at the Sagittal plane of the MRI and also on the 3D section bit not for two other planes. I am aware of Markup line as a valid option but for the code i am working on i found measuring angle in real-time between rulers is easier and also better visualized in both the planes and 3D. Is there is a solution for this?

Also about the Measurements module Modules:Measurements-Documentation-3.6 - Slicer Wiki, it seems no longer supported for Slicer 4, is it the case?

Thank you again so much.

Annotations module has several limitations and issues that will not be fixed anymore, it is not compatible with the new event management model that is needed to support new features (such as right-click menu, measurements in virtual reality, etc) and the entire module will be removed. We only keep the Annotations module around so that developers that started off when markups module did not exist have time to update their modules.

We are constantly improving markups, so if you don’t like anything about them then we can fix those. Just let us know what you would like to change. It helps if you attach a screenshot.

1 Like

@Ahmet_Yildiz Have you tried the Markups module “Angle” object instead of trying to manually determine angle using two lines? Do you not like the look of the “Angle” object?

Thank you again Dr. Lasso,
My issue is refining the code written by you to measure angle between rulers in real-time 3D Slicer scripted module for measuring angle between rulers · GitHub,
I tried multiple times for the code to switch from ruler to markup line by changing
self.rulerNodeClass = ‘vtkMRMLAnnotationRulerNode’
To
self.rulerNodeClass = ‘vtkMRMLMarkupsLineNode’

And a wave of errors show up, mainly
AttributeError: ‘vtkSlicerMarkupsModuleMRMLPython.vtkMRMLMarkupsLin’ object has no attribute ‘GetNthNodeByClass’
and some others.

What exactly should be modified for the script to switch from measuring angle between rulers to markup lines?

Thank you for your reply @jamesobutler,
The markupline/ruler will move with respect to needle tracked by optical tracker, that’s why i added addObserver function.
Not sure if the angle can be attached to the tool tip and measure “error” between current tool trajectory and a predefined desired trajectory.
image

A vtkMRMLMarkupsAngleNode has 3 control points so if you have observers that are already moving endpoints of some line objects you could instead tell it to update the position of the angle node control points instead.

I am not sure i am following here,
Is it possible for one control point from vtkMRMLMarkupsAngleNode to be fixed on top of created needle/imported needle CAD model and another point on the target (tumor) and a third on current trajectory and measures the angle difference in real time? If yes, how is this exactly possible?

Thank you so much @jamesobutler

This is because you are calling markupsNode.GetNthNodeByClass(...), while the correct would be slicer.mrmlScene.GetNthNodeByClass(...). It is not related to using annotations or markups.

There is a complete example in the script repository.

@lassoan @jamesobutler Again thank you for your time,
It seems it’s not possible to “attach” one control point from (markup line/ruler/angle) to a moving needle and observe the angle changing with respect to another fixed markup line/ruler,

As soon as i move the markup line/ruler in transform hierarchy in Data module to the transform where the needle exist “StylusToReference” so they can move at the same rate; the markup line/ruler disappears,

I am wondering how to measure distance/angle between needle (stylus) and target (Tumor) in real time to facilitate navigation. This is my ultimate goal, sorry about this but any idea?

A transform is always attached to a node, but you can add an observer to a transform and update selected points in the callback function.

Breach warning module in SlicerIGT extension is developed exactly for this purpose (for example, it is used extensively for navigated breast tumor resection).

1 Like