Exemplo n.º 1
0
def test_get_shape_for_multiparam_from_len(loop_shape, multiparamtype):
    param = multiparamtype(name='meas_param')
    shapes = detect_shape_of_measurement((param, ), loop_shape)
    expected_shapes = {}
    for i, name in enumerate(param.full_names):
        expected_shapes[name] = tuple(loop_shape) + tuple(param.shapes[i])
    assert shapes == expected_shapes
Exemplo n.º 2
0
def do1d(
        param_set: _BaseParameter,
        xarray,
        delay: float,
        *param_meas: qcnd.ParamMeasT,
        exp: Optional[Experiment] = None,
        use_threads: Optional[bool] = None,
        enter_actions: qcnd.ActionsT = (),
        exit_actions: qcnd.ActionsT = (),
        additional_setpoints: Sequence[qcnd.ParamMeasT] = tuple(),
):

    if not _is_monotonic(xarray):
        warn('Sweep array is not monotonic. This is pretty weird. Reconsider.')

    meas = Measurement(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))

    if (len(measured_parameters) > 2) or (use_threads == True):
        use_threads = True
    else:
        use_threads = False

    try:
        loop_shape = tuple(1 for _ in additional_setpoints) + (len(xarray), )
        shapes: Shapes = detect_shape_of_measurement(measured_parameters,
                                                     loop_shape)
    except TypeError:
        warn(f"Could not detect shape of {measured_parameters} "
             f"falling back to unknown shape.")
        shapes = None

    qcnd._register_parameters(meas, all_setpoint_params)
    qcnd._register_parameters(meas,
                              param_meas,
                              setpoints=all_setpoint_params,
                              shapes=shapes)
    qcnd._register_actions(meas, enter_actions, exit_actions)

    with qcnd._catch_keyboard_interrupts() as interrupted, \
        meas.run(write_in_background=True) as datasaver:

        additional_setpoints_data = qcnd._process_params_meas(
            additional_setpoints)
        for set_point in xarray:
            param_set.set(set_point)
            time.sleep(delay)
            datasaver.add_result(
                (param_set, set_point),
                *qcnd._process_params_meas(param_meas,
                                           use_threads=use_threads),
                *additional_setpoints_data)
        dataset = datasaver.dataset

    return dataset
Exemplo n.º 3
0
def test_get_shape_for_param_with_array_validator_from_shape(loop_shape):
    param = ArrayshapedParam(name='paramwitharrayval',
                             vals=Arrays(shape=(10, )))

    shapes = detect_shape_of_measurement((param, ), loop_shape)
    assert shapes == {
        "paramwitharrayval": tuple(loop_shape) + param.vals.shape
    }
Exemplo n.º 4
0
def test_get_shape_for_multiparam_from_shape(loop_shape, multiparamtype,
                                             range_func):
    param = multiparamtype(name='meas_param')
    loop_sequence = tuple(range_func(x) for x in loop_shape)
    shapes = detect_shape_of_measurement((param, ), loop_sequence)
    expected_shapes = {}
    for i, name in enumerate(param.full_names):
        expected_shapes[name] = tuple(loop_shape) + tuple(param.shapes[i])
    assert shapes == expected_shapes
Exemplo n.º 5
0
def test_get_shape_for_pws_from_len(dummyinstrument, loop_shape, n_points):
    param = dummyinstrument.A.dummy_parameter_with_setpoints
    dummyinstrument.A.dummy_n_points(n_points)
    shapes = detect_shape_of_measurement((param, ), loop_shape)

    expected_shapes = {}
    expected_shapes[param.full_name] = (tuple(loop_shape) +
                                        tuple(param.vals.shape))
    assert shapes == expected_shapes
    assert (dummyinstrument.A.dummy_n_points(), ) == param.vals.shape
Exemplo n.º 6
0
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)
Exemplo n.º 7
0
def test_get_shape_for_multiple_parameters(dummyinstrument, loop_shape,
                                           n_points_1, n_points_2):
    param1 = dummyinstrument.A.dummy_parameter_with_setpoints
    dummyinstrument.A.dummy_n_points(n_points_1)
    param2 = dummyinstrument.B.dummy_parameter_with_setpoints
    dummyinstrument.B.dummy_n_points(n_points_2)
    shapes = detect_shape_of_measurement((param1, param2), loop_shape)

    expected_shapes = {}
    expected_shapes[param1.full_name] = (tuple(loop_shape) +
                                         tuple(param1.vals.shape))
    expected_shapes[param2.full_name] = (tuple(loop_shape) +
                                         tuple(param2.vals.shape))
    assert shapes == expected_shapes
    assert (dummyinstrument.A.dummy_n_points(), ) == param1.vals.shape
    assert (dummyinstrument.B.dummy_n_points(), ) == param2.vals.shape
Exemplo n.º 8
0
def do0d(
        *param_meas: ParamMeasT,
        write_period: Optional[float] = None,
        do_plot: bool = True
        ) -> 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.
        do_plot: should png and pdf versions of the images be saved after the
            run.

    Returns:
        The QCoDeS dataset.
    """
    meas = Measurement()

    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))
        dataset = datasaver.dataset

    return _handle_plotting(dataset, do_plot)
Exemplo n.º 9
0
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())
Exemplo n.º 10
0
def do2d(
        param_setx,
        xarray,
        delayx,
        param_sety,
        yarray,
        delayy,
        *param_meas: qcnd.ParamMeasT,
        enter_actions: qcnd.ActionsT = (),
        exit_actions: qcnd.ActionsT = (),
        before_inner_actions: qcnd.ActionsT = (),
        after_inner_actions: qcnd.ActionsT = (),
        exp: Optional[Experiment] = None,
        use_threads: Optional[bool] = None,
        additional_setpoints: Sequence[qcnd.ParamMeasT] = tuple(),
):

    meas = Measurement(exp=exp)
    all_setpoint_params = (
        param_sety,
        param_setx,
    ) + tuple(s for s in additional_setpoints)

    measured_parameters = tuple(param for param in param_meas
                                if isinstance(param, _BaseParameter))

    if (len(measured_parameters) > 2) or (use_threads == True):
        use_threads = True
    elif (use_threads == False):
        use_threads = False
    else:
        use_threads = False

    try:
        loop_shape = tuple(
            1 for _ in additional_setpoints) + (len(yarray), len(xarray))
        shapes: Shapes = detect_shape_of_measurement(measured_parameters,
                                                     loop_shape)
    except TypeError:
        warn(f"Could not detect shape of {measured_parameters} "
             f"falling back to unknown shape.")
        shapes = None

    qcnd._register_parameters(meas, all_setpoint_params)
    qcnd._register_parameters(meas,
                              param_meas,
                              setpoints=all_setpoint_params,
                              shapes=shapes)
    qcnd._register_actions(meas, enter_actions, exit_actions)

    param_setx.post_delay = 0.0
    param_sety.post_delay = 0.0

    with qcnd._catch_keyboard_interrupts() as interrupted, \
        meas.run(write_in_background=True) as datasaver:

        additional_setpoints_data = qcnd._process_params_meas(
            additional_setpoints)
        for set_pointy in yarray:
            param_setx.set(xarray[0])
            param_sety.set(set_pointy)
            time.sleep(delayy)
            for action in before_inner_actions:
                action()
            for set_pointx in xarray:
                param_setx.set(set_pointx)
                time.sleep(delayx)

                datasaver.add_result(
                    (param_sety, set_pointy), (param_setx, set_pointx),
                    *qcnd._process_params_meas(param_meas,
                                               use_threads=use_threads),
                    *additional_setpoints_data)

            for action in after_inner_actions:
                action()

        dataset = datasaver.dataset
    return dataset
Exemplo n.º 11
0
def field_sweep_ami_2d(
        field_param,
        xarray,
        delayx,
        param_sety,
        yarray,
        delayy,
        *param_meas: qcnd.ParamMeasT,
        exp: Experiment = None,
        use_threads=False,
        enter_actions: qcnd.ActionsT = (),
        exit_actions: qcnd.ActionsT = (),
        additional_setpoints=tuple(),
):

    # get instrument for field param
    magnet = field_param.instrument

    # add field to measured params
    all_setpoint_params = (
        param_sety,
        field_param,
    ) + tuple(s for s in additional_setpoints)

    measured_parameters = tuple(param for param in param_meas
                                if isinstance(param, _BaseParameter))

    if (len(measured_parameters) > 2) or (use_threads == True):
        use_threads = True
    elif (use_threads == False):
        use_threads = False
    else:
        use_threads = False

    try:
        loop_shape = tuple(
            1 for _ in additional_setpoints) + (len(yarray), len(xarray))
        shapes: Shapes = detect_shape_of_measurement(measured_parameters,
                                                     loop_shape)
    except TypeError:
        warn(f"Could not detect shape of {measured_parameters} "
             f"falling back to unknown shape.")
        shapes = None

    meas = Measurement(exp=exp)
    qcnd._register_parameters(meas, all_setpoint_params)
    qcnd._register_parameters(meas,
                              param_meas,
                              setpoints=all_setpoint_params,
                              shapes=None)
    qcnd._register_actions(meas, enter_actions, exit_actions)

    inner_loop_params = (field_param, ) + param_meas
    inner_loop_dict = {k.name: [] for k in inner_loop_params}

    with qcnd._catch_keyboard_interrupts() as interrupted, \
        meas.run(write_in_background=True) as datasaver:

        additional_setpoints_data = qcnd._process_params_meas(
            additional_setpoints)

        for set_pointy in yarray:
            param_sety.set(set_pointy)
            time.sleep(delayy)

            magnet.set_field(xarray[0], block=True)
            magnet.set_field(xarray[-1], block=False)

            while magnet.ramping_state() == 'ramping':
                time.sleep(delayx)

                for param, val in qcnd._process_params_meas(
                        inner_loop_params, use_threads=use_threads):
                    inner_loop_dict[param.name].append(val)

            datasaver.add_result(
                (param_sety, [set_pointy] * len(xarray)),
                *_bin_results_to_fit_shape(field_param, xarray,
                                           inner_loop_params, inner_loop_dict),
                *additional_setpoints_data,
            )

        dataset = datasaver.dataset

    return dataset
Exemplo n.º 12
0
def test_get_shape_for_array_parameter_from_shape(loop_shape, range_func):
    a = ArraySetPointParam(name='a')
    loop_sequence = tuple(range_func(x) for x in loop_shape)
    shape = detect_shape_of_measurement((a, ), loop_sequence)
    expected_shape = tuple(loop_shape) + tuple(a.shape)
    assert shape == {'a': expected_shape}
Exemplo n.º 13
0
def test_plot_dataset_2d_shaped(experiment, request, nan_setpoints, shifted):
    """
    Test plotting of preshaped data on a grid that may or may not be shifted
    with and without nans in the set points.
    """
    inst = DummyInstrument("dummy", gates=["s1", "m1", "s2"])
    request.addfinalizer(inst.close)

    inst.m1.get = np.random.randn

    meas = Measurement()
    meas.register_parameter(inst.s1)
    meas.register_parameter(inst.s2)
    meas.register_parameter(inst.m1, setpoints=(inst.s1, inst.s2))

    outer_shape = 10
    inner_shape = 20

    meas.set_shapes(
        detect_shape_of_measurement((inst.m1, ), (outer_shape, inner_shape)))

    shift = 0

    with meas.run() as datasaver:
        try:
            for outer in np.linspace(0, 9, outer_shape):
                for inner in np.linspace(0 + shift, 10 + shift, inner_shape):
                    datasaver.add_result((inst.s1, outer), (inst.s2, inner),
                                         (inst.m1, inst.m1()))
                    if inner > 7 and outer > 6 and nan_setpoints:
                        raise TerminateLoopException
                if shifted:
                    shift += 1
        except TerminateLoopException:
            pass

    axes, cbs = plot_dataset(datasaver.dataset)
    xlims = axes[0].get_xlim()
    ylims = axes[0].get_ylim()

    # check that this generates a QuadMesh which is the expected output of pcolormesh
    assert any(
        isinstance(mplobj, QuadMesh) for mplobj in axes[0].get_children())

    if nan_setpoints and shifted:
        assert xlims[0] == -0.5
        assert xlims[1] == 7.5
        assert ylims[0] < 0
        assert ylims[0] > -1.0
        assert ylims[1] > 16
        assert ylims[1] < 17
    elif not nan_setpoints and shifted:
        assert xlims[0] == -0.5
        assert xlims[1] == 9.5
        assert ylims[0] < 0
        assert ylims[0] > -1.0
        assert ylims[1] > 19
        assert ylims[1] < 20
    elif nan_setpoints and not shifted:
        assert xlims[0] == -0.5
        assert xlims[1] == 7.5
        assert ylims[0] < 0
        assert ylims[0] > -1.0
        assert ylims[1] > 10
        assert ylims[1] < 11
    else:
        assert xlims[0] == -0.5
        assert xlims[1] == 9.5
        assert ylims[0] < 0
        assert ylims[0] > -1.0
        assert ylims[1] > 10
        assert ylims[1] < 11
Exemplo n.º 14
0
def test_get_shape_for_parameter_from_sequence(loop_shape, range_func):
    a = Parameter(name='a', initial_cache_value=10)
    loop_sequence = tuple(range_func(x) for x in loop_shape)
    shape = detect_shape_of_measurement((a, ), loop_sequence)
    assert shape == {'a': tuple(loop_shape)}
Exemplo n.º 15
0
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,
    flush_columns: bool = False,
    do_plot: bool = True,
    additional_setpoints: Sequence[ParamMeasT] = tuple(),
) -> 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.
        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.

    Returns:
        The QCoDeS dataset.
    """

    meas = Measurement()
    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)

    param_set1.post_delay = delay1
    param_set2.post_delay = delay2

    with _catch_keyboard_interrupts() as interrupted, meas.run() as datasaver:
        additional_setpoints_data = _process_params_meas(additional_setpoints)
        for set_point1 in np.linspace(start1, stop1, num_points1):
            if set_before_sweep:
                param_set2.set(start2)

            param_set1.set(set_point1)
            for action in before_inner_actions:
                action()
            for set_point2 in np.linspace(start2, stop2, num_points2):
                # 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),
                                     *additional_setpoints_data)
            for action in after_inner_actions:
                action()
            if flush_columns:
                datasaver.flush_data_to_database()
        dataset = datasaver.dataset
    return _handle_plotting(dataset, do_plot, interrupted())
Exemplo n.º 16
0
def do1d_repeat_twoway(
        param_setx,
        xarray,
        delayx,
        num_repeats,
        delayy,
        *param_meas: qcnd.ParamMeasT,
        enter_actions: qcnd.ActionsT = (),
        exit_actions: qcnd.ActionsT = (),
        before_inner_actions: qcnd.ActionsT = (),
        after_inner_actions: qcnd.ActionsT = (),
        exp: Optional[Experiment] = None,
        use_threads: Optional[bool] = None,
        additional_setpoints: Sequence[qcnd.ParamMeasT] = tuple(),
):
    if (not _is_monotonic(xarray)) or (not _is_monotonic(yarray)):
        warn('Sweep array is not monotonic. This is pretty weird. Reconsider.')

    meas = Measurement(exp=exp)

    param_county = CountParameter("repeat")
    all_setpoint_params = (
        param_county,
        param_setx,
    ) + tuple(s for s in additional_setpoints)

    measured_parameters = tuple(param for param in param_meas
                                if isinstance(param, _BaseParameter))

    if (len(measured_parameters) > 2) or (use_threads == True):
        use_threads = True
    else:
        use_threads = False

    try:
        loop_shape = tuple(
            1 for _ in additional_setpoints) + (num_repeats, len(xarray))
        shapes: Shapes = detect_shape_of_measurement(measured_parameters,
                                                     loop_shape)
    except TypeError:
        warn(f"Could not detect shape of {measured_parameters} "
             f"falling back to unknown shape.")
        shapes = None

    qcnd._register_parameters(meas, all_setpoint_params)
    qcnd._register_parameters(meas,
                              param_meas,
                              setpoints=all_setpoint_params,
                              shapes=shapes)
    qcnd._register_actions(meas, enter_actions, exit_actions)

    param_setx.post_delay = 0.0

    with qcnd._catch_keyboard_interrupts() as interrupted, \
        meas.run(write_in_background=True) as datasaver:

        additional_setpoints_data = qcnd._process_params_meas(
            additional_setpoints)
        for i in range(num_repeats):
            y = param_county.get()
            if y % 2 == 0:
                xsetpoints = xarray
            else:
                xsetpoints = xarray[::-1]
            param_setx.set(xsetpoints[0])
            time.sleep(delayy)

            for action in before_inner_actions:
                action()

            for set_pointx in xsetpoints:
                param_setx.set(set_pointx)
                time.sleep(delayx)

                datasaver.add_result(
                    (param_county, y), (param_setx, set_pointx),
                    *qcnd._process_params_meas(param_meas,
                                               use_threads=use_threads),
                    *additional_setpoints_data)
            for action in after_inner_actions:
                action()

        dataset = datasaver.dataset
    return dataset
Exemplo n.º 17
0
def test_get_shape_for_parameter_from_len(loop_shape):
    a = Parameter(name='a', initial_cache_value=10)
    shape = detect_shape_of_measurement((a, ), loop_shape)
    assert shape == {'a': tuple(loop_shape)}
Exemplo n.º 18
0
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)
Exemplo n.º 19
0
def test_cache_2d_shape(experiment,
                        DAC,
                        DMM,
                        n_points_outer,
                        n_points_inner,
                        pws_n_points,
                        bg_writing,
                        channel_array_instrument,
                        cache_size):
    meas = Measurement()

    meas.register_parameter(DAC.ch1)
    meas.register_parameter(DAC.ch2)

    meas_parameters = (DMM.v1,
                       channel_array_instrument.A.dummy_multi_parameter,
                       channel_array_instrument.A.dummy_scalar_multi_parameter,
                       channel_array_instrument.A.dummy_2d_multi_parameter,
                       channel_array_instrument.A.dummy_2d_multi_parameter_2,
                       channel_array_instrument.A.dummy_array_parameter,
                       channel_array_instrument.A.dummy_complex_array_parameter,
                       channel_array_instrument.A.dummy_complex,
                       channel_array_instrument.A.dummy_parameter_with_setpoints,
                       channel_array_instrument.A.dummy_parameter_with_setpoints_complex,
                       )

    channel_array_instrument.A.dummy_start(0)
    channel_array_instrument.A.dummy_stop(10)
    channel_array_instrument.A.dummy_n_points(pws_n_points)
    for param in meas_parameters:
        meas.register_parameter(param, setpoints=(DAC.ch1, DAC.ch2))

    if cache_size == "too_small":
        meas.set_shapes(detect_shape_of_measurement(
            meas_parameters,
            (int(ceil(n_points_outer/2)), n_points_inner))
        )
    elif cache_size == "too_large":
        meas.set_shapes(detect_shape_of_measurement(
            meas_parameters,
            (n_points_outer*2, n_points_inner))
        )
    else:
        meas.set_shapes(detect_shape_of_measurement(
            meas_parameters,
            (n_points_outer, n_points_inner))
        )

    expected_shapes = {
        'dummy_dmm_v1': (n_points_outer, n_points_inner),
        'dummy_channel_inst_ChanA_multi_setpoint_param_this': (n_points_outer, n_points_inner, 5),
        'dummy_channel_inst_ChanA_multi_setpoint_param_that': (n_points_outer, n_points_inner, 5),
        'dummy_channel_inst_ChanA_thisparam': (n_points_outer, n_points_inner),
        'dummy_channel_inst_ChanA_thatparam': (n_points_outer, n_points_inner),
        'dummy_channel_inst_ChanA_this': (n_points_outer, n_points_inner, 5, 3),
        'dummy_channel_inst_ChanA_that': (n_points_outer, n_points_inner, 5, 3),
        'dummy_channel_inst_ChanA_this_5_3': (n_points_outer, n_points_inner, 5, 3),
        'dummy_channel_inst_ChanA_this_2_7': (n_points_outer, n_points_inner, 2, 7),
        'dummy_channel_inst_ChanA_dummy_array_parameter': (n_points_outer, n_points_inner, 5),
        'dummy_channel_inst_ChanA_dummy_complex_array_parameter': (n_points_outer, n_points_inner, 5),
        'dummy_channel_inst_ChanA_dummy_complex': (n_points_outer, n_points_inner),
        'dummy_channel_inst_ChanA_dummy_parameter_with_setpoints': (n_points_outer, n_points_inner, pws_n_points),
        'dummy_channel_inst_ChanA_dummy_parameter_with_setpoints_complex': (n_points_outer, n_points_inner, pws_n_points)
    }

    if cache_size == "correct":
        assert meas._shapes == expected_shapes

    with meas.run(write_in_background=bg_writing) as datasaver:
        dataset = datasaver.dataset
        # Check that parameter data and cache data are indential for empty datasets
        _assert_parameter_data_is_identical(dataset.get_parameter_data(), dataset.cache.data())
        n_points_measured = 0
        for v1 in np.linspace(-1, 1, n_points_outer):
            for v2 in np.linspace(-1, 1, n_points_inner):
                n_points_measured += 1
                DAC.ch1.set(v1)
                DAC.ch2.set(v2)
                meas_vals = [(param, param.get()) for param in meas_parameters]

                datasaver.add_result((DAC.ch1, v1),
                                     (DAC.ch2, v2),
                                     *meas_vals)
                datasaver.flush_data_to_database(block=True)
                param_data_trees = dataset.get_parameter_data()
                cache_data_trees = dataset.cache.data()

                _assert_partial_cache_is_as_expected(
                    cache_data_trees,
                    expected_shapes,
                    n_points_measured,
                    param_data_trees,
                    cache_size == "correct"
                )
    cache_data_trees = dataset.cache.data()
    param_data_trees = dataset.get_parameter_data()
    _assert_completed_cache_is_as_expected(cache_data_trees,
                                           param_data_trees,
                                           flatten=cache_size == "too_small",
                                           clip=cache_size == "too_large")
Exemplo n.º 20
0
def test_cache_1d_shape(experiment, DAC, DMM, n_points, bg_writing,
                  channel_array_instrument, setpoints_type,
                  in_memory_cache):

    setpoints_param, setpoints_values = _prepare_setpoints_1d(
        DAC, channel_array_instrument,
        n_points, setpoints_type
    )

    meas = Measurement()

    meas.register_parameter(setpoints_param)

    meas_parameters = (DMM.v1,
                       channel_array_instrument.A.dummy_multi_parameter,
                       channel_array_instrument.A.dummy_scalar_multi_parameter,
                       channel_array_instrument.A.dummy_2d_multi_parameter,
                       channel_array_instrument.A.dummy_2d_multi_parameter_2,
                       channel_array_instrument.A.dummy_array_parameter,
                       channel_array_instrument.A.dummy_complex_array_parameter,
                       channel_array_instrument.A.dummy_complex,
                       channel_array_instrument.A.dummy_parameter_with_setpoints,
                       channel_array_instrument.A.dummy_parameter_with_setpoints_complex,
                       )
    pws_n_points = 10
    channel_array_instrument.A.dummy_start(0)
    channel_array_instrument.A.dummy_stop(10)
    channel_array_instrument.A.dummy_n_points(pws_n_points)

    expected_shapes = {
        'dummy_dmm_v1': (n_points, ),
        'dummy_channel_inst_ChanA_multi_setpoint_param_this': (n_points, 5),
        'dummy_channel_inst_ChanA_multi_setpoint_param_that': (n_points, 5),
        'dummy_channel_inst_ChanA_thisparam': (n_points, ),
        'dummy_channel_inst_ChanA_thatparam': (n_points, ),
        'dummy_channel_inst_ChanA_this': (n_points, 5, 3),
        'dummy_channel_inst_ChanA_that': (n_points, 5, 3),
        'dummy_channel_inst_ChanA_this_5_3': (n_points, 5, 3),
        'dummy_channel_inst_ChanA_this_2_7': (n_points, 2, 7),
        'dummy_channel_inst_ChanA_dummy_array_parameter': (n_points, 5),
        'dummy_channel_inst_ChanA_dummy_complex_array_parameter': (n_points, 5),
        'dummy_channel_inst_ChanA_dummy_complex': (n_points, ),
        'dummy_channel_inst_ChanA_dummy_parameter_with_setpoints': (n_points, pws_n_points),
        'dummy_channel_inst_ChanA_dummy_parameter_with_setpoints_complex': (n_points, pws_n_points)
    }

    for param in meas_parameters:
        meas.register_parameter(param, setpoints=(setpoints_param,))
    meas.set_shapes(detect_shape_of_measurement(
        meas_parameters,
        (n_points,))
    )
    n_points_measured = 0
    with meas.run(write_in_background=bg_writing,
                  in_memory_cache=in_memory_cache) as datasaver:
        dataset = datasaver.dataset
        _assert_parameter_data_is_identical(dataset.get_parameter_data(), dataset.cache.data())
        for i, v in enumerate(setpoints_values):
            n_points_measured += 1
            setpoints_param.set(v)

            meas_vals = [(param, param.get()) for param in meas_parameters[:-2]]
            meas_vals += expand_setpoints_helper(meas_parameters[-2])
            meas_vals += expand_setpoints_helper(meas_parameters[-1])

            datasaver.add_result((setpoints_param, v),
                                 *meas_vals)
            datasaver.flush_data_to_database(block=True)
            cache_data_trees = dataset.cache.data()
            param_data_trees = dataset.get_parameter_data()
            _assert_partial_cache_is_as_expected(
                cache_data_trees,
                expected_shapes,
                n_points_measured,
                param_data_trees,
                cache_correct=True
            )
    cache_data_trees = dataset.cache.data()
    param_data_trees = dataset.get_parameter_data()

    _assert_completed_cache_is_as_expected(cache_data_trees,
                                           param_data_trees,
                                           flatten=False)
Exemplo n.º 21
0
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())
Exemplo n.º 22
0
def test_get_shape_for_array_parameter_from_len(loop_shape):
    a = ArraySetPointParam(name='a')
    shape = detect_shape_of_measurement((a, ), loop_shape)
    expected_shape = tuple(loop_shape) + tuple(a.shape)
    assert shape == {'a': expected_shape}
Exemplo n.º 23
0
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())
Exemplo n.º 24
0
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,
    do_plot: bool = True,
    additional_setpoints: Sequence[ParamMeasT] = tuple(),
) -> 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.
        do_plot: should png and pdf versions of the images be saved after the
            run.

    Returns:
        The QCoDeS dataset.
    """
    meas = Measurement()

    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)
    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:
        additional_setpoints_data = _process_params_meas(additional_setpoints)
        for set_point in np.linspace(start, stop, num_points):
            param_set.set(set_point)
            datasaver.add_result((param_set, set_point),
                                 *_process_params_meas(param_meas),
                                 *additional_setpoints_data)
        dataset = datasaver.dataset
    return _handle_plotting(dataset, do_plot, interrupted())