예제 #1
0
    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
예제 #2
0
    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))
예제 #3
0
        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
예제 #4
0
    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
예제 #5
0
    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
예제 #6
0
    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
예제 #7
0
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')
예제 #8
0
    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
예제 #9
0
    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
예제 #10
0
    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