# How to link link a MarkUp point list to be a sequence in one SequenceBrowser using python script?

**URL:** <https://discourse.slicer.org/t/how-to-link-link-a-markup-point-list-to-be-a-sequence-in-one-sequencebrowser-using-python-script/24951>\
**Category:** Support\
**Tags:** sequences, python, markups-fiducials, module, markups\
**Created:** [August 27, 2022, 9:16pm UTC](https://discourse.slicer.org/t/how-to-link-link-a-markup-point-list-to-be-a-sequence-in-one-sequencebrowser-using-python-script/24951 "2022-08-27T21:16:54Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![sunshine](https://avatars.discourse-cdn.com/v4/letter/s/3ec8ea/32.png) [@sunshine](https://discourse.slicer.org/u/sunshine)\
**Post date:** [August 27, 2022, 9:16pm UTC](https://discourse.slicer.org/t/how-to-link-link-a-markup-point-list-to-be-a-sequence-in-one-sequencebrowser-using-python-script/24951/1 "2022-08-27T21:16:54Z")

</div>

Hi everyone,

I am trying to write a module that can manually add landmarks using the MarkUp point list (vtkMRMLMarkupsFiducialNode) to different SequenceBrowsers.

I hope to link the point list node to one sequence of the target SequenceBrowser, and add an attribute of “pointListExist = True” to the SequenceBrowser.

What are the possible functions I should use to achieve it?

Thank you so much in advance!

---

<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:** [August 27, 2022, 10:15pm UTC](https://discourse.slicer.org/t/how-to-link-link-a-markup-point-list-to-be-a-sequence-in-one-sequencebrowser-using-python-script/24951/2 "2022-08-27T22:15:33Z")

</div>

You can create a new sequence node and add it to the sequence browser by calling [AddProxyNode](https://apidocs.slicer.org/master/classvtkMRMLSequenceBrowserNode.html#aba16a856688831e670c26c9f4cd7fc34).

---

<div class="post-metadata">

**Author:** ![sunshine](https://avatars.discourse-cdn.com/v4/letter/s/3ec8ea/32.png) [@sunshine](https://discourse.slicer.org/u/sunshine)\
**Post date:** [August 28, 2022, 1:13am UTC](https://discourse.slicer.org/t/how-to-link-link-a-markup-point-list-to-be-a-sequence-in-one-sequencebrowser-using-python-script/24951/3 "2022-08-28T01:13:14Z")

</div>

Hi Andras,

Thank you so much for your help! I made it using AddProxyNode.

```auto
node_Browser = slicer.mrmlScene.GetFirstNodeByClass('vtkMRMLSequenceBrowserNode')
node_Seq = slicer.mrmlScene.AddNewNodeByClass("vtkMRMLSequenceNode", 'nodeSeq_pList_SeqBrowser_1')
node_Browser.AddProxyNode(getNode('pList_1'), node_Seq, False)

```

Could you please help me understand what is a ProxyNode? I would like to ask because I may not want it this way.  
For all the other Proxy Node before and after a sequence recording, the ProxyNode share the same for different SequenceBrowsers; however, if I use AddProxyNode to link node\_PoinList to the SequenceBrowser, I need multiple node\_PointList (from ‘pList\_1’ to ‘pList\_n’) to be the ProxyNode for different SequenceBrowser, which is not ideal.

Could you please let me know what should I do?

---

<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:** [August 28, 2022, 10:04am UTC](https://discourse.slicer.org/t/how-to-link-link-a-markup-point-list-to-be-a-sequence-in-one-sequencebrowser-using-python-script/24951/4 "2022-08-28T10:04:25Z")

</div>

> [@sunshine](#):
>
> Could you please help me understand what is a ProxyNode?

The proxy node brings one item from the sequence into the scene.

Typically, each proxy node is used by one sequence browser node. However, if you are careful (e.g., don’t simultaneously replay two sequences that use the same proxy nodes) then you can use the same proxy nodes in multiple browsers, by setting `copy` argument to`False`when calling `AddProxyNode`.

---

<div class="post-metadata">

**Author:** ![sunshine](https://avatars.discourse-cdn.com/v4/letter/s/3ec8ea/32.png) [@sunshine](https://discourse.slicer.org/u/sunshine)\
**Post date:** [August 28, 2022, 3:31pm UTC](https://discourse.slicer.org/t/how-to-link-link-a-markup-point-list-to-be-a-sequence-in-one-sequencebrowser-using-python-script/24951/5 "2022-08-28T15:31:13Z")

</div>

So, in my case that each `pList_Seq_n` should be not only an independent PointList node that can be displayed in module MarkUp, but also should be the ProxyNode of `'SequenceBrowser_n'` added by

```auto
node_SeqBrowser_n.AddProxyNode(getNode('pList_n'), node_Seq_n, True)

```

am I correct?

If yes, does that mean the actual PointList\_n is saved twice, one in the format of `'vtkMRMLMarkupsFiducialNode'`, and the other one in the format of `"vtkMRMLSequenceNode"` ?

---

<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:** [August 28, 2022, 6:32pm UTC](https://discourse.slicer.org/t/how-to-link-link-a-markup-point-list-to-be-a-sequence-in-one-sequencebrowser-using-python-script/24951/6 "2022-08-28T18:32:31Z")

</div>

If you have one sequence node with many items then you can retrieve (and represent in the scene) one item by each browser node. So, there is some duplication, but by default a shallow-copy is performed from the sequence item into the proxy node, so bulk data (such as voxel array of an image) is not copied.

---

<div class="post-metadata">

**Author:** ![sunshine](https://avatars.discourse-cdn.com/v4/letter/s/3ec8ea/32.png) [@sunshine](https://discourse.slicer.org/u/sunshine)\
**Post date:** [August 28, 2022, 7:49pm UTC](https://discourse.slicer.org/t/how-to-link-link-a-markup-point-list-to-be-a-sequence-in-one-sequencebrowser-using-python-script/24951/7 "2022-08-28T19:49:44Z")

</div>

Thank you so much, Andras!

I am not sure if using the MarkUp PointList (`vtkMRMLMarkupsFiducialNode`) would be the same case because it seems that there is not a node called MarkUp point (only PointList).

I need to call the MarkUp module to help SetActive a PointList node in order to add/drop a new control point, which means the copy has to be a shallow copy. Did I make sense?

In the meantime, to make sure I can find all PointList nodes in MarkUp module for different SequenceBrowser, I need to set `copy=True` when assigning a PointList to be the ProxyNode of a SequenceBrowser,

```auto
node_SeqBrowser_n.AddProxyNode(getNode('pList_n'), node_Seq_n, True)

```

would this achieve a sequence format, so that I can display the Point (if exists) of at different frames in a SequenceBrowser?

---

<div class="post-metadata">

**Author:** ![sunshine](https://avatars.discourse-cdn.com/v4/letter/s/3ec8ea/32.png) [@sunshine](https://discourse.slicer.org/u/sunshine)\
**Post date:** [August 29, 2022, 3:09am UTC](https://discourse.slicer.org/t/how-to-link-link-a-markup-point-list-to-be-a-sequence-in-one-sequencebrowser-using-python-script/24951/8 "2022-08-29T03:09:22Z")

</div>

I might be confused about how to synchronize the MarkUp PointList (`vtkMRMLMarkupsFiducialNode`) to a SequenceBrowser.

Instead of making the `node_PointList` a `ProxyNode`, I should make the ControlPoint a `ProxyNode`, because each frame corresponds to one `ControlPoint`, am I correct?

However, `ControlPoint` is not a node. What should I do to make the `PointList` a synchronized `SequenceNode` in a `SequenceBrowser`?

Or, maybe I can create a `PointList` for every single frame in the `SequenceBrowser`, so that the `PointList` is the `ProxyNode`. In this case, what are the possible functions I should use to add/save the nodes of `PointList` in the `SequenceBroswer`?  
In this case, I should not use `slicer.mrmlScene.AddNewNodeByClass("vtkMRMLMarkupsFiducialNode")`, because it will then be added to the `MarkUp` module and shown in the `Data` module. How to make it only available in SequenceBrowser as a Sequence?

---

<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:** [August 29, 2022, 4:02am UTC](https://discourse.slicer.org/t/how-to-link-link-a-markup-point-list-to-be-a-sequence-in-one-sequencebrowser-using-python-script/24951/9 "2022-08-29T04:02:05Z")

</div>

Changes in a proxy node are automatically saved into the sequence node if you [enable `SaveChanges` for the sequence](https://apidocs.slicer.org/master/classvtkMRMLSequenceBrowserNode.html#ab2671ed3ee9eb413bb122f91b9c1029a).

---

<div class="post-metadata">

**Author:** ![sunshine](https://avatars.discourse-cdn.com/v4/letter/s/3ec8ea/32.png) [@sunshine](https://discourse.slicer.org/u/sunshine)\
**Post date:** [August 30, 2022, 3:51am UTC](https://discourse.slicer.org/t/how-to-link-link-a-markup-point-list-to-be-a-sequence-in-one-sequencebrowser-using-python-script/24951/12 "2022-08-30T03:51:31Z")

</div>

So glad I made it !! 😁 To make it work, the newly added `SequenceNode` must be filled up by all empty `PointList`, otherwise the later annotated `DataNode` will always be affected by the previous added `DataNode` and the SequenceNode will not be able to Update during the PlayBack

Empty node\_PointList: `slicer.vtkMRMLMarkupsFiducialNode()`  
Fill Sequence: ` nodeSeq_Annotation.SetDataNodeAtValue(node_EmptyPointList, str_IndexValue_Time)`

```auto
nodeSeqBrowser.AddProxyNode(node_SeqBrowserProxy_Annotation, nodeSeq_Annotation, False)
nodeSeqBrowser.SetSaveChanges(nodeSeq_Annotation, True)

# Fill up the SequenceNode with all empty 'PointList'
num_DataNodes = nodeSeqBrowser.GetNumberOfItems()
nodeSeq_Image = nodeSeqBrowser.GetSequenceNode(slicer.util.getNode('Existing_ProxyNodeName'))
for idx_DataNode in range(num_DataNodes):
    str_IndexValue_Time = nodeSeq_Image.GetNthIndexValue(idx_DataNode)
    nodeSeq_Annotation.SetDataNodeAtValue(slicer.vtkMRMLMarkupsFiducialNode(), str_IndexValue_Time)

```
