예제 #1
0
    def _run_loop(self,
                  first_delay=0,
                  action_indices=(),
                  loop_indices=(),
                  current_values=(),
                  **ignore_kwargs):
        """
        the routine that actually executes the loop, and can be called
        from one loop to execute a nested loop

        first_delay: any delay carried over from an outer loop
        action_indices: where we are in any outer loop action arrays
        loop_indices: setpoint indices in any outer loops
        current_values: setpoint values in any outer loops
        signal_queue: queue to communicate with main process directly
        ignore_kwargs: for compatibility with other loop tasks
        """

        # at the beginning of the loop, the time to wait after setting
        # the loop parameter may be increased if an outer loop requested longer
        delay = max(self.delay, first_delay)

        callables = self._compile_actions(self.actions, action_indices)

        t0 = time.time()
        last_task = t0
        last_task_failed = False
        imax = len(self.sweep_values)
        for i, value in enumerate(self.sweep_values):
            if self.progress_interval is not None:
                tprint('loop %s: %d/%d (%.1f [s])' %
                       (self.sweep_values.name, i, imax, time.time() - t0),
                       dt=self.progress_interval,
                       tag='outerloop')

            set_val = self.sweep_values.set(value)

            new_indices = loop_indices + (i, )
            new_values = current_values + (value, )
            data_to_store = {}

            if hasattr(self.sweep_values, "parameters"):
                set_name = self.data_set.action_id_map[action_indices]
                if hasattr(self.sweep_values, 'aggregate'):
                    value = self.sweep_values.aggregate(*set_val)
                self.data_set.store(new_indices, {set_name: value})
                for j, val in enumerate(set_val):
                    set_index = action_indices + (j + 1, )
                    set_name = (self.data_set.action_id_map[set_index])
                    data_to_store[set_name] = val
            else:
                set_name = self.data_set.action_id_map[action_indices]
                data_to_store[set_name] = value

            self.data_set.store(new_indices, data_to_store)

            if not self._nest_first:
                # only wait the delay time if an inner loop will not inherit it
                self._wait(delay)

            try:
                for f in callables:
                    f(first_delay=delay,
                      loop_indices=new_indices,
                      current_values=new_values)

                    # after the first action, no delay is inherited
                    delay = 0
            except _QcodesBreak:
                break

            # after the first setpoint, delay reverts to the loop delay
            delay = self.delay

            # now check for a background task and execute it if it's
            # been long enough since the last time
            # don't let exceptions in the background task interrupt
            # the loop
            # if the background task fails twice consecutively, stop
            # executing it
            if self.bg_task is not None:
                t = time.time()
                if t - last_task >= self.bg_min_delay:
                    try:
                        self.bg_task()
                        last_task_failed = False
                    except Exception:
                        if last_task_failed:
                            self.bg_task = None
                        last_task_failed = True
                    last_task = t

        if self.progress_interval is not None:
            # final progress note: set dt=-1 so it *always* prints
            tprint('loop %s DONE: %d/%d (%.1f [s])' %
                   (self.sweep_values.name, i + 1, imax, time.time() - t0),
                   dt=-1,
                   tag='outerloop')

        # run the background task one last time to catch the last setpoint(s)
        if self.bg_task is not None:
            self.bg_task()

        # the loop is finished - run the .then actions
        for f in self._compile_actions(self.then_actions, ()):
            f()

        # run the bg_final_task from the bg_task:
        if self.bg_final_task is not None:
            self.bg_final_task()
예제 #2
0
파일: loops.py 프로젝트: tinix84/Qcodes
    def _run_loop(self, first_delay=0, action_indices=(),
                  loop_indices=(), current_values=(),
                  **ignore_kwargs):
        """
        the routine that actually executes the loop, and can be called
        from one loop to execute a nested loop

        first_delay: any delay carried over from an outer loop
        action_indices: where we are in any outer loop action arrays
        loop_indices: setpoint indices in any outer loops
        current_values: setpoint values in any outer loops
        signal_queue: queue to communicate with main process directly
        ignore_kwargs: for compatibility with other loop tasks
        """

        # at the beginning of the loop, the time to wait after setting
        # the loop parameter may be increased if an outer loop requested longer
        delay = max(self.delay, first_delay)

        callables = self._compile_actions(self.actions, action_indices)
        n_callables = 0
        for item in callables:
            if hasattr(item, 'param_ids'):
                n_callables += len(item.param_ids)
            else:
                n_callables += 1
        t0 = time.time()
        last_task = t0
        imax = len(self.sweep_values)

        self.last_task_failed = False

        for i, value in enumerate(self.sweep_values):
            if self.progress_interval is not None:
                tprint('loop %s: %d/%d (%.1f [s])' % (
                    self.sweep_values.name, i, imax, time.time() - t0),
                    dt=self.progress_interval, tag='outerloop')
                if i:
                    tprint("Estimated finish time: %s" % (
                        time.asctime(time.localtime(t0 + ((time.time() - t0) * imax / i)))),
                           dt=self.progress_interval, tag="finish")

            set_val = self.sweep_values.set(value)

            new_indices = loop_indices + (i,)
            new_values = current_values + (value,)
            data_to_store = {}

            if hasattr(self.sweep_values, "parameters"):  # combined parameter
                set_name = self.data_set.action_id_map[action_indices]
                if hasattr(self.sweep_values, 'aggregate'):
                    value = self.sweep_values.aggregate(*set_val)
                # below is useful but too verbose even at debug
                # log.debug('Calling .store method of DataSet because '
                #           'sweep_values.parameters exist')
                self.data_set.store(new_indices, {set_name: value})
                # set_val list of values to set [param1_setpoint, param2_setpoint ..]
                for j, val in enumerate(set_val):
                    set_index = action_indices + (j+n_callables, )
                    set_name = (self.data_set.action_id_map[set_index])
                    data_to_store[set_name] = val
            else:
                set_name = self.data_set.action_id_map[action_indices]
                data_to_store[set_name] = value
            # below is useful but too verbose even at debug
            # log.debug('Calling .store method of DataSet because a sweep step'
            #           ' was taken')
            self.data_set.store(new_indices, data_to_store)

            if not self._nest_first:
                # only wait the delay time if an inner loop will not inherit it
                self._wait(delay)

            try:
                for f in callables:
                    # below is useful but too verbose even at debug
                    # log.debug('Going through callables at this sweep step.'
                    #           ' Calling {}'.format(f))
                    f(first_delay=delay,
                      loop_indices=new_indices,
                      current_values=new_values)

                    # after the first action, no delay is inherited
                    delay = 0
            except _QcodesBreak:
                break

            # after the first setpoint, delay reverts to the loop delay
            delay = self.delay

            # now check for a background task and execute it if it's
            # been long enough since the last time
            # don't let exceptions in the background task interrupt
            # the loop
            # if the background task fails twice consecutively, stop
            # executing it
            if self.bg_task is not None:
                t = time.time()
                if t - last_task >= self.bg_min_delay:
                    try:
                        self.bg_task()
                    except Exception:
                        if self.last_task_failed:
                            self.bg_task = None
                        self.last_task_failed = True
                        log.exception("Failed to execute bg task")

                    last_task = t

        # run the background task one last time to catch the last setpoint(s)
        if self.bg_task is not None:
            log.debug('Running the background task one last time.')
            self.bg_task()

        # the loop is finished - run the .then actions
        #log.debug('Finishing loop, running the .then actions...')
        for f in self._compile_actions(self.then_actions, ()):
            #log.debug('...running .then action {}'.format(f))
            f()

        # run the bg_final_task from the bg_task:
        if self.bg_final_task is not None:
            log.debug('Running the bg_final_task')
            self.bg_final_task()
예제 #3
0
    def _run_loop(self,
                  first_delay=0,
                  action_indices=(),
                  loop_indices=(),
                  current_values=(),
                  **ignore_kwargs):
        """
        the routine that actually executes the loop, and can be called
        from one loop to execute a nested loop

        first_delay: any delay carried over from an outer loop
        action_indices: where we are in any outer loop action arrays
        loop_indices: setpoint indices in any outer loops
        current_values: setpoint values in any outer loops
        signal_queue: queue to communicate with main process directly
        ignore_kwargs: for compatibility with other loop tasks
        """

        # at the beginning of the loop, the time to wait after setting
        # the loop parameter may be increased if an outer loop requested longer
        ActiveLoop.action_indices = action_indices

        delay = max(self.delay, first_delay)

        callables = self._compile_actions(self.actions, action_indices)
        self.timings = [[callable, 0] for callable in callables]
        n_callables = 0
        for item in callables:
            if hasattr(item, 'param_ids'):
                n_callables += len(item.param_ids)
            else:
                n_callables += 1
        t0 = time.time()
        last_task = t0
        imax = len(self.sweep_values)

        self.last_task_failed = False

        for i, value in enumerate(self.sweep_values):

            if self.progress_interval is not None:
                tprint('loop %s: %d/%d (%.1f [s])' %
                       (self.sweep_values.name, i, imax, time.time() - t0),
                       dt=self.progress_interval,
                       tag='outerloop')

            set_val = self.sweep_values.set(value)

            new_indices = loop_indices + (i, )
            ActiveLoop.loop_indices = new_indices
            new_values = current_values + (value, )
            data_to_store = {}

            if hasattr(self.sweep_values, "parameters"):  # combined parameter
                set_name = self.data_set.action_id_map[action_indices]
                if hasattr(self.sweep_values, 'aggregate'):
                    value = self.sweep_values.aggregate(*set_val)
                # below is useful but too verbose even at debug
                # log.debug('Calling .store method of DataSet because '
                #           'sweep_values.parameters exist')
                self.data_set.store(new_indices, {set_name: value})
                # set_val list of values to set [param1_setpoint, param2_setpoint ..]
                for j, val in enumerate(set_val):
                    set_index = action_indices + (j + n_callables, )
                    set_name = (self.data_set.action_id_map[set_index])
                    data_to_store[set_name] = val
            else:
                set_name = self.data_set.action_id_map[action_indices]
                data_to_store[set_name] = value
            # below is useful but too verbose even at debug
            # log.debug('Calling .store method of DataSet because a sweep step'
            #           ' was taken')
            self.data_set.store(new_indices, data_to_store)

            if not self._nest_first:
                # only wait the delay time if an inner loop will not inherit it
                self._wait(delay)

            f = None
            try:
                current_action_idx = 0
                for k, f in enumerate(callables):
                    t0 = time.time()
                    # below is useful but too verbose even at debug
                    # log.debug('Going through callables at this sweep step.'
                    #           ' Calling {}'.format(f))
                    if not isinstance(f, _Measure):
                        # Register current action as active one, a _Measure
                        # does this internally for each of its actions
                        ActiveLoop.action_indices = action_indices + (
                            current_action_idx, )
                        ActiveLoop.active_action = f

                    if ActiveLoop.interleave_actions:
                        try:
                            ActiveLoop.interleave_action_results = [
                                action()
                                for action in ActiveLoop.interleave_actions
                            ]
                            print('Finished all interleaved actions')
                        except Exception as e:
                            traceback.print_tb(e.__traceback__)
                        finally:
                            ActiveLoop.interleave_actions = []

                    # Before continuing with a measurement, wait until pause is
                    # removed.
                    while self.flags['pause']:
                        # Update is_paused here, since the pause flag may be
                        # True, but it is still executing a previous function
                        self.is_paused = True
                        time.sleep(0.1)
                    self.is_paused = False

                    f(first_delay=delay,
                      action_indices=action_indices,
                      current_action_idx=current_action_idx,
                      loop_indices=new_indices,
                      current_values=new_values)

                    self.timings[k][1] += time.time() - t0

                    if not isinstance(f, _Measure):
                        # Increment current action idx so that loop_position is
                        # maintained (done internally for _Measure)
                        current_action_idx += 1
                    else:
                        current_action_idx += len(f.param_ids)

                    # after the first action, no delay is inherited
                    delay = 0
            except _QcodesBreak:
                if not isinstance(f, (ContinueIf, SkipIf)):
                    break

            # after the first setpoint, delay reverts to the loop delay
            delay = self.delay

            # now check for a background task and execute it if it's
            # been long enough since the last time
            # don't let exceptions in the background task interrupt
            # the loop
            # if the background task fails twice consecutively, stop
            # executing it
            if self.bg_task is not None:
                t = time.time()
                if t - last_task >= self.bg_min_delay:
                    try:
                        self.bg_task()
                    except _QcodesBreak:
                        log.error('QCodes break raise, stopping')
                        break
                    except Exception:
                        if self.last_task_failed:
                            self.bg_task = None
                        self.last_task_failed = True
                        log.exception("Failed to execute bg task")

                    last_task = t

        # run the background task one last time to catch the last setpoint(s)
        if self.bg_task is not None:
            log.debug('Running the background task one last time.')
            try:
                self.bg_task()
            except _QcodesBreak:
                pass

        # the loop is finished - run the .then actions
        #log.debug('Finishing loop, running the .then actions...')
        for f in self._compile_actions(self.then_actions, ()):
            #log.debug('...running .then action {}'.format(f))
            f()

        # run the bg_final_task from the bg_task:
        if self.bg_final_task is not None:
            log.debug('Running the bg_final_task')
            self.bg_final_task()