示例#1
0
def send_map_layers_to_samp(maps, defer_cleanup_s=5):
    client = SAMPIntegratedClient()
    client.connect()
    params = {}
    message = {"samp.mtype": "jhv.load.image", "samp.params": params}

    tmp_files = []
    for energy_band in maps:
        params["url"] = []
        for i in range(len(maps[energy_band])):
            f = NamedTemporaryFile(delete=False, suffix=".fits")
            f.close()
            maps[energy_band][i].save(f.name)
            tmp_files.append(f.name)
            # use file:/// workaround for windows as JHV currently can't handle windows paths
            params["url"].append(("file:///" + f.name.replace("\\", "/")
                                  ) if f.name.find("\\") >= 0 else f.name)
        client.notify_all(
            message
        )  # message holds a reference to params which is updated in the loop
    client.disconnect()

    time.sleep(
        defer_cleanup_s
    )  # wait to make sure JHV could read the files before they're removed
    for filename in tmp_files:
        del_file(filename)  # cleanup
示例#2
0
class SAMP4JHVClient:
    def __init__(self):
        self.client = SAMPIntegratedClient()
        self.tmp_files = []

    def send_image_maps(self, maps):
        """ Takes a list of SunPy Map objects, saves them to disk one by one and sends the file-locations to JHV """

        params = {}
        params["url"] = []
        for m in maps:
            f = NamedTemporaryFile(delete=False, suffix=".fits")
            f.close()
            m.save(f.name)
            self.tmp_files.append(f.name)
            # use file:/// workaround for windows as JHV currently can't handle windows paths
            params["url"].append(("file:///" + f.name.replace("\\", "/")
                                  ) if f.name.find("\\") >= 0 else f.name)

        self.client.connect()
        self.client.notify_all({
            "samp.mtype": "jhv.load.image",
            "samp.params": params
        })
        self.client.disconnect()

    def remove_tmp_files(self):
        """ Removes temporary files that were created for JHV to be read.
        Mind that after calling this function, the images might not be available in JHV anymore
        due to JHVs internal memory management, that might require to re-read the files at some point.
        """

        for f in self.tmp_files:
            del_file(f)  # cleanup
示例#3
0
class A2p2SampClient():
    # TODO watch hub disconnection
    def __init__(self):
        self.sampClient = SAMPIntegratedClient("A2P2 samp relay") # TODO get title from main program class instead of HardCoded value

    def __del__(self):
        self.disconnect()

    def connect(self):
        self.sampClient.connect()
        # an error is thrown here if no hub is present

        # TODO get samp client name and display it in the UI

        # Instantiate the receiver
        self.r = Receiver(self.sampClient)
        # Listen for any instructions to load a table
        self.sampClient.bind_receive_call("ob.load.data", self.r.receive_call)
        self.sampClient.bind_receive_notification("ob.load.data", self.r.receive_notification)
        # TODO fix next call which thwrows an execption
        # <class 'astropy.samp.errors.SAMPProxyError'>,
        # <Fault 1: 'java.lang.IllegalArgumentException: Bad arguments: samp.hub.notifyAll[string, map] got [string, string]'>
        self.sampClient.notify_all("hello")

    def disconnect(self):
        self.sampClient.disconnect()

    def is_connected(self):
        # Workarround the 'non' reliable is_connected attribute
        # this helps to reconnect after hub connection lost
        try:
            return self.sampClient.is_connected and (self.sampClient.ping() or self.sampClient.is_connected)
        except:
            # consider connection refused exception as not connected state
            return False


    def get_status(self):
        if self.is_connected():
            return "connected [%s]" % (self.sampClient.get_public_id())
        else:
            return "not connected"


    def has_message(self):
        return self.is_connected() and self.r.received

    def clear_message(self):
        return self.r.clear()

    def get_ob_url(self):
        url = self.r.params['url']
        if url.startswith("file:///"):
            return url[7:]
        elif url.startswith("file:/"): # work arround bugged file urls
            return url[5:]
        return url
示例#4
0
class AladinViaSAMP(object):

    def __init__(self):
        self._client = SAMPIntegratedClient()
        
    def send_file(self, infile=str()):
        """Sending a file (image or table) to Aladin Sky Atlas using the SAMPIntegratedClient class.
             http://docs.astropy.org/en/stable/vo/samp/example_table_image.html
        """   
     
        self._client.connect()
        params = {}

        if sys.version > '3':
            params["url"] = urllib.parse.urljoin('file:', os.path.abspath(infile))
        else:
            params["url"] = urlparse.urljoin('file:', os.path.abspath(infile))
            
        message = {}
        message[ "samp.mtype" ] = "image.load.fits"
        message[ "samp.params" ] = params
     
        self._client.notify_all(message)
        self._client.disconnect()

    def move(self, script=str()):
        """Sending a script to Aladin Sky Atlas using the SAMPIntegratedClient class.
           http://docs.astropy.org/en/stable/vo/samp/example_table_image.html
         """

        self._client.connect()

        params = {}
        message = {} 
        message[ "samp.mtype" ] = "coord.pointAt.sky"
        message[ "samp.params" ] = { "script" : script }  

        self._client.notify_all(message)
        self._client.disconnect()

    def send_script_command(self, script=str()):
        """Sending a script to Aladin Sky Atlas using the SAMPIntegratedClient class.
           http://docs.astropy.org/en/stable/vo/samp/example_table_image.html
         """

        self._client.connect()

        params = {}
        message = {} 
        message[ "samp.mtype" ] = "script.aladin.send"
        message[ "samp.params" ] = { "script" : script }  

        self._client.notify_all(message)
        self._client.disconnect()
parser.add_argument("-i",
                    "--input",
                    required=True,
                    metavar="file",
                    help="input JHV request file")
parser.add_argument("-value",
                    help="Send request as message value",
                    action="store_true")
args = parser.parse_args()

input_file = os.path.abspath(args.input)

client = SAMPIntegratedClient()
client.connect()

params = {}

if args.value:
    with open(input_file, "r") as f:
        params["value"] = f.read()
else:
    params["url"] = input_file

message = {}
message["samp.mtype"] = "jhv.load.request"
message["samp.params"] = params

client.notify_all(message)

client.disconnect()
示例#6
0
class SAMPManager():

    __client = None
    __received = False
    __params = {}
    __hub = None
    __server_name = "frastro server"
    __server_description = "frastro Web client"
    __server_description_html = "<h1>frastro Web client</h1>"
    __author = "Camilo E. Jimenez-Angel"
    __instritution = "IAC"
    __email_contact = "*****@*****.**"
    __url_icon = "http://localhost:8000/static/img/frastro_icon.jpg"

    def __init__(self, server_name=""):
        # Instantiate the client and connect to the hub
        self.__server_name = server_name if server_name != "" else self.__server_name
        self.connect()

    def starHubServer(self, web_profile=True):
        if self.__hub is None:
            self.__hub = SAMPHubServer(web_profile=web_profile,
                                       label=self.__server_name)
        self.__hub.start()

    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

    def bind_to_server(self):
        # Listen for any instructions to load a table
        self.__client.bind_receive_call("table.load.votable",
                                        self.receive_call)
        self.__client.bind_receive_notification("table.load.votable",
                                                self.receive_notification)

    def sampMetadata(self):
        meta = {
            "samp.name": self.__server_name,
            "samp.description.text": self.__server_description,
            "samp.description.html": self.__server_description_html,
            "samp.icon.url": self.__url_icon,
            "author.affiliation": self.__instritution,
            "author.name": self.__author,
            "author.email": self.__email_contact
        }
        return meta

    def getRegisteredClients(self):
        clients = self.__client.get_registered_clients()
        run_clients = {}
        for client in clients:
            client_data = self.getMetadata(client)
            run_clients[client] = client_data
        return run_clients

    def getMetadata(self, client_id):
        return self.__client.get_metadata(client_id)

    def sendTable(self, message, recipient="all"):
        if recipient == "all":
            self.__client.notify_all(message)
        else:
            self.__client.notify(recipient, message)

    def connect(self):
        self.__client = SAMPIntegratedClient(name=self.__server_name,
                                             metadata=self.sampMetadata())
        self.__client.connect()
        self.bind_to_server()

    def sendImage(self, params, id=""):
        message = {}
        message["samp.mtype"] = "image.load.fits"
        message["samp.params"] = params
        if id == "" or id == "all":
            self.__client.notify_all(message)
        else:
            self.__client.notify(recipient_id=id, message=message)

    def sendMessage(self, params, id=""):
        message = {}
        message["samp.mtype"] = "table.load.votable"
        message["samp.params"] = params
        if id == "" or id == "all":
            self.__client.notify_all(message)
        else:
            self.__client.notify(recipient_id=id, message=message)

    def disconnect(self):
        self.__client.disconnect()

    def __del__(self):
        self.disconnect()
示例#7
0
class SAMPState(State):

    status = CallbackProperty('Not connected to SAMP Hub')
    connected = CallbackProperty(False)
    clients = CallbackProperty([])
    highlight_is_selection = CallbackProperty(False)

    def __init__(self):
        super(SAMPState, self).__init__()
        self.hub = SAMPHubServer()
        self.client = SAMPIntegratedClient()
        self.add_callback('connected', self.on_connected)

    def start_samp(self):
        if not self.client.is_connected:
            try:
                self.client.connect()
            except SAMPHubError:
                try:
                    self.hub.start()
                    self.client.connect()
                except Exception:
                    self.connected = False
                    self.status = 'Could not connect to Hub'
                else:
                    self.connected = True
                    self.status = 'Connected to (glue) SAMP Hub'
            except:
                self.connected = False
                self.status = 'Could not connect to Hub'
            else:
                self.connected = True
                self.status = 'Connected to SAMP Hub'

    def stop_samp(self):
        if self.client.is_connected:
            self.client.disconnect()
        if self.hub.is_running:
            self.hub.stop()
        self.connected = False
        self.status = 'Not connected to SAMP Hub'

    def on_connected(self, *args):
        if self.connected:
            metadata = {
                'author.email': '*****@*****.**',
                'author.name': 'Thomas Robitaille',
                'home.page': 'http://www.glueviz.org',
                'samp.description.text':
                'Multi-dimensional linked data exploration',
                'samp.documentation.url': 'http://www.glueviz.org',
                'samp.icon.url': 'file://' + ICON_PATH,
                'samp.name': 'glueviz',
                'glue.version': glue_version
            }
            self.client.declare_metadata(metadata)
            self.on_client_change()

    def on_client_change(self):
        clients = []
        for client in self.client.get_registered_clients():
            metadata = self.client.get_metadata(client)
            clients.append((client, metadata.get('samp.name', client)))
        self.clients = clients

    def send_data(self, layer=None, client=None):

        filename = tempfile.mktemp()

        message = {}
        message["samp.params"] = {}

        if isinstance(layer, Data):

            if layer.ndim == 1:
                table = data_to_astropy_table(layer)
                table.write(filename, format='votable')
                message["samp.mtype"] = "table.load.votable"
                if 'samp-table-id' not in layer.meta:
                    layer.meta['samp-table-id'] = layer.label
                message["samp.params"]['table-id'] = layer.meta[
                    'samp-table-id']
            elif layer.ndim == 2:
                fits_writer(filename, layer)
                message["samp.mtype"] = "image.load.fits"
                if 'samp-image-id' not in layer.meta:
                    layer.meta['samp-image-id'] = layer.label
                message["samp.params"]['image-id'] = layer.meta[
                    'samp-image-id']
            else:
                return

            message["samp.params"]['name'] = layer.label
            message["samp.params"]['url'] = 'file://' + os.path.abspath(
                filename)

        else:

            message['samp.mtype'] = 'table.select.rowList'

            if layer.ndim == 1:
                message["samp.params"]['table-id'] = layer.data.meta[
                    'samp-table-id']
                message["samp.params"]['row-list'] = np.nonzero(
                    layer.to_mask())[0].astype(str).tolist()
            else:
                return

        if client is None:
            self.client.notify_all(message)
        else:
            # Make sure client is subscribed otherwise an exception is raised
            subscriptions = self.client.get_subscriptions(client)
            for mtype in subscriptions:
                if fnmatch(message['samp.mtype'], mtype):
                    self.client.notify(client, message)
                    return
            else:
                return