def evaluate_sequence(self, root_vars, sequence_locals, missings, errors): """Evaluate the entries of the items making the context. """ # Check the channel mapping makes sense. if not self.context.prepare_compilation(errors): return False # Definition evaluation. self.eval_entries(root_vars, sequence_locals, missings, errors) prefix = '{}_'.format(self.index) # Template vars evaluation. for name, formula in self.template_vars.items(): if name not in self._evaluated_vars: try: val = eval_entry(formula, sequence_locals, missings) self._evaluated_vars[name] = val except Exception: errors[prefix + name] = format_exc() # Local vars computation. for name, formula in self.local_vars.items(): if name not in self._evaluated_vars: try: val = eval_entry(formula, sequence_locals, missings) self._evaluated_vars[name] = val except Exception: errors[prefix + name] = format_exc() local_namespace = self._evaluated_vars.copy() local_namespace['sequence_end'] = self.duration res = self._evaluate_items(local_namespace, local_namespace, missings, errors) if res: overtime = [] self._update_times(self.items, errors, overtime) if overtime: msg = ('The stop time of the following items {} is larger ' 'than the stop time of the sequence {}') ind = [p.index for p in overtime] errors[self.name + '-stop'] = msg.format(ind, self.index) if errors: return False return True
def load_sequence(self, mode='file'): """ Load an existing sequence to edit it. Parameters ---------- mode : {'file', 'template'} - file : load a sequence from a file chosen by the user. - template : lod a sequence from a template chosen by the user. """ if mode == 'file': factory = FileDialogEx.get_open_file_name path = '' if self.state.sequence_path: path = os.path.dirname(self.state.sequence_path) load_path = factory(self.content, current_path=path, name_filters=['*.pulse.ini']) if load_path: try: seq = self._load_sequence_from_file(load_path) except Exception: core = self.workbench.get_plugin('enaml.workbench.core') cmd = 'ecpy.app.errors.signal' msg = 'Failed to rebuild sequence {} :\n\n{}' core.invoke_command( cmd, dict(kind='error', message=msg.format(load_path, format_exc()))) else: self.state.sequence = seq self.state.sequence_type = 'Standard' self.state.sequence_path = load_path logger = logging.getLogger(__name__) logger.debug('Sequence correctly loaded from %s.' % load_path) # elif mode == 'template': # dial = TemplateLoadDialog(self.content, manager=self.plugin) # dial.exec_() # if dial.result: # seq = self._load_sequence_from_template(dial.prefs) # self.state.sequence = seq # self.state.sequence_type = 'Template' # self.state.sequence_path = dial.t_infos.metadata['path'] # self.state.sequence_doc = dial.t_infos.metadata['doc'] # logger = logging.getLogger(__name__) # logger.info('Sequence correctly loaded from template.') else: mess = cleandoc('''Invalid mode for load sequence : {}. Admissible values are 'file' and 'template'.''') raise ValueError(mess.format(mode))
def wrapper(self, *args, **kwargs): i = 0 # Try at most `max_iter` times to excute method while i < max_iter + 1: try: return method(self, *args, **kwargs) # Catch all the exception specified by the driver except self.secure_com_except: if i == max_iter: raise else: print(format_exc()) self.reopen_connection() i += 1
def check(self, *args, **kwargs): """Check that the sequence can be compiled. """ test, traceback = super(TransferPulseSequenceTask, self).check(*args, **kwargs) err_path = self.path + '/' + self.name + '-' if not self.sequence: traceback[err_path + 'sequence'] = 'There is no selected sequence.' return False, traceback msg = 'Failed to evaluate {} ({}): {}' seq = self.sequence for k, v in self.sequence_vars.items(): try: seq.external_vars[k] = self.format_and_eval_string(v) except Exception: test = False traceback[err_path + k] = msg.format(k, v, format_exc()) if not test: return test, traceback context = seq.context res, infos, errors = context.compile_and_transfer_sequence(seq) if not res: traceback[err_path + 'compil'] = errors return False, traceback for k, v in infos.items(): self.write_in_database(k, v) if self.sequence_path: if not (self.sequence_timestamp == os.path.getmtime( self.sequence_path)): msg = 'The sequence is outdated, consider refreshing it.' traceback[err_path + 'outdated'] = msg return test, traceback
def register(self, collector, traceback): """Collect sequence and view and add infos to the DeclaratorCollector contributions member. The group declared by a parent if any is taken into account. All Interface children are also registered. """ # Build the sequence id by assembling the package name and the class # name. sequence_id = self.id # If the sequence only specifies a name update the matching infos. if ':' not in self.sequence: if self.sequence not in collector.contributions: collector._delayed.append(self) return infos = collector.contributions[sequence_id] infos.metadata.update(self.metadata) self.is_registered = True return # Determine the path of sequence and view path = self.get_path() try: s_path, sequence = (path + '.' + self.sequence if path else self.sequence).split(':') v_path, view = (path + '.' + self.view if path else self.view).split(':') except ValueError: msg = 'Incorrect %s (%s), path must be of the form a.b.c:Class' err_id = s_path.split('.', 1)[0] + '.' + sequence msg = msg % ('view', self.view) traceback[err_id] = msg return # Check that the sequence does not already exist. if sequence_id in collector.contributions or sequence_id in traceback: i = 1 while True: err_id = '%s_duplicate%d' % (sequence_id, i) if err_id not in traceback: break msg = 'Duplicate definition of {}, found in {}' traceback[err_id] = msg.format(sequence, s_path) return infos = SequenceInfos(metadata=self.metadata) # Get the sequence class. s_cls = import_and_get(s_path, sequence, traceback, sequence_id) if s_cls is None: return try: infos.cls = s_cls except TypeError: msg = '{} should be a subclass of AbstractSequence. \n{}' traceback[sequence_id] = msg.format(s_cls, format_exc()) return # Get the sequence view. s_view = import_and_get(v_path, view, traceback, sequence_id) if s_view is None: return try: infos.view = s_view except TypeError: msg = '{} should be a subclass of AbstractSequenceView,.\n{}' traceback[sequence_id] = msg.format(s_view, format_exc()) return # Add group and add to collector infos.metadata['group'] = self.get_group() collector.contributions[sequence_id] = infos self.is_registered = True
def register(self, collector, traceback): """Collect config and view and add infos to the DeclaratorCollector contributions member under the supported task name. """ # Determine the path to the config and view. path = self.get_path() try: c_path, config = (path + '.' + self.config if path else self.config).split(':') v_path, view = (path + '.' + self.view if path else self.view).split(':') except ValueError: msg = 'Incorrect %s (%s), path must be of the form a.b.c:Class' if ':' in self.config: msg = msg % ('view', self.view) else: msg = msg % ('config', self.config) traceback[self.id] = msg return try: s_cls = self.get_sequence_class() except Exception: msg = 'Failed to get supported sequence : %s' traceback[self.id] = msg % format_exc() return # Check that the configurer does not already exist. if self.id in traceback: i = 1 while True: err_id = '%s_duplicate%d' % (self.id, i) if err_id not in traceback: break msg = 'Duplicate definition of {}, found in {}' traceback[err_id] = msg.format(s_cls, c_path) return if s_cls in collector.contributions: msg = 'Duplicate definition for {}, found in {}' traceback[self.id] = msg.format(s_cls, c_path) return infos = ConfigInfos() # Get the config class. c_cls = import_and_get(c_path, config, traceback, self.id) if c_cls is None: return try: infos.cls = c_cls except TypeError: msg = '{} should a subclass of AbstractConfig.\n{}' traceback[self.id] = msg.format(c_cls, format_exc()) return # Get the config view. view = import_and_get(v_path, view, traceback, self.id) if view is None: return try: infos.view = view except TypeError: msg = '{} should a subclass of AbstractConfigView.\n{}' traceback[self.id] = msg.format(c_cls, format_exc()) return collector.contributions[s_cls] = infos self.is_registered = True
def main(cmd_line_args=None): """Main entry point of the Ecpy application. """ # Build parser from ArgParser and parse arguemnts parser = ArgParser() parser.add_choice('workspaces', 'ecpy.measure.workspace', 'measure') parser.add_argument("-s", "--nocapture", help="Don't capture stdout/stderr", action='store_true') parser.add_argument("-w", "--workspace", help='Select start-up workspace', default='measure', choices='workspaces') parser.add_argument("-r", "--reset-app-folder", help='Reset the application startup folder.', action='store_true') modifiers = [] for i, ep in enumerate(iter_entry_points('ecpy_cmdline_args')): try: modifier, priority = ep.load(require=False) modifiers.append((ep, modifier, priority, i)) except Exception as e: text = 'Error loading extension %s' % ep.name content = ('The following error occurred when trying to load the ' 'entry point {} :\n {}'.format(ep.name, e)) details = format_exc() display_startup_error_dialog(text, content, details) modifiers.sort(key=itemgetter(1, 2)) try: for m in modifiers: m[1](parser) except Exception as e: text = 'Error modifying cmd line arguments' content = ('The following error occurred when the entry point {} ' 'tried to add cmd line options :\n {}'.format(ep.name, e)) details = format_exc() display_startup_error_dialog(text, content, details) try: args = parser.parse_args(cmd_line_args) except BaseException as e: if e.args == (0,): sys.exit(0) text = 'Failed to parse cmd line arguments' content = ('The following error occurred when trying to parse the ' 'command line arguments :\n {}'.format(e)) details = format_exc() display_startup_error_dialog(text, content, details) # Patch Thread to use sys.excepthook setup_thread_excepthook() workbench = Workbench() workbench.register(CoreManifest()) workbench.register(UIManifest()) workbench.register(AppManifest()) workbench.register(StateManifest()) workbench.register(ErrorsManifest()) workbench.register(PreferencesManifest()) workbench.register(IconManagerManifest()) workbench.register(LogManifest()) workbench.register(PackagesManifest()) workbench.register(DependenciesManifest()) workbench.register(InstrumentManagerManifest()) workbench.register(TasksManagerManifest()) workbench.register(MeasureManifest()) workbench.register(TextMonitorManifest()) ui = workbench.get_plugin(u'enaml.workbench.ui') # Create the application try: app = workbench.get_plugin('ecpy.app') app.run_app_startup(args) except Exception as e: text = 'Error starting plugins' content = ('The following error occurred when executing plugins ' 'application start ups :\n {}'.format(e)) details = format_exc() display_startup_error_dialog(text, content, details) core = workbench.get_plugin('enaml.workbench.core') # Install global except hook. core.invoke_command('ecpy.app.errors.install_excepthook', {}) # Select workspace core.invoke_command('enaml.workbench.ui.select_workspace', {'workspace': args.workspace}, workbench) ui = workbench.get_plugin(u'enaml.workbench.ui') ui.show_window() ui.window.maximize() ui.start_application() core.invoke_command('enaml.workbench.ui.close_workspace', {}, workbench) # Unregister all contributed packages workbench.unregister('ecpy.app.packages') workbench.unregister('ecpy.measure.monitors.text_monitor') workbench.unregister('ecpy.measure') workbench.unregister('ecpy.tasks') workbench.unregister('ecpy.instruments') workbench.unregister('ecpy.app.icons') workbench.unregister('ecpy.app.preferences') workbench.unregister('ecpy.app.states') workbench.unregister('ecpy.app.dependencies') workbench.unregister('ecpy.app.errors') workbench.unregister('ecpy.app.logging') workbench.unregister('ecpy.app') workbench.unregister(u'enaml.workbench.ui') workbench.unregister(u'enaml.workbench.core')
def eval_entries(self, global_vars, local_vars, missings, errors): """Evaluate and format all tagged members. The result of the evaluation is written to the _cache dictionary. Parameters ---------- global_vars : dict Dictionary of global variables. This will be update will the valid values whose tag specify they should be stored as global. local_vars : dict Dictionary of variables used for evaluation. This will be update will the valid values whose tag specify they should be stored as global. missings : set Set of unfound local variables. errors : dict Dict of the errors which happened when performing the evaluation. Returns ------- flag : bool Boolean indicating whether or not the evaluation succeeded. """ res = True cache = self._cache for member, m in tagged_members(self, 'fmt').items(): if member in cache: continue fmt_str = getattr(self, member) try: fmt = fmt_str.format(**local_vars) self._cache[member] = fmt if m.metadata['fmt']: id_ = self.format_global_vars_id(member) global_vars[id_] = fmt local_vars[id_] = fmt # This can only occur if a {} field was found and an entry is # missing except KeyError: res = False aux_strings = fmt_str.split('{') elements = [el for aux in aux_strings for el in aux.split('}')] absent = [el for el in elements[1::2] if el not in local_vars] missings.update(absent) except Exception: res = False errors[self.format_error_id(member)] = format_exc() for member, m in tagged_members(self, 'feval').items(): feval = m.metadata['feval'] if member in cache: continue if not feval.should_test(self, member): continue try: val, store = feval.evaluate(self, member, local_vars) valid, msg = feval.validate(self, val) if not valid: res = False errors[self.format_error_id(member)] = msg else: self._cache[member] = val if store: id_ = self.format_global_vars_id(member) global_vars[id_] = val local_vars[id_] = val except MissingLocalVars as e: res = False missings.update(e.missings) except Exception: res = False errors[self.format_error_id(member)] = format_exc() return res
def evaluate_sequence(self): """Evaluate the root sequence entries and all sub items. Returns ----------- result : bool Flag indicating whether or not the compilation succeeded. missing : set Set of the entries whose values where never found and a dict of the errors which occured during compilation. errors : dict Dict describing the errors that occured during evaluation. """ # First make sure the cache is clean self.clean_cached_values() missings = set() errors = {} root_vars = self.external_vars.copy() # Local vars computation. for name, formula in self.local_vars.items(): if name not in self._cache: try: val = eval_entry(formula, root_vars) self._cache[name] = val except MissingLocalVars as e: missings.update(e.missings) except Exception: errors['root_' + name] = format_exc() root_vars.update(self._cache) if self.time_constrained: try: duration = eval_entry(self.sequence_duration, root_vars) self.stop = self.duration = duration root_vars['sequence_end'] = duration except MissingLocalVars as e: missings.update(e.missings) except Exception: errors['root_seq_duration'] = format_exc() res = self.context.eval_entries(root_vars, root_vars, missings, errors) res &= self._evaluate_items(root_vars, root_vars, missings, errors) if not res: return False, missings, errors if self.time_constrained: overtime = [] self._validate_times(self.items, overtime) if overtime: mess = ('The stop time of the following pulses {} is larger ' 'than the duration of the sequence.') ind = [p.index for p in overtime] errors['root-stop'] = mess.format(ind) return False, missings, errors return True, missings, errors
def evaluate_sequence(self, root_vars, sequence_locals, missings, errors): """ Evaluate the sequence vars and compile the list of pulses. Parameters ---------- root_vars : dict Dictionary of global variables for the all items. This will tipically contains the i_start/stop/duration and the root vars. This dict must be updated with global new values but for evaluation sequence_locals must be used. sequence_locals : dict Dictionary of variables whose scope is limited to this sequence parent. This dict must be updated with global new values and must be used to perform evaluation (It always contains all the names defined in root_vars). missings : set Set of unfound local variables. errors : dict Dict of the errors which happened when performing the evaluation. Returns ------- flag : bool Boolean indicating whether or not the evaluation succeeded. """ prefix = '{}_'.format(self.index) # Definition evaluation. if self.time_constrained: self.eval_entries(root_vars, sequence_locals, missings, errors) # Local vars computation. for name, formula in self.local_vars.items(): if name not in self._cache: try: val = eval_entry(formula, sequence_locals) self._cache[name] = val except MissingLocalVars as e: missings.update(e.missings) except Exception: errors[prefix + name] = format_exc() local_namespace = sequence_locals.copy() local_namespace.update(self._cache) res = self._evaluate_items(root_vars, local_namespace, missings, errors) if res: if self.time_constrained: # Check if start, stop and duration of sequence are compatible. start_err = [item for item in self.items if item.start and item.stop and item.duration and item.start < self.start] stop_err = [item for item in self.items if item.start and item.stop and item.duration and item.stop > self.stop] if start_err: msg = ('The start time of the following items {} is ' 'smaller than the start time of the sequence {}') ind = [p.index for p in start_err] errors[self.name + '-start'] = msg.format(ind, self.index) if stop_err: msg = ('The stop time of the following items {} is ' 'larger than the stop time of the sequence {}') ind = [p.index for p in stop_err] errors[self.name + '-stop'] = msg.format(ind, self.index) if errors: return False return True else: return False