def test_member_set_behaviors_wrong_args(mode, msg): """Test handling bad arguments to set_setattr_mode """ m = Int() with pytest.raises(TypeError) as excinfo: m.set_setattr_mode(getattr(SetAttr, mode), 1) assert msg in excinfo.exconly()
def test_using_object_method_mode(): """Test using object_method mode. """ m = Int() m.set_getattr_mode(GetAttr.ObjectMethod, 'getter') class CustomGetAtom(Atom): val = m count = Int() def getter(self): self.count += 1 return self.count a = CustomGetAtom() assert a.val == 1 assert a.val == 2 with pytest.raises(TypeError): m.set_getattr_mode(GetAttr.CallObject_Object, 1)
def test_using_call_object_object_mode(): """Test using call_object_object mode. """ def getter(object): object.count += 1 return object.count m = Int() m.set_getattr_mode(GetAttr.CallObject_Object, getter) class CustomGetAtom(Atom): val = m count = Int() a = CustomGetAtom() assert a.val == 1 assert a.val == 2 with pytest.raises(TypeError): m.set_getattr_mode(GetAttr.CallObject_Object, 1)
class QtSlider(QtControl, ProxySlider): """ A Qt implementation of an Enaml ProxySlider. """ #: A reference to the widget created by the proxy. widget = Typed(QSlider) #: Cyclic notification guard flags. _guard = Int(0) #-------------------------------------------------------------------------- # Initialization API #-------------------------------------------------------------------------- def create_widget(self): """ Create the underlying QSlider widget. """ self.widget = QSlider(self.parent_widget()) def init_widget(self): """ Initialize the underlying widget. """ super(QtSlider, self).init_widget() d = self.declaration self.set_minimum(d.minimum) self.set_maximum(d.maximum) self.set_value(d.value) self.set_orientation(d.orientation) self.set_page_step(d.page_step) self.set_single_step(d.single_step) self.set_tick_interval(d.tick_interval) self.set_tick_position(d.tick_position) self.set_tracking(d.tracking) self.widget.valueChanged.connect(self.on_value_changed) #-------------------------------------------------------------------------- # Signal Handlers #-------------------------------------------------------------------------- def on_value_changed(self): """ Send the 'value_changed' action to the Enaml widget when the slider value has changed. """ if not self._guard & VALUE_FLAG: self._guard |= VALUE_FLAG try: self.declaration.value = self.widget.value() finally: self._guard &= ~VALUE_FLAG #-------------------------------------------------------------------------- # ProxySlider API #-------------------------------------------------------------------------- def set_maximum(self, maximum): """ Set the maximum value of the underlying widget. """ self.widget.setMaximum(maximum) def set_minimum(self, minimum): """ Set the minimum value of the underlying widget. """ self.widget.setMinimum(minimum) def set_value(self, value): """ Set the value of the underlying widget. """ if not self._guard & VALUE_FLAG: self._guard |= VALUE_FLAG try: self.widget.setValue(value) finally: self._guard &= ~VALUE_FLAG def set_page_step(self, page_step): """ Set the page step of the underlying widget. """ self.widget.setPageStep(page_step) def set_single_step(self, single_step): """ Set the single step of the underlying widget. """ self.widget.setSingleStep(single_step) def set_tick_interval(self, interval): """ Set the tick interval of the underlying widget. """ self.widget.setTickInterval(interval) def set_tick_position(self, tick_position): """ Set the tick position of the underlying widget. """ self.widget.setTickPosition(TICK_POSITION[tick_position]) def set_orientation(self, orientation): """ Set the orientation of the underlying widget. """ self.widget.setOrientation(ORIENTATION[orientation]) def set_tracking(self, tracking): """ Set the tracking of the underlying widget. """ self.widget.setTracking(tracking)
class RootTask(ComplexTask): """Special task which is always the root of a measurement. On this class and this class only perform can and should be called directly. """ #: Path to which log infos, preferences, etc should be written by default. default_path = Unicode('').tag(pref=True) #: Should the execution be profiled. should_profile = Bool().tag(pref=True) #: Dict storing data needed at execution time (ex: drivers classes) run_time = Dict() #: Inter-process event signaling the task it should stop execution. should_stop = Typed(Event) #: Inter-process event signaling the task it should pause execution. should_pause = Typed(Event) #: Inter-process event signaling the task is paused. paused = Typed(Event) #: Inter-process event signaling the main thread is done, handling the #: measurement resuming, and hence notifying the task execution has #: resumed. resumed = Typed(Event) #: Dictionary used to store errors occuring during performing. errors = Dict() #: Dictionary used to store references to resources that may need to be #: shared between task and which must be released when all tasks have been #: performed. #: Each key is associated to a different kind of resource. Resources must #: be stored in SharedDict subclass. #: By default three kind of resources exists: #: #: - threads : used threads grouped by pool. #: - active_threads : currently active threads. #: - instrs : used instruments referenced by profiles. #: - files : currently opened files by path. #: resources = Dict() #: Counter keeping track of the active threads. active_threads_counter = Typed(SharedCounter, kwargs={'count': 1}) #: Counter keeping track of the paused threads. paused_threads_counter = Typed(SharedCounter, ()) #: Thread from which the perform method has been called. thread_id = Int() # Those must not be modified so freeze them name = Constant('Root') depth = Constant(0) path = Constant('root') database_entries = set_default({'default_path': ''}) # HINT: RootTask instance tracking code # __slots__ = ('__weakref__',) def __init__(self, *args, **kwargs): self.preferences = ConfigObj(indent_type=' ', encoding='utf-8') self.database = TaskDatabase() super(RootTask, self).__init__(*args, **kwargs) self.register_in_database() self.root = self self.parent = self self.active_threads_counter.observe('count', self._state) self.paused_threads_counter.observe('count', self._state) # HINT: RootTask instance tracking code # ROOTS.add(self) # print(len(ROOTS)) def check(self, *args, **kwargs): """Check that the default path is a valid directory. """ traceback = {} test = True if not os.path.isdir(self.default_path): test = False traceback[self.path + '/' + self.name] =\ 'The provided default path is not a valid directory' self.write_in_database('default_path', self.default_path) check = super(RootTask, self).check(*args, **kwargs) test = test and check[0] traceback.update(check[1]) return test, traceback @smooth_crash def perform(self): """Run sequentially all child tasks, and close ressources. """ result = True self.thread_id = threading.current_thread().ident self.prepare() pr = Profile() if self.should_profile else None try: if pr: pr.enable() for child in self.children: child.perform_() except Exception: log = logging.getLogger(__name__) msg = 'The following unhandled exception occured :\n' log.exception(msg) self.should_stop.set() result = False self.errors['unhandled'] = msg + format_exc() finally: if pr: pr.disable() meas_name = self.get_from_database('meas_name') meas_id = self.get_from_database('meas_id') path = os.path.join(self.default_path, meas_name + '_' + meas_id + '.prof') pr.dump_stats(path) self.release_resources() if self.should_stop.is_set(): result = False return result def prepare(self): """Optimise the database for running state and prepare children. """ # We cannot assume that the checks were run (in the case of a # forced-enqueueing) so we need to make sure we set the default path. self.write_in_database('default_path', self.default_path) self.database.prepare_to_run() super().prepare() def release_resources(self): """Release all the resources used by tasks. """ # Release by priority to be sure that their is no-conflict # (Threads vs instruments for example) for resource in sorted(self.resources.values(), key=attrgetter('priority')): resource.release() def register_in_database(self): """Don't create a node for the root task. """ BaseTask.register_in_database(self) # ComplexTask defines children so we always get something for child in self.gather_children(): child.register_in_database() @classmethod def build_from_config(cls, config, dependencies): """Create a new instance using the provided infos for initialisation. Parameters ---------- config : dict(str) Dictionary holding the new values to give to the members in string format, or dictionnary like for instance with prefs. dependencies : dict Dictionary holding the necessary classes needed when rebuilding. This is assembled by the TaskManager. Returns ------- task : RootTask Newly created and initiliazed task. Notes ----- This method is fairly powerful and can handle a lot of cases so don't override it without checking that it works. """ task = super(RootTask, cls).build_from_config(config, dependencies) task._post_setattr_root(None, task) task.register_in_database() task.register_preferences() return task def get_used_names(self): """Return the list of all names used in the tree Returns ------- names : List(str) List of all the names used in the tree. """ names = [] for i in self.traverse(): # Effectively ignores TaskInterface objects if hasattr(i, 'name'): names.append(i.name) return names # ========================================================================= # --- Private API --------------------------------------------------------- # ========================================================================= def _default_task_id(self): pack, _ = self.__module__.split('.', 1) return pack + '.' + ComplexTask.__name__ def _child_path(self): """Overriden here to not add the task name. """ return self.path def _task_entry(self, entry): """Do not prepend the name of the root task. """ return entry def _state(self, change): """Determine whether the task is paused or not. This is done by checking the number of active and paused thread and setting accordingly the paused event. """ p_count = self.paused_threads_counter.count a_count = self.active_threads_counter.count if a_count == p_count: self.paused.set() if p_count == 0: self.paused.clear() def _default_resources(self): """Default resources. """ return {'threads': ThreadPoolResource(), # Reduce priority to stop through the thread resource. # This is far less likely to cause a deadlock. 'active_threads': ThreadPoolResource(priority=0), 'instrs': InstrsResource(), 'files': FilesResource()}
class ContactsResponse(Response): """ Expected response from api/contacts """ Limit = Int() Total = Int() Contacts = List(Contact)
class MessagesResponse(Response): """ Expected response from api/messages """ Limit = Int() Total = Int() Messages = List(Message)
class MessageEvent(Model): ID = Int() Action = Int() Message = Instance(Message)
class QtNotebook(QtConstraintsWidget, ProxyNotebook): """ A Qt implementation of an Enaml ProxyNotebook. """ #: A reference to the widget created by the proxy. widget = Typed(QNotebook) #: A bitfield of guard flags for the object. _guard = Int(0) #-------------------------------------------------------------------------- # Initialization API #-------------------------------------------------------------------------- def create_widget(self): """ Create the underlying notebook widget. """ widget = QNotebook(self.parent_widget()) if sys.platform == 'darwin': # On OSX, the widget item layout rect is too small. # Setting this attribute forces the widget item to # use the widget rect for layout. widget.setAttribute(Qt.WA_LayoutUsesWidgetRect, True) self.widget = widget def init_widget(self): """ Initialize the underyling widget. """ super(QtNotebook, self).init_widget() d = self.declaration self.set_tab_style(d.tab_style) self.set_tab_position(d.tab_position) self.set_tabs_closable(d.tabs_closable) self.set_tabs_movable(d.tabs_movable) self.set_size_hint_mode(d.size_hint_mode, update=False) # the selected tab is synchronized during init_layout def init_layout(self): """ Handle the layout initialization for the notebook. """ super(QtNotebook, self).init_layout() widget = self.widget for page in self.pages(): widget.addPage(page) self.init_selected_tab() widget.layoutRequested.connect(self.on_layout_requested) widget.currentChanged.connect(self.on_current_changed) #-------------------------------------------------------------------------- # Utility Methods #-------------------------------------------------------------------------- def pages(self): """ Get the pages defined for the notebook. """ for p in self.declaration.pages(): w = p.proxy.widget if w is not None: yield w def find_page(self, name): """ Find the page with the given name. Parameters ---------- name : unicode The object name for the page of interest. Returns ------- result : QPage or None The target page or None if one is not found. """ for page in self.pages(): if page.objectName() == name: return page def init_selected_tab(self): """ Initialize the selected tab. This should be called only during widget initialization. """ d = self.declaration if d.selected_tab: self.set_selected_tab(d.selected_tab) else: current = self.widget.currentWidget() name = current.objectName() if current is not None else u'' self._guard |= CHANGE_GUARD try: d.selected_tab = name finally: self._guard &= ~CHANGE_GUARD #-------------------------------------------------------------------------- # Child Events #-------------------------------------------------------------------------- def child_added(self, child): """ Handle the child added event for a QtNotebook. """ super(QtNotebook, self).child_added(child) if isinstance(child, QtPage): for index, dchild in enumerate(self.children()): if child is dchild: self.widget.insertPage(index, child.widget) def child_removed(self, child): """ Handle the child removed event for a QtNotebook. """ super(QtNotebook, self).child_removed(child) if isinstance(child, QtPage): self.widget.removePage(child.widget) #-------------------------------------------------------------------------- # Signal Handlers #-------------------------------------------------------------------------- def on_layout_requested(self): """ Handle the `layoutRequested` signal from the QNotebook. """ self.geometry_updated() def on_current_changed(self): """ Handle the 'currentChanged' signal from the QNotebook. """ if not self._guard & CHANGE_GUARD: self._guard |= CHANGE_GUARD try: page = self.widget.currentWidget() name = page.objectName() if page is not None else u'' self.declaration.selected_tab = name finally: self._guard &= ~CHANGE_GUARD #-------------------------------------------------------------------------- # ProxyNotebook API #-------------------------------------------------------------------------- def set_tab_style(self, style): """ Set the tab style for the tab bar in the widget. """ self.widget.setDocumentMode(DOCUMENT_MODES[style]) def set_tab_position(self, position): """ Set the position of the tab bar in the widget. """ self.widget.setTabPosition(TAB_POSITIONS[position]) def set_tabs_closable(self, closable): """ Set whether or not the tabs are closable. """ self.widget.setTabsClosable(closable) def set_tabs_movable(self, movable): """ Set whether or not the tabs are movable. """ self.widget.setMovable(movable) def set_selected_tab(self, name): """ Set the selected tab of the widget. """ if not self._guard & CHANGE_GUARD: page = self.find_page(name) if page is None: import warnings msg = "cannot select tab '%s' - tab not found" warnings.warn(msg % name, UserWarning) return self._guard |= CHANGE_GUARD try: self.widget.setCurrentWidget(page) finally: self._guard &= ~CHANGE_GUARD def set_size_hint_mode(self, mode, update=True): """ Set the size hint mode for the widget. """ self.widget.setSizeHintMode(SIZE_HINT_MODE[mode]) if update: self.geometry_updated()
class Multi(Multi1, Multi2): i4 = Int(12) # Test that conflicts do not mess up overridden members
class Multi2(Atom): i3 = Int() i4 = Int()
class Multi1(Atom): i1 = Int() i2 = Int()
class Default1(Atom): i = Int() i2 = Int()
class A(Atom): val = Int()
class FreezingTest(Atom): a = Int()
class PicklingTest(Atom): __slots__ = ('d',) a = b = c = Int()
class QtField(QtControl, ProxyField): """ A Qt4 implementation of an Enaml ProxyField. """ #: A reference to the widget created by the proxy. widget = Typed(QFocusLineEdit) #: A collapsing timer for auto sync text. _text_timer = Typed(QTimer) #: Cyclic notification guard. This a bitfield of multiple guards. _guard = Int(0) #-------------------------------------------------------------------------- # Initialization API #-------------------------------------------------------------------------- def create_widget(self): """ Creates the underlying QFocusLineEdit widget. """ self.widget = QFocusLineEdit(self.parent_widget()) def init_widget(self): """ Create and initialize the underlying widget. """ super(QtField, self).init_widget() d = self.declaration if d.text: self.set_text(d.text) if d.mask: self.set_mask(d.mask) if d.placeholder: self.set_placeholder(d.placeholder) self.set_echo_mode(d.echo_mode) self.set_max_length(d.max_length) self.set_read_only(d.read_only) self.set_submit_triggers(d.submit_triggers) self.widget.textEdited.connect(self.on_text_edited) #-------------------------------------------------------------------------- # Private API #-------------------------------------------------------------------------- def _validate_and_apply(self): """ Validate and apply the text in the control. """ d = self.declaration v = d.validator text = self.widget.text() if v and not v.validate(text): text = v.fixup(text) if not v.validate(text): return if text != self.widget.text(): self.widget.setText(text) self._clear_error_state() d.text = text def _set_error_state(self): """ Set the error state of the widget. """ # A temporary hack until styles are implemented if not self._guard & ERROR_FLAG: self._guard |= ERROR_FLAG s = u'QLineEdit { border: 2px solid red; background: rgb(255, 220, 220); }' self.widget.setStyleSheet(s) v = self.declaration.validator self.widget.setToolTip(v and v.message or u'') def _clear_error_state(self): """ Clear the error state of the widget. """ # A temporary hack until styles are implemented if self._guard & ERROR_FLAG: self._guard &= ~ERROR_FLAG self.widget.setStyleSheet(u'') self.widget.setToolTip(u'') def _maybe_valid(self, text): """ Get whether the text is valid or can be valid. Returns ------- result : bool True if the text is valid, or can be made to be valid, False otherwise. """ v = self.declaration.validator return v is None or v.validate(text) or v.validate(v.fixup(text)) #-------------------------------------------------------------------------- # Signal Handlers #-------------------------------------------------------------------------- def on_submit_text(self): """ The signal handler for the text submit triggers. """ self._guard |= TEXT_GUARD try: self._validate_and_apply() finally: self._guard &= ~TEXT_GUARD def on_text_edited(self): """ The signal handler for the 'textEdited' signal. """ if not self._maybe_valid(self.widget.text()): self._set_error_state() else: self._clear_error_state() if self._text_timer is not None: self._text_timer.start() #-------------------------------------------------------------------------- # ProxyField API #-------------------------------------------------------------------------- def set_text(self, text): """ Set the text in the widget. """ if not self._guard & TEXT_GUARD: self.widget.setText(text) self._clear_error_state() def set_mask(self, mask): """ Set the make for the widget. """ self.widget.setInputMask(mask) def set_submit_triggers(self, triggers): """ Set the submit triggers for the widget. """ widget = self.widget handler = self.on_submit_text try: widget.lostFocus.disconnect() except (TypeError, RuntimeError): # was never connected pass try: widget.returnPressed.disconnect() except (TypeError, RuntimeError): # was never connected pass if 'lost_focus' in triggers: widget.lostFocus.connect(handler) if 'return_pressed' in triggers: widget.returnPressed.connect(handler) if 'auto_sync' in triggers: if self._text_timer is None: timer = self._text_timer = QTimer() timer.setSingleShot(True) timer.setInterval(300) timer.timeout.connect(handler) else: if self._text_timer is not None: self._text_timer.stop() self._text_timer = None def set_placeholder(self, text): """ Set the placeholder text of the widget. """ self.widget.setPlaceholderText(text) def set_echo_mode(self, mode): """ Set the echo mode of the widget. """ self.widget.setEchoMode(ECHO_MODES[mode]) def set_max_length(self, length): """ Set the maximum text length in the widget. """ if length <= 0 or length > 32767: length = 32767 self.widget.setMaxLength(length) def set_read_only(self, read_only): """ Set whether or not the widget is read only. """ self.widget.setReadOnly(read_only) def field_text(self): """ Get the text stored in the widget. """ return self.widget.text()
class NIScopeInstrument(Instrument): DeviceName = Member() data = Member() # holds acquired data until they are written FFTdata = Member() mode = Str('experiment') # experiment vs. video analysis = Member() # holds a link to the GUI display scope = Member() TrigSlope = Int(0) TrigMode = Int(0) TrigSource = Int(2) TrigLevel = Member() TrigDelay = Member() FFTMeas = Bool(False) HorizScale = Int(0) HorizRecordLength = Member() Chan0VertScale = Int(0) Chan0Coupling = Int(0) Chan0Impedance = Int(0) Chan0Atten = Int(0) Chan0Offset = Member() Chan1VertScale = Int(0) Chan1Coupling = Int(0) Chan1Impedance = Int(0) Chan1Atten = Int(0) Chan1Offset = Member() voltageranges = [2.5, 2.0, 1.0, 0.50, 0.20, 0.10] horizscales = [ 0.33, 0.20, 0.10, 50.0e-3, 20.0e-3, 10.0e-3, 5.0e-3, 2.0e-3, 1.0e-3, 0.50e-3, 0.20e-3, 0.10e-3, 50e-6, 20e-6, 10e-6, 5.0e-6, 2.0e-6, 1.0e-6, 0.50e-6, 0.25e-6 ] if niScopeImported: couplings = [ COUPLING.DC, COUPLING.AC, COUPLING.GND, COUPLING.HF_REJECT, COUPLING.AC_PLUS_HF_REJECT ] triggerSources = [ '0', '1', TRIGGER_SOURCE.EXTERNAL, TRIGGER_SOURCE.IMMEDIATE ] triggerSlopes = [SLOPE.POSITIVE, SLOPE.NEGATIVE] else: couplings = range(20) triggerSources = range(20) triggerSlopes = range(20) attens = [1, 10] def __init__(self, name, experiment, description=''): super(NIScopeInstrument, self).__init__(name, experiment, description) self.DeviceName = StrProp('DeviceName', experiment, 'NI Device Name', 'Dev0') self.TrigLevel = FloatProp('TrigLevel', experiment, 'Trigger Level (V)', '0') self.TrigDelay = FloatProp('TrigDelay', experiment, 'Trigger Delay (s)', '0') self.HorizRecordLength = IntProp( 'HorizRecordLength', experiment, 'Number of points to take per trigger', '0') self.Chan0Offset = FloatProp('Chan0Offset', experiment, 'CH0 Offset (V)', '0') self.Chan1Offset = FloatProp('Chan1Offset', experiment, 'CH1 Offset (V)', '0') self.properties += [ 'DeviceName', 'TrigLevel', 'TrigDelay', 'HorizRecordLength', 'Chan0Offset', 'Chan1Offset', 'Chan1Atten', 'Chan1Impedance', 'Chan1Coupling', 'Chan1VertScale', 'Chan0Atten', 'Chan0Impedance', 'Chan0Coupling', 'Chan0VertScale', 'HorizScale', 'TrigSource', 'TrigMode', 'TrigSlope', 'FFTMeas' ] def initialize(self): try: self.scope = niScope.Scope(resourceName=self.DeviceName.value) logger.info('Initializing niScope') except Exception as e: logger.error( "Failed to initialize niScope (name: {}). Exception: {}". format(self.DeviceName.value, e)) raise PauseError self.isInitialized = True def start(self): if self.scope.AcquisitionStatus(): self.scope.Abort() self.scope.InitiateAcquisition() self.isDone = True def update(self): logger.info('updating NIScope') if self.enable: if not self.isInitialized: logger.info('Initializing NIScope') self.initialize() #logger.warning('Checking Acquisition Status') #acqstat = self.scope.AcquisitionStatus() #logger.warning('Acquisition status = {}'.format(acqstat)) #if acqstat: #logger.warning('Aborting old acquisition') self.scope.Abort() #logger.warning('Initiating Acquisition') samplerate = self.getSampleRate() self.scope.ConfigureHorizontalTiming( numPts=self.HorizRecordLength.value, sampleRate=samplerate) chanList = "0:1" if self.Chan0Impedance: impedance = 50 else: impedance = 1000000 self.scope.ConfigureChanCharacteristics(chanList, impedance, 0) self.scope.ConfigureVertical( channelList='0', voltageRange=self.voltageranges[self.Chan0VertScale], offset=self.Chan0Offset.value, coupling=self.couplings[self.Chan0Coupling], probeAttenuation=self.attens[self.Chan0Atten]) self.scope.ConfigureVertical( channelList='1', voltageRange=self.voltageranges[self.Chan0VertScale], offset=self.Chan1Offset.value, coupling=self.couplings[self.Chan1Coupling], probeAttenuation=self.attens[self.Chan0Atten]) #logger.warning('Configuring Trigger') if self.TrigSource != 3: self.scope.ConfigureTrigger( trigger_type="Edge", triggerSource=self.triggerSources[self.TrigSource], level=self.TrigLevel.value, slope=self.triggerSlopes[self.TrigSlope], triggerCoupling=COUPLING.DC, holdoff=0, delay=self.TrigDelay.value) else: self.scope.ConfigureTrigger(trigger_type="Immediate") self.scope.InitiateAcquisition() #was in start def setup_video_thread(self, analysis): thread = threading.Thread(target=self.setup_video, args=(analysis, )) #thread.daemon = True thread.start() def setup_video(self, analysis): if self.experiment.status != 'idle': logger.warning( 'Cannot start video mode unless experiment is idle.') return self.mode = 'video' self.analysis = analysis previouslyenabled = self.enable self.enable = True self.experiment.evaluate() self.enable = previouslyenabled if not self.isInitialized: self.initialize() #(do some config shit here) self.StartAcquisition() # run the video loop in a new thread self.start_video_thread() def start_video_thread(self): while self.mode == 'video': if self.getData(): # if there is new data, then redraw image self.analysis.redraw_video() time.sleep(.1) def stop_video(self): # stop the video thread from looping self.mode = 'idle' time.sleep(.01) self.AbortAcquisition() def acquire_data(self): """Overwritten from Instrument, this function is called by the experiment after each measurement run to make sure all pictures have been acquired.""" if self.enable: data = self.scope.Fetch(channelList='0,1').T print "data.shape={}".format(data.shape) fx, FFTdata = self.scope.FetchMeasurement( channelList='0,1', arrayMeasurement=NISCOPE_VAL_FFT_AMP_SPECTRUM_DB) x = numpy.linspace(0, self.horizscales[self.HorizScale], self.HorizRecordLength.value) self.data = numpy.stack((x, data[0], data[1])) print "fx.shape={}".format(fx.shape) print "FFTdata.shape={}".format(FFTdata.shape) self.FFTdata = numpy.stack((fx[0], FFTdata[0], FFTdata[1])) def writeResults(self, hdf5): """Overwritten from Instrument. This function is called by the experiment after data acquisition to write the obtained images to hdf5 file.""" if self.enable: try: hdf5['NIScope_{}'.format(self.DeviceName.value)] = self.data hdf5['NIScope_FFT_{}'.format( self.DeviceName.value)] = self.FFTdata except Exception as e: logger.error('in NIScope.writeResults:\n{}'.format(e)) raise PauseError def getLimits(self): return self.HorizScale, self.VertScale #How to set vert scale? def getSampleRate(self): index = self.HorizScale rate = self.HorizRecordLength.value / (self.horizscales[index]) return rate
class ViewerProcess(ProcessLineReceiver): #: Window id obtained after starting the process window_id = Int() #: Process handle process = Instance(object) #: Reference to the plugin plugin = ForwardInstance(lambda: ViewerPlugin) #: Document document = ForwardInstance(document_type) #: Rendering error errors = Str() #: Process terminated intentionally terminated = Bool(False) #: Count restarts so we can detect issues with startup s restarts = Int() #: Max number it will attempt to restart max_retries = Int(20) #: ID count _id = Int() #: Holds responses temporarily _responses = Dict() #: Seconds to ping _ping_rate = Int(40) #: Capture stderr separately err_to_out = set_default(False) def redraw(self): if self.document: # Trigger a reload self.document.version += 1 else: self.set_version(self._id) @observe('document', 'document.version') def _update_document(self, change): doc = self.document if doc is None: self.set_filename('-') else: self.set_filename(doc.name) self.set_version(doc.version) def send_message(self, method, *args, **kwargs): # Defer until it's ready if not self.transport or not self.window_id: #log.debug('renderer | message not ready deferring') timed_call(1000, self.send_message, method, *args, **kwargs) return _id = kwargs.pop('_id') _silent = kwargs.pop('_silent', False) request = { 'jsonrpc': '2.0', 'method': method, 'params': args or kwargs } if _id is not None: request['id'] = _id if not _silent: log.debug(f'renderer | sent | {request}') self.transport.write(jsonpickle.dumps(request).encode() + b'\r\n') def _default_process(self): from twisted.internet import reactor atexit.register(self.terminate) cmd = [sys.executable] if not sys.executable.endswith('declaracad'): cmd.extend(['-m', 'declaracad']) cmd.extend(['view', '-', '-f']) return reactor.spawnProcess(self, sys.executable, args=cmd, env=os.environ) def _default_window_id(self): # Spawn the process timed_call(0, lambda: self.process) return 0 def restart(self): self.window_id = 0 self.restarts += 1 # TODO: 100 is probably excessive if self.restarts > self.max_retries: plugin = self.plugin plugin.workbench.message_critical( "Viewer failed to start", "Could not get the viewer to start after several attempts.") raise RuntimeError( "renderer | Failed to successfully start renderer aborting!") self.process = self._default_process() def connectionMade(self): super(ViewerProcess, self).connectionMade() self.schedule_ping() self.terminated = False def lineReceived(self, line): try: line = line.decode() response = jsonpickle.loads(line) #log.debug(f"viewer | resp | {response}") except Exception as e: log.debug(f"viewer | out | {line}") response = {} doc = self.document if not isinstance(response, dict): log.debug(f"viewer | out | {response}") return #: Special case for startup response_id = response.get('id') if response_id == 'window_id': self.window_id = response['result'] self.restarts = 0 # Clear the restart count return elif response_id == 'keep_alive': return elif response_id == 'render_error': if doc: doc.errors.extend(response['error']['message'].split("\n")) return elif response_id == 'render_success': if doc: doc.errors = [] return elif response_id == 'capture_output': # Script output capture it if doc: doc.output = response['result'].split("\n") return elif response_id == 'shape_selection': #: TODO: Do something with this? if doc: doc.output.append(str(response['result'])) return elif response_id is not None: # Lookup the deferred object that should be stored for this id # when it is called and invoke the callback or errback based on the # result d = self._responses.get(response_id) if d is not None: del self._responses[response_id] try: error = response.get('error') if error is not None: if doc: doc.errors.extend( error.get('message', '').split("\n")) d.errback(error) else: d.callback(response.get('result')) return except Exception as e: log.warning("RPC response not properly handled!") log.exception(e) else: log.warning("Got unexpected reply") # else we got a response from something else, possibly an error? if 'error' in response and doc: doc.errors.extend(response['error'].get('message', '').split("\n")) doc.output.append(line) elif 'message' in response and doc: doc.output.extend(response['message'].split("\n")) elif doc: # Append to output doc.output.extend(line.split("\n")) def errReceived(self, data): """ Catch and log error output attempting to decode it """ for line in data.split(b"\n"): if not line: continue if line.startswith(b"QWidget::") or line.startswith(b"QPainter::"): continue try: line = line.decode() log.debug(f"render | err | {line}") if self.document: self.document.errors.append(line) except Exception as e: log.debug(f"render | err | {line}") def inConnectionLost(self): log.warning("renderer | stdio closed (we probably did it)") def outConnectionLost(self): if not self.terminated: # Clear the filename on crash so it works when reset #self.document = None self.restart() log.warning("renderer | stdout closed") def errConnectionLost(self): log.warning("renderer | stderr closed") def processEnded(self, reason): super(ViewerProcess, self).processEnded(reason) log.warning(f"renderer | process ended: {reason}") def terminate(self): super(ViewerProcess, self).terminate() self.terminated = True def schedule_ping(self): """ Ping perioidcally so the process stays awake """ if self.terminated: return # Ping the viewer to tell it to keep alive self.send_message("ping", _id="keep_alive", _silent=True) timed_call(self._ping_rate * 1000, self.schedule_ping) def __getattr__(self, name): """ Proxy all calls not defined here to the remote viewer. This makes doing `setattr(renderer, attr, value)` get passed to the remote viewer. """ def remote_viewer_call(*args, **kwargs): d = Deferred() self._id += 1 kwargs['_id'] = self._id self._responses[self._id] = d self.send_message(name, *args, **kwargs) return d return remote_viewer_call
class EventsResult(Model): Locations = List(Location) Labels = List(Label) Starred = Int()
class AgilentNetworkAnalyzer(COM_Instrument): base_name = "E8354B" @private_property def S_names(self): return ('S11', 'S21', 'S12', 'S22') @private_property def main_params(self): return [ "doS11", "doS21", "doS12", "doS22", "trigger_mode", "VNA_abort", "start_freq", "stop_freq", "points", "averaging", "averages", 'timeout', "power", 'clear_average', 'acquire_data', 'error_query' ] #::inst0::INSTR" #enable SICL in system settings #"TCPIP::129.16.115.134::5025::SOCKET" address = Unicode("TCPIP::129.16.115.134").tag(sub=True, no_spacer=True) simulate = Bool(False).tag(sub=True) VNA = Value().tag(private=True, desc="a link to the session of the instrument.") ch1 = Value().tag(private=True, desc="link to main instrument channel") measS11 = Value().tag(private=True, desc="link to measurement S11") measS12 = Value().tag(private=True, desc="link to measurement S12") measS21 = Value().tag(private=True, desc="link to measurement S21") measS22 = Value().tag(private=True, desc="link to measurements S22") trace_plot = Typed(Plotter).tag(private=True) def update_trace_plot(self): self.trace_plot.plot_dict["trace_mag S21"].clt.set_xdata(self.freq) S21dB = absolute(self.S21) #20.0*log10(absolute(self.S21)) print shape(self.freq) print shape(S21dB) if self.simulate: S21dB = absolute(self.S21) self.trace_plot.plot_dict["trace_mag S21"].clt.set_ydata(S21dB) if min(self.freq) != max(self.freq): self.trace_plot.set_xlim(min(self.freq), max(self.freq)) if min(S21dB) != max(S21dB): self.trace_plot.set_ylim(min(S21dB), max(S21dB)) self.trace_plot.draw() def _default_trace_plot(self): tp = Plotter(name=self.name + ' trace plot') print self.freq print absolute(self.S21) print shape(self.freq) print shape(self.S21) tp.line_plot('trace_mag S21', self.freq, absolute(self.S21)) #S20.0*log10(absolute(self.S21))) return tp doS11 = Bool(False) doS21 = Bool(False) doS12 = Bool(False) doS22 = Bool(False) do_freq = Bool(False) timeout = Int(10000) #clear_average=Bool(True).tag(sub=True) @observe("doS11", "doS21", "doS21", "doS22") def observe_doSs(self, change): log_debug(change) if change['type'] == 'update': Sname = change["name"][2:] if change.get("oldvalue", False): log_debug('del old meas') log_debug(getattr(self, 'meas' + Sname).Delete()) self.error_query() elif change["value"]: ReceiverPort = int(Sname[1]) SourcePort = int(Sname[2]) log_debug(ReceiverPort, SourcePort) if Sname not in self.query_measurements().values(): self.writer("CALC:PAR:DEF:EXT MEAS{0},{0}".format(Sname)) log_debug( getattr(self, 'meas' + Sname).Create(ReceiverPort, SourcePort)) self.error_query() print self.query_measurements() sleep(1) getattr(self, 'meas' + Sname).Format = 0 #self.error_query() def query_measurements(self): sAll = self.asker("CALC:PAR:CAT:EXT?")[1:-1] if self.simulate: sAll = 'NO CATALOG' if sAll == 'NO CATALOG': return {} t = sAll.split(",") return {t[i]: t[i + 1] for i in range(0, len(t), 2)} @reader def reader(self): """calls VNA ReadString""" return self.VNA.System2.ReadString() @writer def writer(self, VNA_string): """calls VNA WriteString using string formatting by kwargs""" self.VNA.System2.WriteString(VNA_string) @asker def asker(self, VNA_string): """calls VNA WriteString followed by VNA ReadString""" self.writer(VNA_string) return self.reader() @tag_Callable(do=True) def VNA_abort(self): self.VNA.Channels.Abort() self.writer("CALC:PAR:DEL:ALL") self.VNA.Status.Clear() #self.ch1.TriggerMode=TriggerModeDict['Hold'] @booter def booter(self, address): self.VNA = CreateObject("AgilentNA.AgilentNA") init_list = [ 'Simulate={0}'.format(self.simulate), #'QueryInstrStatus=true' ] init_str = ','.join(init_list) print init_str log_debug(self.VNA.Initialize(self.address, False, False, init_str)) self.ch1 = self.VNA.Channels["Channel1"] if not self.simulate: print self.VNA.System2.IO.IO.LockRsrc() if get_tag(self, 'abort', 'do', False): self.VNA_abort() #self.VNA_write("CALC:PAR:DEL:ALL") self.error_query() #log_debug(self.VNA.System2.WaitForOperationComplete(self.timeout)) #self.error_query() self.measS11 = self.ch1.Measurements["Measurement1"] self.measS21 = self.ch1.Measurements["Measurement2"] self.measS12 = self.ch1.Measurements["Measurement3"] self.measS22 = self.ch1.Measurements["Measurement4"] if self.simulate: self.stop_freq = 4.0e9 #sleep(1) #self.measS11.Create(1, 1) #self.error_query() #sleep(1) #self.measS11.Delete() #self.synchronize() self.error_query() def synchronize(self): self.receive('points') @tag_Callable() def error_query(self): for n in range(11): err_query = self.VNA.Utility.ErrorQuery() log_debug(err_query, n=3) if err_query[0] == 0: break def clear_all_traces(self): self.VNA.System2.WriteString("CALC:PAR:DEL:ALL") # def close_measurement(self, key): # try: # self.meas_dict[key].Delete() # except COMError as e: # log_debug(e) # # def close_all_measurements(self): # for key in self.meas_dict: # self.close_measurement(key) @closer def closer(self): for key in self.S_names: if getattr(self, 'do' + key): getattr(self, 'meas' + key).Delete() #self.VNA_abort() if not self.simulate: print self.VNA.System2.IO.IO.UnlockRsrc() log_debug(self.VNA.Close()) for n in self.loop(10): if self.VNA.Release() == 0: break #VNA.Channels["Channel1"].StimulusRange.Span #VNA.Channels["Channel1"].StimulusRange.Center #VNA.System2.WriteString(":OUTP 0") @tag_Callable() def clear_average(self): self.ch1.ClearAverage() # def acq2(self): # log_debug('acq2 started') # self.ch1.TriggerMode=1 # self.ch1.ClearAverage() # for n in range(self.averages): # self.ch1.TriggerSweep(1000) # self.VNA.System2.WaitForOperationComplete(10000) # log_debug('acq2 stopped') # # def acq(self): # log_debug('acq started') # self.VNA_write("SENSE:SWE:GRO:COUN {}".format(self.averages)) # # self.ch1.ClearAverage() # self.VNA.System2.WriteString("SENSE:SWE:MODE GROUPS") # getattr(self, 'meas'+'S21').Trace.AutoScale() # try: # log_debug(self.VNA.System2.WaitForOperationComplete(30000)) # #print self.error_query() # except Exception as e: # raise Exception(str(e)) # log_debug('acq stopped') @tag_Callable() def acquire_data(self): self.send(trigger_mode='Hold') #if get_tag(self, "clear_average", "do"): self.clear_average() if self.averaging: numTriggers = self.averages else: numTriggers = 1 for n in self.loop(numTriggers): self.ch1.TriggerSweep(1000) self.VNA.System2.WaitForOperationComplete(self.timeout) if n == 9: for key in self.S_names: if getattr(self, "do" + key): getattr(self, 'meas' + key).Trace.AutoScale() for key in self.S_names: if getattr(self, "do" + key): data = array(getattr(self, 'meas' + key).FetchComplex()) setattr(self, key, data[0] + 1.0j * data[1]) #log_debug(getattr(self, key)) if self.do_freq: self.freq = getattr(self, 'meas' + key).FetchX() if not self.do_freq: self.freq = linspace(self.start_freq, self.stop_freq, self.points) self.update_trace_plot() #print list(frq)==list(self.freq) start_freq = Float(4.0e9).tag(high=50.0e9, low=10.0e6, label='VNA start frequency', unit2='GHz', aka="self.ch1.StimulusRange.Start", show_value=True) stop_freq = Float(5.0e9).tag(low=10.0e6, high=50.0e9, label='VNA stop frequency', unit2='GHz', aka="self.ch1.StimulusRange.Stop", show_value=True) points = Int(1601).tag(low=1, high=20001, aka="self.ch1.Points") averages = Int(1).tag(low=1, high=50000, aka="self.ch1.AveragingFactor") averaging = Bool(True).tag(aka="self.ch1.Averaging") power = Float(-27.0).tag(low=-27.0, high=0.0, display_unit='dBm', aka="self.ch1.SourcePower.Level[1]") #electrical_delay = Float(0).tag(label='VNA electrical delay', unit = 's', # GPIB_writes=":CALCulate1:CORRection:EDELay:TIME {electrical_delay}") #subtract_background = Bool(False) #measurement_type = Enum('S11', 'S12', 'S21', 'S22') #start = Button() #adjust_electrical_delay = Button() #acquire_background = Button() freq = Array().tag(label='Frequency', sub=True) S11 = Array().tag(sub=True) S12 = Array().tag(sub=True) S21 = Array().tag(sub=True) S22 = Array().tag(sub=True) trigger_mode = Enum('Continuous', 'Hold').tag(mapping=TriggerModeDict, aka="self.ch1.TriggerMode")
class ConversationEvent(Model): Action = Int() Conversation = Instance(Conversation)
class AndroidApplication(BridgedApplication): """ An Android implementation of an Enaml Native BridgedApplication. A AndroidApplication uses the native Android widget toolkit to implement an Enaml UI that runs in the local process. """ #: Attributes so it can be serialized over the bridge as a reference __nativeclass__ = Unicode('android.content.Context') #: Bridge widget widget = Typed(Activity) #: Application Window window = Typed(Window) #: Android Activity (jnius class) activity = Value() #: Pixel density of the device #: Loaded immediately as this is used often. dp = Float() #: Build info from #: https://developer.android.com/reference/android/os/Build.VERSION.html build_info = Dict() #: SDK version #: Loaded immediately api_level = Int() #: Triggered when the back button is pressed. This can be observed #: to handle back presses. back_pressed = Event(dict) #: Permission code increments on each request _permission_code = Int() #: Pending permission request listeners _permission_requests = Dict() # ------------------------------------------------------------------------- # Defaults # ------------------------------------------------------------------------- def _default_widget(self): """ Return a bridge object reference to the MainActivity """ return Activity(__id__=-1) # ------------------------------------------------------------------------- # AndroidApplication Constructor # ------------------------------------------------------------------------- def __init__(self, *args, **kwargs): """ Initialize a AndroidApplication. Uses jnius to retrieve an instance of the activity. """ super(AndroidApplication, self).__init__(*args, **kwargs) self.resolver = ProxyResolver(factories=factories.ANDROID_FACTORIES) def init_widget(self): """ Initialize on the first call """ #: Add a ActivityLifecycleListener to update the application state activity = self.widget activity.addActivityLifecycleListener(activity.getId()) activity.onActivityLifecycleChanged.connect( self.on_activity_lifecycle_changed) #: Add BackPressedListener to trigger the event activity.addBackPressedListener(activity.getId()) activity.onBackPressed.connect(self.on_back_pressed) #: Add ConfigurationChangedListener to trigger the event activity.addConfigurationChangedListener(activity.getId()) activity.onConfigurationChanged.connect(self.on_configuration_changed) activity.getWindow().then(self.init_window) def init_window(self, window): """ """ self.window = Window(__id__=window) self.set_keep_screen_on(self.keep_screen_on) if self.statusbar_color: self.set_statusbar_color(self.statusbar_color) # ------------------------------------------------------------------------- # App API Implementation # ------------------------------------------------------------------------- def has_permission(self, permission): """ Return a future that resolves with the result of the permission """ f = self.create_future() #: Old versions of android did permissions at install time if self.api_level < 23: f.set_result(True) return f def on_result(allowed): result = allowed == Activity.PERMISSION_GRANTED self.set_future_result(f, result) self.widget.checkSelfPermission(permission).then(on_result) return f def request_permissions(self, permissions): """ Return a future that resolves with the results of the permission requests """ f = self.create_future() #: Old versions of android did permissions at install time if self.api_level < 23: f.set_result({p: True for p in permissions}) return f w = self.widget request_code = self._permission_code self._permission_code += 1 #: So next call has a unique code #: On first request, setup our listener, and request the permission if request_code == 0: w.setPermissionResultListener(w.getId()) w.onRequestPermissionsResult.connect(self._on_permission_result) def on_results(code, perms, results): #: Check permissions f.set_result({ p: r == Activity.PERMISSION_GRANTED for (p, r) in zip(perms, results) }) #: Save a reference self._permission_requests[request_code] = on_results #: Send out the request self.widget.requestPermissions(permissions, request_code) return f def show_toast(self, msg, long=True): """ Show a toast message for the given duration. This is an android specific api. Parameters ----------- msg: str Text to display in the toast message long: bool Display for a long or short (system defined) duration """ from .android_toast import Toast def on_toast(ref): t = Toast(__id__=ref) t.show() Toast.makeText(self, msg, 1 if long else 0).then(on_toast) def on_activity_lifecycle_changed(self, state): """ Update the state when the android app is paused, resumed, etc.. Widgets can observe this value for changes if they need to react to app lifecycle changes. """ self.state = state def on_back_pressed(self): """ Fire the `back_pressed` event with a dictionary with a 'handled' key when the back hardware button is pressed If 'handled' is set to any value that evaluates to True the default event implementation will be ignored. """ try: event = {'handled': False} self.back_pressed(event) return bool(event.get('handled', False)) except Exception as e: #: Must return a boolean or we will cause android to abort return False def on_configuration_changed(self, config): """ Handles a screen configuration change. """ self.width = config['width'] self.height = config['height'] self.orientation = ('square', 'portrait', 'landscape')[config['orientation']] # -------------------------------------------------------------------------- # Bridge API Implementation # -------------------------------------------------------------------------- def show_view(self): """ Show the current `app.view`. This will fade out the previous with the new view. """ if not self.build_info: def on_build_info(info): """ Make sure the build info is ready before we display the view """ self.dp = info['DISPLAY_DENSITY'] self.width = info['DISPLAY_WIDTH'] self.height = info['DISPLAY_HEIGHT'] self.orientation = ('square', 'portrait', 'landscape')[info['DISPLAY_ORIENTATION']] self.api_level = info['SDK_INT'] self.build_info = info self._show_view() self.init_widget() self.widget.getBuildInfo().then(on_build_info) else: self._show_view() def _show_view(self): """ Show the view """ self.widget.setView(self.get_view()) def dispatch_events(self, data): """ Send the data to the Native application for processing """ nativehooks.publish(data) # ------------------------------------------------------------------------- # Android utilities API Implementation # ------------------------------------------------------------------------- def _on_permission_result(self, code, perms, results): """ Handles a permission request result by passing it to the handler with the given code. """ #: Get the handler for this request handler = self._permission_requests.get(code, None) if handler is not None: del self._permission_requests[code] #: Invoke that handler with the permission request response handler(code, perms, results) def _observe_keep_screen_on(self, change): """ Sets or clears the flag to keep the screen on. """ self.set_keep_screen_on(self.keep_screen_on) def set_keep_screen_on(self, keep_on): """ Set or clear the window flag to keep the screen on """ window = self.window if not window: return if keep_on: window.addFlags(Window.FLAG_KEEP_SCREEN_ON) else: window.clearFlags(Window.FLAG_KEEP_SCREEN_ON) def _observe_statusbar_color(self, change): """ Sets or clears the flag to keep the screen on. """ self.set_statusbar_color(self.statusbar_color) def set_statusbar_color(self, color): """ Set the color of the system statusbar. """ window = self.window if not window: return window.setStatusBarColor(color) def get_system_service(self, service): """ Wrapper for getSystemService. You MUST wrap the class with the appropriate object. """ return self.widget.getSystemService(service) # ------------------------------------------------------------------------- # Plugin API Implementation # ------------------------------------------------------------------------- def load_plugin_factories(self): """ Add any plugin toolkit widgets to the ANDROID_FACTORIES """ for plugin in self.get_plugins(group='enaml_native_android_factories'): get_factories = plugin.load() PLUGIN_FACTORIES = get_factories() factories.ANDROID_FACTORIES.update(PLUGIN_FACTORIES)
class ConversationsResponse(Response): """ Expected response from api/conversations """ Limit = Int() Total = Int() Conversations = List(Conversation)
class PSASetParam(InstrumentTask): """ Set important parameters of the Power Spectrum Analyzer. """ trace = Int(1).tag(pref=True) mode = Enum('Start/Stop', 'Center/Span').tag(pref=True) start_freq = Str().tag(pref=True, feval=EMPTY_REAL) end_freq = Str().tag(pref=True, feval=EMPTY_REAL) center_freq = Str().tag(pref=True, feval=EMPTY_REAL) span_freq = Str().tag(pref=True, feval=EMPTY_REAL) average_nb = Str().tag(pref=True, feval=EMPTY_INT) resolution_bandwidth = Str().tag(pref=True, feval=EMPTY_REAL) video_bandwidth = Str().tag(pref=True, feval=EMPTY_REAL) database_entries = set_default({'psa_config': ''}) def perform(self): """Set the specified parameters. """ if self.driver.owner != self.name: self.driver.owner = self.name if self.mode == 'Start/Stop': if self.start_freq: self.driver.start_frequency_SA = \ self.format_and_eval_string(self.start_freq) if self.stop_freq: self.driver.stop_frequency_SA = \ self.format_and_eval_string(self.stop_freq) # start_freq is set again in case the former value of stop # prevented to do it if self.start_freq: self.driver.start_frequency_SA = \ self.format_and_eval_string(self.start_freq) else: if self.center_freq: self.driver.center_frequency = \ self.format_and_eval_string(self.center_freq) if self.span_freq: self.driver.span_frequency = \ self.format_and_eval_string(self.span_freq) # center_freq is set again in case the former value of span # prevented to do it if self.center_freq: self.driver.center_frequency = \ self.format_and_eval_string(self.center_freq) if self.average_nb: self.driver.average_count_SA = \ self.format_and_eval_string(self.average_nb) if self.resolution_bandwidth: self.driver.RBW = \ self.format_and_eval_string(self.resolution_bandwidth) if self.video_bandwidth: self.driver.VBW_SA = \ self.format_and_eval_string(self.video_bandwidth) sweep_modes = { 'SA': 'Spectrum Analyzer', 'SPEC': 'Basic Spectrum Analyzer', 'WAV': 'Waveform' } d = self.driver psa_config = '''Start freq {}, Stop freq {}, Span freq {}, Center freq {}, Average number {}, Resolution Bandwidth {}, Video Bandwidth {}, Number of points {}, Mode {}'''.format(d.start_frequency_SA, d.stop_frequency_SA, d.span_frequency, d.center_frequency, d.average_count_SA, d.RBW, d.VBW_SA, d.sweep_points_SA, sweep_modes[self.mode]) self.write_in_database('psa_config', psa_config) def check(self, *args, **kwargs): """ """ test, traceback = super(PSAGetTrace, self).check(*args, **kwargs) err_path = self.get_error_path() if kwargs.get('test_instr'): if self.driver.mode != 'SA': test = False traceback[err_path] = 'PSA is not in Spectrum Analyzer mode' if self.mode == 'Start/Stop': try: if self.start_freq: start = self.format_and_eval_string(self.start_freq) # if type(self.driver).__name__ == 'AgilentPSA': # is a new PSA needs to be encoded, it would be best to use task_interfaces if (start < 3) or (start > 26500000000): raise Exception('out_of_range') except Exception as e: test = False if e.args == 'out_of_range': traceback[err_path + '-start_freq'] = 'Start frequency {} out of ' + \ 'range'.format(self.start_freq) else: traceback[err_path + '-start_freq'] = 'Failed to eval the start' + \ 'formula {}'.format(self.start_freq) try: if self.stop_freq: toto = self.format_and_eval_string(self.stop_freq) if (toto < 3) or (toto > 26500000000): raise Exception('out_of_range') except Exception as e: test = False if e.args == 'out_of_range': traceback[err_path + '-stop_freq'] = 'Stop frequency {} out of ' + \ 'range'.format(self.start_freq) else: traceback[err_path + '-stop_freq'] = 'Failed to eval the stop' + \ 'formula {}'.format(self.stop_freq) else: try: if self.span_freq: toto = self.format_and_eval_string(self.span_freq) if (toto < 0) or (toto > 26500000000): raise Exception('out_of_range') except Exception as e: test = False if e.args == 'out_of_range': traceback[err_path + '-span_freq'] = 'Span frequency {} out of ' + \ 'range'.format(self.span_freq) else: traceback[err_path + '-span_freq'] = 'Failed to eval the span' + \ 'formula {}'.format(self.span_freq) try: if self.center_freq: toto = self.format_and_eval_string(self.center_freq) if (toto < 3) or (toto > 26500000000): raise Exception('out_of_range') except Exception as e: test = False if e.args == 'out_of_range': traceback[err_path + '-center_freq'] = 'Center frequency {} out of ' + \ 'range'.format(self.center_freq) else: traceback[err_path + '-center_freq'] = 'Failed to eval the stop' + \ 'formula {}'.format(self.center_freq) try: if self.average_nb: toto = self.format_and_eval_string(self.average_nb) if (toto < 1) or (toto > 8192): raise Exception('out_of_range') except Exception as e: test = False if e.args == 'out_of_range': traceback[err_path + '-average_nb'] = 'Average number {} out of ' + \ 'range'.format(self.average_nb) else: traceback[err_path + '-average_nb'] = 'Failed to eval the average_nb' + \ 'formula {}'.format(self.average_nb) try: if self.average_nb: toto = self.format_and_eval_string(self.resolution_bandwidth) if (toto < 1) or (toto > 8000000): raise Exception('out_of_range') except Exception as e: test = False if e.args == 'out_of_range': traceback[err_path + '-resolution_bandwidth'] = 'Resolution BW number' + \ '{} out of range'.format(self.average_nb) else: traceback[err_path + '-resolution_bandwidth'] = 'Failed to eval the ' + \ 'resolution_bandwidth formula {}' + \ ''.format(self.resolution_bandwidth) try: if self.average_nb: toto = self.format_and_eval_string(self.video_bandwidth) if (toto < 1) or (toto > 50000000): raise Exception('out_of_range') except Exception as e: test = False if e.args == 'out_of_range': traceback[err_path + '-video_bandwidth'] = 'Video BW number' + \ '{} out of range'.format(self.video_bandwidth) else: traceback[err_path + '-video_bandwidth'] = 'Failed to eval the ' + \ 'video_bandwidth formula {}' + \ ''.format(self.video_bandwidth) return test, traceback
class KeysResponse(Response): """ Expected response from api/keys """ Keys = List(Key) RecipientType = Int()
class Qubit(Agent): """Theoretical description of qubit""" base_name="qubit" Cc=Float(1e-15).tag(desc="coupling capacitance", unit="fF") qubit_type=Enum("transmon", "scb") dephasing=Float(0.0).tag(unit="GHz") dephasing_slope=Float(0.0) @private_property def view_window(self): return QubitView(agent=self) superconductor=Enum("Al").tag(label="material") def _observe_superconductor(self, change): if self.superconductor=="Al": self.Delta=Delta_Al Tc=Float(Tc_Al).tag(desc="Critical temperature of superconductor", unit="K", label="Critical temperature") Delta=SProperty().tag(label="Gap", tex_str=r"$\Delta(0)$", unit="ueV", desc="BCS superconducting gap, 200 ueV for Al", reference="BCS", expression=r"$\Delta(0)=1.764 k_B T_c$") @Delta.getter def _get_Delta(self, Tc): """BCS theory superconducting gap""" return 1.764*kB*Tc @Delta.setter def _get_Tc(self, Delta): return Delta/(1.764*kB) loop_width=Float(1.0e-6).tag(desc="loop width of SQUID", unit="um", label="loop width") loop_height=Float(1.0e-6).tag(desc="loop height of SQUID", unit="um", label="loop height") loop_area=SProperty().tag(desc="Area of SQUID loop", unit="um^2", expression="$width \times height$", comment="Loop width times loop height", label="loop area") @loop_area.getter def _get_loop_area(self, loop_width, loop_height): return loop_width*loop_height Ct=Float(1.3e-13).tag(desc="shunt capacitance", unit="fF", tex_str=r"$C_q$") Rn=Float(5.0e3).tag(desc="Normal resistance of SQUID", unit="kOhm", label="DC Junction resistance", expression=r"$R_N$") Ic=SProperty().tag(desc="critical current of SQUID, Ambegaokar Baratoff formula", unit="nA", label="Critical current", expression=r"$I_C=\pi \Delta/(2e R_N)$") @Ic.getter def _get_Ic(self, Rn, Delta): """Ic*Rn=pi*Delta/(2.0*e) #Ambegaokar Baratoff formula""" return pi*Delta/(2.0*e)/Rn @Ic.setter def _get_Rn(self, Ic, Delta): """Ic*Rn=pi*Delta/(2.0*e) #Ambegaokar Baratoff formula""" return pi*Delta/(2.0*e)/Ic Ejmax=SProperty().tag(desc="""Max Josephson Energy""", unit="hGHz", expression=r'$E_{Jmax}=\hbar I_C/2e$', label="Max Josephson energy")#, unit_factor=1.0e9*h) @Ejmax.getter def _get_Ejmax(self, Ic): """Josephson energy""" return hbar*Ic/(2.0*e) @Ejmax.setter def _get_Ic_get_Ejmax(self, Ejmax): """inverse Josephson energy""" return Ejmax*(2.0*e)/hbar Ec=SProperty().tag(desc="Charging Energy", unit="hGHz", label="Charging energy", expression=r"$E_C=e^2/2 C_t$")#, unit_factor=1.0e9*h) @Ec.getter def _get_Ec(self, Ct, Cc): """Charging energy""" return e**2/(2.0*(Ct+Cc)) @Ec.setter def _get_Ct(self, Ec, Cc): """inverse charging energy""" return e**2/(2.0*Ec)-Cc @Ec.setter def _get_Ejmax_get_Ec(self, Ec, EjmaxdivEc): return EjmaxdivEc*Ec EjmaxdivEc=SProperty().tag(desc="Maximum Ej over Ec", label=r"Maximum $E_J$ over $E_C$", expression=r"$E_{Jmax}/E_C$") @EjmaxdivEc.getter def _get_EjmaxdivEc(self, Ejmax, Ec): return Ejmax/Ec Ej=SProperty().tag(unit="hGHz", label="Josephson energy", expression=r"$E_J=E_{Jmax}|\cos(\Phi/\Phi_0)|$") @Ej.getter def _get_Ej(self, Ejmax, flux_over_flux0): return Ejmax*absolute(cos(flux_over_flux0)) #*pi @Ej.setter def _get_flux_over_flux0_get_Ej(self, Ej, Ejmax): return arccos(Ej/Ejmax)#/pi EjdivEc=SProperty().tag(desc="Ej over Ec", label="Ej over Ec", expression=r"$E_J/E_C$") @EjdivEc.getter def _get_EjdivEc(self, Ej, Ec): return Ej/Ec fq_approx_max=SProperty().tag(unit="GHz", label="fq approx max", desc="qubit frequency using approximate transmon formula", expression=r"$f_{qmax} \approx (\sqrt{8E_{Jmax} E_C}-E_C)/h$") @fq_approx_max.getter def _get_fq_approx_max(self, Ejmax, Ec): return self._get_fq_approx(Ej=Ejmax, Ec=Ec) fq_approx=SProperty().tag(unit="GHz", expression=r"$f_q \approx (\sqrt{8E_J E_C}-E_C)/h$") @fq_approx.getter def _get_fq_approx(self, Ej, Ec): return (sqrt(8.0*Ej*Ec)-Ec)/h fq_max=SProperty().tag(unit="GHz", label="fq max", expression=r"$f_{qmax}$") @fq_max.getter def _get_fq_max(self, Ejmax, Ec, qubit_type, ng, Nstates): return self._get_fq(Ej=Ejmax, Ec=Ec, qubit_type=qubit_type, ng=ng, Nstates=Nstates) fq=SProperty().tag(desc="""Operating frequency of qubit""", unit="GHz", expression=r"$f_q$") @fq.getter def _get_fq(self, Ej, Ec, qubit_type, ng, Nstates): E0, E1=self._get_energy_levels(Ej=Ej, Ec=Ec, n_energy=2, qubit_type=qubit_type, ng=ng, Nstates=Nstates) return (E1-E0)/h @fq.setter def _get_Ej_get_fq(self, fq, Ec): """h*fq=sqrt(8.0*Ej*Ec) - Ec""" return ((h*fq+Ec)**2)/(8.0*Ec) L=SProperty().tag(label="Kinetic inductance of SQUID", expression=r"$L$") @L.getter def _get_L(self, fq, Ct): return 1.0/(Ct*(2*pi*fq)**2) anharm=SProperty().tag(desc="absolute anharmonicity", unit="GHz") @anharm.getter def _get_anharm(self, Ej, Ec, qubit_type, ng, Nstates): E0, E1, E2=self._get_energy_levels(Ej=Ej, Ec=Ec, n_energy=3, qubit_type=qubit_type, ng=ng, Nstates=Nstates) return (E2-E1)/h-(E1-E0)/h fq2=SProperty().tag(desc="""20 over 2 freq""", unit="GHz", expression = r"$f_{20}/2$") @fq2.getter def _get_fq2(self, Ej, Ec, qubit_type, ng, Nstates): E0, E1, E2=self._get_energy_levels(Ej=Ej, Ec=Ec, n_energy=3, qubit_type=qubit_type, ng=ng, Nstates=Nstates) return (E2-E0)/h/2.0 voltage=Float().tag(unit="V", desc="Yoko voltage on coil") offset=Float(0.09).tag(unit="V", desc="offset of flux in volts") flux_factor=Float(0.195).tag(desc="converts voltage to flux") flux_factor_beta=Float().tag(desc="linear dependenc on magnetic field") flux_over_flux0=SProperty().tag(expression=r"$\Phi/\Phi_0=$(voltage-offset)fluxfactor", unit="pi") @flux_over_flux0.getter def _get_flux_over_flux0(self, voltage, offset, flux_factor, flux_factor_beta): return (voltage-offset)*flux_factor#/(1.0-flux_factor_beta*(voltage-offset)) #return (voltage-offset)*flux_factor @flux_over_flux0.setter def _get_voltage(self, flux_over_flux0, offset, flux_factor, flux_factor_beta): #return flux_over_flux0/flux_factor*(1-flux_factor_beta/flux_factor*flux_over_flux0)+offset #return flux_over_flux0/flux_factor+offset+sign(flux_over_flux0)*flux_factor_beta*flux_over_flux0**2 #return flux_over_flux0/flux_factor+offset+flux_factor_beta*flux_over_flux0**3 return flux_over_flux0/flux_factor+offset flux_parabola=SProperty() @flux_parabola.getter def _get_flux_parabola(self, voltage, offset, flux_factor, Ejmax, Ec, qubit_type, ng, Nstates): flx_d_flx0=self._get_flux_over_flux0(voltage=voltage, offset=offset, flux_factor=flux_factor) qEj=self._get_Ej(Ejmax=Ejmax, flux_over_flux0=flx_d_flx0) return self._get_fq(Ej=qEj, Ec=Ec, qubit_type=qubit_type, ng=ng, Nstates=Nstates)#, fq2(qEj, Ec) #freq_arr=Array().tag(desc="array of frequencies to evaluate over") f=Float(4.4e9).tag(label="Operating frequency", desc="what frequency is being stimulated/measured", unit="GHz") flux_from_fq=SProperty().tag(sub=True) @flux_from_fq.getter def _get_flux_from_fq(self, fq, Ct, Ejmax): Ec=self._get_Ec(Ct=Ct) Ej=self._get_Ej_get_fq(fq=fq, Ec=Ec) return self._get_flux_over_flux0_get_Ej(Ej=Ej, Ejmax=Ejmax) voltage_from_flux_par=SProperty().tag(sub=True) @voltage_from_flux_par.getter def _get_voltage_from_flux_par(self, fq, Ct, Ejmax, offset, flux_factor): #Ec=self._get_Ec(Ct=Ct) #Ej=self._get_Ej_get_fq(fq=fq, Ec=Ec) flux_d_flux0=self._get_flux_from_fq(fq, Ct, Ejmax) #self._get_flux_over_flux0_get_Ej(Ej=Ej, Ejmax=Ejmax) return self._get_voltage(flux_over_flux0=flux_d_flux0, offset=offset, flux_factor=flux_factor) voltage_from_flux_par_many=SProperty().tag(sub=True) @voltage_from_flux_par_many.getter def _get_voltage_from_flux_par_many(self, fq, Ct, Ejmax, offset, flux_factor, flux_factor_beta): #Ec=self._get_Ec(Ct=Ct) #Ej=self._get_Ej_get_fq(fq=f, Ec=Ec) fdf0=self._get_flux_from_fq(fq, Ct, Ejmax) #self._get_flux_over_flux0_get_Ej(Ej=Ej, Ejmax=Ejmax) #fdf0=self._get_flux_over_flux0_get_Ej(Ej=Ej, Ejmax=Ejmax) flux_d_flux0=append(fdf0, -fdf0) flux_d_flux0=append(flux_d_flux0, -fdf0+pi*(1+flux_factor_beta)) flux_d_flux0=append(flux_d_flux0, fdf0-pi*(1+flux_factor_beta)) freq=append(fq, fq) freq=append(freq, freq) return freq/1e9, self._get_voltage(flux_over_flux0=flux_d_flux0, offset=offset, flux_factor=flux_factor) def detuning(self, fq_off): return 2.0*pi*(self.fq - fq_off) def transmon_energy(self, Ej, Ec, m): return -Ej+sqrt(8.0*Ej*Ec)*(m+0.5) - (Ec/12.0)*(6.0*m**2+6.0*m+3.0) transmon_energy_levels=SProperty().tag(sub=True) @transmon_energy_levels.getter def _get_transmon_energy_levels(self, Ej, Ec, n_energy): return [self.transmon_energy(Ej, Ec, m) for m in range(n_energy)] n_energy=Int(3) ng=Float(0.5).tag(desc="charge on gate line", log=False) Nstates=Int(50).tag(desc="number of states to include in mathieu approximation. More states is better approximation") order=Int(3) EkdivEc=Array().tag(unit2="Ec", sub=True) energy_levels=SProperty().tag(sub=True) @energy_levels.getter def _get_energy_levels(self, Ej, Ec, n_energy, qubit_type, ng, Nstates): if qubit_type=="scb": return self._get_scb_energy_levels(Ej=Ej, Ec=Ec, n_energy=n_energy, ng=ng, Nstates=Nstates) return self._get_transmon_energy_levels(Ej=Ej, Ec=Ec, n_energy=n_energy) def indiv_EkdivEc(self, EjdivEc, n_energy, ng, Nstates): """calculates energies assuming float values given""" NL=2*Nstates+1 A=zeros((NL, NL)) for b in range(0,NL): A[b, b]=4.0*(b-Nstates-ng)**2 if b!=NL-1: A[b, b+1]= -EjdivEc/2.0 if b!=0: A[b, b-1]= -EjdivEc/2.0 #w,v=eig(A) w=eigvalsh(A) return w[0:n_energy] scb_energy_levels=SProperty().tag(sub=True) @scb_energy_levels.getter def _get_scb_energy_levels(self, Ej, Ec, n_energy, ng, Nstates): if isinstance(Ej, float): Ej=array([Ej]) if isinstance(ng, float): ng=[ng] EjdivEc=Ej/Ec energies=Ec*squeeze([[self.indiv_EkdivEc(EjdivEc=ejc, n_energy=n_energy, ng=ng_s, Nstates=Nstates) for ejc in EjdivEc] for ng_s in ng]) return [spl.transpose() for spl in split(energies.transpose(), n_energy)] #energies=squeeze(energies) NL=2*Nstates+1 A=zeros((NL, NL)) for b in range(0,NL): A[b, b]=4.0*Ec*(b-Nstates-ng)**2 if b!=NL-1: A[b, b+1]= -Ej/2.0 if b!=0: A[b, b-1]= -Ej/2.0 #w,v=eig(A) w=eigvalsh(A) return w[0:n_energy] def update_EkdivEc(self, ng, Ec, Ej, Nstates, order): """calculates transmon energy level with N states (more states is better approximation) effectively solves the mathieu equation but for fractional inputs (which doesn't work in scipy.special.mathieu_a)""" # if type(ng) not in (int, float): # d=zeros((order, len(ng))) # elif type(Ec) not in (int, float): # d=zeros((order, len(Ec))) # elif type(Ej) not in (int, float): # d=zeros((order, len(Ej))) if type(ng) in (int, float): ng=array([ng]) d1=[] d2=[] d3=[] Ej=Ej/Ec Ec=1.0#/4.0 for a in ng: NL=2*Nstates+1 A=zeros((NL, NL)) for b in range(0,NL): A[b, b]=4.0*Ec*(b-Nstates-a)**2 if b!=NL-1: A[b, b+1]= -Ej/2.0 if b!=0: A[b, b-1]= -Ej/2.0 #w,v=eig(A) w=eigvalsh(A) d=w[0:order] # d1.append(min(w))#/h*1e-9) # w=delete(w, w.argmin()) # d2.append(min(w))#/h*1e-9) # w=delete(w, w.argmin()) # d3.append(min(w))#/h*1e-9) return array([array(d1), array(d2), array(d3)]).transpose() def sweepEc(): Ecarr=Ej/EjoverEc E01a=sqrt(8*Ej*Ecarr)-Ecarr data=[] for Ec in Ecarr: d1, d2, d3= EkdivEc(ng=ng, Ec=Ec, Ej=Ej, N=50) E12=d3[0]-d2[0] E01=d2[0]-d1[0] anharm2=(E12-E01)#/E01 data.append(anharm2) Ctr=e**2/(2.0*Ecarr*h*1e9) return E01a, Ctr, data, d1, d2, d3
class BaseTask(Atom): """Base class defining common members of all Tasks. This class basically defines the minimal skeleton of a Task in term of members and methods. Notes ----- A number of the member used by the task have a definite meaning only when a root is present. They are listed below: - depth - path - database - parent """ #: Identifier for the build dependency collector dep_type = Constant(DEP_TYPE).tag(pref=True) #: Name of the class, used for persistence. task_id = Unicode().tag(pref=True) #: Name of the task this should be unique in hierarchy. name = Unicode().tag(pref=True) #: Depth of the task in the hierarchy. this should not be manipulated #: directly by user code. depth = Int() #: Reference to the Section in which the task stores its preferences. preferences = Typed(Section) #: Reference to the database used by the task to exchange information. database = Typed(TaskDatabase) #: Entries the task declares in the database and the associated default #: values. This should be copied and re-assign when modified not modfied #: in place. database_entries = Dict(Unicode(), Value()) #: Path of the task in the hierarchy. This refers to the parent task and #: is used when writing in the database. path = Unicode() #: Reference to the root task in the hierarchy. root = ForwardTyped(lambda: RootTask) #: Refrence to the parent task. parent = ForwardTyped(lambda: BaseTask) #: Unbound method called when the task is asked to do its job. This is #: basically the perform method but wrapped with useful stuff such as #: interruption check or parallel, wait features. perform_ = Callable() #: Flag indicating if this task can be stopped. stoppable = Bool(True).tag(pref=True) #: Dictionary indicating whether the task is executed in parallel #: ('activated' key) and which is pool it belongs to ('pool' key). parallel = Dict(Unicode()).tag(pref=True) #: Dictionary indicating whether the task should wait on any pool before #: performing its job. Three valid keys can be used : #: - 'activated' : a bool indicating whether or not to wait. #: - 'wait' : the list should then specify which pool should be waited. #: - 'no_wait' : the list should specify which pool not to wait on. wait = Dict(Unicode()).tag(pref=True) #: Dict of access exception in the database. This should not be manipulated #: by user code. access_exs = Dict().tag(pref=True) def perform(self): """ Main method of the task called when the measurement is performed. """ raise NotImplementedError( fill(cleandoc('''This method should be implemented by subclasses of BaseTask. This method is called when the program requires the task to perform its job.'''))) def check(self, *args, **kwargs): """Check that everything is alright before starting a measurement. By default tries to format all members tagged with 'fmt' and try to eval all members tagged with 'feval'. """ res = True traceback = {} err_path = self.get_error_path() for n, m in tagged_members(self, 'fmt').items(): try: val = self.format_string(getattr(self, n)) if n in self.database_entries: self.write_in_database(n, val) except Exception: if m.metadata['fmt'] != 'Warn': res = False msg = 'Failed to format %s : %s' % (n, format_exc()) traceback[err_path + '-' + n] = msg for n, m in tagged_members(self, 'feval').items(): val = m.metadata['feval'] if not isinstance(val, validators.Feval): res = False msg = 'Feval validator is not a subclass validators.Feval' else: value, f_res, msg = val.check(self, n) res &= f_res if msg: traceback[err_path + '-' + n] = msg elif value is not None and n in self.database_entries: self.write_in_database(n, value) return res, traceback def prepare(self): """Prepare the task to be performed. This method is called once by the root task before starting the execution of its children tasks. By default it simply build the perform\_ method by wrapping perform with the appropriate decorators. This method can be overridden to execute other actions, however keep in my mind that those actions must not depende on the state of the system (no link to database). """ perform_func = self.perform.__func__ parallel = self.parallel if parallel.get('activated') and parallel.get('pool'): perform_func = make_parallel(perform_func, parallel['pool']) wait = self.wait if wait.get('activated'): perform_func = make_wait(perform_func, wait.get('wait'), wait.get('no_wait')) if self.stoppable: perform_func = make_stoppable(perform_func) self.perform_ = MethodType(perform_func, self) def register_preferences(self): """Create the task entries in the preferences object. """ raise NotImplementedError() def update_preferences_from_members(self): """Update the entries in the preference object. """ raise NotImplementedError() @classmethod def build_from_config(cls, config, dependencies): """Create a new instance using the provided infos for initialisation. Parameters ---------- config : dict(str) Dictionary holding the new values to give to the members in string format, or dictionnary like for instance with prefs. dependencies : dict Dictionary holding the necessary classes needed when rebuilding.. """ raise NotImplementedError() def traverse(self, depth=-1): """Yield a task and all of its components. The base implementation simply yields the task itself. Parameters ---------- depth : int How deep should we explore the tree of tasks. When this number reaches zero deeper children should not be explored but simply yielded. """ yield self def register_in_database(self): """ Register the task entries into the database. """ if self.database_entries: for entry in self.database_entries: # Perform a deepcopy of the entry value as I don't want to # alter that default value when dealing with the database later # on (apply for list and dict). value = deepcopy(self.database_entries[entry]) self.write_in_database(entry, value) for access_ex, level in self.access_exs.items(): self._add_access_exception(access_ex, level) def unregister_from_database(self): """ Remove the task entries from the database. """ if self.database_entries: for entry in self.database_entries: self.database.delete_value(self.path, self._task_entry(entry)) for access_ex, level in self.access_exs.items(): self._remove_access_exception(access_ex, level) def add_access_exception(self, entry, level): """Add an access exception for an entry. Parameters ---------- entry : unicode Name of the task database entry for which to add an exception. level : int Number of hierarchical levels to go up when adding the exception. """ self._add_access_exception(entry, level) access_exs = self.access_exs.copy() access_exs[entry] = level self.access_exs = access_exs def modify_access_exception(self, entry, new): """Modify the level of an existing access exception. Parameters ---------- entry : unicode Name of the task database entry for which to modify an exception. new : int New level for the access exception. If this is not strictly positive the access exception is simply removed. """ access_exs = self.access_exs.copy() old = access_exs[entry] if new > 0: access_exs[entry] = new else: del access_exs[entry] full_name = self._task_entry(entry) parent = self while old: parent = parent.parent old -= 1 self.database.remove_access_exception(parent.path, full_name) if new > 0: parent = self while new: parent = parent.parent new -= 1 self.database.add_access_exception(parent.path, self.path, full_name) self.access_exs = access_exs def remove_access_exception(self, entry): """Remove an access exception . Parameters ---------- entry : unicode Name of the task database entry for which to remove an exception. """ access_exs = self.access_exs.copy() level = access_exs.pop(entry) self.access_exs = access_exs self._remove_access_exception(entry, level) def write_in_database(self, name, value): """Write a value to the right database entry. This method build a task specific database entry from the name and the name argument and set the database entry to the specified value. Parameters ---------- name : str Simple name of the entry whose value should be set, ie no task name required. value: Value to give to the entry. """ value_name = self._task_entry(name) return self.database.set_value(self.path, value_name, value) def get_from_database(self, full_name): """Access to a database value using full name. Parameters ---------- full_name : str Full name of the database entry, ie name + '_' + entry, where name is the name of the task that wrote the value in the database. """ return self.database.get_value(self.path, full_name) def remove_from_database(self, full_name): """Delete a database entry using its full name. Parameters ---------- full_name : str Full name of the database entry, ie name + '_' + entry, where name is the name of the task that wrote the value in the database. """ return self.database.delete_value(self.path, full_name) def list_accessible_database_entries(self): """List the database entries accessible from this task. """ return self.database.list_accessible_entries(self.path) def format_string(self, string): """Replace values between {} by their corresponding database value. Parameters ---------- string : str The string to format using the current values of the database. Returns ------- formatted : str Formatted version of the input. """ # If a cache evaluation of the string already exists use it. if string in self._format_cache: preformatted, ids = self._format_cache[string] vals = self.database.get_values_by_index(ids, PREFIX) return preformatted.format(**vals) # Otherwise if we are in running mode build a cache formatting. elif self.database.running: database = self.database aux_strings = string.split('{') if len(aux_strings) > 1: elements = [el for aux in aux_strings for el in aux.split('}')] database_indexes = database.get_entries_indexes(self.path, elements[1::2]) str_to_format = '' length = len(elements) for i in range(0, length, 2): if i + 1 < length: repl = PREFIX + str(database_indexes[elements[i + 1]]) str_to_format += elements[i] + '{' + repl + '}' else: str_to_format += elements[i] indexes = database_indexes.values() self._format_cache[string] = (str_to_format, indexes) vals = self.database.get_values_by_index(indexes, PREFIX) return str_to_format.format(**vals) else: self._format_cache[string] = (string, []) return string # In edition mode simply perfom the formatting as execution time is not # critical. else: database = self.database aux_strings = string.split('{') if len(aux_strings) > 1: elements = [el for aux in aux_strings for el in aux.split('}')] replacement_values = [database.get_value(self.path, key) for key in elements[1::2]] str_to_format = '' for key in elements[::2]: str_to_format += key + '{}' str_to_format = str_to_format[:-2] return str_to_format.format(*replacement_values) else: return string def format_and_eval_string(self, string): """ Replace values in {} by their corresponding database value and eval Parameters ---------- string : str The string to eval using the current values of the database. Returns ------- value : object Evaluated version of the input. """ # If a cache evaluation of the string already exists use it. if string in self._eval_cache: preformatted, ids = self._eval_cache[string] vals = self.database.get_values_by_index(ids, PREFIX) return safe_eval(preformatted, vals) # Otherwise if we are in running mode build a cache evaluation. elif self.database.running: database = self.database aux_strings = string.split('{') if len(aux_strings) > 1: elements = [el for aux in aux_strings for el in aux.split('}')] database_indexes = database.get_entries_indexes(self.path, elements[1::2]) str_to_eval = '' length = len(elements) for i in range(0, length, 2): if i + 1 < length: repl = PREFIX + str(database_indexes[elements[i + 1]]) str_to_eval += elements[i] + repl else: str_to_eval += elements[i] indexes = database_indexes.values() self._eval_cache[string] = (str_to_eval, indexes) vals = self.database.get_values_by_index(indexes, PREFIX) return safe_eval(str_to_eval, vals) else: self._eval_cache[string] = (string, []) return safe_eval(string, {}) # In edition mode simply perfom the evaluation as execution time is not # critical and as the database has not been collapsed to an indexed # representation. else: database = self.database aux_strings = string.split('{') if len(aux_strings) > 1: elements = [el for aux in aux_strings for el in aux.split('}')] replacement_token = [PREFIX + str(i) for i in range(len(elements[1::2]))] repl = {PREFIX + str(i): database.get_value(self.path, key) for i, key in enumerate(elements[1::2])} str_to_format = '' for key in elements[::2]: str_to_format += key + '{}' str_to_format = str_to_format[:-2] expr = str_to_format.format(*replacement_token) return safe_eval(expr, repl) else: return safe_eval(string, {}) def get_error_path(self): """Build the path to use when reporting errors during checks. """ return self.path + '/' + self.name # ========================================================================= # --- Private API --------------------------------------------------------- # ========================================================================= #: Dictionary storing infos necessary to perform fast formatting. #: Only used in running mode. _format_cache = Dict() #: Dictionary storing infos necessary to perform fast evaluation. #: Only used in running mode. _eval_cache = Dict() def _default_task_id(self): """Default value for the task_id member. """ pack, _ = self.__module__.split('.', 1) return pack + '.' + type(self).__name__ def _post_setattr_database_entries(self, old, new): """Update the database content each time the database entries change. """ if self.database: new = set(new) old = set(old) if old else set() added = new - old removed = old - new for entry in removed: full_name = self._task_entry(entry) self.remove_from_database(full_name) for entry in added: new_value = deepcopy(self.database_entries[entry]) self.write_in_database(entry, new_value) for r in [r for r in removed if r in self.access_exs]: self.remove_access_exception(r) def _post_setattr_name(self, old, new): """Update the database entries as they use the task name. """ if not old or not self.database: return olds = [old + '_' + e for e in self.database_entries] news = [new + '_' + e for e in self.database_entries] old_access = {old + '_' + k: v for k, v in self.access_exs.items() if old + '_' + k in olds} self.database.rename_values(self.path, olds, news, old_access) def _add_access_exception(self, entry, level): """Add an access exception without modifying the access_exs member. """ parent = self while level: parent = parent.parent level -= 1 self.database.add_access_exception(parent.path, self.path, self._task_entry(entry)) def _remove_access_exception(self, entry, level): """Remove the access without modifying the access_exs member. """ parent = self while level: parent = parent.parent level -= 1 full_name = self._task_entry(entry) self.database.remove_access_exception(parent.path, full_name) def _task_entry(self, entry): """Build the full name of an entry for a task. """ return self.name + '_' + entry
class Extension(Declarative): """ A declarative class which represents a plugin extension. An Extension must be declared as a child of a PluginManifest. """ #: The globally unique identifier for the extension. id = d_(Unicode()) #: The fully qualified id of the target extension point. point = d_(Unicode()) #: An optional rank to use for order the extension among others. rank = d_(Int()) #: A callable which will create the implementation object for the #: extension point. The call signature and return type are defined #: by the extension point plugin which invokes the factory. factory = d_(Callable()) #: An optional description of the extension. description = d_(Unicode()) @property def plugin_id(self): """ Get the plugin id from the parent plugin manifest. """ return self.parent.id @property def qualified_id(self): """ Get the fully qualified extension identifer. """ this_id = self.id if '.' in this_id: return this_id return '%s.%s' % (self.plugin_id, this_id) def get_child(self, kind, reverse=False): """ Find a child by the given type. Parameters ---------- kind : type The declarative type of the child of interest. reverse : bool, optional Whether to search in reversed order. The default is False. Returns ------- result : child or None The first child found of the requested type. """ it = reversed if reverse else iter for child in it(self.children): if isinstance(child, kind): return child return None def get_children(self, kind): """ Get all the children of the given type. Parameters ---------- kind : type The declarative type of the children of interest. Returns ------- result : list The list of children of the request type. """ return [c for c in self.children if isinstance(c, kind)]
class DelSlot(Atom): i = Int(10)
class Lyzer(TA45_Fund): rd_hdf = Typed(TA45_Read) comment = Unicode().tag(read_only=True, spec="multiline") rt_atten = Float(40) rt_gain = Float(23 * 2) frequency = Array().tag(unit="GHz", plot=True, label="Frequency") yoko = Array().tag(unit="V", plot=True, label="Yoko") Magcom = Array().tag(private=True) pwr = Array() probe_frq = Float().tag(unit="GHz", label="Probe frequency", read_only=True) probe_pwr = Float().tag(label="Probe power", read_only=True, display_unit="dBm/mW") frqind = Int(1) @tag_Property(display_unit="dB", plot=True) def MagdB(self): return self.Magcom[self.frqind, :, :] / dB @tag_Property(plot=True) def Phase(self): return angle( self.Magcom[self.frqind, :, :] ) #-mean(self.Magcom[:, self.powind, 297:303], axis=1, keepdims=True)) @tag_Property(plot=True) def MagAbs(self): #return absolute(self.Magcom[:, :]) #bg=mean(self.Magcom[self.frqind, :, 0:1], axis=1, keepdims=True) bg = mean(self.Magcom[self.frqind, :, 299:300], axis=1, keepdims=True) return absolute( self.Magcom[self.frqind, :, :] - bg ) #mean(self.Magcom[self.frqind, :, 299:300], axis=1, keepdims=True)) def _default_rd_hdf(self): return TA45_Read(main_file="Data_0227/S4A4_TA45_testpwrswp.hdf5") def read_data(self): with File(self.rd_hdf.file_path, 'r') as f: print f["Traces"].keys() self.comment = f.attrs["comment"] print f["Instrument config"].keys() self.probe_frq = f["Instrument config"][ 'Rohde&Schwarz Network Analyzer - IP: 169.254.107.192, RS VNA at localhost'].attrs[ "Start frequency"] self.probe_pwr = f["Instrument config"][ 'Rohde&Schwarz Network Analyzer - IP: 169.254.107.192, RS VNA at localhost'].attrs[ "Output power"] print f["Instrument config"][ 'Rohde&Schwarz Network Analyzer - IP: 169.254.107.192, RS VNA at localhost'].attrs # print f["Data"]["Channel names"][:] Magvec = f["Traces"]["RS VNA - S21"] #[:] data = f["Data"]["Data"] print shape(data) # self.yoko = data[0, 1, :].astype(float64) self.pwr = data[:, 0, 0].astype(float64) print self.yoko fstart = f["Traces"]['RS VNA - S21_t0dt'][0][0] fstep = f["Traces"]['RS VNA - S21_t0dt'][0][1] print shape(Magvec) sm = shape(Magvec)[0] sy = shape(data) s = (sm, sy[0], sy[2]) print s Magcom = Magvec[:, 0, :] + 1j * Magvec[:, 1, :] Magcom = reshape(Magcom, s, order="F") self.frequency = linspace(fstart, fstart + fstep * (sm - 1), sm) print shape(Magcom) self.Magcom = squeeze(Magcom)
class QtAction(QtToolkitObject, ProxyAction): """ A Qt implementation of an Enaml ProxyAction. """ #: A reference to the widget created by the proxy. widget = Typed(QAction) #: Cyclic notification guard. This a bitfield of multiple guards. _guard = Int(0) # FIXME Currently, the checked state of the action is lost when # switching from checkable to non-checkable and back again. #-------------------------------------------------------------------------- # Initialization API #-------------------------------------------------------------------------- def create_widget(self): """ Create the underlying QAction object. """ self.widget = QAction(self.parent_widget()) def init_widget(self): """ Initialize the underlying control. """ super(QtAction, self).init_widget() d = self.declaration if d.text: self.set_text(d.text) if d.tool_tip: self.set_tool_tip(d.tool_tip) if d.status_tip: self.set_status_tip(d.status_tip) if d.icon: self.set_icon(d.icon) self.set_checkable(d.checkable) self.set_checked(d.checked) self.set_enabled(d.enabled) self.set_visible(d.visible) self.set_separator(d.separator) widget = self.widget widget.triggered.connect(self.on_triggered) widget.toggled.connect(self.on_toggled) #-------------------------------------------------------------------------- # Signal Handlers #-------------------------------------------------------------------------- def on_triggered(self): """ The signal handler for the 'triggered' signal. """ # PySide does pass the 'checked' arg to the slot like PyQt, so # grab the checked attribute directly, which works on both. checked = self.widget.isChecked() if not self._guard & CHECKED_GUARD: self.declaration.checked = checked self.declaration.triggered(checked) def on_toggled(self, checked): """ The signal handler for the 'toggled' signal. """ if not self._guard & CHECKED_GUARD: self.declaration.checked = checked self.declaration.toggled(checked) #-------------------------------------------------------------------------- # ProxyAction API #-------------------------------------------------------------------------- def set_text(self, text): """ Set the text on the underlying control. """ widget = self.widget widget.setText(text) parts = text.split('\t') if len(parts) > 1: shortcut = QKeySequence(parts[-1]) widget.setShortcut(shortcut) def set_tool_tip(self, tool_tip): """ Set the tool tip on the underlying control. """ self.widget.setToolTip(tool_tip) def set_status_tip(self, status_tip): """ Set the status tip on the underyling control. """ self.widget.setStatusTip(status_tip) def set_icon(self, icon): """ Set the icon for the action. """ if icon: qicon = get_cached_qicon(icon) else: qicon = QIcon() self.widget.setIcon(qicon) def set_checkable(self, checkable): """ Set the checkable state on the underlying control. """ self.widget.setCheckable(checkable) def set_checked(self, checked): """ Set the checked state on the underlying control. """ self._guard |= CHECKED_GUARD try: self.widget.setChecked(checked) finally: self._guard &= ~CHECKED_GUARD def set_enabled(self, enabled): """ Set the enabled state on the underlying control. """ self.widget.setEnabled(enabled) def set_visible(self, visible): """ Set the visible state on the underlying control. """ self.widget.setVisible(visible) def set_separator(self, separator): """ Set the separator state on the underlying control. """ self.widget.setSeparator(separator)
class MembersTest(Atom): a = b = c = d = e = Int()