def connect_to_station(config_file=None): """ Loads a QCoDeS station configuration file, or starts a new station. Parameters --------- config_file: The file path to the desired configuration file. Returns --------- A loaded or new QCoDeS station for conducting experiments. """ if os.path.isfile(os.environ['MeasureItHome'] + '\\cfg\\qcodesrc.json'): qc.config.update_config(os.environ['MeasureItHome'] + '\\cfg\\') station = Station() try: station.load_config_file(config_file) except Exception: print( "Couldn't open the station configuration file. Started new station." ) return station
def __set_qcodes(self): initialise_or_create_database_at(self.__database) self.station = Station() #### instruments needs change # A dummy instrument dac with two parameters ch1 and ch2 self.dac = DummyInstrument('dac', gates=['amp']) # A dummy instrument dmm with two parameters ch1 and Ch2 self.dmm = DummyInstrument('dmm', gates=['v1']) #These are the parameters which come ready to use from the intruments drivers #dac.add_parameter('amp',label='Amplitude', unit="V", get_cmd=None, set_cmd=None) self.dac.add_parameter('freq', label='Frequency', unit="Hz", get_cmd=None, set_cmd=None) #puts current time in a string to facilitate control of the samples #makes the sample name now = datetime.now() now = now.strftime("%Y-%m-%d_%H-%M-%S") print(now) #the experiment is a unit of data inside the database it's made #out self.exp = load_or_create_experiment(experiment_name=self.__exp_name, sample_name=now) self.dmm.v1 = dmm_parameter('dmm_v1', self.dac)
def __init__( self, parent: Optional[QtCore.QObject] = None, port: int = 5555, allowUserShutdown: bool = False, addresses: List[str] = [], initScript: Optional[str] = None, ) -> None: super().__init__(parent) if addresses is None: addresses = [] if initScript == None: initScript = '' self.SAFEWORD = ''.join( random.choices([chr(i) for i in range(65, 91)], k=16)) self.serverRunning = False self.port = int(port) self.station = Station() self.allowUserShutdown = allowUserShutdown self.listenAddresses = list(set(['127.0.0.1'] + addresses)) self.initScript = initScript self.broadcastPort = self.port + 1 self.broadcastSocket = None self.parameterSet.connect( lambda n, v: logger.info(f"Parameter '{n}' set to: {str(v)}")) self.parameterGet.connect( lambda n, v: logger.debug(f"Parameter '{n}' retrieved: {str(v)}")) self.funcCalled.connect( lambda n, args, kw, ret: logger.debug(f"Function called:" f"'{n}', args: {str(args)}, " f"kwargs: {str(kw)})'."))
def test_integration_station_and_measurement(two_empty_temp_db_connections, inst): """ An integration test where the runs in the source DB file are produced with the Measurement object and there is a Station as well """ source_conn, target_conn = two_empty_temp_db_connections source_path = path_to_dbfile(source_conn) target_path = path_to_dbfile(target_conn) source_exp = Experiment(conn=source_conn) # Set up measurement scenario station = Station(inst) meas = Measurement(exp=source_exp, station=station) meas.register_parameter(inst.back) meas.register_parameter(inst.plunger) meas.register_parameter(inst.cutter, setpoints=(inst.back, inst.plunger)) with meas.run() as datasaver: for back_v in [1, 2, 3]: for plung_v in [-3, -2.5, 0]: datasaver.add_result((inst.back, back_v), (inst.plunger, plung_v), (inst.cutter, back_v+plung_v)) extract_runs_into_db(source_path, target_path, 1) target_ds = DataSet(conn=target_conn, run_id=1) assert datasaver.dataset.the_same_dataset_as(target_ds)
def init(): a_property = Parameter('a_property', set_cmd=None, get_cmd=None, initial_value=0) another_property = Parameter('another_property', set_cmd=None, get_cmd=None, initial_value='abc', vals=validators.Strings()) station = Station(a_property, another_property) return station
def get_station(): # Create a station magnetism_station = Station() # Get the associated instruments for instrument in setup_instruments(): magnetism_station.add_component(instrument) # Give the user the station return magnetism_station
def get_station(): # Create a station cryo_station = Station() # Associate the instruments with the station for instrument in setup_instruments(): cryo_station.add_component(instrument) # Send the station to the user return cryo_station
def fill_station_zerodim(param_meas): station = Station() allinstr=qc.instrument.base.Instrument._all_instruments for key,val in allinstr.items(): instr = qc.instrument.base.Instrument.find_instrument(key) station.add_component(instr) measparstring = "" for parameter in param_meas: station.add_component(parameter) measparstring += parameter.name + ',' return measparstring
def import_json(cls, json_dict, station=Station()): """Loads desired attributes into current SweepQueue.""" sq = SweepQueue(json_dict['inter_delay']) for item_json in json_dict['queue']: item_module = importlib.import_module(item_json['module']) item_class = getattr(item_module, item_json['class']) item = item_class.import_json(item_json, station) sq.append(item) return sq
def fill_station(param_set, param_meas): station = Station() allinstr=qc.instrument.base.Instrument._all_instruments for key,val in allinstr.items(): instr = qc.instrument.base.Instrument.find_instrument(key) station.add_component(instr) measparstring = "" for parameter in param_set: station.add_component(parameter) measparstring += parameter.name + ',' for parameter in param_meas: try: # Prevent station crash when component of parameter is not unique station.add_component(parameter) measparstring += parameter.name + ',' except Exception as e: print('Error ignored when filling station: \n', e) pass return measparstring
def __init__(self, parent=None, port=5555, allowUserShutdown=False): super().__init__(parent) self.SAFEWORD = ''.join( random.choices([chr(i) for i in range(65, 91)], k=16)) self.serverRunning = False self.port = port self.station = Station() self.allowUserShutdown = allowUserShutdown self.parameterSet.connect( lambda n, v: logger.info(f"Parameter '{n}' set to: {str(v)}")) self.parameterGet.connect( lambda n, v: logger.debug(f"Parameter '{n}' retrieved: {str(v)}")) self.funcCalled.connect( lambda n, args, kw, ret: logger.debug(f"Function called:" f"'{n}', args: {str(args)}, " f"kwargs: {str(kw)})'."))
def test_nest(): n_sample_points = 100 x = ManualParameter("x") sweep_values_x = np.linspace(-1, 1, n_sample_points) y = ManualParameter("y") sweep_values_y = np.linspace(-1, 1, n_sample_points) m = ManualParameter("m") m.get = lambda: np.sin(x()) n = ManualParameter("n") n.get = lambda: np.cos(x()) + 2 * np.sin(y()) sweep_object = sweep(x, sweep_values_x)(m, sweep(y, sweep_values_y)(n)) experiment = new_experiment("sweep_measure", sample_name="sine") station = Station() meas = SweepMeasurement(exp=experiment, station=station) meas.register_sweep(sweep_object) with meas.run() as datasaver: for data in sweep_object: datasaver.add_result(*data.items()) data_set = datasaver._dataset assert data_set.paramspecs["x"].depends_on == "" assert data_set.paramspecs["y"].depends_on == "" assert data_set.paramspecs["m"].depends_on == "x" assert data_set.paramspecs["n"].depends_on == "x, y" data_x = data_set.get_data('x') data_y = data_set.get_data('y') assert data_x[::n_sample_points + 1] == [[xi] for xi in sweep_values_x] assert data_y[::n_sample_points + 1] == [[None] for _ in sweep_values_x] coordinate_layout = itertools.product(sweep_values_x, sweep_values_y) expected_x, expected_y = zip(*coordinate_layout) assert [ix for c, ix in enumerate(data_x) if c % (n_sample_points + 1)] == [[xi] for xi in expected_x] assert [iy for c, iy in enumerate(data_y) if c % (n_sample_points + 1)] == [[yi] for yi in expected_y]
def test_column_mismatch(two_empty_temp_db_connections, some_interdeps, inst): """ Test insertion of runs with no metadata and no snapshot into a DB already containing a run that has both """ source_conn, target_conn = two_empty_temp_db_connections source_path = path_to_dbfile(source_conn) target_path = path_to_dbfile(target_conn) target_exp = Experiment(conn=target_conn) # Set up measurement scenario station = Station(inst) meas = Measurement(exp=target_exp, station=station) meas.register_parameter(inst.back) meas.register_parameter(inst.plunger) meas.register_parameter(inst.cutter, setpoints=(inst.back, inst.plunger)) with meas.run() as datasaver: for back_v in [1, 2, 3]: for plung_v in [-3, -2.5, 0]: datasaver.add_result((inst.back, back_v), (inst.plunger, plung_v), (inst.cutter, back_v+plung_v)) datasaver.dataset.add_metadata('meta_tag', 'meta_value') Experiment(conn=source_conn) source_ds = DataSet(conn=source_conn) source_ds.set_interdependencies(some_interdeps[1]) source_ds.mark_started() source_ds.add_results([{name: 2.1 for name in some_interdeps[1].names}]) source_ds.mark_completed() extract_runs_into_db(source_path, target_path, 1) # compare target_copied_ds = DataSet(conn=target_conn, run_id=2) assert target_copied_ds.the_same_dataset_as(source_ds)
def test_toParamDict_paramsBasic(): """Test serializing a few parameters added to a station""" paramNames = [f"parameter_{i}" for i in range(4)] paramValues = [123, None, True, 'abcdef'] params = [] for n, v in zip(paramNames, paramValues): params.append(Parameter(n, unit="unit", set_cmd=None, initial_value=v)) station = Station(*params) # test simple format paramDict_test = toParamDict(station, simpleFormat=True) paramDict_expt = {} for n, v in zip(paramNames, paramValues): paramDict_expt[n] = v assert paramDict_test == paramDict_expt
def take_buffer_keysight(self): """ takes a frequency sweep, not setting any values on the hardware """ from qcodes import Station station = Station() station.add_component(self.vna) # import pdb; pdb.set_trace() meas = Measurement(station=station) # qcodes measurement # self.vna.points.set(20) self.vna.auto_sweep(False) meas.register_parameter(self.vna.real) meas.register_parameter(self.vna.imaginary) meas.register_parameter(self.vna.magnitude) meas.register_parameter(self.vna.phase) # actually get the data with meas.run( ) as datasaver: # try to run the measurement (? but this doesn't yet write to the database) self.vna.active_trace.set(1) # there are Tr1 and Tr2 # self.vna.traces.tr1.run_sweep() imag = self.vna.imaginary() real = self.vna.real() mag = self.vna.magnitude() phase = self.vna.phase() datasaver.add_result( (self.vna.magnitude, mag), (self.vna.phase, phase), (self.vna.real, real), (self.vna.imaginary, imag)) dataid = datasaver.run_id pd = datasaver.dataset.get_parameter_data() snapshot = datasaver.dataset.snapshot plot_by_id(dataid)
def init_from_json(cls, fn, station=Station()): """ Loads previously saved sweep information. Sends the sweep attributes to the import_json module. Parameters --------- fn: Filename path where sweep information is stored. station: Initializes a QCoDeS station. Returns --------- Located data is sent to import_json method. """ with open(fn) as json_file: data = json.load(json_file) return SweepQueue.import_json(data, station)
def load_station_and_connect_instruments(self, config_file=None): self.station = Station() try: self.station.load_config_file(config_file) except Exception as e: self.show_error( "Error", "Couldn't open the station configuration file. Started new station.", e) return if self.station.config is None: return for name, instr in self.station.config['instruments'].items(): try: dev = self.station.load_instrument(name) self.devices[str(name)] = dev except Exception as e: self.show_error( 'Instrument Error', f'Error connecting to {name}, ' 'either the name is already in use or the device is unavailable.', e) self.update_instrument_menu()
def test_inferred(): x = ManualParameter("x", unit="V") @setter([("xmv", "mV")], inferred_parameters=[("x", "V")]) def xsetter(milivolt_value): volt_value = milivolt_value / 1000.0 # From mV to V x.set(volt_value) return volt_value m = ManualParameter("m") m.get = lambda: np.sin(x()) sweep_values = np.linspace(-1000, 1000, 100) # We sweep in mV sweep_object = nest(sweep(xsetter, sweep_values), m) experiment = new_experiment("sweep_measure", sample_name="sine") station = Station() meas = SweepMeasurement(exp=experiment, station=station) meas.register_sweep(sweep_object) with meas.run() as datasaver: for data in sweep_object: datasaver.add_result(*data.items()) data_set = datasaver._dataset assert data_set.paramspecs["x"].depends_on == "" assert data_set.paramspecs["x"].inferred_from == "xmv" assert data_set.paramspecs["xmv"].depends_on == "" assert data_set.paramspecs["m"].depends_on == "x" expected_xmv = [[xi] for xi in sweep_values] expected_x = [[xi / 1000] for xi in sweep_values] assert data_set.get_data('xmv') == expected_xmv assert data_set.get_data('x') == expected_x
def test_simple(): x = ManualParameter("x") sweep_values = np.linspace(-1, 1, 100) m = ManualParameter("m") m.get = lambda: np.sin(x()) sweep_object = nest(sweep(x, sweep_values), m) experiment = new_experiment("sweep_measure", sample_name="sine") station = Station() meas = SweepMeasurement(exp=experiment, station=station) meas.register_sweep(sweep_object) with meas.run() as datasaver: for data in sweep_object: datasaver.add_result(*data.items()) data_set = datasaver._dataset assert data_set.paramspecs["x"].depends_on == "" assert data_set.paramspecs["m"].depends_on == "x" expected_x = [[xi] for xi in sweep_values] assert data_set.get_data('x') == expected_x
# Virtual AWG settings = HardwareSettings() virtual_awg = VirtualAwg([awg_adapter.instrument], settings) marker_delay = 16e-6 virtual_awg.digitizer_marker_delay(marker_delay) marker_uptime = 1e-2 virtual_awg.digitizer_marker_uptime(marker_uptime) # Station gates = VirtualIVVI('gates', gates=['P1', 'P2'], model=None) station = Station(virtual_awg, scope_reader.adapter.instrument, awg_adapter.instrument, gates) #%% Enable the stimulus demodulator = 1 signal_output = 1 oscillator = demodulator update_stimulus(is_enabled=True, signal_output=signal_output, amplitude=0.1, oscillator=oscillator) #%% Sensing a resonance signal_input = signal_output scanjob = scanjob_t(wait_time_startscan=1) scanjob.add_sweep(param=stimulus.set_oscillator_frequency(oscillator), start=140e6, end=180e6, step=0.2e6)
def record_S21_sweep_power_sweep_frequency(self): # -- setting vna parameters # vna.sweep_mode.set('CONT') self.vna.power.set(self.vnapower) self.vna.center.set(self.center_frequency) self.vna.span.set(self.frequency_span) self.vna.points.set(self.num_freq_points) self.vna.if_bandwidth.set(self.ifbandwidth) self.vna.trace.set(self.measuredtrace) self.vna.auto_sweep.set(False) from qcodes import Station station = Station() station.add_component(self.vna) # import pdb; pdb.set_trace() meas = Measurement(station=station) # qcodes measurement # vna.groupdelay.set(groupdelayref) #does not work yet meas = Measurement() # register the first independent parameter meas.register_parameter(self.vna.power) # register the second independent parameter meas.register_parameter(self.vna.real, setpoints=(self.vna.power, )) # ^ (? Why would vna.real be an independent parameter?) Does it not get measured (dependent) as a function of freq? meas.register_parameter( self.vna.imaginary, setpoints=(self.vna.power, )) # now register the dependent one meas.register_parameter( self.vna.phase, setpoints=(self.vna.power, )) # now register the dependent one meas.register_parameter( self.vna.magnitude, setpoints=(self.vna.power, )) # now register the dependent one # -- taking data with meas.run() as datasaver: for v1 in np.linspace(self.powersweepstart, self.powersweepstop, self.num_power_points, endpoint=True): self.vna.active_trace.set(1) power = self.vna.power.set(v1) print(self.vna.power.get()) # check # vna.auto_sweep.set(False) # vna.auto_sweep.set(True) # some bug not taking the last row therefore two sweeps self.vna.traces.tr1.run_sweep() # power=vna.power() # vna.auto_sweep.set(False) imag = self.vna.imaginary() real = self.vna.real() phase = self.vna.phase() mag = self.vna.magnitude() # vna.active_trace.set(2) # vna.traces.tr2.run_sweep() power = self.vna.power( ) # should still be the same as a few lines above # time.sleep(2) datasaver.add_result( (self.vna.magnitude, mag), (self.vna.phase, phase), (self.vna.real, real), (self.vna.imaginary, imag), (self.vna.power, power)) print(self.vna.power.get()) plot_by_id(datasaver.run_id) pd = datasaver.dataset.get_parameter_data() # import pdb; pdb.set_trace() # noqa BREAKPOINT magnitude_table = np.vstack( (np.ravel(pd[self.vna_name + "_tr1_magnitude"][self.vna_name + "_power"]), np.ravel(pd[self.vna_name + "_tr1_magnitude"][self.vna_name + "_tr1_frequency"]), np.ravel(pd[self.vna_name + "_tr1_magnitude"][self.vna_name + "_tr1_magnitude"]))) phase_table = np.vstack( (np.ravel(pd[self.vna_name + "_tr1_phase"][self.vna_name + "_power"]), np.ravel(pd[self.vna_name + "_tr1_phase"][self.vna_name + "_tr1_frequency"]), np.ravel(pd[self.vna_name + "_tr1_phase"][self.vna_name + "_tr1_phase"]))) real_table = np.vstack( (np.ravel(pd[self.vna_name + "_tr1_real"][self.vna_name + "_power"]), np.ravel(pd[self.vna_name + "_tr1_real"][self.vna_name + "_tr1_frequency"]), np.ravel(pd[self.vna_name + "_tr1_real"][self.vna_name + "_tr1_real"]))) imaginary_table = np.vstack( (np.ravel(pd[self.vna_name + "_tr1_imaginary"][self.vna_name + "_power"]), np.ravel(pd[self.vna_name + "_tr1_imaginary"][self.vna_name + "_tr1_frequency"]), np.ravel(pd[self.vna_name + "_tr1_imaginary"][self.vna_name + "_tr1_imaginary"]))) np.savetxt( os.path.join( self.raw_path_with_date, str(datasaver.run_id) + '_powersweep' + '_' + str(self.exp_name) + '_magnitude.txt'), magnitude_table) np.savetxt( os.path.join( self.raw_path_with_date, str(datasaver.run_id) + '_powersweep' + '_' + str(self.exp_name) + '_phase.txt'), phase_table) np.savetxt( os.path.join( self.raw_path_with_date, str(datasaver.run_id) + '_powersweep' + '_' + str(self.exp_name) + '_real.txt'), real_table) np.savetxt( os.path.join( self.raw_path_with_date, str(datasaver.run_id) + '_powersweep' + '_' + str(self.exp_name) + '_imaginary.txt'), imaginary_table)
for record in records: plot.plot(record.set_arrays[0].flatten(), record.flatten(), color=next(color_cycler), label=record.name) plot.legend(loc='upper right') plot.draw() plot.pause(0.001) # CREATE THE SCOPE READER AND STATION device_id = 'dev2338' scope_reader = UHFLIScopeReader(device_id) uhfli = scope_reader.adapter.instrument station = Station(uhfli, update_snapshot=False) # INITIALIZE THE SCOPE READER file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'uhfli.dat') configuration = load_configuration(file_path) scope_reader.initialize(configuration) # PREPARE THE SCOPE FOR READOUT scope_reader.number_of_averages = 1 scope_reader.input_range = (0.5, 1.0) scope_reader.sample_rate = 450e6 scope_reader.period = 1e-5
def import_json(cls, json_dict, station=Station()): """ Loads previously exported Station setup. Reassigns all dictionary values exported as JSON to their appropriate objects. """ def load_parameter(name, instr_name, instr_type, station): if instr_name in station.components.keys(): if isinstance(station.components[instr_name], instr_type): return station.components[instr_name].parameters[name] for i_name, instr in station.components.items(): if isinstance(instr, instr_type): return instr.parameters[name] sweep_class = json_dict['class'] sweep_module = json_dict['module'] if 'Sweep1D' in sweep_class: sp = json_dict['set_param'] module = importlib.import_module(sweep_module) sc = getattr(module, sweep_class) instr_module = importlib.import_module(sp['instr_module']) instrument = getattr(instr_module, sp['instr_class']) set_param = load_parameter(sp['param'], sp['instr_name'], instrument, station) sweep = sc(set_param, sp['start'], sp['stop'], sp['step'], **json_dict['attributes']) elif 'Sweep0D' in sweep_class: module = importlib.import_module(sweep_module) sc = getattr(module, sweep_class) sweep = sc(**json_dict['attributes']) elif 'Sweep2D' in sweep_class: module = importlib.import_module(sweep_module) sc = getattr(module, sweep_class) in_param = json_dict['inner_sweep'] in_instr_module = importlib.import_module(in_param['instr_module']) in_instrument = getattr(in_instr_module, in_param['instr_class']) inner_param = load_parameter(in_param['param'], in_param['instr_name'], in_instrument, station) out_param = json_dict['outer_sweep'] out_instr_module = importlib.import_module(out_param['instr_module']) out_instrument = getattr(out_instr_module, out_param['instr_class']) outer_param = load_parameter(out_param['param'], out_param['instr_name'], out_instrument, station) inner_list = [inner_param, in_param['start'], in_param['stop'], in_param['step']] outer_list = [outer_param, out_param['start'], out_param['stop'], out_param['step']] sweep = sc(inner_list, outer_list, **json_dict['attributes']) elif 'SimulSweep' in sweep_class: module = importlib.import_module(sweep_module) sc = getattr(module, sweep_class) set_params_dict = {} for p, items in json_dict['set_params'].items(): instr_module = importlib.import_module(items['instr_module']) instrument = getattr(instr_module, items['instr_class']) param = load_parameter(p, items['instr_name'], instrument, station) set_params_dict[param] = {} set_params_dict[param]['start'] = items['start'] set_params_dict[param]['stop'] = items['stop'] set_params_dict[param]['step'] = items['step'] sweep = sc(set_params_dict, **json_dict['attributes']) else: return for p, instr in json_dict['follow_params'].items(): instr_module = importlib.import_module(instr[1]) instrument = getattr(instr_module, instr[2]) param = load_parameter(p, instr[0], instrument, station) sweep.follow_param(param) return sweep
# -*- coding: utf-8 -*- #%% imports import inspect import numpy as np from qcodes import Station, Instrument from qcodes.utils import validators from instrumentserver import QtWidgets from instrumentserver.serialize import (saveParamsToFile, loadParamsFromFile, toParamDict, fromParamDict) from instrumentserver.gui import widgetDialog from instrumentserver.params import ParameterManager from instrumentserver.gui.instruments import ParameterManagerGui from instrumentserver.client import Client, ProxyInstrument #%% run the PM locally Instrument.close_all() pm = ParameterManager('pm') station = Station() station.add_component(pm) dialog = widgetDialog(ParameterManagerGui(pm)) #%% instantiate PM in the server. Instrument.close_all() cli = Client() pm = ProxyInstrument('pm', cli=cli, remotePath='pm') dialog = widgetDialog(ParameterManagerGui(pm))
def generate_DB_file_with_runs_and_snapshots(): """ Generate a .db-file with a handful of runs some of which have snapshots. Generated runs: #1: run with a snapshot that has some content #2: run with a snapshot of an empty station #3: run without a snapshot """ v4fixturepath = os.path.join(utils.fixturepath, 'version4') os.makedirs(v4fixturepath, exist_ok=True) path = os.path.join(v4fixturepath, 'with_runs_and_snapshots.db') if os.path.exists(path): os.remove(path) from qcodes.dataset.sqlite_base import is_column_in_table from qcodes.dataset.measurements import Measurement from qcodes.dataset.experiment_container import Experiment from qcodes import Parameter, Station from qcodes.dataset.descriptions import RunDescriber from qcodes.dataset.dependencies import InterDependencies exp = Experiment(path_to_db=path, name='experiment_1', sample_name='no_sample_1') conn = exp.conn # Now make some parameters to use in measurements params = [] for n in range(4): params.append(Parameter(f'p{n}', label=f'Parameter {n}', unit=f'unit {n}', set_cmd=None, get_cmd=None)) # We are going to make 3 runs run_ids = [] # Make a run with a snapshot with some content full_station = Station(*params[0:1], default=False) assert Station.default is None meas = Measurement(exp, full_station) meas.register_parameter(params[0]) meas.register_parameter(params[1]) meas.register_parameter(params[2], basis=(params[1],)) meas.register_parameter(params[3], setpoints=(params[1], params[2])) with meas.run() as datasaver: for x in np.random.rand(4): for y in np.random.rand(4): z = np.random.rand() datasaver.add_result((params[1], x), (params[2], y), (params[3], z)) run_ids.append(datasaver.run_id) # Make a run with a snapshot of empty station empty_station = Station(default=False) assert Station.default is None meas = Measurement(exp, empty_station) meas.register_parameter(params[0]) meas.register_parameter(params[1]) meas.register_parameter(params[2]) meas.register_parameter(params[3], setpoints=(params[1], params[2])) with meas.run() as datasaver: for x in np.random.rand(4): for y in np.random.rand(4): z = np.random.rand() datasaver.add_result((params[1], x), (params[2], y), (params[3], z)) run_ids.append(datasaver.run_id) # Make a run without a snapshot (i.e. station is None) assert Station.default is None meas = Measurement(exp) meas.register_parameter(params[0]) meas.register_parameter(params[1]) meas.register_parameter(params[2], basis=(params[1],)) meas.register_parameter(params[3], setpoints=(params[1], params[2])) with meas.run() as datasaver: for x in np.random.rand(4): for y in np.random.rand(4): z = np.random.rand() datasaver.add_result((params[1], x), (params[2], y), (params[3], z)) run_ids.append(datasaver.run_id) # Check correctness of run_id's assert [1, 2, 3] == run_ids, 'Run ids of generated runs are not as ' \ 'expected after generating runs #1-3' # Ensure snapshot column assert is_column_in_table(conn, 'runs', 'snapshot')