def test_load_experiment_by_name_defaults(empty_temp_db): exp1 = Experiment(exp_id=None) exp2 = load_experiment_by_name('experiment_1') assert_experiments_equal(exp1, exp2) exp3 = load_experiment_by_name('experiment_1', 'some_sample') assert_experiments_equal(exp1, exp3)
def test_load_experiment_by_name_bad_sample_name(empty_temp_db): Experiment(exp_id=None, sample_name='mysample') with pytest.raises(ValueError, match='Experiment not found'): _ = load_experiment_by_name('experiment_1', 'mysample__') with pytest.raises(ValueError, match='Experiment not found'): _ = load_experiment_by_name('experiment_1__', 'mysample') with pytest.raises(ValueError, match='Experiment not found'): _ = load_experiment_by_name('experiment_1__', 'mysample__')
def test_load_experiment_by_name_duplicate_sample_name(empty_temp_db): exp1 = Experiment(exp_id=None, name='exp1', sample_name='sss') exp2 = Experiment(exp_id=None, name='exp2', sample_name='sss') exp1_loaded = load_experiment_by_name('exp1') assert_experiments_equal(exp1, exp1_loaded) exp2_loaded = load_experiment_by_name('exp2') assert_experiments_equal(exp2, exp2_loaded) exp1_loaded_with_sample = load_experiment_by_name('exp1', 'sss') assert_experiments_equal(exp1, exp1_loaded_with_sample) exp2_loaded_with_sample = load_experiment_by_name('exp2', 'sss') assert_experiments_equal(exp2, exp2_loaded_with_sample)
def test_load_experiment_by_name(empty_temp_db): exp1 = Experiment(exp_id=None, name='myname') exp2 = load_experiment_by_name('myname') assert_experiments_equal(exp1, exp2) exp3 = load_experiment_by_name('myname', 'some_sample') assert_experiments_equal(exp1, exp3) exp4 = Experiment(exp_id=None, name='with_sample', sample_name='mysample') exp5 = load_experiment_by_name('with_sample') assert_experiments_equal(exp4, exp5) exp6 = load_experiment_by_name('with_sample', 'mysample') assert_experiments_equal(exp4, exp6)
def get_results_from_db_path(db_path, return_as_dict=False, flatten_values=False): """ We define the data base path as "<experiment name>/<sample name>/<run number>". If we have used "do_experiment" to perform acquire the results, then the experiment name and sample name combination will be unique. """ path_parts = db_path.split("/") experiment_name = path_parts[0] run_number = int(path_parts[-1]) sample_name = "/".join(path_parts[1:-1]) try: exp = load_experiment_by_name(experiment_name, sample_name) except ValueError: raise ValueError( "The experiment and sample name combination is not unique. " "Are you sure you have used the 'do_experiment' function to " "acquire data?") results = exp.data_sets()[run_number] if return_as_dict: results = dataset_to_dict(results, flatten_values=flatten_values) return results
def test_load_experiment_by_name_duplicate_name_and_sample_name(empty_temp_db): exp1 = Experiment(exp_id=None, name='exp', sample_name='sss') exp2 = Experiment(exp_id=None, name='exp', sample_name='sss') repr_str = f"Many experiments matching your request found:\n" \ f"exp_id:{exp1.exp_id} ({exp1.name}-{exp1.sample_name}) " \ f"started at ({exp1.started_at})\n" \ f"exp_id:{exp2.exp_id} ({exp2.name}-{exp2.sample_name}) " \ f"started at ({exp2.started_at})" repr_str_regex = re.escape(repr_str) with pytest.raises(ValueError, match=repr_str_regex): load_experiment_by_name('exp') with pytest.raises(ValueError, match=repr_str_regex): load_experiment_by_name('exp', 'sss')
def do_experiment(experiment_name, sweep_object, setup=None, cleanup=None, station=None, live_plot=False): if "/" in experiment_name: experiment_name, sample_name = experiment_name.split("/") else: sample_name = None try: experiment = load_experiment_by_name(experiment_name, sample_name) except ValueError: # experiment does not exist yet db_location = qcodes.config["core"]["db_location"] DataSet(db_location) experiment = new_experiment(experiment_name, sample_name) def add_actions(action, callables): if callables is None: return for cabble in np.atleast_1d(callables): if not isinstance(cabble, tuple): cabble = (cabble, ()) action(*cabble) if live_plot: try: from plottr.qcodes_dataset import QcodesDatasetSubscriber from plottr.tools import start_listener start_listener() except ImportError: warn("Cannot perform live plots, plottr not installed") live_plot = False meas = SweepMeasurement(exp=experiment, station=station) meas.register_sweep(sweep_object) add_actions(meas.add_before_run, setup) add_actions(meas.add_after_run, cleanup) with meas.run() as datasaver: if live_plot: datasaver.dataset.subscribe(QcodesDatasetSubscriber( datasaver.dataset), state=[], min_wait=0, min_count=1) for data in sweep_object: datasaver.add_result(*data.items()) return _DataExtractor(datasaver)
def test_load_experiment_by_name_duplicate_name(empty_temp_db): exp1 = Experiment(exp_id=None, name="exp") exp2 = Experiment(exp_id=None, name="exp") repr_str_1_2 = (f"Many experiments matching your request found:\n" f"exp_id:{exp1.exp_id} ({exp1.name}-{exp1.sample_name}) " f"started at ({exp1.started_at})\n" f"exp_id:{exp2.exp_id} ({exp2.name}-{exp2.sample_name}) " f"started at ({exp2.started_at})") repr_str_1_2_regex = re.escape(repr_str_1_2) with pytest.raises(ValueError, match=repr_str_1_2_regex): load_experiment_by_name("exp", "some_sample") last_exp = load_experiment_by_name("exp", load_last_duplicate=True) assert last_exp.name == "exp" assert last_exp.sample_name == "some_sample" assert last_exp.exp_id == 2 exp3 = Experiment(exp_id=None, name="exp", sample_name="my_sample") repr_str_1_2_3 = (repr_str_1_2 + "\n" + f"exp_id:{exp3.exp_id} ({exp3.name}-{exp3.sample_name}) " f"started at ({exp3.started_at})") repr_str_1_2_3_regex = re.escape(repr_str_1_2_3) with pytest.raises(ValueError, match=repr_str_1_2_3_regex): load_experiment_by_name("exp") last_exp = load_experiment_by_name("exp", load_last_duplicate=True) assert last_exp.name == "exp" assert last_exp.sample_name == "my_sample" assert last_exp.exp_id == 3 exp3_loaded = load_experiment_by_name('exp', 'my_sample') assert_experiments_equal(exp3, exp3_loaded)
def create_database(self, filename, experiment_name, sample_name): #database.initialise_database() initialise_or_create_database_at(filename) try: experiment = exc.load_experiment_by_name(name=experiment_name, sample=sample_name) except ValueError: experiment = exc.new_experiment(name=experiment_name, sample_name=sample_name) print('new_experiment')
def test_run_loaded_experiment(empty_temp_db): """ Test that we can resume a measurement after loading by name """ new_experiment("test", "test1") exp_loaded = load_experiment_by_name("test", "test1") meas = Measurement(exp=exp_loaded) with meas.run(): pass with meas.run(): pass
def test_run_loaded_experiment(): """ Test that we can resume a measurement after loading by name """ new_experiment("test", "test1") exp_loaded = load_experiment_by_name("test", "test1") meas = Measurement(exp=exp_loaded) meas.register_custom_parameter(name='dummy', paramtype='text') with meas.run(): pass with meas.run(): pass
def test_load_experiment_by_name_duplicate_name(empty_temp_db): exp1 = Experiment(exp_id=None, name='exp') exp2 = Experiment(exp_id=None, name='exp') exp3 = Experiment(exp_id=None, name='exp', sample_name='my_sample') repr_str_1_2 = f"Many experiments matching your request found:\n" \ f"exp_id:{exp1.exp_id} ({exp1.name}-{exp1.sample_name}) " \ f"started at ({exp1.started_at})\n" \ f"exp_id:{exp2.exp_id} ({exp2.name}-{exp2.sample_name}) " \ f"started at ({exp2.started_at})" repr_str_1_2_3 = repr_str_1_2 + "\n" + \ f"exp_id:{exp3.exp_id} ({exp3.name}-{exp3.sample_name}) " \ f"started at ({exp3.started_at})" repr_str_1_2_regex = re.escape(repr_str_1_2) repr_str_1_2_3_regex = re.escape(repr_str_1_2_3) with pytest.raises(ValueError, match=repr_str_1_2_3_regex): load_experiment_by_name('exp') with pytest.raises(ValueError, match=repr_str_1_2_regex): load_experiment_by_name('exp', 'some_sample') exp3_loaded = load_experiment_by_name('exp', 'my_sample') assert_experiments_equal(exp3, exp3_loaded)
def select_experiment(exp_name, sample_name): """ Convenience function that will check if the experiment/sample combination already exists in the current database. If so, it'll return the existing one. Otherwise it will create a new one and return that. Potential issue: if multiple experiments with the same experiment/sample combination exist, our detection method will fail, and another copy of this combination will be created. """ try: exp = load_experiment_by_name(exp_name, sample_name) except ValueError: exp = new_experiment(exp_name, sample_name) return exp
def create_database_experiment_and_folders(self): # -- set the path where the raw data should be saved to (pngs, txts) self.raw_path = ('C:\\Users\\nanospin\\Nextcloud\\Lab-Shared\\measurements\\chris\\keysight_tests_data' + '\\' + self.cooldown_date + '_' + self.sample_name + '\\' 'raw') # set the .db path qc.config["core"]["db_location"] = ( os.path.join('C:\\Users\\nanospin\\Nextcloud\\Lab-Shared\\measurements\\chris\\keysight_tests_data', 'keysight_tests.db')) # store a qcodesrc file with the loaded .db path to the measurements folder qc.config.save_config( os.path.join("C:\\Users\\nanospin\\Nextcloud\\Lab-Shared\\measurements", ".qcodesrc")) # self.raw_path = 'C:\\Users\\nanospin\\Nextcloud\\Lab-Shared\\measurements\\Data\\'+self.cooldown_date+'_'+self.sample_name+"\\raw\\" # qc.config["core"]["db_location"] = ( # os.path.join('C:\\Users\\nanospin\\Nextcloud\\Lab-Shared\\measurements\\Data', 'experiments.db')) # -- check if in the standard folder -see qcodes config file- an experiment with exp_name already exists # if not, create a new folder at path # if so, just print the last exp. ID and go on try: # qcodes interface of loading an experiment: # -- tries to connect to a database (specificed in config data structure) and searches for the exp_name self.exp = load_experiment_by_name( self.exp_name, sample=self.sample_name) # keep track of the experiment number print('Experiment loaded. Last ID no: ', self.exp.last_counter) except ValueError: print("Experiment name `", self.exp_name, "` with sample name `", self.sample_name, "` not found in ", qc.config["core"]["db_location"]) print('Starting new experiment.') self.exp = new_experiment(self.exp_name, self.sample_name) os.makedirs(self.raw_path, exist_ok=True) # ---- always create a new folder for each day of taking measurements self.raw_path_with_date = os.path.join( self.raw_path, date.today().strftime("%y-%m-%d")) if not os.path.isdir(self.raw_path_with_date): # force-create the directory os.makedirs(self.raw_path_with_date, exist_ok=True)
def test_active_experiment(empty_temp_db): conn = conn_from_dbpath_or_conn(conn=None, path_to_db=empty_temp_db) with pytest.raises(ValueError): get_default_experiment_id(conn) exp_1 = load_or_create_experiment("test_exp", sample_name="no_sample") assert get_default_experiment_id(conn) == exp_1.exp_id exp_2 = new_experiment("test_exp_2", sample_name="no_sample") assert get_default_experiment_id(conn) == exp_2.exp_id exp_3 = load_experiment(1) assert get_default_experiment_id(conn) == exp_1.exp_id assert get_default_experiment_id(conn) == exp_3.exp_id exp_4 = new_experiment("test_exp_3", sample_name="no_sample") exp_5 = load_experiment_by_name("test_exp_2", sample="no_sample") assert get_default_experiment_id(conn) == exp_2.exp_id assert get_default_experiment_id(conn) == exp_5.exp_id exp_6 = load_last_experiment() assert get_default_experiment_id(conn) == exp_4.exp_id assert get_default_experiment_id(conn) == exp_6.exp_id last_exp = new_experiment("last_exp", sample_name="no_sample") load_experiment(3) reset_default_experiment_id(conn) assert get_default_experiment_id(conn) is last_exp.exp_id load_experiment(exp_1.exp_id) assert get_default_experiment_id(conn) == exp_1.exp_id reset_default_experiment_id() assert get_default_experiment_id(conn) is last_exp.exp_id
def test_load_or_create_experiment_creating(): """Test that an experiment is correctly created""" exp = load_or_create_experiment("experiment_name", "sample_name") exp_2 = load_experiment_by_name("experiment_name", "sample_name") assert_experiments_equal(exp, exp_2)
def __init__(self): """ 1. setup the VNA as an instrument (if it's not already setup) 2. specify experimental parameters 3. specify paths of the target files: database file and a new folder with raw (txt, png) files """ self.vna_name = 'VNA' self.vna_class = Anritsu_MS46522B # this is a qcodes VisaInstrument (interface between visa and qcodes) # Anritsu_MS46522B("VNA2", "TCPIP0::169.254.235.118::5001::SOCKET", 50e6, 20e9, -30, 30, 2) # -- check if instrument 'VNA' already exists. If not, create it if Instrument.exist(self.vna_name, self.vna_class): # an instrument is created by qcodes in a global context, # from which it can be retrieved manually using find_instrument self.vna = Instrument.find_instrument(self.vna_name, self.vna_class) else: self.vna = self.vna_class(self.vna_name, 'TCPIP0::169.254.235.118::5001::SOCKET', 50e6, 20e9, -30, 30, 2) # -- name the experiment -> automatic file names self.exp_name = 'Warm_VNA_Noise' # name used by qcodes self.cooldown_date = '20-09-18' self.sample_name = 'no_sample' # -- set experiment parameters (global constants, used in different measurement functions) self.numberofpoints = 20 # 2001 # number of measurement points self.vnapower = -10 # applied power self.start_frequency = 3.7e9 #3.387015e9 #6.608e9-3.5e6 # start frequency of sweep self.stop_frequency = 5.7e9 #3.387065e9 #6.611e9 +3.5e6 # stop frequency of sweep self.frequency_span = self.stop_frequency - self.start_frequency self.center_frequency = (self.stop_frequency - self.start_frequency)/2. + self.start_frequency # just used for power sweep self.measuredtrace='S21' # spectral density measured between port 1 and 2 self.ifbandwidth=10 # IF Bandwidth, must be in (10,30,50,70,100,300,500,700,1000,3000,5000,7000,10000)Hz self.powersweepstart=-30 # start for power sweep self.powersweepstop=20 # stop for powersweep self.powersweepnum=6 # number of power sweeps (perhaps +/-1) MUST BE AN EVEN NUMBER AT LEAST 6 # groupdelayref=0.0000000225 # vna.groupdelay.set(groupdelayref)#resets to 0 instead of working -> rounding to 0 # print(vna.groupdelay.get()) # -- set the path where the raw data should be saved to (pngs, txts) self.raw_path = ('C:\\Users\\Desktop\\tests' + '\\' + self.cooldown_date + '_' + self.sample_name + '\\' 'raw') # set the .db path qc.config["core"]["db_location"] = ( os.path.join('C:\\Users\\Desktop\\tests', 'test.db')) # store a qcodesrc file with the loaded .db path to the measurements folder qc.config.save_config( os.path.join("C:\\Users\\Desktop\\tests", ".qcodesrc")) # -- check if in the standard folder -see qcodes config file- an experiment with exp_name already exists # if not, create a new folder at path # if so, just print the last exp. ID and go on try: # qcodes interface of loading an experiment: # -- tries to connect to a database (specificed in config data structure) and searches for the exp_name self.exp = load_experiment_by_name(self.exp_name, sample=self.sample_name) print('Experiment loaded. Last ID no: ', self.exp.last_counter) # keep track of the experiment number except ValueError: print("Experiment name ", self.exp_name, " with sample name ", self.sample_name, " not found in ", qc.config["core"]["db_location"]) print('Starting new experiment.') self.exp = new_experiment(self.exp_name, self.sample_name) os.makedirs(self.raw_path, exist_ok=True) # ---- always create a new folder for each day of taking measurements self.raw_path_with_date = os.path.join(self.raw_path, date.today().strftime("%y-%m-%d")) if not os.path.isdir(self.raw_path_with_date): os.makedirs(self.raw_path_with_date, exist_ok=True) # force-create the directory
def test_copy_datasets_and_add_new(two_empty_temp_db_connections, some_interdeps): """ Test that new runs get the correct captured_run_id and captured_counter when adding on top of a dataset with partial exports """ source_conn, target_conn = two_empty_temp_db_connections source_exp_1 = Experiment(conn=source_conn, name='exp1', sample_name='no_sample') source_exp_2 = Experiment(conn=source_conn, name='exp2', sample_name='no_sample') source_datasets_1 = [ DataSet(conn=source_conn, exp_id=source_exp_1.exp_id) for i in range(5) ] source_datasets_2 = [ DataSet(conn=source_conn, exp_id=source_exp_2.exp_id) for i in range(5) ] source_datasets = source_datasets_1 + source_datasets_2 for ds in source_datasets: ds.set_interdependencies(some_interdeps[1]) ds.mark_started() ds.add_results([{name: 0.0 for name in some_interdeps[1].names}]) ds.mark_completed() # now let's insert only some of the datasets # and verify that the ids and counters are set correctly for ds in source_datasets[-3:]: extract_runs_into_db(ds.conn.path_to_dbfile, target_conn.path_to_dbfile, ds.run_id) loaded_datasets = [ load_by_run_spec(captured_run_id=i, conn=target_conn) for i in range(8, 11) ] expected_run_ids = [1, 2, 3] expected_captured_run_ids = [8, 9, 10] expected_counter = [1, 2, 3] expected_captured_counter = [3, 4, 5] for ds, eri, ecri, ec, ecc in zip(loaded_datasets, expected_run_ids, expected_captured_run_ids, expected_counter, expected_captured_counter): assert ds.run_id == eri assert ds.captured_run_id == ecri assert ds.counter == ec assert ds.captured_counter == ecc exp = load_experiment_by_name('exp2', conn=target_conn) # add additional runs and verify that the ids and counters increase as # expected new_datasets = [ DataSet(conn=target_conn, exp_id=exp.exp_id) for i in range(3) ] for ds in new_datasets: ds.set_interdependencies(some_interdeps[1]) ds.mark_started() ds.add_results([{name: 0.0 for name in some_interdeps[1].names}]) ds.mark_completed() expected_run_ids = [4, 5, 6] expected_captured_run_ids = [11, 12, 13] expected_counter = [4, 5, 6] expected_captured_counter = [6, 7, 8] for ds, eri, ecri, ec, ecc in zip(new_datasets, expected_run_ids, expected_captured_run_ids, expected_counter, expected_captured_counter): assert ds.run_id == eri assert ds.captured_run_id == ecri assert ds.counter == ec assert ds.captured_counter == ecc
# Module to use system1.yaml from qdev_wrappers.station_configurator import StationConfigurator # Close any instruments that may already be open instruments = list(qc.Instrument._all_instruments.keys()) for instrument in instruments: instr = qc.Instrument._all_instruments.pop(instrument) instr = instr() instr.close() # Set up experiment exp_name = 'qcodes_controls_mdac' sample_name = 'mdac' try: exp = load_experiment_by_name(exp_name, sample=sample_name) print('Experiment loaded. Last ID no:', exp.last_counter) except ValueError: exp = new_experiment(exp_name, sample_name) print('Started new experiment') scfg = StationConfigurator() mdac = scfg.load_instrument('mdac') #lockin = scfg.load_instrument('sr860') #ithaco = scfg.load_instrument('ithaco') multimeter = scfg.load_instrument('Keysight') dummy_time = DummyInstrument(name="dummy_time") time_zero = time.time()
def do_experiment(base_path, setup, sweep_object, cleanup, live_plot_axes=None, return_format=None): """ Perform a sweep experiment and put the result in a QCoDeS data set Args: base_path (str): Experiment database base path in the format <experiment_name>/<sample_name> The eventual path of the data set will be given by <experiment_name>/<sample_name>/<run number> Note: This is *not* a path on the file system. Use the "get_results_from_db_path" function to retrieve your data. setup (list): A list of tuples, e.g. [(function1, args1), (function2, args2), etc...] sweep_object: Defining the experiment cleanup (list): A list of tuples, e.g. [(function1, args1), (function2, args2), etc...] live_plot_axes (dict): The keys are the axis labels and the values are the columns to be plotted. No plots will be shown if None is given return_format (list): Defines in which way(s) we want to return the results of the experiment. Possible options are: data_set_path, dataid, dataset, experiment, measurement. Default value is "data_set_path". """ # By default we only return the data set path. if return_format is None: return_format = ["data_set_path"] name_parts = base_path.split("/") experiment_name = name_parts[0] if len(name_parts) == 1: sample_name = "None" else: sample_name = "/".join(name_parts[1:]) try: experiment = load_experiment_by_name(experiment_name, sample_name) experiment.id = experiment.exp_id # This is needed because of a bug # in the "load_experiment_by_name" method # A PR for a fix has been submitted (PR 997) except ValueError: # experiment does not exist yet db_location = qcodes.config["core"]["db_location"] DataSet(db_location) experiment = new_experiment(experiment_name, sample_name) counter = experiment.last_counter measurement = SweepMeasurement(exp=experiment) if live_plot_axes is not None: for live_plot_axis in live_plot_axes: measurement.add_subscriber(Plot1DSubscriber(live_plot_axis), {}) # init for func, args in setup: measurement.add_before_run(func, args) # meas measurement.register_sweep(sweep_object) measurement.write_period = 1.0 # end for func, args in cleanup: measurement.add_after_run(func, args) # perform exp with measurement.run() as datasaver: for data in sweep_object: datasaver.add_result(*data.items()) dataid = datasaver.run_id data_set_path = f"{base_path}/{counter}" dataset = datasaver.dataset print(f"Completed measurement. Database path: {data_set_path}") results = { "data_set_path": data_set_path, "dataid": dataid, "dataset": dataset, "experiment": experiment, "measurement": measurement } return [results[k] for k in return_format]