# OpenIGTLink event in case of a new incoming MRML node

**URL:** <https://discourse.slicer.org/t/openigtlink-event-in-case-of-a-new-incoming-mrml-node/18397>\
**Category:** Development\
**Tags:** python, openigtlink\
**Created:** [June 29, 2021, 2:45pm UTC](https://discourse.slicer.org/t/openigtlink-event-in-case-of-a-new-incoming-mrml-node/18397 "2021-06-29T14:45:07Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![atracsys-sbt](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/atracsys-sbt/32/11434_2.png) [@atracsys-sbt](https://discourse.slicer.org/u/atracsys-sbt)\
**Post date:** [June 29, 2021, 2:45pm UTC](https://discourse.slicer.org/t/openigtlink-event-in-case-of-a-new-incoming-mrml-node/18397/1 "2021-06-29T14:45:07Z")

</div>

Hi,  
I’m coding a scripted module that handles an OpenIGTLink connection to a tracker and I experience some delay between the call to start the connection and when the incoming data is actually streamed.  
I have tried using the solution proposed [here](https://discourse.slicer.org/t/igt-vtkmrmligtlconnectornode-best-way-to-know-how-long-to-wait-for-connection-and-node-access/5417/2) by @lassoan but it seems the ConnectedEvent is still sent prior to the actual streaming. With the code below, I still get 0 incoming MRML node at run time, but shortly after I can definitely see the incoming node in the Data tree of Slicer.

```auto
self.cnode = slicer.vtkMRMLIGTLConnectorNode()
self.cnode.SetName('PointerConnector')
slicer.mrmlScene.AddNode(self.cnode)
self.addObserver(self.cnode, slicer.vtkMRMLIGTLConnectorNode.ConnectedEvent, self.onConnected)
if self.cnode.Start() != 1:
   slicer.util.errorDisplay("Cannot connect to openIGTLink")

def onConnected(self, caller, event):
  if self.cnode.GetNumberOfIncomingMRMLNodes() == 0:
    slicer.util.errorDisplay("No data streamed")
  elif cnode.GetIncomingMRMLNode(0).GetClassName() != 'vtkMRMLLinearTransformNode':
    slicer.util.errorDisplay("Streamed data not a linear transform")
  else:
    self.pointerTransform = cnode.GetIncomingMRMLNode(0)

```

Thank you for any help,  
S.

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [June 29, 2021, 4:12pm UTC](https://discourse.slicer.org/t/openigtlink-event-in-case-of-a-new-incoming-mrml-node/18397/2 "2021-06-29T16:12:25Z")

</div>

Establishing a connection and receiving messages are independent events. You can receive messages anytime after the connection is established. The server may send new transform names, images, etc. anytime, even several hours after the connection is established (whenever the server wants to send them).

If you want to get notified about a new node then you can add an observer to the MRML scene. See an example [here](https://slicer.readthedocs.io/en/latest/developer_guide/script_repository.html#show-volume-rendering-automatically-when-a-volume-is-loaded).

---

<div class="post-metadata">

**Author:** ![atracsys-sbt](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/atracsys-sbt/32/11434_2.png) [@atracsys-sbt](https://discourse.slicer.org/u/atracsys-sbt)\
**Post date:** [June 29, 2021, 10:03pm UTC](https://discourse.slicer.org/t/openigtlink-event-in-case-of-a-new-incoming-mrml-node/18397/3 "2021-06-29T22:03:14Z")

</div>

Thank you for your response.  
If I understand correctly, I should have in my module widget class:

```auto
class MyModuleWidget(ScriptedLoadableModuleWidget, VTKObservationMixin):
  ...
  def setup(self):
    ...
    slicer.mrmlScene.AddObserver(slicer.vtkMRMLScene.NodeAddedEvent, self.onNodeAdded)
    self.cnode = slicer.vtkMRMLIGTLConnectorNode()
    self.cnode.SetName('PointerConnector')
    slicer.mrmlScene.AddNode(self.cnode)
    self.cnode.Start()

  def onNodeAdded(self, caller, event, calldata):
    calledNode = calldata
    if isinstance(calledNode, slicer.vtkMRMLLinearTransformNode): # check new node class
      if self.cnode.GetNumberOfIncomingMRMLNodes() > 0: # connection has at least one node
        if self.cnode.GetIncomingMRMLNode(0).GetID() == calledNode.GetID(): # check if nodes identical
          self.logic.process(self.phantomModel, self.pointerModel, calledNode)

```

However, by doing so I get an error on my callback:

```auto
TypeError: onNodeAdded() missing 1 required positional argument: 'calldata'

```

Is it possible to have a callback with calldata and as a member function of the widget class (using self to get cnode) ?

---

<div class="post-metadata">

**Author:** ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)\
**Post date:** [June 30, 2021, 1:05am UTC](https://discourse.slicer.org/t/openigtlink-event-in-case-of-a-new-incoming-mrml-node/18397/4 "2021-06-30T01:05:03Z")

</div>

You need to add the `@vtk.calldata_type(vtk.VTK_OBJECT)` decorator as it is shown in the example I referenced in my previous post.
