diff --git a/qutil/measurement/VNA/inst_E5071C.py b/qutil/measurement/VNA/inst_E5071C.py index 0f241b31d27b069506b24ca1c2a86cd3314bf5c2..96d2868de56b5bc2997b14766171cb574529275e 100644 --- a/qutil/measurement/VNA/inst_E5071C.py +++ b/qutil/measurement/VNA/inst_E5071C.py @@ -7,63 +7,64 @@ Created on Sun Oct 2 13:27:14 2022 modified according to Python Example Retrieve the Data as .csv for all the Traces at the Screen on a E5071C https://support.keysight.com/KeysightdCX/s/knowledge-article-detail?language=en_US&keyid=ka05a000000V6MY """ - +from typing import Optional import numpy as np import pandas as pd import matplotlib.pyplot as plt import time -import visa +import pyvisa import csv + class VNA: def __init__(self, remote_address): self.remote_address = remote_address - self.inst = None - self.timeout=50000 + self.inst: Optional[pyvisa.resources.MessageBasedResource] = None + self.timeout = 50000 def connect_to_VNA(self): - rm=visa.ResourceManager() + rm = pyvisa.ResourceManager() # print(rm.list_resources()) self.inst = rm.open_resource(self.remote_address) - def identify_inst(self): - self.inst.write('*IDN?') - IDN = self.inst.read() - return IDN + def identify_inst(self) -> str: + return self.inst.query('*IDN?') def get_traces(self): - MatHeader=[] - MatAllData=[] + mat_header = [] + mat_all_data = [] param, getDispMaxChannel = self.get_disp() - for Channel in range(1,getDispMaxChannel+1): - #print(':CALCulate'+str(Channel)+':PARameter1:SELect') + for channel in range(1, getDispMaxChannel + 1): + # print(':CALCulate'+str(Channel)+':PARameter1:SELect') self.inst.write(':FORMat:DATA %s' % ('ASCii')) - self.inst.write(':CALCulate'+str(Channel)+':PARameter1:SELect') - MaxNumTraces = int(self.inst.query(':CALCulate'+str(Channel)+':PARameter:COUNt?')) + self.inst.write(f':CALCulate{channel}:PARameter1:SELect') + max_num_traces = int(self.inst.query(f':CALCulate{channel}:PARameter:COUNt?')) self.inst.write(':FORMat:DATA %s' % ('ASCii')) - Frequency = (self.inst.query_ascii_values(':SENSe'+str(Channel)+':FREQuency:DATA?')) - MatAllData.append(Frequency) + Frequency = (self.inst.query_ascii_values(f':SENSe{channel}:FREQuency:DATA?')) + mat_all_data.append(Frequency) - for Trace in range(1,MaxNumTraces+1): - #print(Trace) + for trace in range(1, max_num_traces + 1): + # print(Trace) param1 = self.inst.query(':SENSe1:SWEep:TYPE?') self.inst.write(':FORMat:DATA %s' % ('ASCii')) - Data = (self.inst.query_ascii_values(':CALCulate'+str(Channel)+':TRACe'+str(Trace)+':DATA:FDATa?')) - #print(Data) - #print('Channel'+str(Channel)+'_Trace'+str(Trace)+'amp'+'_Trace'+str(Trace)+'phase') - MatHeader.append('Frequency_Channel'+str(Channel)+'_Trace'+str(Trace)+'amp'+'_Trace'+str(Trace)+'phase') + data = self.inst.query_ascii_values(f':CALCulate{channel}:TRACe{trace}:DATA:FDATa?') + # print(Data) + # print('Channel'+str(Channel)+'_Trace'+str(Trace)+'amp'+'_Trace'+str(Trace)+'phase') - MatAllData.append(Data[0::2]) - MatAllData.append(Data[1::2]) + mat_header.append(f'Frequency_Channel{channel}_Trace' + str(trace) + 'amp' + '_Trace' + str( + trace) + 'phase') - A=MatAllData - A=np.array(A).transpose() - Headers=' '.join([str(item) for item in MatHeader]) - return Headers, A + mat_all_data.append(data[0::2]) + mat_all_data.append(data[1::2]) + + mat = mat_all_data + mat = np.array(mat).transpose() + headers = ' '.join(mat_header) + return headers, mat def setup_measurement(self): # 1 channel 4 traces S11, S12, S21, S22 @@ -74,8 +75,8 @@ class VNA: self.inst.write(':CALC1:PAR3:DEF S21') self.inst.write(':CALC1:PAR4:DEF S22') - sweep_type = self.inst.query(':SENSe1:SWEep:TYPE?') - if sweep_type[:-1] == 'LIN': + sweep_type = self.inst.query(':SENSe1:SWEep:TYPE?').strip() + if sweep_type == 'LIN': pass else: self.inst.write(':SENS1:SWE:TYPE LIN\n') @@ -92,126 +93,28 @@ class VNA: def get_disp(self): # Get the Shape of the display to know how many channels are needed to be scanned - param = self.inst.query(':DISPlay:SPLit?') - param = param[0:-1]#remove the \n at the end - - if param=="D1": - getDispMaxChannel = 1 - elif param=="1X1": - getDispMaxChannel = 1 - elif param=="D12": - getDispMaxChannel = 2 - elif param=="D1_2": - getDispMaxChannel = 2 - elif param=="D112": - getDispMaxChannel = 2 - elif param=="D1_1_2": - getDispMaxChannel = 2 - elif param=="D1X2": - getDispMaxChannel = 2 - elif param=="D2X1": - getDispMaxChannel = 2 - - elif param=="D123": - getDispMaxChannel = 3 - elif param=="D1_2_3": - getDispMaxChannel = 3 - elif param=="D3X1": - getDispMaxChannel = 3 - elif param=="D12_33": - getDispMaxChannel = 3 - elif param=="D11_23": - getDispMaxChannel = 3 - elif param=="D13_23": - getDispMaxChannel = 3 - elif param=="D12_13": - getDispMaxChannel = 3 - elif param=="D1X3": - getDispMaxChannel = 3 - - elif param=="D1234": - getDispMaxChannel = 4 - elif param=="D1_2_3_4": - getDispMaxChannel = 4 - elif param=="D12_34": - getDispMaxChannel = 4 - elif param=="D1X4": - getDispMaxChannel = 4 - elif param=="D4X1": - getDispMaxChannel = 4 - elif param=="D2X2": - getDispMaxChannel = 4 - - elif param=="D123_456": - getDispMaxChannel = 6 - elif param=="D12_34_56": - getDispMaxChannel = 6 - elif param=="D2X3": - getDispMaxChannel = 6 - elif param=="D3X2": - getDispMaxChannel = 6 - - elif param=="D1234_5678": - getDispMaxChannel = 8 - elif param=="D12_34_56_78": - getDispMaxChannel = 8 - elif param=="D2X4": - getDispMaxChannel = 8 - elif param=="D4X2": - getDispMaxChannel = 8 - - elif param=="D123_456_789": - getDispMaxChannel = 9 - elif param=="D3X3": - getDispMaxChannel = 9 - - elif param=="D123__ABC": - getDispMaxChannel = 12 - elif param=="D1234__9ABC": - getDispMaxChannel = 12 - elif param=="D3X4": - getDispMaxChannel = 12 - elif param=="D4X3": - getDispMaxChannel = 12 - - elif param=="D1234_DEFG": - getDispMaxChannel = 16 - elif param=="D1234__CDEF": - getDispMaxChannel = 16 - elif param=="D4X4": - getDispMaxChannel = 16 - - elif param=="D4X5": - getDispMaxChannel = 20 - - elif param=="D4X6": - getDispMaxChannel = 24 - - elif param=="D4X7": - getDispMaxChannel = 28 - - elif param=="D4X8": - getDispMaxChannel = 32 - - elif param=="D4X9": - getDispMaxChannel = 36 - - elif param=="D8X9": - getDispMaxChannel = 72 - elif param=="D6X12": - getDispMaxChannel = 72 - - elif param=="D8X12": - getDispMaxChannel = 96 - - elif param=="D10X16": - getDispMaxChannel = 160 + param: str = self.inst.query(':DISPlay:SPLit?') + param = param.strip() # remove the \n at the end + + split = param.lstrip('D').replace('_', '') + + if 'X' in split: + a, b = split.split('X') + max_disp_chan = int(a) * int(b) + + elif any(l in split for l in 'ABCD'): + if split in ("D123__ABC", 'D1234__9ABC'): + max_disp_chan = 12 + elif split in ("D1234_DEFG", 'D1234__CDEF'): + return 16 + + raise NotImplementedError(split) else: - getDispMaxChannel=1 + chans = list(map(int, split)) + max_disp_chan = len(set(chans)) - return param, getDispMaxChannel + return param, max_disp_chan def disconnect_inst(self): self.inst.close() - rm.close() diff --git a/qutil/measurement/VNA/scheduled_measurement.py b/qutil/measurement/VNA/scheduled_measurement.py index 8971926587f4d790d0275d94aaaa58f7f5bb65e3..bd277c6f51e387070c68f6546122dbd7128495fa 100644 --- a/qutil/measurement/VNA/scheduled_measurement.py +++ b/qutil/measurement/VNA/scheduled_measurement.py @@ -36,10 +36,12 @@ def make_scheduled_single_trace(): np.savetxt(filename, data, delimiter=',', fmt='%5s', header= headers) print(f'[{timestamp}] - VNA measurement saved.') -print('>>> Start a scheduled measurement: VNA trace during cooling down <<<') -schedule.every(10).minutes.do(make_scheduled_single_trace) -print('Sleep for 10 min') -while True: - schedule.run_pending() - time.sleep(1) \ No newline at end of file +if __name__ == "__main__": + print('>>> Start a scheduled measurement: VNA trace during cooling down <<<') + schedule.every(10).minutes.do(make_scheduled_single_trace) + print('Sleep for 10 min') + + while True: + schedule.run_pending() + time.sleep(1) diff --git a/setup.cfg b/setup.cfg index bc0fb8b8f3a62efca8d7f0f276db2a9825833280..043b4bb375f16a61e6cfb281dbb0b348ab004322 100644 --- a/setup.cfg +++ b/setup.cfg @@ -31,6 +31,8 @@ install_requires = pandas more-itertools matplotlib + schedule + pyvisa [options.extras_require] fancy_progressbar = tqdm;ipynbname