""" Provide basic class to operate scope Created by Eugeniy E. Mikhailov 2021/11/29 """ from qolab.hardware.scpi import SCPIinstr from qolab.data.trace import TraceSetSameX from qolab.file_utils import get_next_data_file import yaml class Scope: # Minimal set of methods to be implemented by a scope. def __init__(self): self.config={} self.config['Device type'] = 'Scope' self.config['Device model'] = 'Generic Scope Without Hardware interface' self.numberOfChannels = 0 self.fname_prefix = 'scope' self.savepath = './scope' # deviceProperties must have 'get' and preferably 'set' methods available, # i.e. 'SampleRate' needs getSampleRate() and love to have setSampleRate(value) # they will be used to obtain config and set device according to it self.deviceProperties = ['SampleRate', 'TimePerDiv', 'TrigDelay', ]; # same is applied to channelProperties but we need setter/getter with channel number # i.e. VoltsPerDiv -> getChanVoltsPerDiv(chNum) and setSampleRate(chNum, value) self.channelProperties = ['VoltsPerDiv', 'Offset', ] def getTrace(self, chNum, availableNpnts=None, maxRequiredPoints=None): # Should work with minimal arguments list # but might be faster if parameters provided: less IO requests warnings.warn( 'this function is not implemented' ) def getAllTraces(self, availableNpnts=None, maxRequiredPoints=None): allTraces=TraceSetSameX('scope traces') allTraces.config['tags']['DAQ']=self.getConfig() for chNum in range(1, self.numberOfChannels+1): allTraces.addTrace( self.getTrace(chNum, availableNpnts, maxRequiredPoints) ) return( allTraces ) def getConfig(self): config = self.config.copy() dconfig = {} dconfig['id'] = self.idn for p in self.deviceProperties: getter = f'get{p}' if not hasattr(self, getter): print(f'warning no getter for {p}, i.e. {getter} is missing') continue res = getattr(self, getter)() dconfig[p] = res config['DeviceConfig'] = dconfig chconfig = {} for chNum in range(1, self.numberOfChannels+1): chNconfig = {} for p in self.channelProperties: getter = f'getChan{p}' if not hasattr(self, getter): print(f'warning no getter for {p}, i.e. {getter} is missing') continue res = getattr(self, getter)(chNum) chNconfig[p] = res chconfig[chNum] = chNconfig config['ChannelsConfig']=chconfig return config def getHeader(self): header = yaml.dump(self.getConfig(), default_flow_style=False, sort_keys=False) header = header.split('\n') return header def save(self, fname=None, item_format='e', availableNpnts=None, maxRequiredPoints=None, extention='dat'): allTraces = self.getAllTraces(availableNpnts=availableNpnts, maxRequiredPoints=maxRequiredPoints) if fname is None: fname = get_next_data_file(self.fname_prefix, self.savepath, extention=extention) allTraces.save(fname, item_format=item_format) return(fname) class ScopeSCPI(SCPIinstr, Scope): """ Do not instantiate directly, use rm = pyvisa.ResourceManager() ScopeSCPI(rm.open_resource('TCPIP::192.168.0.2::INSTR')) """ pass def __init__(self, resource): SCPIinstr.__init__(self, resource) Scope.__init__(self) from .sds1104x import SDS1104X