Exemplo n.º 1
0
def test_convert_dummy_val_to_nan():
    status = ['C', 'V', 'N', 'V', 'N', 'N']
    value = [0, 199.999e99, 1, 199.999e99, 2, 3]
    channel = [1, 1, 1, 1, 1, 1]
    param_type = ['V', 'V', 'V', 'V', 'V', 'V']
    param = _FMTResponse(value, status, channel, param_type)
    convert_dummy_val_to_nan(param)
    assert math.isnan(param.value[1])
    assert math.isnan(param.value[3])
Exemplo n.º 2
0
    def get_raw(self) -> Tuple[Tuple[float, ...], Tuple[float, ...]]:
        measurement_mode = self.instrument.get_measurement_mode()
        if len(measurement_mode['channels']) != 2:
            raise ValueError('Two measurement channels are needed, one for '
                             'gate current and other for source drain '
                             'current.')

        smu = self.instrument.by_channel[measurement_mode['channels'][0]]

        if not smu.setup_fnc_already_run:
            raise Exception(f'Sweep setup has not yet been run successfully '
                            f'on {smu.full_name}')

        delay_time = smu.iv_sweep.step_delay()
        if smu._average_coefficient < 0:
            # negative coefficient means nplc and positive means just
            # averaging
            nplc = 128 * abs(smu._average_coefficient)
            power_line_time_period = 1 / smu.power_line_frequency
            calculated_time = 2 * nplc * power_line_time_period
        else:
            calculated_time = smu._average_coefficient * \
                              delay_time
        num_steps = smu.iv_sweep.sweep_steps()
        estimated_timeout = max(delay_time, calculated_time) * num_steps
        new_timeout = estimated_timeout * self._fudge

        format_and_mode = self.instrument.get_response_format_and_mode()
        fmt_format = format_and_mode['format']
        fmt_mode = format_and_mode['mode']
        try:
            self.root_instrument.write(MessageBuilder().fmt(1, 1).message)
            with self.root_instrument.timeout.set_to(new_timeout):
                raw_data = self.instrument.ask(MessageBuilder().xe().message)
                parsed_data = fmt_response_base_parser(raw_data)
        finally:
            self.root_instrument.write(MessageBuilder().fmt(fmt_format,
                                                            fmt_mode).message)

        self.param1 = _FMTResponse(
            *[parsed_data[i][::3] for i in range(0, 4)])
        self.param2 = _FMTResponse(
            *[parsed_data[i][1::3] for i in range(0, 4)])
        self.source_voltage = _FMTResponse(
            *[parsed_data[i][2::3] for i in range(0, 4)])

        self.shapes = ((len(self.source_voltage.value),),) * 2
        self.setpoints = ((self.source_voltage.value,),) * 2

        convert_dummy_val_to_nan(self.param1)
        convert_dummy_val_to_nan(self.param2)

        return self.param1.value, self.param2.value
Exemplo n.º 3
0
    def get_raw(self) -> Tuple[Tuple[float, ...], ...]:
        measurement_mode = self.instrument.get_measurement_mode()
        channels = measurement_mode['channels']
        n_channels = len(channels)

        if n_channels < 1:
            raise ValueError('At least one measurement channel is needed for '
                             'an IV sweep.')

        if (len(self.names) != n_channels or len(self.units) != n_channels
                or len(self.labels) != n_channels
                or len(self.shapes) != n_channels):
            raise ValueError(
                f"The number of `.names` ({len(self.names)}), "
                f"`.units` ({len(self.units)}), `.labels` ("
                f"{len(self.labels)}), or `.shapes` ({len(self.shapes)}) "
                f"of the {self.full_name} parameter "
                f"does not match the number of channels expected for the IV "
                f"sweep measurement, which is {n_channels}. One must set "
                f"enough names, units, and labels for all the channels that "
                f"are to be measured.")

        smu = self.instrument.by_channel[channels[0]]

        if not smu.setup_fnc_already_run:
            raise Exception(f'Sweep setup has not yet been run successfully '
                            f'on {smu.full_name}')

        delay_time = smu.iv_sweep.step_delay()
        if smu._average_coefficient < 0:
            # negative coefficient means nplc and positive means just
            # averaging, see B1517A.set_average_samples_for_high_speed_adc
            # for more info
            nplc = 128 * abs(smu._average_coefficient)
            power_line_time_period = 1 / smu.power_line_frequency
            calculated_time = 2 * nplc * power_line_time_period
        else:
            calculated_time = smu._average_coefficient * delay_time
        num_steps = smu.iv_sweep.sweep_steps()
        estimated_timeout = max(delay_time, calculated_time) * num_steps
        new_timeout = estimated_timeout * self._fudge

        format_and_mode = self.instrument.get_response_format_and_mode()
        fmt_format = format_and_mode['format']
        fmt_mode = format_and_mode['mode']
        try:
            self.root_instrument.write(MessageBuilder().fmt(1, 1).message)
            with self.root_instrument.timeout.set_to(new_timeout):
                raw_data = self.instrument.ask(MessageBuilder().xe().message)
        finally:
            self.root_instrument.write(MessageBuilder().fmt(
                fmt_format, fmt_mode).message)

        parsed_data = fmt_response_base_parser(raw_data)

        # The `4` comes from the len(_FMTResponse(None, None, None, None)),
        # the _FMTResponse tuple declares these items that the instrument
        # gives for each data point
        n_items_per_data_point = 4

        # sourced voltage values are also returned, hence the `+1`
        n_all_data_channels = n_channels + 1

        for channel_index in range(n_channels):
            parsed_data_items = [
                parsed_data[i][channel_index::n_all_data_channels]
                for i in range(0, n_items_per_data_point)
            ]
            single_channel_data = _FMTResponse(*parsed_data_items)
            convert_dummy_val_to_nan(single_channel_data)

            # Store the results to `.param#` attributes for convenient access
            # to all the data, e.g. status of each value in the arrays
            setattr(self, f"param{channel_index+1}", single_channel_data)

        channel_values_to_return = tuple(
            getattr(self, f"param{n + 1}").value for n in range(n_channels))

        source_voltage_index = n_channels
        parsed_source_voltage_items = [
            parsed_data[i][source_voltage_index::n_all_data_channels]
            for i in range(0, n_items_per_data_point)
        ]
        self.source_voltage = _FMTResponse(*parsed_source_voltage_items)

        self.shapes = ((len(self.source_voltage.value), ), ) * n_channels
        self.setpoints = ((self.source_voltage.value, ), ) * n_channels

        return channel_values_to_return