通过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'])