Source code for lightlab.equipment.lab_instruments.HP_8152A_PM

from . import VISAInstrumentDriver
from lightlab.equipment.abstract_drivers import PowerMeterAbstract
from lightlab.laboratory.instruments import PowerMeter


[docs]class HP_8152A_PM(VISAInstrumentDriver, PowerMeterAbstract): ''' HP8152A power meter `Manual <http://www.lightwavestore.com/product_datasheet/OTI-OPM-L-030C_pdf4.pdf>`__ Usage: :any:`/ipynbs/Hardware/PowerMeter.ipynb` Todo: Maybe allow a rapid continuous mode that just spits out numbers ('T0') ''' instrument_category = PowerMeter channelDescriptions = {1: 'A', 2: 'B', 3: 'A/B'} doReadDoubleCheck = False def __init__(self, name='The HP power meter', address=None, **kwargs): VISAInstrumentDriver.__init__(self, name=name, address=address, **kwargs)
[docs] def startup(self): self.close() self.write('T1') # single shot mode to make sure averaging occurs correctly
[docs] def open(self): super().open() self.termination = '' self.clear()
[docs] @staticmethod def proccessWeirdRead(readString): ''' The HP 8152 *sometimes* sends double characters. This tries to fix it based on reasonable value ranges. We assume that the values encountered have a decimal point and have two digits before and after the decimal point Arg: readString (str): what is read from query('TRG') Returns: (str): checked string ''' # is there a negative sign? unsignStrArr = readString.split('-') minus = len(unsignStrArr) > 1 try: decSplit = unsignStrArr[-1].split('.') onesHundredthsStrs = [decSplit[0], decSplit[-1]] except ValueError: raise ValueError('Power meter did not find a decimal point in return string') # There are now several options for when we expect two digits # there is an ambiguity when there are two digits, so we assume they are both intended onesHundredthsVals = [0] * 2 for i, s in enumerate(onesHundredthsStrs): if len(s) in [1, 2]: onesHundredthsVals[i] = float(s) elif len(s) in [3, 4]: # at least one has been repeated, so skip the middle (3) or seconds (4) onesHundredthsVals[i] = float(s[::2]) else: raise ValueError('Too many digits one one side of the decimal point') # reconstitute from floats val = onesHundredthsVals[0] + .01 * onesHundredthsVals[1] if minus: val *= -1 return str(val)
[docs] def robust_query(self, *args, **kwargs): # pylint: disable=arguments-differ ''' Conditionally check for read character doubling ''' retRaw = self.query(*args, **kwargs) # pylint: disable=arguments-differ if self.doReadDoubleCheck: return self.proccessWeirdRead(retRaw) else: return retRaw
[docs] def powerDbm(self, channel=1): ''' The detected optical power in dB on the specified channel Args: channel (int): Power Meter channel Returns: (double): Power in dB or dBm ''' self.validateChannel(channel) trial = 0 while trial < 10: # Sometimes it gets out of range, so we have to try a few times self.write('CH' + str(channel)) powStr = self.robust_query('TRG') v = float(powStr) if abs(v) < 999: # check if it's reasonable break else: # continue trial += 1 else: raise Exception('Power meter values are unreasonable.' ' Got {}'.format(v)) return v