Esempio n. 1
0
    def ramp_to(self,
                vals_dict,
                start_on_finish=False,
                persist=None,
                multiplier=1):
        # Ensure we aren't currently running
        if self.is_ramping:
            print(
                f"Currently ramping. Finish current ramp before starting another."
            )
            return
        if self.is_running:
            print(f"Already running. Stop the sweep before ramping.")
            return

        ramp_params_dict = {}
        n_steps = 1
        for p, v in vals_dict.items():
            if p not in self.set_params_dict.keys():
                print("Cannot ramp parameter not in our sweep.")
                return

            p_step = self.set_params_dict[p]['step']
            if abs(v - safe_get(p)) - abs(p_step / 2) < abs(p_step) * 1e-4:
                continue

            ramp_params_dict[p] = {}
            ramp_params_dict[p]['start'] = safe_get(p)
            ramp_params_dict[p]['stop'] = v

            p_steps = abs(
                (ramp_params_dict[p]['stop'] - ramp_params_dict[p]['start']) /
                p_step * multiplier)
            if p_steps > n_steps:
                n_steps = math.ceil(p_steps)

        if len(ramp_params_dict.keys()) == 0:
            print("Already at the values, no ramp needed.")
            self.done_ramping(vals_dict,
                              start_on_finish=start_on_finish,
                              pd=persist)
            return

        for p, v in ramp_params_dict.items():
            v['step'] = (v['stop'] - v['start']) / n_steps

        self.ramp_sweep = SimulSweep(ramp_params_dict,
                                     n_steps=n_steps,
                                     inter_delay=self.inter_delay,
                                     plot_data=True,
                                     save_data=False,
                                     complete_func=partial(
                                         self.done_ramping,
                                         vals_dict,
                                         start_on_finish=start_on_finish,
                                         pd=persist))
        self.is_ramping = True
        self.is_running = False
        self.ramp_sweep.start(ramp_to_start=False)
Esempio n. 2
0
    def estimate_time(self, verbose=True):
        rate = safe_get(self.magnet.sweeprate_field)
        B_range = abs(safe_get(self.magnet.field) - self.setpoint)

        t_est = B_range * 60 / rate

        hours = int(t_est / 3600)
        minutes = int((t_est % 3600) / 60)
        seconds = t_est % 60
        if verbose is True:
            print(
                f'Estimated time for {repr(self)} to run: {hours}h:{minutes:2.0f}m:{seconds:2.0f}s'
            )
        return t_est
Esempio n. 3
0
    def done_ramping(self, vals_dict, start_on_finish=False, pd=None):
        self.is_ramping = False
        self.is_running = False

        # Check if we are at the value we expect, otherwise something went wrong with the ramp
        for p, v in vals_dict.items():
            p_step = self.set_params_dict[p]['step']
            if abs(safe_get(p) - v) - abs(p_step / 2) > abs(p_step) * 1e-4:
                print(
                    f'Ramping failed (possible that the direction was changed while ramping). '
                    f'Expected {p.label} final value: {v}. Actual value: {safe_get(p)}. '
                    f'Stopping the sweep.')

                if self.ramp_sweep is not None:
                    self.ramp_sweep.kill()
                    self.ramp_sweep = None

                return

        print(f'Done ramping!')
        for p, v in vals_dict.items():
            safe_set(p, v)
            self.set_params_dict[p][
                'setpoint'] = v - self.set_params_dict[p]['step']

        if self.ramp_sweep is not None:
            self.ramp_sweep.kill()
            self.ramp_sweep = None

        if start_on_finish is True:
            self.start(ramp_to_start=False, persist_data=pd)
Esempio n. 4
0
    def update_values(self):
        """
        Iterates our data points, changing our setpoint if we are sweeping, and refreshing
        the values of all our followed parameters. If we are saving data, it happens here,
        and the data is returned.

        Returns:
            data - A list of tuples with the new data. Each tuple is of the format
                   (<QCoDeS Parameter>, measurement value). The tuples are passed in order of
                   time, then set_param (if applicable), then all the followed params.
        """
        t = time.monotonic() - self.t0

        data = [('time', t)]

        sp_data = self.step_param()
        if sp_data is not None:
            data += sp_data
        else:
            return None

        for i, (l, _, gain) in enumerate(self._srs):
            _autorange_srs(l, 3)

        for i, p in enumerate(self._params):
            if p not in self.simul_params:
                v = safe_get(p)
                data.append((p, v))

        if self.save_data and self.is_running:
            self.runner.datasaver.add_result(*data)

        # self.send_updates()

        return data
Esempio n. 5
0
    def __init__(self,
                 _p,
                 n_steps=None,
                 bidirectional=False,
                 continual=False,
                 *args,
                 **kwargs):
        if len(_p.keys()) < 1 or not all(
                isinstance(p, dict) for p in _p.values()):
            raise ValueError(
                'Must pass at least one Parameter and the associated values as dictionaries.'
            )

        self.simul_params = []
        self.set_params_dict = _p.copy()
        self.bidirectional = bidirectional
        self.continuous = continual
        self.direction = 0
        self.n_steps = n_steps
        self.is_ramping = False
        self.ramp_sweep = None

        # Take the first parameter, and set it as the normal Sweep1D set param
        sp = list(_p.keys())[0]
        # Force time to be on the x axis
        kwargs['x_axis_time'] = 1
        QObject.__init__(self)
        BaseSweep.__init__(self, set_param=sp, *args, **kwargs)

        if n_steps is not None:
            for p, v in self.set_params_dict.items():
                v['step'] = (v['stop'] - v['start']) / n_steps
        else:
            _n_steps = []
            for key, p in _p.items():
                _n_steps.append(
                    int(abs(p['stop'] - p['start']) / abs(p['step'])))

            if not all(steps == _n_steps[0] for steps in _n_steps):
                raise ValueError(
                    'Parameters have a different number of steps for the sweep. The Parameters must have '
                    'the same number of steps to sweep them simultaneously.'
                    f'\nStep numbers: {_n_steps}')
            self.n_steps = _n_steps[0]

        for p, v in self.set_params_dict.items():
            self.simul_params.append(p)

            # Make sure the step is in the right direction
            if (v['stop'] - v['start']) > 0:
                v['step'] = abs(v['step'])
            else:
                v['step'] = (-1) * abs(v['step'])

            v['setpoint'] = safe_get(p) - v['step']

        self.follow_param(
            [p for p in self.simul_params if p is not self.set_param])
        self.persist_data = []
Esempio n. 6
0
 def get_param(self, p):
     try:
         return str(safe_get(p))
     except ParameterException as e:
         self.show_error(
             'Error',
             f'Could not get {p.label}. Check the exception and try again.',
             e)
         return ''
Esempio n. 7
0
    def step_AMI430(self):
        """
        Used to control sweeps of AMI430 Instrument. 
        
        The endpoint is determined prior to the sweep, and the current 
        field is measured during ramping.
        
        Returns
        ---------
        The parameter-value pair that was measured.
        """
        
        # Check if we have set the magnetic field yet
        if self.magnet_initialized is False:
            self.instrument.set_field(self.end, block=False)
            self.magnet_initialized = True
            time.sleep(self.inter_delay)

            while safe_get(self.instrument.ramping_state) != 'ramping':
                time.sleep(self.inter_delay)

        # Grab our data
        dt = safe_get(self.set_param)
        data_pair = (self.set_param, dt)
        self.setpoint = dt

        # Check our stop conditions- being at the end point
        if safe_get(self.instrument.ramping_state) == 'holding':
            self.magnet_initialized = False
            if self.save_data:
                self.runner.flush_flag = True
            self.is_running = False
            print(f"Done with the sweep, {self.set_param.label}={self.set_param.get()}")
            self.flip_direction()
            self.completed.emit()
            if self.parent is None:
                self.runner.kill_flag = True

        # Return our data pair, just like any other sweep
        return [data_pair]
Esempio n. 8
0
    def estimate_time(self, verbose=True):
        t_est = 0

        if isinstance(self.instrument, AMI430):
            rate = safe_get(self.instrument.ramp_rate)
            if safe_get(self.instrument.ramp_rate_units) == 0:
                t_est = abs((self.end - self.begin) / rate)
            else:
                t_est = abs((self.end - self.begin) * 60 / rate)
        else:
            t_est = abs((self.begin - self.end) / self.step) * self.inter_delay

            if self.continuous is True:
                print(f'No estimated time for {repr(self)} to run.')
                return 0
            elif self.bidirectional is True:
                t_est *= 2

        hours = int(t_est / 3600)
        minutes = int((t_est % 3600) / 60)
        seconds = t_est % 60
        if verbose is True:
            print(f'Estimated time for {repr(self)} to run: {hours}h:{minutes:2.0f}m:{seconds:2.0f}s')
        return t_est
Esempio n. 9
0
    def update_values(self):
        """
        Called as Runner Thread loops to update parameter values.
        
        Verifies the data to be updated depending on type of sweep.
        Iterates through data point intervals, assigning collected values to 
        their respective parameters. If data is to be saved, it happens here,
        and the updated data is emitted to all connected slots.
        
        Returns
        ---------
        data: 
            A dictionary of tuples with the updated data. Each tuple is of the format 
            (<QCoDeS Parameter>, measurement value). The tuples are passed in order of
            time, then set_param (if applicable), then all the followed params.
        """
        
        t = time.monotonic() - self.t0

        data = [('time', t)]

        if self.set_param is not None:
            sp_data = self.step_param()
            if sp_data is not None:
                data += sp_data
            else:
                return None

        persist_param = None
        if self.persist_data is not None:
            data.append(self.persist_data)
            persist_param = self.persist_data[0]

        for i, (l, _, gain) in enumerate(self._srs):
            _autorange_srs(l, 3)

        for i, p in enumerate(self._params):
            if p is not persist_param:
                v = safe_get(p)
                data.append((p, v))

        if self.save_data and self.is_running:
            self.runner.datasaver.add_result(*data)

        self.send_updates()

        return data
Esempio n. 10
0
    def done_ramping(self, value, start_on_finish=False, pd=None):
        """
        Alerts the sweep that the ramp is finished.
        
        Parameters
        ---------
        value:
            The starting value for the sweep, also the current parameter value.
        start_on_finish:
            Sweep will be called to start immediately after ramping when set to True.
        pd:
            Sets persistent data if running Sweep2D.
        """
        
        self.is_ramping = False
        self.is_running = False
        # Grab the beginning 
        # value = self.ramp_sweep.begin

        # Check if we are at the value we expect, otherwise something went wrong with the ramp
        if abs(safe_get(self.set_param) - value) - abs(self.step/2) > abs(self.step) * 1e-4:
            print(f'Ramping failed (possible that the direction was changed while ramping). '
                  f'Expected {self.set_param.label} final value: {value}. Actual value: {safe_get(self.set_param)}. '
                  f'Stopping the sweep.')

            if self.ramp_sweep is not None:
                self.ramp_sweep.kill()
                self.ramp_sweep = None

            return

        print(f'Done ramping {self.set_param.label} to {value}')
        safe_set(self.set_param, value)
        self.setpoint = value - self.step
        # if self.ramp_sweep is not None and self.ramp_sweep.plotter is not None:
        #    self.ramp_sweep.plotter.clear()

        if self.ramp_sweep is not None:
            self.ramp_sweep.kill()
            self.ramp_sweep = None

        if start_on_finish is True:
            self.start(persist_data=pd, ramp_to_start=False)
Esempio n. 11
0
    def ramp_to(self, value, start_on_finish=False, persist=None, multiplier=1):
        """
        Ramps the set_param to a given value, at a rate dictated by the multiplier.
        
        Parameters
        ---------
        value:
            The desired starting value for the sweep.
        start_on_finish:
            Flag to determine whether to begin the sweep as soon as ramp is finished.
        multiplier:
            Factor to alter the step size, used to ramp quicker than the sweep speed.
        """

        # Ensure we aren't currently running
        if self.is_ramping:
            print(f"Currently ramping. Finish current ramp before starting another.")
            return
        if self.is_running:
            print(f"Already running. Stop the sweep before ramping.")
            return

        # Check if we are already at the value
        curr_value = safe_get(self.set_param)
        if abs(value - curr_value) - abs(self.step/2) < abs(self.step) * 1e-4:
            # print(f"Already within {self.step} of the desired ramp value. Current value: {curr_value},
            # ramp setpoint: {value}.\nSetting our setpoint directly to the ramp value.")
            self.done_ramping(value, start_on_finish, persist)
            return

        # Create a new sweep to ramp our outer parameter to zero
        self.ramp_sweep = Sweep1D(self.set_param, curr_value, value, multiplier * self.step,
                                  inter_delay=self.inter_delay,
                                  complete_func=partial(self.done_ramping, value, start_on_finish, persist),
                                  save_data=False, plot_data=self.plot_data)

        self.is_running = False
        self.is_ramping = True
        self.ramp_sweep.start(ramp_to_start=False)

        print(f'Ramping {self.set_param.label} to {value} . . . ')
Esempio n. 12
0
    def update_values(self):
        """
        Obtains all parameter values for each sweep step.
        
        Sends data through signal for saving and/or live-plotting.
        
        Returns
        ---------
        data:
            A list of tuples with the new data. Each tuple is of the format 
            (<QCoDeS Parameter>, measurement value). The tuples are passed in order of
            time, set_param (if applicable), then all the followed parameters.
        """

        if not self.initialized:
            print("Checking the status of the magnet and switch heater.")
            self.magnet.leave_persistent_mode()
            time.sleep(1)

            # Set the field setpoint
            self.magnet.field_setpoint.set(self.setpoint)
            time.sleep(0.5)
            # Set us to go to setpoint
            self.magnet.activity(1)
            self.initialized = True

        data = []
        t = time.monotonic() - self.t0

        data.append(('time', t))

        # Check our stop conditions- being at the end point
        if self.magnet.mode2() == 'At rest':
            self.is_running = False
            if self.save_data:
                self.runner.datasaver.flush_data_to_database()
            print(
                f"Done with the sweep, B={self.magnet.field.get():.2f} T, t={t:.2f} s."
            )

            # Set status to 'hold'
            self.magnet.activity(0)
            time.sleep(1)
            self.magnet_initialized = False

            print("Done with the sweep!")

            if self.persistent_magnet is True:
                self.magnet.set_persistent()

            self.completed.emit()

        persist_param = None
        if self.persist_data is not None:
            data.append(self.persist_data)
            persist_param = self.persist_data[0]

        for i, (l, _, gain) in enumerate(self._srs):
            _autorange_srs(l, 3)

        for i, p in enumerate(self._params):
            if p is not persist_param:
                v = safe_get(p)
                data.append((p, v))

        if self.save_data and self.is_running:
            self.runner.datasaver.add_result(*data)

        self.send_updates()

        # print(data)
        return data