# Communicate with Slicer from external Python application

**URL:** <https://discourse.slicer.org/t/communicate-with-slicer-from-external-python-application/14687>\
**Category:** Support\
**Tags:** surgical-navigation\
**Created:** [November 19, 2020, 1:14pm UTC](https://discourse.slicer.org/t/communicate-with-slicer-from-external-python-application/14687 "2020-11-19T13:14:53Z")\
**Posts on this page:** 19\
**Page:** 1

<div class="post-metadata">

**Author:** ![tharisata\_c](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/tharisata_c/32/8677_2.png) [@tharisata\_c](https://discourse.slicer.org/u/tharisata_c)\
**Post date:** [November 19, 2020, 1:14pm UTC](https://discourse.slicer.org/t/communicate-with-slicer-from-external-python-application/14687/1 "2020-11-19T13:14:53Z")

</div>

Hi,

I’m still a bit unsure about this, so any advice would be great.

What I want to do is create a few fiducial points on my CT Scan and export these into an external python IDE, like Spyder, automatically (as oppose to saving them as a JSON file manually).

1. How do I connect an external python environment (like Spyder) with my Slicer environment so that they can communicate?

i.e. to be even more clear, I want to write an external python script that could access the information in Slicer. Is this possible and how can I do it?

---

<div class="post-metadata">

**Author:** ![Alex\_Vergara](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/alex_vergara/32/15205_2.png) [@Alex\_Vergara](https://discourse.slicer.org/u/Alex_Vergara)\
**Post date:** [November 19, 2020, 1:22pm UTC](https://discourse.slicer.org/t/communicate-with-slicer-from-external-python-application/14687/2 "2020-11-19T13:22:04Z")

</div>

Why do you need external python IDE when you can use an IDE connected to the Slicer bundled python and access everything from there?  
Anyways, you can use either jsons or pickle object for what you want, but it makes no sense to me.

---

<div class="post-metadata">

**Author:** ![tharisata\_c](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/tharisata_c/32/8677_2.png) [@tharisata\_c](https://discourse.slicer.org/u/tharisata_c)\
**Post date:** [November 19, 2020, 2:07pm UTC](https://discourse.slicer.org/t/communicate-with-slicer-from-external-python-application/14687/3 "2020-11-19T14:07:36Z")

</div>

Hi Alex,

Let me be more concise.

My project uses RoboDK to simulate an industrial robot. This has a python interface. I intend to call Slicer through this python interface to take the coordinates of the fiducial points.

I want to this autonomously, i.e. when I select a fiducial point on Slicer, I want it to then be loaded into my RoboDK via interface. I don’t want to be manually pickling or saving objects.

Would this be possible with IDE connected to Slicer bundled python? Please can you expand on what you mean by that and how I can set that up?

---

<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:** [November 19, 2020, 4:09pm UTC](https://discourse.slicer.org/t/communicate-with-slicer-from-external-python-application/14687/4 "2020-11-19T16:09:35Z")

</div>

For high-speed streaming of images, transforms, models, etc. we typically use OpenIGLTLink protocol. Slicer can act as OpenIGTLink server and client (provided [SlicerOpenIGTLink extension](https://github.com/openigtlink/SlicerOpenIGTLink)), and there are native Python OpenIGTLink clients and servers that you can use in RoboDK. @Sunderlandkyl does Slicer OpenIGTLink server supports sending of markups fiducial lists?

You can also access Slicer via standard web requests (using [SlicerWeb extension](https://github.com/pieper/SlicerWeb)) via Python.

---

<div class="post-metadata">

**Author:** ![Sunderlandkyl](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/sunderlandkyl/32/79987_2.png) [@Sunderlandkyl](https://discourse.slicer.org/u/Sunderlandkyl)\
**Post date:** [November 19, 2020, 4:12pm UTC](https://discourse.slicer.org/t/communicate-with-slicer-from-external-python-application/14687/5 "2020-11-19T16:12:02Z")

</div>

> [@lassoan](#):
>
> @Sunderlandkyl does Slicer OpenIGTLink server supports sending of markups fiducial lists?

No, markups can’t be received via OpenIGTLink currently.

---

<div class="post-metadata">

**Author:** ![tharisata\_c](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/tharisata_c/32/8677_2.png) [@tharisata\_c](https://discourse.slicer.org/u/tharisata_c)\
**Post date:** [November 19, 2020, 4:13pm UTC](https://discourse.slicer.org/t/communicate-with-slicer-from-external-python-application/14687/6 "2020-11-19T16:13:35Z")

</div>

Thank you for your quick response.

Is there any way I could send the mark ups over somehow?

---

<div class="post-metadata">

**Author:** ![tharisata\_c](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/tharisata_c/32/8677_2.png) [@tharisata\_c](https://discourse.slicer.org/u/tharisata_c)\
**Post date:** [November 19, 2020, 4:16pm UTC](https://discourse.slicer.org/t/communicate-with-slicer-from-external-python-application/14687/7 "2020-11-19T16:16:44Z")

</div>

I was thinking of using ROSIGTLink with Slicer, does this support sending of markups fiducial lists? (I wonder if there’s an easier method than this though)

Really grateful for your help.

---

<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:** [November 19, 2020, 6:15pm UTC](https://discourse.slicer.org/t/communicate-with-slicer-from-external-python-application/14687/8 "2020-11-19T18:15:53Z")

</div>

Slicer can already transfer positions via TRANSFORM or NDARRAY messages. You could add an observer to a markups list and whenever it is changed, update transform nodes or a table node, which are then automatically sent via OpenIGTLink. I’ll have a look if I can add direct sending of markups as POINT message.

I know that ROSIGTLink already supports TRANSFORM and NDARRAY message types, but you would use ROS not just for getting the point positions from Slicer, but for its openness and flexibility. If you just need the simplest possible solution and don’t need all the features that ROS can offer then you can just use RoboDK and get data via a short Python script (see [pyIGTLink](https://github.com/SlicerIGT/pyIGTLink/blob/master/pyIGTLink/pyIGTLink.py)).

---

<div class="post-metadata">

**Author:** ![tharisata\_c](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/tharisata_c/32/8677_2.png) [@tharisata\_c](https://discourse.slicer.org/u/tharisata_c)\
**Post date:** [November 19, 2020, 6:24pm UTC](https://discourse.slicer.org/t/communicate-with-slicer-from-external-python-application/14687/9 "2020-11-19T18:24:16Z")

</div>

Andras, this is brilliant. Thank you very much.

I’ll try it with OpenIGTLink first. And you’re absolutely right, I don’t need all the features of ROS.

Please let me know if you manage to directly send markups as a POINT message.

Very grateful for your help.

---

<div class="post-metadata">

**Author:** ![tharisata\_c](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/tharisata_c/32/8677_2.png) [@tharisata\_c](https://discourse.slicer.org/u/tharisata_c)\
**Post date:** [November 20, 2020, 6:17pm UTC](https://discourse.slicer.org/t/communicate-with-slicer-from-external-python-application/14687/10 "2020-11-20T18:17:46Z")

</div>

Hi @Sunderlandkyl and @lassoan ,

I’ve just tried setting up the pyIGTLink and I’ve set up the connection node like so:

 ![Capture1](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/f/9/f923ea03182bd4db6fefe3e0f6e610a8e2d77171.jpeg)

Setting Slicer as a SERVER so I could request its Linear Transforms Message from Python. Does the pyIGTLink only work as a server? If so, can I still extract information about the Slicer Scene such as LinearTransform Nodes and set Slicer as a Client instead?

If this is possible, what code do I write to do it?

Thank you again for your help!

---

<div class="post-metadata">

**Author:** ![Sunderlandkyl](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/sunderlandkyl/32/79987_2.png) [@Sunderlandkyl](https://discourse.slicer.org/u/Sunderlandkyl)\
**Post date:** [November 20, 2020, 6:33pm UTC](https://discourse.slicer.org/t/communicate-with-slicer-from-external-python-application/14687/11 "2020-11-20T18:33:21Z")

</div>

We have an experimental branch that allows pyIGTLink to send as well as receive messages.  
You can find the branch here: [https://github.com/SlicerIGT/pyIGTLink/tree/pyIGTLink\_client](https://github.com/SlicerIGT/pyIGTLink/tree/pyIGTLink_client)

---

<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:** [November 22, 2020, 3:20am UTC](https://discourse.slicer.org/t/communicate-with-slicer-from-external-python-application/14687/12 "2020-11-22T03:20:58Z")

</div>

I’ve added sending/receiving of markups fiducial lists via OpenIGTLink.

I’ll update the Python client to make it easy to send/receive points in Python, too.

---

<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:** [November 22, 2020, 9:11pm UTC](https://discourse.slicer.org/t/communicate-with-slicer-from-external-python-application/14687/13 "2020-11-22T21:11:46Z")

</div>

I’ve created a new OpenIGTLink Python package (originally based on pyIGTlink, but much improved) that can send/receive markups fiducial lists: [https://github.com/lassoan/pyigtl](https://github.com/lassoan/pyigtl)

I plan to make it available on PyPI within 1-2 weeks, but you can already use it by downloading it and adding it to your Python path.

---

<div class="post-metadata">

**Author:** ![tharisata\_c](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/tharisata_c/32/8677_2.png) [@tharisata\_c](https://discourse.slicer.org/u/tharisata_c)\
**Post date:** [November 23, 2020, 4:18pm UTC](https://discourse.slicer.org/t/communicate-with-slicer-from-external-python-application/14687/14 "2020-11-23T16:18:55Z")

</div>

![Capture](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/a/d/ad60d539c57391208bf3e14f9e07d3d6c2212a1d.jpeg)

Hi @lassoan,

Your pyIGTL works amazingly! I’m able to get the linear transforms across.

However, you said above that I can now also send fiducial points? But when I try to select that as an output in I/O Configuration in OpenIGTLinkIF, I’m unable to do so.

Any ideas about this?

Thanks!

---

<div class="post-metadata">

**Author:** ![tharisata\_c](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/tharisata_c/32/8677_2.png) [@tharisata\_c](https://discourse.slicer.org/u/tharisata_c)\
**Post date:** [November 23, 2020, 5:29pm UTC](https://discourse.slicer.org/t/communicate-with-slicer-from-external-python-application/14687/15 "2020-11-23T17:29:09Z")

</div>

Sorry! I was being stupid. Just re-installed the extension and I’ve got it. Thank you Andras! You’ve really, really helped me out with this project.

Extremely grateful.

---

<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:** [November 23, 2020, 9:39pm UTC](https://discourse.slicer.org/t/communicate-with-slicer-from-external-python-application/14687/16 "2020-11-23T21:39:07Z")

</div>

Now pyigtl is available on PyPI, so you can install it by `pip install pyigtl`

> **[pyigtl](https://pypi.org/project/pyigtl/)**
>
> Python interface for OpenIGTLink

---

<div class="post-metadata">

**Author:** ![tokjun](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/tokjun/32/1057_2.png) [@tokjun](https://discourse.slicer.org/u/tokjun)\
**Post date:** [November 23, 2020, 11:36pm UTC](https://discourse.slicer.org/t/communicate-with-slicer-from-external-python-application/14687/17 "2020-11-23T23:36:52Z")

</div>

This is great! Thanks @lassoan !

By the way, I recently reviewed the Python wrapper work by @franklinwk ([https://github.com/franklinwk/openigtlink](https://github.com/franklinwk/openigtlink)), and it seems to work for some applications.

He hasn’t incorporated it into the C++ library because he had to modify the C++ codes, but it turned out that most of those modifications are not needed. You can find my version of the C++ library with Python Wrapping option at [https://github.com/tokjun/OpenIGTLink/tree/Swig-Python](https://github.com/tokjun/OpenIGTLink/tree/Swig-Python)

I only tested it on Linux, and it still needs some helper functions to make it useful. I will continue to play with it to see if this approach works well.

Junichi

---

<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:** [November 24, 2020, 12:01am UTC](https://discourse.slicer.org/t/communicate-with-slicer-from-external-python-application/14687/18 "2020-11-24T00:01:34Z")

</div>

Native Python implementation is easier to develop, maintain, and install, there is no need to build, it is easier to make it more Pythonic, and interface it with other Python packages (numpy, pandas, json,… ). You can also easily add custom message types in Python.

The only advantage of a Python-wrapped C++ implementation could be speed, but if you prepare the inputs/process outputs in Python anyway then the slight performance gain in the encoding/decoding might not be perceivable. Maybe maintenance workload could be also decreased by reusing an existing implementation (but maintenance of the Python on wrapping may require some of extra non-trivial effort).

---

<div class="post-metadata">

**Author:** ![tokjun](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/tokjun/32/1057_2.png) [@tokjun](https://discourse.slicer.org/u/tokjun)\
**Post date:** [November 24, 2020, 3:27am UTC](https://discourse.slicer.org/t/communicate-with-slicer-from-external-python-application/14687/19 "2020-11-24T03:27:05Z")

</div>

I agree. I’m playing with the wrapped library partly because I have an existing project that depends on it, but I generally prefer native Python implementation to Python-wrapped C++ implementation.

If there is another advantage of wrapping, it’s the potential to wrap with other languages. But I’m not sure if there will be much need other than C++/Python.
