def do0d( *param_meas: ParamMeasT, write_period: Optional[float] = None, measurement_name: str = "", exp: Optional[Experiment] = None, do_plot: Optional[bool] = None, use_threads: Optional[bool] = None, ) -> AxesTupleListWithDataSet: """ Perform a measurement of a single parameter. This is probably most useful for an ArrayParameter that already returns an array of data points Args: *param_meas: Parameter(s) to measure at each step or functions that will be called at each step. The function should take no arguments. The parameters and functions are called in the order they are supplied. write_period: The time after which the data is actually written to the database. measurement_name: Name of the measurement. This will be passed down to the dataset produced by the measurement. If not given, a default value of 'results' is used for the dataset. exp: The experiment to use for this measurement. do_plot: should png and pdf versions of the images be saved after the run. If None the setting will be read from ``qcodesrc.json`` use_threads: If True measurements from each instrument will be done on separate threads. If you are measuring from several instruments this may give a significant speedup. Returns: The QCoDeS dataset. """ if do_plot is None: do_plot = config.dataset.dond_plot meas = Measurement(name=measurement_name, exp=exp) measured_parameters = tuple(param for param in param_meas if isinstance(param, _BaseParameter)) try: shapes: Shapes = detect_shape_of_measurement(measured_parameters, ) except TypeError: LOG.exception(f"Could not detect shape of {measured_parameters} " f"falling back to unknown shape.") shapes = None _register_parameters(meas, param_meas, shapes=shapes) _set_write_period(meas, write_period) with meas.run() as datasaver: datasaver.add_result( *process_params_meas(param_meas, use_threads=use_threads)) dataset = datasaver.dataset return _handle_plotting(dataset, do_plot)
def dond( *params: Union[AbstractSweep, ParamMeasT], write_period: Optional[float] = None, measurement_name: str = "", exp: Optional[Experiment] = None, enter_actions: ActionsT = (), exit_actions: ActionsT = (), do_plot: Optional[bool] = None, show_progress: Optional[bool] = None, use_threads: Optional[bool] = None, additional_setpoints: Sequence[ParamMeasT] = tuple(), ) -> AxesTupleListWithDataSet: """ Perform n-dimentional scan from slowest (first) to the fastest (last), to measure m measurement parameters. The dimensions should be specified as sweep objects, and after them the parameters to measure should be passed. Args: *params: Instances of n sweep classes and m measurement parameters, e.g. if linear sweep is considered: .. code-block:: LinSweep(param_set_1, start_1, stop_1, num_points_1, delay_1), ..., LinSweep(param_set_n, start_n, stop_n, num_points_n, delay_n), param_meas_1, param_meas_2, ..., param_meas_m write_period: The time after which the data is actually written to the database. measurement_name: Name of the measurement. This will be passed down to the dataset produced by the measurement. If not given, a default value of 'results' is used for the dataset. exp: The experiment to use for this measurement. enter_actions: A list of functions taking no arguments that will be called before the measurements start. exit_actions: A list of functions taking no arguments that will be called after the measurements ends. do_plot: should png and pdf versions of the images be saved and plots are shown after the run. If None the setting will be read from ``qcodesrc.json`` show_progress: should a progress bar be displayed during the measurement. If None the setting will be read from ``qcodesrc.json` use_threads: If True, measurements from each instrument will be done on separate threads. If you are measuring from several instruments this may give a significant speedup. additional_setpoints: A list of setpoint parameters to be registered in the measurement but not scanned/swept-over. """ if do_plot is None: do_plot = config.dataset.dond_plot if show_progress is None: show_progress = config.dataset.dond_show_progress meas = Measurement(name=measurement_name, exp=exp) def _parse_dond_arguments( *params: Union[AbstractSweep, ParamMeasT] ) -> Tuple[List[AbstractSweep], List[ParamMeasT]]: """ Parse supplied arguments into sweep objects and measurement parameters. """ sweep_instances: List[AbstractSweep] = [] params_meas: List[ParamMeasT] = [] for par in params: if isinstance(par, AbstractSweep): sweep_instances.append(par) else: params_meas.append(par) return sweep_instances, params_meas def _make_nested_setpoints(sweeps: List[AbstractSweep]) -> np.ndarray: """Create the cartesian product of all the setpoint values.""" if len(sweeps) == 0: return np.array([[]]) # 0d sweep (do0d) setpoint_values = [sweep.get_setpoints() for sweep in sweeps] setpoint_grids = np.meshgrid(*setpoint_values, indexing="ij") flat_setpoint_grids = [ np.ravel(grid, order="C") for grid in setpoint_grids ] return np.vstack(flat_setpoint_grids).T sweep_instances, params_meas = _parse_dond_arguments(*params) nested_setpoints = _make_nested_setpoints(sweep_instances) all_setpoint_params = tuple(sweep.param for sweep in sweep_instances) + tuple( s for s in additional_setpoints) measured_parameters = tuple(par for par in params_meas if isinstance(par, _BaseParameter)) try: loop_shape = tuple(1 for _ in additional_setpoints) + tuple( sweep.num_points for sweep in sweep_instances) shapes: Shapes = detect_shape_of_measurement(measured_parameters, loop_shape) except TypeError: LOG.exception(f"Could not detect shape of {measured_parameters} " f"falling back to unknown shape.") shapes = None _register_parameters(meas, all_setpoint_params) _register_parameters(meas, params_meas, setpoints=all_setpoint_params, shapes=shapes) _set_write_period(meas, write_period) _register_actions(meas, enter_actions, exit_actions) original_delays: Dict[_BaseParameter, float] = {} params_set: List[_BaseParameter] = [] for sweep in sweep_instances: original_delays[sweep.param] = sweep.param.post_delay sweep.param.post_delay = sweep.delay params_set.append(sweep.param) try: with _catch_keyboard_interrupts() as interrupted, meas.run( ) as datasaver: dataset = datasaver.dataset additional_setpoints_data = process_params_meas( additional_setpoints) for setpoints in tqdm(nested_setpoints, disable=not show_progress): param_set_list = [] param_value_pairs = zip(params_set[::-1], setpoints[::-1]) for setpoint_param, setpoint in param_value_pairs: setpoint_param(setpoint) param_set_list.append((setpoint_param, setpoint)) datasaver.add_result( *param_set_list, *process_params_meas(params_meas, use_threads=use_threads), *additional_setpoints_data, ) finally: for parameter, original_delay in original_delays.items(): parameter.post_delay = original_delay return _handle_plotting(dataset, do_plot, interrupted())
def do1d( param_set: _BaseParameter, start: float, stop: float, num_points: int, delay: float, *param_meas: ParamMeasT, enter_actions: ActionsT = (), exit_actions: ActionsT = (), write_period: Optional[float] = None, measurement_name: str = "", exp: Optional[Experiment] = None, do_plot: Optional[bool] = None, use_threads: Optional[bool] = None, additional_setpoints: Sequence[ParamMeasT] = tuple(), show_progress: Optional[None] = None, ) -> AxesTupleListWithDataSet: """ Perform a 1D scan of ``param_set`` from ``start`` to ``stop`` in ``num_points`` measuring param_meas at each step. In case param_meas is an ArrayParameter this is effectively a 2d scan. Args: param_set: The QCoDeS parameter to sweep over start: Starting point of sweep stop: End point of sweep num_points: Number of points in sweep delay: Delay after setting parameter before measurement is performed *param_meas: Parameter(s) to measure at each step or functions that will be called at each step. The function should take no arguments. The parameters and functions are called in the order they are supplied. enter_actions: A list of functions taking no arguments that will be called before the measurements start exit_actions: A list of functions taking no arguments that will be called after the measurements ends write_period: The time after which the data is actually written to the database. additional_setpoints: A list of setpoint parameters to be registered in the measurement but not scanned. measurement_name: Name of the measurement. This will be passed down to the dataset produced by the measurement. If not given, a default value of 'results' is used for the dataset. exp: The experiment to use for this measurement. do_plot: should png and pdf versions of the images be saved after the run. If None the setting will be read from ``qcodesrc.json` use_threads: If True measurements from each instrument will be done on separate threads. If you are measuring from several instruments this may give a significant speedup. show_progress: should a progress bar be displayed during the measurement. If None the setting will be read from ``qcodesrc.json` Returns: The QCoDeS dataset. """ if do_plot is None: do_plot = config.dataset.dond_plot if show_progress is None: show_progress = config.dataset.dond_show_progress meas = Measurement(name=measurement_name, exp=exp) all_setpoint_params = (param_set, ) + tuple(s for s in additional_setpoints) measured_parameters = tuple(param for param in param_meas if isinstance(param, _BaseParameter)) try: loop_shape = tuple(1 for _ in additional_setpoints) + (num_points, ) shapes: Shapes = detect_shape_of_measurement(measured_parameters, loop_shape) except TypeError: LOG.exception(f"Could not detect shape of {measured_parameters} " f"falling back to unknown shape.") shapes = None _register_parameters(meas, all_setpoint_params) _register_parameters(meas, param_meas, setpoints=all_setpoint_params, shapes=shapes) _set_write_period(meas, write_period) _register_actions(meas, enter_actions, exit_actions) original_delay = param_set.post_delay param_set.post_delay = delay # do1D enforces a simple relationship between measured parameters # and set parameters. For anything more complicated this should be # reimplemented from scratch with _catch_keyboard_interrupts() as interrupted, meas.run() as datasaver: dataset = datasaver.dataset additional_setpoints_data = process_params_meas(additional_setpoints) setpoints = np.linspace(start, stop, num_points) # flush to prevent unflushed print's to visually interrupt tqdm bar # updates sys.stdout.flush() sys.stderr.flush() for set_point in tqdm(setpoints, disable=not show_progress): param_set.set(set_point) datasaver.add_result((param_set, set_point), *process_params_meas(param_meas, use_threads=use_threads), *additional_setpoints_data) param_set.post_delay = original_delay return _handle_plotting(dataset, do_plot, interrupted())
def do2d( param_set1: _BaseParameter, start1: float, stop1: float, num_points1: int, delay1: float, param_set2: _BaseParameter, start2: float, stop2: float, num_points2: int, delay2: float, *param_meas: ParamMeasT, set_before_sweep: Optional[bool] = True, enter_actions: ActionsT = (), exit_actions: ActionsT = (), before_inner_actions: ActionsT = (), after_inner_actions: ActionsT = (), write_period: Optional[float] = None, measurement_name: str = "", exp: Optional[Experiment] = None, flush_columns: bool = False, do_plot: Optional[bool] = None, use_threads: Optional[bool] = None, additional_setpoints: Sequence[ParamMeasT] = tuple(), show_progress: Optional[None] = None, ) -> AxesTupleListWithDataSet: """ Perform a 1D scan of ``param_set1`` from ``start1`` to ``stop1`` in ``num_points1`` and ``param_set2`` from ``start2`` to ``stop2`` in ``num_points2`` measuring param_meas at each step. Args: param_set1: The QCoDeS parameter to sweep over in the outer loop start1: Starting point of sweep in outer loop stop1: End point of sweep in the outer loop num_points1: Number of points to measure in the outer loop delay1: Delay after setting parameter in the outer loop param_set2: The QCoDeS parameter to sweep over in the inner loop start2: Starting point of sweep in inner loop stop2: End point of sweep in the inner loop num_points2: Number of points to measure in the inner loop delay2: Delay after setting parameter before measurement is performed *param_meas: Parameter(s) to measure at each step or functions that will be called at each step. The function should take no arguments. The parameters and functions are called in the order they are supplied. set_before_sweep: if True the outer parameter is set to its first value before the inner parameter is swept to its next value. enter_actions: A list of functions taking no arguments that will be called before the measurements start exit_actions: A list of functions taking no arguments that will be called after the measurements ends before_inner_actions: Actions executed before each run of the inner loop after_inner_actions: Actions executed after each run of the inner loop write_period: The time after which the data is actually written to the database. measurement_name: Name of the measurement. This will be passed down to the dataset produced by the measurement. If not given, a default value of 'results' is used for the dataset. exp: The experiment to use for this measurement. flush_columns: The data is written after a column is finished independent of the passed time and write period. additional_setpoints: A list of setpoint parameters to be registered in the measurement but not scanned. do_plot: should png and pdf versions of the images be saved after the run. If None the setting will be read from ``qcodesrc.json`` use_threads: If True measurements from each instrument will be done on separate threads. If you are measuring from several instruments this may give a significant speedup. show_progress: should a progress bar be displayed during the measurement. If None the setting will be read from ``qcodesrc.json` Returns: The QCoDeS dataset. """ if do_plot is None: do_plot = config.dataset.dond_plot if show_progress is None: show_progress = config.dataset.dond_show_progress meas = Measurement(name=measurement_name, exp=exp) all_setpoint_params = ( param_set1, param_set2, ) + tuple(s for s in additional_setpoints) measured_parameters = tuple(param for param in param_meas if isinstance(param, _BaseParameter)) try: loop_shape = tuple( 1 for _ in additional_setpoints) + (num_points1, num_points2) shapes: Shapes = detect_shape_of_measurement(measured_parameters, loop_shape) except TypeError: LOG.exception(f"Could not detect shape of {measured_parameters} " f"falling back to unknown shape.") shapes = None _register_parameters(meas, all_setpoint_params) _register_parameters(meas, param_meas, setpoints=all_setpoint_params, shapes=shapes) _set_write_period(meas, write_period) _register_actions(meas, enter_actions, exit_actions) original_delay1 = param_set1.post_delay original_delay2 = param_set2.post_delay param_set1.post_delay = delay1 param_set2.post_delay = delay2 with _catch_keyboard_interrupts() as interrupted, meas.run() as datasaver: dataset = datasaver.dataset additional_setpoints_data = process_params_meas(additional_setpoints) setpoints1 = np.linspace(start1, stop1, num_points1) for set_point1 in tqdm(setpoints1, disable=not show_progress): if set_before_sweep: param_set2.set(start2) param_set1.set(set_point1) for action in before_inner_actions: action() setpoints2 = np.linspace(start2, stop2, num_points2) # flush to prevent unflushed print's to visually interrupt tqdm bar # updates sys.stdout.flush() sys.stderr.flush() for set_point2 in tqdm(setpoints2, disable=not show_progress, leave=False): # skip first inner set point if `set_before_sweep` if set_point2 == start2 and set_before_sweep: pass else: param_set2.set(set_point2) datasaver.add_result( (param_set1, set_point1), (param_set2, set_point2), *process_params_meas(param_meas, use_threads=use_threads), *additional_setpoints_data) for action in after_inner_actions: action() if flush_columns: datasaver.flush_data_to_database() param_set1.post_delay = original_delay1 param_set2.post_delay = original_delay2 return _handle_plotting(dataset, do_plot, interrupted())
def dond( *params: Union[AbstractSweep, Union[ParamMeasT, Sequence[ParamMeasT]]], write_period: Optional[float] = None, measurement_name: str = "", exp: Optional[Experiment] = None, enter_actions: ActionsT = (), exit_actions: ActionsT = (), do_plot: Optional[bool] = None, show_progress: Optional[bool] = None, use_threads: Optional[bool] = None, additional_setpoints: Sequence[ParamMeasT] = tuple(), log_info: Optional[str] = None, ) -> Union[AxesTupleListWithDataSet, MultiAxesTupleListWithDataSet]: """ Perform n-dimentional scan from slowest (first) to the fastest (last), to measure m measurement parameters. The dimensions should be specified as sweep objects, and after them the parameters to measure should be passed. Args: *params: Instances of n sweep classes and m measurement parameters, e.g. if linear sweep is considered: .. code-block:: LinSweep(param_set_1, start_1, stop_1, num_points_1, delay_1), ..., LinSweep(param_set_n, start_n, stop_n, num_points_n, delay_n), param_meas_1, param_meas_2, ..., param_meas_m If multiple DataSets creation is needed, measurement parameters should be grouped, so one dataset will be created for each group. e.g.: .. code-block:: LinSweep(param_set_1, start_1, stop_1, num_points_1, delay_1), ..., LinSweep(param_set_n, start_n, stop_n, num_points_n, delay_n), [param_meas_1, param_meas_2], ..., [param_meas_m] write_period: The time after which the data is actually written to the database. measurement_name: Name of the measurement. This will be passed down to the dataset produced by the measurement. If not given, a default value of 'results' is used for the dataset. exp: The experiment to use for this measurement. enter_actions: A list of functions taking no arguments that will be called before the measurements start. exit_actions: A list of functions taking no arguments that will be called after the measurements ends. do_plot: should png and pdf versions of the images be saved and plots are shown after the run. If None the setting will be read from ``qcodesrc.json`` show_progress: should a progress bar be displayed during the measurement. If None the setting will be read from ``qcodesrc.json` use_threads: If True, measurements from each instrument will be done on separate threads. If you are measuring from several instruments this may give a significant speedup. additional_setpoints: A list of setpoint parameters to be registered in the measurement but not scanned/swept-over. log_info: Message that is logged during the measurement. If None a default message is used. Returns: A tuple of QCoDeS DataSet, Matplotlib axis, Matplotlib colorbar. If more than one group of measurement parameters is supplied, the output will be a tuple of tuple(QCoDeS DataSet), tuple(Matplotlib axis), tuple(Matplotlib colorbar), in which each element of each sub-tuple belongs to one group, and the order of elements is the order of the supplied groups. """ if do_plot is None: do_plot = config.dataset.dond_plot if show_progress is None: show_progress = config.dataset.dond_show_progress sweep_instances, params_meas = _parse_dond_arguments(*params) nested_setpoints = _make_nested_setpoints(sweep_instances) all_setpoint_params = tuple(sweep.param for sweep in sweep_instances) + tuple( s for s in additional_setpoints ) ( all_meas_parameters, grouped_parameters, measured_parameters, ) = _extract_paramters_by_type_and_group(measurement_name, params_meas) try: loop_shape = tuple(sweep.num_points for sweep in sweep_instances) + tuple( 1 for _ in additional_setpoints ) shapes: Shapes = detect_shape_of_measurement(measured_parameters, loop_shape) except TypeError: LOG.exception( f"Could not detect shape of {measured_parameters} " f"falling back to unknown shape." ) shapes = None meas_list = _create_measurements( all_setpoint_params, enter_actions, exit_actions, exp, grouped_parameters, shapes, write_period, log_info, ) post_delays: List[float] = [] params_set: List[_BaseParameter] = [] post_actions: List[ActionsT] = [] for sweep in sweep_instances: post_delays.append(sweep.delay) params_set.append(sweep.param) post_actions.append(sweep.post_actions) datasets = [] plots_axes = [] plots_colorbar = [] if use_threads is None: use_threads = config.dataset.use_threads params_meas_caller = ( ThreadPoolParamsCaller(*all_meas_parameters) if use_threads else SequentialParamsCaller(*all_meas_parameters) ) try: with _catch_keyboard_interrupts() as interrupted, ExitStack() as stack, params_meas_caller as call_params_meas: datasavers = [stack.enter_context(measure.run()) for measure in meas_list] additional_setpoints_data = process_params_meas(additional_setpoints) previous_setpoints = np.empty(len(sweep_instances)) for setpoints in tqdm(nested_setpoints, disable=not show_progress): active_actions, delays = _select_active_actions_delays( post_actions, post_delays, setpoints, previous_setpoints, ) previous_setpoints = setpoints param_set_list = [] param_value_action_delay = zip( params_set, setpoints, active_actions, delays, ) for setpoint_param, setpoint, action, delay in param_value_action_delay: _conditional_parameter_set(setpoint_param, setpoint) param_set_list.append((setpoint_param, setpoint)) for act in action: act() time.sleep(delay) meas_value_pair = call_params_meas() for group in grouped_parameters.values(): group["measured_params"] = [] for measured in meas_value_pair: if measured[0] in group["params"]: group["measured_params"].append(measured) for ind, datasaver in enumerate(datasavers): datasaver.add_result( *param_set_list, *grouped_parameters[f"group_{ind}"]["measured_params"], *additional_setpoints_data, ) finally: for datasaver in datasavers: ds, plot_axis, plot_color = _handle_plotting( datasaver.dataset, do_plot, interrupted() ) datasets.append(ds) plots_axes.append(plot_axis) plots_colorbar.append(plot_color) if len(grouped_parameters) == 1: return datasets[0], plots_axes[0], plots_colorbar[0] else: return tuple(datasets), tuple(plots_axes), tuple(plots_colorbar)