通过SAMP发送和接收表和图像#

在以下示例中,我们利用:

  • TOPCAT ,这是一种探索表格数据的工具。

  • SAO DS9 _,这是一个图像可视化工具,可以过度打印目录。

  • Aladin Desktop _,这是另一个可以可视化图像和目录的工具。

如果找不到SAMP集线器,TOPCAT和Aladin将运行一个SAMP集线器,因此对于以下示例,您可以先启动其中一个应用程序,也可以启动 astropy.samp 轮毂。您可以使用以下命令启动它:

$ samp_hub

向TOPCAT和DS9发送表#

向TOPCAT发送VO表的最简单方法是使用 SAMPIntegratedClient 班级。一旦TOPCAT打开,首先实例化一个 SAMPIntegratedClient 实例,然后连接到集线器:

>>> from astropy.samp import SAMPIntegratedClient
>>> client = SAMPIntegratedClient()
>>> client.connect()

接下来,我们必须设置一个字典,其中包含要发送的表的详细信息。这应该包括 url ,这是文件的URL,以及 name ,这是表的可读名称。URL可以是本地URL(以开头 file:/// ):

>>> params = {}
>>> params["url"] = 'file:///Users/tom/Desktop/aj285677t3_votable.xml'
>>> params["name"] = "Robitaille et al. (2008), Table 3"

备注

要构造本地URL,还可以使用 urlparse 如下:

>>> import urlparse
>>> params["url"] = urlparse.urljoin('file:', os.path.abspath("aj285677t3_votable.xml"))

现在我们可以设置消息本身。这包括消息的类型(这里我们使用 table.load.votable ,表示应该加载一个VO表,以及上面设置的表的详细信息):

>>> message = {}
>>> message["samp.mtype"] = "table.load.votable"
>>> message["samp.params"] = params

最后,我们可以将此消息广播给所有正在监听的客户 table.load.votable 消息使用 notify_all() ::

>>> client.notify_all(message)

上述消息实际上将被广播到通过SAMP连接的所有应用程序。例如,如果我们打开 SAO DS9 除了TOPCAT之外,我们运行上面的命令,两个应用程序都将加载表。我们可以使用 get_registered_clients() 方法查找连接到集线器的所有客户端::

>>> client.get_registered_clients()
['hub', 'c1', 'c2']

这些ID没有多大意义,但我们可以使用以下工具找到更多信息:

>>> client.get_metadata('c1')
{'author.affiliation': 'Astrophysics Group, Bristol University',
 'author.email': 'm.b.taylor@bristol.ac.uk',
 'author.name': 'Mark Taylor',
 'home.page': 'http://www.starlink.ac.uk/topcat/',
 'samp.description.text': 'Tool for OPerations on Catalogues And Tables',
 'samp.documentation.url': 'http://127.0.0.1:2525/doc/sun253/index.html',
 'samp.icon.url': 'http://127.0.0.1:2525/doc/images/tc_sok.gif',
 'samp.name': 'topcat',
 'topcat.version': '4.0-1'}

我们可以看到 c1 是顶级客户。我们现在可以重新发送数据,但这次只发送给TOPCAT,使用 notify() 方法:

>>> client.notify('c1', message)

完成后,我们应该确保与集线器断开连接:

>>> client.disconnect()

从TOPCAT收到一张桌子#

要从TOPCAT接收表,我们必须设置一个客户端来监听来自集线器的消息。如前所述,我们实例化一个 SAMPIntegratedClient 实例并连接到集线器:

>>> from astropy.samp import SAMPIntegratedClient
>>> client = SAMPIntegratedClient()
>>> client.connect()

我们现在设置了一个receiver类来处理任何接收到的消息。我们需要注意为通知和调用编写处理程序(两者之间的区别是调用需要一个应答)::

>>> class Receiver(object):
...     def __init__(self, client):
...         self.client = client
...         self.received = False
...     def receive_call(self, private_key, sender_id, msg_id, mtype, params, extra):
...         self.params = params
...         self.received = True
...         self.client.reply(msg_id, {"samp.status": "samp.ok", "samp.result": {}})
...     def receive_notification(self, private_key, sender_id, mtype, params, extra):
...         self.params = params
...         self.received = True

我们将其实例化:

>>> r = Receiver(client)

我们现在可以使用 bind_receive_call()bind_receive_notification() 方法告诉我们的接受者听所有的 table.load.votable 信息::

>>> client.bind_receive_call("table.load.votable", r.receive_call)
>>> client.bind_receive_notification("table.load.votable", r.receive_notification)

我们现在可以检查消息是否尚未收到:

>>> r.received
False

我们现在可以从TOPCAT广播这张表了。几秒钟后,我们可以再次检查是否已收到消息:

>>> r.received
True

成功!表URL现在应该在中可用 r.params['url'] ,所以我们可以:

>>> from astropy.table import Table
>>> t = Table.read(r.params['url'])
Downloading http://127.0.0.1:2525/dynamic/4/t12.vot [Done]
>>> t
           col1             col2     col3    col4     col5    col6 col7  col8 col9 col10
------------------------- -------- ------- -------- -------- ----- ---- ----- ---- -----
SSTGLMC G000.0046+01.1431   0.0046  1.1432 265.2992 -28.3321  6.67 5.04  6.89 5.22     N
SSTGLMC G000.0106-00.7315   0.0106 -0.7314 267.1274 -29.3063  7.18 6.07   nan 5.17     Y
SSTGLMC G000.0110-01.0237   0.0110 -1.0236 267.4151 -29.4564  8.32 6.30  8.34 6.32     N
...

如前所述,完成后,我们应该记住断开与集线器的连接:

>>> client.disconnect()

例子#

以下是可用于接收和读取表的脚本的完整示例。它包括一个循环,该循环将一直等到收到消息,并在收到消息后读取该表:

import time

from astropy.samp import SAMPIntegratedClient
from astropy.table import Table

 # Instantiate the client and connect to the hub
client=SAMPIntegratedClient()
client.connect()

# Set up a receiver class
class Receiver(object):
    def __init__(self, client):
        self.client = client
        self.received = False
    def receive_call(self, private_key, sender_id, msg_id, mtype, params, extra):
        self.params = params
        self.received = True
        self.client.reply(msg_id, {"samp.status": "samp.ok", "samp.result": {}})
    def receive_notification(self, private_key, sender_id, mtype, params, extra):
        self.params = params
        self.received = True

# Instantiate the receiver
r = Receiver(client)

# Listen for any instructions to load a table
client.bind_receive_call("table.load.votable", r.receive_call)
client.bind_receive_notification("table.load.votable", r.receive_notification)

# We now run the loop to wait for the message in a try/finally block so that if
# the program is interrupted e.g. by control-C, the client terminates
# gracefully.

try:

    # We test every 0.1s to see if the hub has sent a message
    while True:
        time.sleep(0.1)
        if r.received:
            t = Table.read(r.params['url'])
            break

finally:

    client.disconnect()

# Print out table
print t

向DS9和Aladin发送图像#

最方便的方法是发送图像 SAMPIntegratedClient 班级。一旦Aladin或DS9打开,首先实例化一个 SAMPIntegratedClient 实例,然后像以前一样连接到集线器:

>>> from astropy.samp import SAMPIntegratedClient
>>> client = SAMPIntegratedClient()
>>> client.connect()

接下来,我们必须设置一个字典,其中包含要发送的图像的详细信息。这应该包括 url ,这是文件的URL,以及 name ,这是表的可读名称。URL可以是本地URL(以开头 file:/// ):

>>> params = {}
>>> params["url"] = 'file:///Users/tom/Desktop/MSX_E.fits'
>>> params["name"] = "MSX Band E Image of the Galactic Center"

Sending a Table to TOPCAT and DS9 以获取构造本地URL的推荐方法的示例。现在我们可以设置消息本身。这包括消息的类型(这里我们使用 image.load.fits 它指示应加载FITS图像,以及我们在上面设置的表的详细信息)::

>>> message = {}
>>> message["samp.mtype"] = "image.load.fits"
>>> message["samp.params"] = params

最后,我们可以将此消息广播给所有正在监听的客户 table.load.votable 信息::

>>> client.notify_all(message)

至于 Sending a Table to TOPCAT and DS9 , the notify_all() 方法将图像广播到所有侦听客户端,对于表,可以改为使用 notify() 方法将其发送到特定客户端。

完成后,我们应该确保与集线器断开连接:

>>> client.disconnect()

从DS9或Aladin接收表#

通过SAMP接收图像与 Receiving a Table from TOPCAT ,但消息类型应为 image.load.fits 而不是 table.load.votable . 收到URL后,可以使用以下命令打开FITS图像:

>>> from astropy.io import fits
>>> fits.open(r.params['url'])