Source code for techconnect.oscilloscopes.keysight

"""
Keysight
--------
This module contains the instrument classes for keysight oscilloscopes. It uses the methods created in the base class for the data parsing and saving,
but the communication is handled by the methods defined here.

Pieces salvaged from InfiniiVision_SegmentedMemory_Waveform.py
"""
import os
import time

import numpy as np 
import pickle as pkl

from techconnect.base._instrument import VISAInstrument
import techconnect.tools.file_handling as file_handling
from techconnect.oscilloscopes._ossc_base import Oscilloscope 

__all__ = ['Keysight3000T']

[docs] class Keysight3000T(Oscilloscope): """ Class representing the Keysight 3000T series oscilloscope. Attributes ---------- query_delay : float The delay between query and read in seconds. Methods ------- __init__() Initializes the Keysight3000T object. segmented_initialization(channel) Perform segmented initialization for a specific channel. calculate_segment_number(acquistion_time) Calculate the number of segments based on the acquisition time. setup_time_window(time_window) Set up the time window for each segment. setup_triggering() Set up the triggering mode for the oscilloscope. segmented_acquistion_setup(segment_count, acquistion_type='NORMAL', sample_rate='AUTO') Set up the segmented acquisition mode. manual_channel_setup(channel, vertical_scale, vertical_range, vertical_offset, bw_limit, coupling) Perform manual setup for a specific channel. auto_scale() Perform automatic scale of the oscilloscope. single_acquisition() Perform a single acquisition. digitize_acquisition(channels) Digitize the acquisition for the specified channels. retrieve_channel_info(channel) Retrieve information about a specific channel. data_export_setup(channel) Set up data export for a specific channel. get_number_of_points(channel) Get the number of points for a specific channel. generate_x_data(channel_info) Generate the x-axis data based on the channel information. stitch_multiseg_x_data(x_data, time_tags) Stitch together the x-axis data for multi-segment acquisition. scale_y_data(y_data, channel_info) Scale the y-axis data based on the channel information. collect_single_segment_data(segment_index, channel, channel_info) Collect data for a single segment and channel. collect_multi_segment_data(number_of_segments, channel, stitched) Collect data for multiple segments and a specific channel. parse_and_save(save_directory, save_dict, acquisition_info) Parse and save the acquired data. stitched_data_acquisition(acquisition_time, channels, segment_number=1000, save_directory=None, acquisition_type='HRESOLUTION') Perform stitched data acquisition. unstitched_data_acquisition(time_window, segment_number, channels, save_directory=None, acquisition_type='HRESOLUTION') Perform unstitched data acquisition. """ def __init__(self): super().__init__() self.query_delay = 0.1
[docs] def segmented_initialization(self, channel): """ Initializes the given channel by turning on the display, enabling automatic sample rate selection, and enabling automatic points selection. Parameters ---------- channel : int The channel number to be initialized. Returns ------- None """ lines = ( f":CHAN{channel}:DISPLAY ON", f":ACQUIRE:CHAN {channel}:SRATE:AUTO ON", f":ACQUIRE:CHAN {channel}:POINTS:AUTO ON" ) self.write_lines(lines)
def retrieve_channel_info(self, channel): channel_info = self.query_SCPI(f":WAVEFORM:SOURCE CHAN{channel};:WAVEFORM:PREAMBLE?").split(',') return { 'format': int(channel_info[0]), 'type': int(channel_info[1]), 'points': int(float(channel_info[2])), 'count': int(channel_info[3]), 'xincrement': float(channel_info[4]), 'xorigin': float(channel_info[5]), 'xreference': float(channel_info[6]), 'yincrement': float(channel_info[7]), 'yorigin': float(channel_info[8]), 'yreference': float(channel_info[9]) }
[docs] def calculate_segment_number(self, acquisition_time): """ Calculate the segment number based on the acquisition time. Parameters ---------- acquisition_time : float The acquisition time in seconds. Returns ------- segment_number : int The calculated segment number. """ sample_rate = int(float(self.query_SCPI(f":ACQUIRE:SRATE?"))) points_per_segment = int(float(self.query_SCPI(f":ACQUIRE:POINTS?"))) segment_number = int(np.ceil((acquisition_time*sample_rate)/points_per_segment)) return segment_number
[docs] def setup_time_window(self, time_window): """ Sets up the time window for the instrument. Parameters ---------- time_window : float The time window value to be set. Returns ------- None This function does not return anything. """ self.write_SCPI(f":TIMEBASE:SCALE {time_window/10}")
[docs] def setup_triggering(self): """ Sets up triggering for the device. It will be edge triggered externally, and on a positive slope """ lines = (":TRIGGER:MODE EDGE", ":TRIGGER:EDGE:SOURCE EXT", ":TRIGGER:EDGE:SLOPE POSITIVE") self.write_lines(lines)
[docs] def segmented_acquistion_setup(self, segment_count:int, acquistion_type='NORMAL', sample_rate='AUTO' ): """ Set up the segmented acquisition mode for the oscilloscope. Parameters ---------- segment_count : int The number of segments to acquire. acquistion_type : str, optional The type of acquisition. Defaults to 'NORMAL'. sample_rate : str, optional The sample rate. Defaults to 'AUTO'. Returns ------- None """ lines = ( f":ACQUIRE:MODE SEGMENTED", f":ACQUIRE:SEGMENTED:COUNT {segment_count}", f":ACQUIRE:TYPE {acquistion_type}" ) self.write_lines(lines)
[docs] def manual_channel_setup(self, channel: int, vertical_scale, vertical_range, vertical_offset, bw_limit, coupling, ): """ Sets up the manual configuration for a specific channel. Parameters ---------- channel : int The channel number. vertical_scale : The vertical scale. vertical_range : The vertical range. vertical_offset : The vertical offset. bw_limit : The bandwidth limit. coupling : The coupling type. Returns ------- None This function does not return anything. """ lines = ( f":CHAN{channel}:DISPLAY ON", f":CHAN{channel}:BWLIMIT{bw_limit}", f":CHAN{channel}:COUPLING{coupling}", f":CHAN{channel}:OFFSET{vertical_offset}", f":CHAN{channel}:RANGE{vertical_range}", f":CHAN{channel}:SCALE{vertical_scale}", ) self.write_lines(lines)
[docs] def auto_scale(self): """ Automatically sets up the instrument by sending the SCPI command ":AUTOSCALE". """ self.write_SCPI(f":AUTOSCALE")
[docs] def single_acquisition(self): """ Sends a command to the SCPI instrument to perform a single acquisition. """ self.write_SCPI(f":SINGLE")
[docs] def digitize_acquisition(self, channels): """ Digitize the acquisition for the given channels. Parameters ---------- channels : list of int A list of channel numbers to digitize. Returns ------- None This function does not return anything. """ line = ":DIGITIZE" if len(channels)>1: for channel in channels: line += f" CHANNEL{channel}" self.write_SCPI(line)
[docs] def data_export_setup(self, channel): """ Set up the data export for a specific channel. Parameters ---------- channel : int The channel number. Returns ------- None This function does not return anything. """ lines = ( f":WAVEFORM:SOURCE CHAN{channel}", f":WAVEFORM:FORMAT WORD", f":WAVEFORM:BYTEORDER LSBFIRST", f":WAVEFORM:UNSIGNED 0", f":WAVEFORM:POINTS MAX", f":WAVEFORM:POINTS:MODE RAW" ) self.write_lines(lines)
[docs] def get_number_of_points(self, channel): """ Get the number of points in a waveform for a given channel. Parameters ---------- channel : str The channel number. Returns ------- int The number of points in the waveform. """ return int(self.write_SCPI(f"WAVEFORM:SOURCE CHAN{channel};:WAVEFORM:POINTS?"))
[docs] def collect_single_segment_data(self, segment_index, channel, channel_info): """ Collects data for a single segment in the waveform. Parameters ---------- segment_index : int The index of the segment to collect data from. channel : str The channel to collect data from. channel_info : dict A dictionary containing information about the channel. Returns ------- tuple A tuple containing the segment time tag (float) and the collected data (ndarray). """ self.write_SCPI(f":ACQUIRE:SEGMENTED:INDEX {segment_index}") segment_time_tag = float(self.query_SCPI(f":WAVEFORM:SEGMENTED:TTAG?")) y_data = np.asarray(self.instrument.query_binary_values(f":WAVEFORM:SOURCE CHAN{channel};DATA?", delay=0, datatype='h', is_big_endian=False)) y_data = self.scale_y_data(y_data, channel_info) return segment_time_tag, y_data