#
import re
import socket
[docs]class HP8560A(object):
MIN_FREQUENCY = 0.0
MAX_FREQUENCY = 2900.0
MIN_SPAN = 0.0001
DEFAULT_VAVG = 20
DEFAULT_REF_LEVEL = 0.0
MAX_REF_LEVEL = 30.0
MIN_REF_LEVEL = -120.0
REF_LEVEL_STEP = 1.0
MIN_ATT = 0.0
MAX_ATT = 70.0
ATT_STEP = 10.0
MIN_MAXMIXER_LEVEL = -80.0
MAX_MAXMIXER_LEVEL = -10.0
MAXMIXER_LEVEL_STEP = 10.0
DETECTOR_MODES = {'POS': 0, 'NRM': 1, 'NEG': 2, 'SMP': 3}
def __init__(self, gpib_controller, gpib_id):
self.gpib = gpib_controller
self.gpib_id = gpib_id
def local(self):
self.gpib.gpib_id = self.gpib_id
self.gpib.local()
def cmd(self, cmd):
self.gpib.gpib_id = self.gpib_id
self.gpib.write(cmd)
def clear(self):
self.gpib.clear()
self.gpib.write("IP;SNGLS;")
@property
def ident(self):
"""Returns the instrument ID string.
:raises: socket.timeout
If the instrument is unavailable
"""
_ident = None
if self.gpib:
self.gpib.gpib_id = self.gpib_id
self.gpib.clear()
self.gpib.write("ID?;")
_ident = self.gpib.gpib.read()
return _ident
@property
def vavg(self):
self.cmd("VAVG?;")
return self.gpib.read_int()
@property
def ref_level(self):
self.cmd("RL?;")
return self.gpib.read_float()
@property
def min_ref_level(self):
return HP8560A.MIN_REF_LEVEL
@property
def max_ref_level(self):
return HP8560A.MAX_REF_LEVEL
@property
def freq(self):
self.cmd("CF?;")
return self.gpib.read_float() / 1e6
@property
def start_freq(self):
self.cmd("FA?;")
return self.gpib.read_float() / 1e6
@property
def stop_freq(self):
self.cmd("FB?")
return self.gpib.read_float() / 1e6
@property
def fspan(self):
self.cmd("SP?;")
return self.gpib.read_float() / 1e6
@property
def rbw(self):
self.cmd("RB?;")
return self.gpib.read_float()
@property
def sweep_time(self):
self.cmd("ST?;")
return self.gpib.read_float()
@property
def vbr(self):
self.cmd("VBR?;")
return self.gpib.read_float()
@property
def vbw(self):
self.cmd("VB?;")
return self.gpib.read_float()
@property
def rbw_auto(self):
self.cmd("RB?;")
return self.gpib.read()
@property
def atten(self):
self.cmd("AT?;")
return self.gpib.read_int()
@property
def atten_auto(self):
self.cmd("AT?;")
return self.gpib.read()
@property
def scale(self):
self.cmd("LG?;")
return self.gpib.read_float()
@property
def mixer_level(self):
self.cmd("ML?;")
return self.gpib.read_float()
@property
def unit(self):
self.cmd("AUNITS?;")
return self.gpib.read()
@property
def detector_mode(self):
return self.query("DET?;")
@vavg.setter
def vavg(self, vavg):
self.cmd("VAVG {};".format(vavg))
@ref_level.setter
def ref_level(self, level):
self.cmd("RL {}DBM;".format(level))
@freq.setter
def freq(self, f):
self.cmd("CF {}MHZ;".format(f))
@start_freq.setter
def start_freq(self, f):
self.cmd("FA {}MHZ;".format(f))
@stop_freq.setter
def stop_freq(self, f):
self.cmd("FB {}MHZ;".format(f))
@fspan.setter
def fspan(self, span):
self.cmd("SP {}MHZ;".format(span))
@rbw.setter
def rbw(self, res):
self.cmd("RB {}HZ;".format(res))
@sweep_time.setter
def sweep_time(self, t):
self.cmd("ST {}S;".format(t))
@vbr.setter
def vbr(self, ratio):
self.cmd("VBR {};".format(ratio))
@vbw.setter
def vbw(self, v):
self.cmd("VB {}HZ;", v)
@rbw_auto.setter
def rbw_auto(self, auto):
if auto:
self.cmd("RB AUTO;")
else:
self.cmd("RB MAN;")
@atten.setter
def atten(self, att):
self.cmd("AT {}DB;".format(att))
@atten_auto.setter
def atten_auto(self, auto):
if auto:
self.cmd("AT AUTO;")
else:
self.cmd("AT MAN;")
@scale.setter
def scale(self, s):
self.cmd("LG {}DB;".format(s))
@mixer_level.setter
def mixer_level(self, lvl):
self.cmd("ML {}DBM;".format(lvl))
@unit.setter
def unit(self, u):
self.cmd("AUNITS {};".format(u))
@detector_mode.setter
def detector_mode(self, det):
self.cmd("DET {};".format(det))
def err_check(self):
self.cmd("ERR?;")
errs = self.gpib.read()
err_list = errs.strip().split(',')
return err_list
def sweep(self):
self.gpib.write("TS;DONE?;")
self.gpib.wait_for_done()
def trace_raw_data(self):
trace_len = 601*2
self.gpib.write("TDF B;TRA?;")
data = self.gpib.read_bin(trace_len)
return [(data[i]*256)+data[i+1] for i in range(0, trace_len, 2)]
def trace_data(self):
tstr = ''
self.gpib.write("TDF P;TRA?;")
while True:
try:
raw_str = self.gpib.read()
# Remove possible garbage chars
tstr += re.sub('[:;><?]+', '', raw_str)
if tstr[-1] == '\n':
break
except socket.timeout:
pass
tbuf = [float(tval) for tval in tstr[:-1].split(',')]
return tbuf
[docs] def initialize(self):
"""Initialize the analyzer state.
"""
self.gpib.gpib_id = self.gpib_id
self.gpib.clear()
self.gpib.write("IP;SNGLS;")
self.gpib.write("DET POS;")
self.gpib.write("TS;DONE?;")
self.gpib.wait_for_done()
def reset(self):
self.gpib.gpib_id = self.gpib_id
self.gpib.write("IP;CONTS;")
self.gpib.write("DONE?;")
self.gpib.wait_for_done()
[docs] def measure_pwr(self, freq):
"""Measure the power at a specified frequency.
This assumes that the relevant spectrum analyzer configuration
has already been set. This would include: ref. level,
freq. span, vavg, detector mode. For exaample:
.. code-block:: python
>>> sa.vavg = 5
>>> sa.fspan = 0.1
>>> sa.ref_level = 10.0
>>> sa.measure_pwr(250.0)
(2.732128, 250.000166)
:param freq: The centre frequency to make the measurement (in MHz).
:type freq: float
:return: A tuple of two floats with the measured power being first
and the frequency of the marker being the second.
"""
self.gpib.gpib_id = self.gpib_id
self.gpib.write("CF {}MHZ;TS;DONE?;".format(freq))
self.gpib.wait_for_done()
self.gpib.write("MKPK HI;MKA?;")
mkr_pwr = self.gpib.read_float()
self.gpib.write("MKF?;")
mkr_freq = self.gpib.read_float() / 1e6
return mkr_pwr, mkr_freq
[docs] def measure_next_pwr(self):
"""Measure the power and freq. of the next highest peak.
This assumes that the measure_pwr method has already
been called.
.. code-block:: python
>>> sa.vavg = 5
>>> sa.fspan = 0.1
>>> sa.ref_level = 10.0
>>> sa.measure_pwr(250.0)
(2.732128, 250.000166)
>>> sa.measure_next_pwr()
(1.986321, 250.050134)
Note that if the analyzer cannot find another peak the
cal to :py:`measure_next_pwr` will return the power and
frequency values for the first peak.
:return: A tuple of two floats with the power of next highest
peak being first and the second being the frequency of
the peak.
"""
self.gpib.gpib_id = self.gpib_id
self.gpib.write("MKPK NH;MKA?;")
mkr_pwr = self.gpib.read_float()
self.gpib.write("MKF?;")
mkr_freq = self.gpib.read_float() / 1e6
return mkr_pwr, mkr_freq