diff --git a/qcodes/__init__.py b/qcodes/__init__.py index 859bcaf45dd3..307d1ac7b1de 100644 --- a/qcodes/__init__.py +++ b/qcodes/__init__.py @@ -34,6 +34,7 @@ 'try "from qcodes.plots.pyqtgraph import QtPlot" ' 'to see the full error') +from qcodes.utils.wrappers import do1d, do2d, do1dDiagonal, show_num, init # only import in name space if the gui is set to noebook # and there is multiprocessing if config['gui']['notebook'] and config['core']['legacy_mp']: diff --git a/qcodes/data/io.py b/qcodes/data/io.py index 4b7a82c8588b..4b2fd45381c3 100644 --- a/qcodes/data/io.py +++ b/qcodes/data/io.py @@ -91,7 +91,6 @@ def open(self, filename, mode, encoding=None): raise ValueError('mode {} not allowed in IO managers'.format(mode)) filepath = self.to_path(filename) - # make directories if needed dirpath = os.path.dirname(filepath) if not os.path.exists(dirpath): diff --git a/qcodes/data/location.py b/qcodes/data/location.py index 91af8594cf1d..b342b0bfbf0b 100644 --- a/qcodes/data/location.py +++ b/qcodes/data/location.py @@ -85,6 +85,7 @@ class FormatLocation: default_fmt = config['core']['default_fmt'] + def __init__(self, fmt=None, fmt_date=None, fmt_time=None, fmt_counter=None, record=None): #TODO(giulioungaretti) this should be @@ -95,7 +96,7 @@ def __init__(self, fmt=None, fmt_date=None, fmt_time=None, self.fmt_counter = fmt_counter or '{:03}' self.base_record = record self.formatter = SafeFormatter() - + self.counter = 0 for testval in (1, 23, 456, 7890): if self._findint(self.fmt_counter.format(testval)) != testval: raise ValueError('fmt_counter must produce a correct integer ' @@ -163,7 +164,8 @@ def __call__(self, io, record=None): cnt = self._findint(f[len(head):]) existing_count = max(existing_count, cnt) - format_record['counter'] = self.fmt_counter.format(existing_count + 1) + self.counter = existing_count +1 + format_record['counter'] = self.fmt_counter.format(self.counter) location = self.formatter.format(loc_fmt, **format_record) return location diff --git a/qcodes/utils/wrappers.py b/qcodes/utils/wrappers.py new file mode 100644 index 000000000000..80d01b73f685 --- /dev/null +++ b/qcodes/utils/wrappers.py @@ -0,0 +1,244 @@ +import qcodes as qc +from os.path import abspath +from os.path import sep +import logging +from qcodes.plots.pyqtgraph import QtPlot +from IPython import get_ipython +CURRENT_EXPERIMENT = {} + +def init(mainfolder:str, sample_name: str): + """ + + Args: + mainfolder: base loacation for the data + sample_name: name of the sample + + """ + if sep in sample_name: + raise TypeError("Use Relative names. That is wihtout {}".format(sep)) + if mainfolder[-1] == sep: + mainfolder = mainfolder[:-1] + + mainfolder = abspath(mainfolder) + CURRENT_EXPERIMENT["mainfolder"] = mainfolder + CURRENT_EXPERIMENT["subfolder"] = sample_name + CURRENT_EXPERIMENT['init'] = True + path_to_experiment_folder = sep.join([mainfolder, sample_name]) + CURRENT_EXPERIMENT["exp_folder"] = path_to_experiment_folder + logging.info("experiment started at {}".format(path_to_experiment_folder)) + loc_provider = qc.FormatLocation( + fmt= path_to_experiment_folder + '{counter}_{name}') + qc.data.data_set.DataSet.location_provider = loc_provider + CURRENT_EXPERIMENT["provider"] = loc_provider + + ipython = get_ipython() + # turn on logging only if in ipython + # else crash and burn + # dirty hack to capture warning from IPYTHON + logging.captureWarnings(True) + log = logging.getLogger("py.warnings") + log.setLevel(level="ERROR") + if ipython is None: + raise RuntimeWarning("History can't be saved refusing to proceed (use IPython/jupyter)") + else: + try: + ipython.magic("%logstart -t {} {}".format(path_to_experiment_folder+"commands.log", "append")) + except UserWarning: + logging.debug("logging already started in current session and experiment") + logging.captureWarnings(False) + +def do1d(inst_set, start, stop, division, delay, *inst_meas): + """ + + Args: + inst_set: Instrument to sweep over + start: Start of sweep + stop: End of sweep + division: Spacing between values + delay: Delay at every step + *inst_meas: any number of instrument to measure + + Returns: + plot, data : returns the plot and the dataset + + """ + if not "{name}" in qc.data.data_set.DataSet.location_provider.fmt: + raise ValueError("missing name in {}".format(qc.data.data_set.DataSet.location_provider.fmt)) + + name = inst_set.label + name = name + "".join([i.label for i in inst_meas]) + name = name.replace(" ", "") + loop = qc.Loop(inst_set.sweep(start, stop, division), delay).each(*inst_meas) + data = loop.get_data_set(name=name) + title = "#{}_{}".format(data.location_provider.counter, inst_set._instrument.name + inst_set.name) + plot = QtPlot() + for j, i in enumerate(inst_meas): + # concat the names of all the "arrays" + if getattr(i, "names", False): + name = "_".join(i.names) + else: + name = i.name + title = title + "{}_{}".format(i._instrument.name, name) + for j, i in enumerate(inst_meas): + if getattr(i, "names", False): + for k, name in enumerate(i.names): + inst_meas_name = "{}_{}".format(i._instrument.name, name) + plot.add(getattr(data, inst_meas_name), subplot=j + k + 1, name=name) + plot.subplots[j].showGrid(True, True) + if j == 0: + plot.subplots[0].setTitle(title) + else: + plot.subplots[j].setTitle("") + else: + inst_meas_name = "{}_{}".format(i._instrument.name, i.name) + plot.add(getattr(data, inst_meas_name), subplot=j + 1, name=name) + plot.subplots[j].showGrid(True, True) + if j == 0: + plot.subplots[0].setTitle(title) + else: + plot.subplots[j].setTitle("") + try: + _ = loop.with_bg_task(plot.update, plot.save).run() + except KeyboardInterrupt: + print("Measurement Interrupted") + return plot, data + + +def do1dDiagonal(inst_set, inst2_set, start, stop, division, delay, start2, slope, *inst_meas): + """ + Perform diagonal sweep in 1 dimension, given two insturments + + Args: + inst_set: Instrument to sweep over + inst2_set: Second instrument to sweep over + start: Start of sweep + stop: End of sweep + division: Spacing between values + delay: Delay at every step + start2: Second start point + slope: slope of the diagonal cut + *inst_meas: any number of instrument to measure + + Returns: + plot, data : returns the plot and the dataset + + """ + if not "{name}" in qc.data.data_set.DataSet.location_provider.fmt: + raise ValueError("missing in {}".format(qc.data.data_set.DataSet.location_provider.fmt)) + + name = inst_set.label + inst2_set.label + name = name + "".join([i.label for i in inst_meas]) + name = name.replace(" ", "") + loop = qc.Loop(inst_set.sweep(start, stop, division), delay).each( + qc.Task(inst2_set, (inst_set) * slope + (slope * start - start2)), *inst_meas, inst2_set) + data = loop.get_data_set(name=name) + title = "#{}_{}".format(data.location_provider.counter, inst_set._instrument.name + inst_set.name) + plot = QtPlot() + for j, i in enumerate(inst_meas): + title = title + "{}_{}".format(i._instrument.name, i.name) + for j, i in enumerate(inst_meas): + inst_meas_name = "{}_{}".format(i._instrument.name, i.name) + plot.add(getattr(data, inst_meas_name), subplot=j + 1, name=name) + plot.subplots[j].showGrid(True, True) + if j == 0: + plot.subplots[0].setTitle(title) + else: + plot.subplots[j].setTitle("") + try: + _ = loop.with_bg_task(plot.update, plot.save).run() + except KeyboardInterrupt: + print("Measurement Interrupted") + return data + + +def do2d(inst_set, start, stop, division, delay, inst_set2, start2, stop2, division2, delay2, *inst_meas): + """ + + Args: + inst_set: Instrument to sweep over + start: Start of sweep + stop: End of sweep + division: Spacing between values + delay: Delay at every step + inst_set_2: Second instrument to sweep over + start_2: Start of sweep for second intrument + stop_2: End of sweep for second intrument + division_2: Spacing between values for second intrument + delay_2: Delay at every step for second intrument + *inst_meas: + + Returns: + plot, data : returns the plot and the dataset + + """ + if not "{name}" in qc.data.data_set.DataSet.location_provider.fmt: + raise ValueError("missing name in {}".format(qc.data.data_set.DataSet.location_provider.fmt)) + for inst in inst_meas: + if getattr(inst, "names", False): + raise ValueError("3d plotting is not supported") + + name = inst_set.label + inst_set2.label + name = name + "".join([i.label for i in inst_meas]) + name = name.replace(" ", "") + + loop = qc.Loop(inst_set.sweep(start, stop, division), delay).loop(inst_set2.sweep(start2,stop2,division2), delay2).each( + *inst_meas) + data = loop.get_data_set(name=name) + title = "#{}_{}_{}".format(data.location_provider.counter, + inst_set._instrument.name + inst_set.name, + inst_set2._instrument.name + inst_set2.name) + plot = QtPlot() + name = "{}{}".format(data.location_provider.counter, name) + for j, i in enumerate(inst_meas): + title = title + "{}_{}".format(i._instrument.name, i.name) + for j, i in enumerate(inst_meas): + inst_meas_name = "{}_{}".format(i._instrument.name, i.name) + plot.add(getattr(data, inst_meas_name), subplot=j + 1, name=name) + plot.subplots[j].showGrid(True, True) + if j == 0: + plot.subplots[0].setTitle(title) + else: + plot.subplots[j].setTitle("") + try: + _ = loop.with_bg_task(plot.update, plot.save).run() + except KeyboardInterrupt: + print("Measurement Interrupted") + return plot, data + + +def show_num(id): + """ + Show and return plot and data for id in current instrument. + Args: + id(number): id of intrumetn + + Returns: + plot, data : returns the plot and the dataset + + """ + if not getattr(CURRENT_EXPERIMENT, "init", True): + raise RuntimeError("Experiment not initalized. use qc.Init(mainfolder, samplename)") + + str_id = '{0:03d}'.format(id) + + t = qc.DataSet.location_provider.fmt.format(counter=str_id, name="*") + try: + file = [i for i in qc.DiskIO(CURRENT_EXPERIMENT["mainfolder"]).list(t) if ".dat" in i][0] + except IndexError: + logging.error("Not able to find the id in experiment {}".format(CURRENT_EXPERIMENT["exp_folder"])) + return None, None + + try: + data = qc.load_data(file) + except Exception as e: + print(e) + + plots = [] + for value in data.arrays.keys(): + if "set" not in value: + plot = QtPlot(getattr(data, value)) + title = "#{}".format(str_id) + plot.subplots[0].setTitle(title) + plot.subplots[0].showGrid(True, True) + plots.append(plot) + return data, plots