class Chronometer(TextView): """ A simple control for displaying read-only text. """ #: Set the time that the count-up timer is in reference to. base = d_(Long()) #: Tick counter ticks = d_(Long(), writable=False) #: Sets the format string used for display. format = d_(Unicode()) #: Counting direction direction = d_(Enum('up','down')) #: Start / stop the counter running = d_(Bool()) #: A reference to the ProxyLabel object. proxy = Typed(ProxyChronometer) @observe('base', 'direction', 'format', 'running') def _update_proxy(self, change): """ An observer which sends the state change to the proxy. """ # The superclass implementation is sufficient. super(Chronometer, self)._update_proxy(change)
class Data(Atom): ival = Int(1) lval = Long(sys.maxint + 1) fval = Float(1.5e6) bval = Bool(False)
m = Value() m.set_validate_mode(Validate.NoOp, None) for value in (1, 1.0, '', [], {}): assert m.do_validate(a, None, value) == value @pytest.mark.parametrize("member, set_values, values, raising_values", [ (Value(), ['a', 1, None], ['a', 1, None], []), (Bool(), [True, False], [True, False], 'r'), (Int(strict=True), [1], [1], [1.0, long(1)] if sys.version_info < (3, ) else [1.0]), (Int(strict=False), [1, 1.0, long(1) ], 3 * [1], ['a'] + [] if sys.version_info >= (3, ) else [1.0e35]), (Long(strict=True), [long(1)], [long(1)], [1.0, 1] if sys.version_info < (3, ) else [0.1]), (Long(strict=False), [1, 1.0, int(1)], 3 * [1], ['a']), (Range(0, 2), [0, 2], [0, 2], [-1, 3, '']), (Range(2, 0), [0, 2], [0, 2], [-1, 3]), (Range(0), [0, 3], [0, 3], [-1]), (Range(high=2), [-1, 2], [-1, 2], [3]), (Float(), [1, int(1), 1.1], [1.0, 1.0, 1.1], ['']), (Float(strict=True), [1.1], [1.1], [1]), (FloatRange(0.0, 0.5), [0.0, 0.5], [0.0, 0.5], [-0.1, 0.6]), (FloatRange(0.5, 0.0), [0.0, 0.5], [0.0, 0.5], [-0.1, 0.6]), (FloatRange(0.0), [0.0, 0.6], [0.0, 0.6], [-0.1, '']), (FloatRange(high=0.5), [-0.3, 0.5], [-0.3, 0.5], [0.6]), (Bytes(), [b'a', u'a'], [b'a'] * 2, [1]), (Bytes(strict=True), [b'a'], [b'a'], [u'a']), (Str(), [b'a', u'a'], ['a'] * 2, [1]),
class UbitrackConnectorBase(Atom): sync_source = Str() adapters = Dict() current_timestamp = Long() update_ignore_ports = List() def setup(self, facade, update_ignore_ports=None): if not hasattr(self, "ports"): raise TypeError( "UbitrackConnector is not set up correctly: ports attribute is missing." ) if update_ignore_ports is not None: self.update_ignore_ports = update_ignore_ports log.info("Setup Ubitrack Connector with %d ports and sync source: %s" % (len(self.ports), self.sync_source)) adapters = {} for pi in self.ports: if pi.port_type == PORT_TYPE_SINK: if pi.mode == PORT_MODE_PUSH: accessor_name = "getApplicationPushSink%s" % pi.data_type if hasattr(facade, accessor_name): accessor = getattr(facade, accessor_name)(pi.name) adapters[pi.name] = PushSinkAdapter(accessor) if pi.name == self.sync_source: log.info("Connect %s as sync source" % pi.name) adapters[pi.name].connect(self.handleSinkData) else: log.warn( "Missing accessor %s from facade, cannot connect PushSink %s" % (accessor_name, pi.name)) else: accessor_name = "getApplicationPullSink%s" % pi.data_type if hasattr(facade, accessor_name): accessor = getattr(facade, accessor_name)(pi.name) adapters[pi.name] = PullSinkAdapter(accessor) else: log.warn( "Missing accessor %s from facade, cannot connect PullSink %s" % (accessor_name, pi.name)) else: if pi.mode == PORT_MODE_PUSH: accessor_name = "getApplicationPushSource%s" % pi.data_type if hasattr(facade, accessor_name): accessor = getattr(facade, accessor_name)(pi.name) adapters[pi.name] = PushSourceAdapter( accessor, pi.data_type) self.observe(pi.name, self.handleSourceData) else: log.warn( "Missing accessor %s from facade, cannot connect PushSource %s" % (accessor_name, pi.name)) elif pi.mode == PORT_MODE_PULL: accessor_name = "getApplicationPullSource%s" % pi.data_type if hasattr(facade, accessor_name): accessor = getattr(facade, accessor_name)(pi.name) adapters[pi.name] = PullSourceAdapter( accessor, pi.data_type) # use default pull implementation for now. adapters[pi.name].connect() self.observe(pi.name, self.handleSourceData) else: log.warn( "Missing accessor %s from facade, cannot connect PushSource %s" % (accessor_name, pi.name)) self.adapters = adapters def teardown(self, facade): log.info("Teardown Ubitrack Connector") for pi in self.ports: if pi.name not in self.adapters: continue if pi.port_type == PORT_TYPE_SINK: if pi.mode == PORT_MODE_PUSH: self.adapters[pi.name].disconnect(self.handleSinkData) else: if pi.mode == PORT_MODE_PULL: self.adapters[pi.name].disconnect(self.handleSourceData) self.adapters = {} def handleSinkData(self, ts): try: uip = self.update_ignore_ports except Exception, e: log.error( "Problem with observer setup in uthelpers connector (self: %s)" % (self, )) log.exception(e) return for pi in self.ports: if pi.name in uip: continue if pi.port_type == PORT_TYPE_SINK: try: val = self.adapters[pi.name].get(ts) setattr(self, pi.name, val) except NoValueException, e: log.debug("No value from sink: %s for timestamp: %d" % (pi.name, ts)) except Exception, e: log.error( "Error while retrieving a value from sink: %s for timestamp: %d" % (pi.name, ts)) log.exception(e)
class Version(Atom): #: Name name = Unicode() #: Key key = Unicode() #: Language language = Unicode() #: Download url url = Unicode() #: Local path on disk path = Unicode() #: If the file was downloaded downloaded = Bool() #: Download progress progress = Int() status = Unicode() downloading = Bool() _total_bytes = Int(1) _bytes = Long() client = Instance(AsyncHttpClient, ()) def _default_url(self): return u"https://github.com/thiagobodruk/bible/raw/master/json/{}.json".format( self.key) def _default_path(self): assets = os.path.dirname(os.path.dirname(__file__)) key = os.path.splitext(os.path.split(self.url)[-1])[0] return os.path.join(assets, 'downloads', "{}.msgp".format(key)) def _default_downloaded(self): return os.path.exists(self.path) _buffer = Instance(io.BytesIO, ()) def download(self): self.status = u"Downloading {}...".format(self.name) self.downloading = True f = self.client.fetch(self.url, self._handle_response, streaming_callback=self._stream_data) #: Watch f.request.response.observe('progress', self._update_progress) def _update_progress(self, change): #: Bind response progress to this progress self.progress = change['value'] def _stream_data(self, chunk): """ Show progress """ self._bytes += self._buffer.write(chunk) #self.progress = int(100*self._bytes/self._total_bytes) def _handle_response(self, response): self.status = u"Converting..." AndroidApplication.instance().force_update() try: #: Load buffer into json self._buffer.seek(3) # First 3 bytes are crap data = json.load(self._buffer) #: Create downloads folder downloads = os.path.dirname(self.path) if not os.path.exists(downloads): os.makedirs(downloads) #: Save in msgpack format with open(self.path, 'wb') as f: msgpack.dump(data, f) self.downloaded = True self.status = u"Done!" except Exception as e: self.status = u"{}".format(e) finally: self.downloading = False
class Stream(Prop): '''A class representing an origin stream ''' name = Str() fullPath = Str() dtype = Str() time = Long() data = Member() stream = Bool() streamName = Str() streamNameFull = Str() server = Member() error = Bool() connection = Member() channels = Int() # number of data entries to be logged in this stream fieldsStr = Str() # str for displaying the stream's fields # list of field names, can be set to be updated in the GUI fieldsList = Member() # these are logged on a new connection so we can detect a change in the # stream parameters old_streamNameFull = Str() old_dtype = Str() # ========================================================================== def __init__(self, name, experiment): super(Stream, self).__init__(name, experiment) self.stream = False self.streamName = "" self.streamNameFull = "" self.server = None self.error = False self.properties += ['name', 'dtype', 'stream', 'streamName', 'fullPath'] self.properties += ['streamNameFull', 'channels', 'fieldsStr', 'fieldsList'] # ========================================================================== def new_entry(self, name, dset, ts): # initialize the non-user settable parameters self.name = name self.fullPath = dset.name self.dtype = str(dset.dtype) self.time = ts # TIMESTAMP self.channels, self.data = formatData(dset[()]) # record the fields names if self.channels == 1: self.fieldsList = [self.name] else: self.fieldsList = range(0, self.channels) self.fieldsStr = '[{}]'.format(', '.join(map(str, self.fieldsList))) # ========================================================================== def print_status(self): '''returns a string listing the status''' streamStatus = self.stream if self.error: streamStatus = "Error" msg = "*--- Dataset: {}, type: {}, streamName: {}, stream?: {}" return msg.format(self.name, self.dtype, self.streamName, streamStatus) # ========================================================================== def is_streamed(self, server, namespace): '''performs error checking and will deactivate a stream for common user errors. If no errors are detected will attempt to register the stream. Returns True if the stream registration succeeded. ''' # if we aren't attempting to stream go about your business if not self.stream: return False # common messages msg = 'You have requested that the `{}` dataset be logged to the Origin data server, but'.format(self.name) msgDisabled = ' The stream has been disabled in the settings.' # the stream needs to have a name if not self.streamName: self.stream = False msg += 'you have not specified a stream name.' msg += msgDisabled logger.warning(msg) return False # the stream needs to have a namespace if not namespace: self.stream = False msg += ' you have not specified a stream namespace.' msg += msgDisabled logger.warning(msg) return False # data type must be recognizable if not (self.dtype in dtype_list): self.stream = False msg += ' the data type you specified `{}` is not recognized.' msg += msgDisabled logger.warning(' The stream has been disabled in the settings.'.format(self.dtype)) return False # define the stream name with the experiment namespace self.streamNameFull = namespace + self.streamName # build the records dictionary records = { self.name: self.dtype } if self.channels != 1: records = {} for i in xrange(self.channels): records[str(i)] = self.dtype # register the stream self.connection = server.registerStream( stream=self.streamNameFull, records=records, timeout=20000 ) # error checking if not self.connection: msg = 'There was a problem registering the stream: `{}` with the server.' logger.error(msg.format(self.name)) self.error = True return False else: # record the settings on a successful registration so we can detect # a change self.old_streamNameFull = self.streamNameFull self.old_dtype = self.dtype self.error = False return True # ========================================================================== def logData(self): if self.channels == 1: data = { TIMESTAMP: self.time, self.name: self.data } else: data = { TIMESTAMP: self.time } for i, d in enumerate(self.data): data[str(i)] = d self.connection.send(**data) msg = 'Stream `{}` for dataset `{}` logged to Origin server.' logger.debug(msg.format(self.streamName, self.name)) # ========================================================================== def connected(self, namespace): """If the stream name or data type has changed then we need to re-register. """ self.streamNameFull = namespace + self.streamName if (self.old_streamNameFull == self.streamNameFull) and (self.dtype == self.old_dtype): if self.connection: return True else: if self.connection: self.connection.close() return False
class ExecuteProgramTask(InstrumentTask): """ Executes a qua program. """ path_to_program_file = Unicode().tag(pref=True) duration_limit = Long(default=int(1000)).tag(pref=True) data_limit = Long(default=int(20000)).tag(pref=True) #: Dictionary containing all the parameters used in the program parameters = Typed(dict).tag(pref=True) #: Dictionary containing the comments for the parameters used in the program comments = Typed(dict).tag(pref=True) def __init__(self, **kwargs): super().__init__(**kwargs) def _post_setattr_path_to_program_file(self, old, new): self.comments = {} if new: try: importlib.invalidate_caches() directory = get_directory_from_path(self.path_to_program_file) module_name = get_module_name_from_path(self.path_to_program_file) sys.path.append(directory) module_with_config = importlib.import_module(module_name) module_with_config = importlib.reload(module_with_config) params = module_with_config.get_parameters() tmp = {} # Temporary dict to avoid updating the view needlessly # find the default values and comments for i in params: if len(params[i]) == 1: if i not in self.parameters: tmp[i] = str(params[i]) else: tmp[i] = self.parameters[i] self.comments = '' else: if i not in self.parameters: tmp[i] = str(params[i][0]) else: tmp[i] = self.parameters[i] self.comments[i] = str(params[i][1]) self.parameters = tmp except: print('Program cannot be loaded from {}\n'.format(new)) self.parameters = {} def perform(self): directory = get_directory_from_path(self.path_to_program_file) module_name = get_module_name_from_path(self.path_to_program_file) sys.path.append(directory) module_with_program = importlib.import_module(module_name) module_with_program = importlib.reload(module_with_program) # Convert all the parameters to floats params = {} for i in self.parameters: params[i] = float(self.format_and_eval_string(self.parameters[i])) program_to_execute = module_with_program.get_prog(params) self.driver.execute_program(program_to_execute, self.duration_limit, self.data_limit)
class VirtualCameraWidget(RawWidget): """ A Qt4 implementation of an Enaml ProxyVirtualCameraWidget. """ __slots__ = '__weakref__' camera_width = d_(Int(1024)) camera_height = d_(Int(768)) #: The scene that should be displayed scene = d_(ForwardTyped(lambda: Scene3D)) #: The camera image measurement background_texture = d_(Value()) #: The camera intrinsics measurement camera_intrinsics = d_(Value()) #: The camera pose measurement camera_pose = d_(Value()) #: The current timestamp current_timestamp = d_(Long()) #: Cyclic notification guard flags. _guard = d_(Int(0)) key_events = d_(Event()) #: . hug_width = set_default('weak') hug_height = set_default('weak') #-------------------------------------------------------------------------- # Initialization API #-------------------------------------------------------------------------- def create_widget(self, parent): """ Create the QListView widget. """ # Create the list model and accompanying controls: widget = QtVirtualCameraWidget( parent=parent, key_event_handler=self.key_events, cam_width=self.camera_width, cam_height=self.camera_height, # add properties for camera near, far, ... ) widget.sigUpdate.connect(self._update_model) if self.scene.grid: widget.addItem(self.scene.grid.item) if self.scene.orientation_axes: widget.addItem(self.scene.orientation_axes.item) for item in self.scene.items: widget.addItem(item.item) def _handle_update(change): if change['type'] == 'create': return self.on_update() self.scene.observe("needs_update", _handle_update) return widget def _update_model(self): """ Synchronize view attributes to the model. """ if self._guard & ITEM_CHANGE_FLAG: return self._guard &= VIEW_SYNC_FLAG widget = self.get_widget() # for (key, value) in widget.opts.items(): # if not key in ['azimuth', 'distance', 'fov', 'center', 'elevation']: # continue # setattr(self, key, value) self._guard &= ~VIEW_SYNC_FLAG #-------------------------------------------------------------------------- # Signal Handlers #-------------------------------------------------------------------------- def on_update_items(self): """ The signal handler for the index changed signal. """ self.set_items(self.scene.items) self.on_update() def on_update(self): """ The signal handler for the index changed signal. """ widget = self.get_widget() widget.updateGL() #-------------------------------------------------------------------------- # ProxyListStrView API #-------------------------------------------------------------------------- def set_items(self, items): """ """ if self._guard & VIEW_SYNC_FLAG: return self._guard &= ITEM_CHANGE_FLAG widget = self.get_widget() for item in widget.items: widget.removeItem(item) if self.scene.grid: widget.addItem(self.scene.grid.item) if self.scene.orientation_axes: widget.addItem(self.scene.orientation_axes.item) for item in items: widget.addItem(item.item) self._guard &= ~ITEM_CHANGE_FLAG def readQImage(self): widget = self.get_widget() if widget is not None: return widget.readQImage() def renderToArray(self, size, format=GL_BGRA, type=GL_UNSIGNED_BYTE, textureSize=1024, padding=256): widget = self.get_widget() if widget is not None: return widget.renderToArray(size, format=format, type=type, textureSize=textureSize, padding=padding) #-------------------------------------------------------------------------- # Observers #-------------------------------------------------------------------------- @observe('scene') def _update_scene(self, change): """ An observer which sends state change to the proxy. """ if change['type'] == 'create': return self._guard |= ITEM_CHANGE_FLAG self.on_update_items() self._guard &= ~ITEM_CHANGE_FLAG @observe( 'current_timestamp', ) def _update_gl(self, change): widget = self.get_widget() if widget: if change["type"] == "update": if self.background_texture is not None: widget.setBackgroundTexture(self.background_texture) if self.camera_intrinsics is not None: widget.setCameraIntrinsics(self.camera_intrinsics) if self.camera_pose is not None: widget.setCameraPose(self.camera_pose) @observe('camera_width', 'camera_height') def _update_camera_parameters(self, change): widget = self.get_widget() if widget: if change["type"] == "update": if change["name"] == "camera_width": print self.camera_width, type(self.camera_width) widget.camera_width = self.camera_width elif change["name"] == "camera_height": print self.camera_height, type(self.camera_height) widget.camera_height = self.camera_height