Beispiel #1
0
    def __init__(self, url):
        self.cache = {}

        print('Epics Bridge', url)
        self._scan_info = {}
        self._scan_data = {}
        self._last_data = []

        self._url = None
        # Setting the url property, causes the xmlrpc serverproxy to connect
        self.url = url
        self.detectors = {}
        self.array_list = [SCAN_TAG]
        self.scan_arrays = {}

        for detector, pv_info in self.server.get_detector_list():
            self.monitor_detector(detector, pv_info)

        self._update_available = True
        self.update_timer = QTimer()
        self.update_timer.start(500)
        self.update_timer.timeout.connect(self.update)
Beispiel #2
0
class EpicsBridge(object):
    instance = None
    init_thread = None

    def __init__(self, url):
        self.cache = {}

        print('Epics Bridge', url)
        self._scan_info = {}
        self._scan_data = {}
        self._last_data = []

        self._url = None
        # Setting the url property, causes the xmlrpc serverproxy to connect
        self.url = url
        self.detectors = {}
        self.array_list = [SCAN_TAG]
        self.scan_arrays = {}

        for detector, pv_info in self.server.get_detector_list():
            self.monitor_detector(detector, pv_info)

        self._update_available = True
        self.update_timer = QTimer()
        self.update_timer.start(500)
        self.update_timer.timeout.connect(self.update)

    def _get_url(self):
        return self._url

    def _set_url(self, url):
        if url != self._url:
            self.server = xmlrpclib.ServerProxy(url)
            self._url = url

    url = property(_get_url, _set_url, doc='XMLRPC server URL')

    def monitor_detector(self, name, pvs):
        print('Monitor detector %s (pvs: %s)' % (name, pvs))
        self.detectors[name] = det = EpicsDetector(name, pvs)
        self.array_list.append(name)
        if hasattr(det, 'calibration'):
            self.array_list.append('%s_PARAM' % name)

    def remove_detector(self, name):
        if name not in self.detectors:
            return

        del self.detectors[name]

    def update(self):
        if self.server is None:
            return

        # check to add/remove detectors
        det_list = self.server.get_detector_list()
        det_dict = dict(det_list)
        det_names = set(det_dict.keys())

        new_detectors = det_names - set(self.detectors.keys())
        for det_name in new_detectors:
            self.monitor_detector(det_name, det_dict[det_name])

        remove_detectors = set(self.detectors.keys()) - det_names
        for det_name in remove_detectors:
            self.remove_detector(det_name)

        # see if scan in progress, and get status

    @property
    def scan_dim(self):
        return self.scan_info.get('nopts', 0), self.scan_info.get('counters', 0)

    def _update_scan_info(self):
        if self.server is None or not self.update_available:
            return

        self._scan_info = info = self.server.get_scan_info()
        if 'key' not in info:
            print('scan info has no key?', info)
            return

        self._scan_key = info['key']

        ndim = info.get('ndim', 1)
        labels = info.get('labels', [])
        label_str = ','.join(labels)
        # todo
        label_str = label_str.replace('(', '')
        label_str = label_str.replace(')', '')

        info['plotlist'] = label_str
        info['axistitles'] = label_str.replace(',', ' ')

        if ndim == 2:
            old_keys = set(self.scan_arrays.keys())
            keys = set(['2D_%s' % label for label in labels])
            if keys != old_keys:
                remove_keys = old_keys - keys
                for remove in remove_keys:
                    del self.scan_arrays[remove]
                for key in keys:
                    if key not in self.scan_arrays:
                        self.scan_arrays[key] = {'key': -1}
        else:
            self.scan_arrays.clear()

        print('got scan info', info)
        self._last_data.append(self._scan_data)
        self._scan_data = np.array(self.server.get_scan_data())
        self._update_available = False
        return info

    def getarrayinfo(self, name):
        # rows, cols, type, flag
        print('get array info', name)
        if name.startswith(SCAN_TAG):
            self._update_scan_info()
            nopts, counters = self.scan_dim
            print('Scan points', nopts, 'Counters', counters)
            return [nopts, counters, sps.FLOAT, sps.TAG_SCAN | sps.TAG_ARRAY]
        elif name in self.detectors:
            det = self.detectors[name]
            return det.sps_info
        elif name.endswith('_PARAM'):  # calibration
            #detector = name.rsplit('_', 1)[0]
            return [3, 1, sps.FLOAT, sps.TAG_ARRAY]
        elif name in self.scan_arrays:
            name = name[3:]
            dim = self.scan_info.get('dimensions')
            print('array info', name, dim)
            return [dim[0], dim[1], sps.FLOAT, sps.TAG_ARRAY | sps.TAG_IMAGE]

    def getarraylist(self):
        return self.array_list + list(self.scan_arrays.keys())

    def _isupdated(self, name):
        if self.server is None:
            return False

        if name in self.detectors:
            if self.detectors[name].updated:
                self.detectors[name].updated = False
                return True

        elif name == SCAN_TAG:
            return self.update_available

        elif name in self.scan_arrays:
            last_key = self.scan_arrays[name]['key']
            return (self.update_available or last_key != self._scan_key)

        return False

    def isupdated(self, name):
        ret = self._isupdated(name)
        print('isupdated %s = %s' % (name, ret))
        return ret

    def getenv(self, shmenv, key):
        print('getenv', shmenv, key)
        if shmenv == SCAN_ENV_TAG:
            return self.scan_info[key]
        else:
            return ''

    @property
    def update_available(self):
        if not self._update_available:
            newest_key = self.server.get_scan_key()
            self._update_available = (newest_key != self._scan_key)
            return self._update_available
        else:
            return True

    @property
    def scan_info(self):
        if self._scan_info is None or self.update_available:
            self._update_scan_info()
        return self._scan_info

    @property
    def scan_data(self):
        if self._scan_data is None or self.update_available:
            self._update_scan_info()
        return self._scan_data

    def _getdata(self, name):
        print('getdata', name)
        if name == SCAN_TAG:
            return self.scan_data
        elif name.endswith('_PARAM'):  # calibration
            detector = name.rsplit('_', 1)[0]
            return np.array([self.detectors[detector].calibration])
        elif name in self.detectors:
            return self.detectors[name].data.T  # expects transpose
        elif name in self.scan_arrays:
            self.scan_arrays[name]['key'] = self._scan_key

            # Strip off the 2D_ prefix
            name = name[3:]
            labels = self.scan_info['labels']
            label_idx = labels.index(name)

            data = self.scan_data
            data = data[:, label_idx]

            if 0:
                data = data + np.random.random(data.shape[0])
            import traceback
            traceback.print_stack()
            return np.array(data).reshape(self.scan_info['dimensions'])
        else:
            return np.zeros(1)

    def getdata(self, name):
        ret = self._getdata(name)
        #print('getdata %s = %s' % (name, ret))
        return ret

    def getkeylist(self, shmenv):
        if shmenv == SCAN_ENV_TAG:
            return self.scan_info.keys()
        else:
            return []

    def specrunning(self):
        return 1

    def getspeclist(self):
        #import traceback; traceback.print_stack()
        return [EPICS_TAG] + sps._getspeclist()

    # unused functions:
    def updatedone(self, shmenv):
        raise NotImplementedError
        # unused in current PyMca code

    def getdatacol(self, shm, idx):
        raise NotImplementedError
        # unused in current PyMca code

    def getdatarow(self, shm, idx):
        raise NotImplementedError
        # unused in current PyMca code

    def putenv(self, shmenv, cmd, outp):
        raise NotImplementedError