diff options
-rw-r--r-- | qolab/hardware/scope/__init__.py | 10 | ||||
-rw-r--r-- | qolab/hardware/scope/sds1104x.py | 32 |
2 files changed, 30 insertions, 12 deletions
diff --git a/qolab/hardware/scope/__init__.py b/qolab/hardware/scope/__init__.py index c573edf..ae311d1 100644 --- a/qolab/hardware/scope/__init__.py +++ b/qolab/hardware/scope/__init__.py @@ -25,16 +25,16 @@ class Scope(BasicInstrument): # i.e. VoltsPerDiv -> getChanVoltsPerDiv(chNum) and setSampleRate(chNum, value) self.channelProperties = ['VoltsPerDiv', 'Offset', ] - def getTrace(self, chNum, availableNpnts=None, maxRequiredPoints=None): + def getTrace(self, chNum, availableNpnts=None, maxRequiredPoints=None, decimate=True): # 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): + def getAllTraces(self, availableNpnts=None, maxRequiredPoints=None, decimate=True): 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) ) + allTraces.addTrace( self.getTrace(chNum, availableNpnts=availableNpnts, maxRequiredPoints=maxRequiredPoints, decimate=decimate) ) return( allTraces ) def plot(self, **kwargs): @@ -63,8 +63,8 @@ class Scope(BasicInstrument): return header - def save(self, fname=None, item_format='e', availableNpnts=None, maxRequiredPoints=None, extention='dat'): - allTraces = self.getAllTraces(availableNpnts=availableNpnts, maxRequiredPoints=maxRequiredPoints) + def save(self, fname=None, item_format='e', availableNpnts=None, maxRequiredPoints=None, decimate=True, extention='dat'): + allTraces = self.getAllTraces(availableNpnts=availableNpnts, maxRequiredPoints=maxRequiredPoints, decimate=decimate) if fname is None: fname = get_next_data_file(self.config['FnamePrefix'], self.config['SavePath'], extention=extention) allTraces.save(fname, item_format=item_format) diff --git a/qolab/hardware/scope/sds1104x.py b/qolab/hardware/scope/sds1104x.py index 1b9b39e..63895f6 100644 --- a/qolab/hardware/scope/sds1104x.py +++ b/qolab/hardware/scope/sds1104x.py @@ -6,6 +6,7 @@ from qolab.hardware.scope import ScopeSCPI from qolab.hardware.scpi import response2numStr from qolab.data.trace import Trace, TraceXY import numpy as np +import scipy.signal class SDS1104X(ScopeSCPI): """ Siglent SDS1104x scope """ @@ -58,14 +59,24 @@ class SDS1104X(ScopeSCPI): Npnts = int(np.floor(availableNpnts/sparsing)) return(sparsing, Npnts, availableNpnts, maxRequiredPoints) - def getRawWaveform(self, chNum, availableNpnts=None, maxRequiredPoints=None): + def getRawWaveform(self, chNum, availableNpnts=None, maxRequiredPoints=None, decimate=True): + """ + If decimate is used, we get all available points and then low-pass filter them. + The result is less noisy. But transfer time from the instrument is longer. + If decimate=False we might see aliasing, if there is a high frequency noise + and sparsing > 1 + """ + (sparsing, Npnts, availableNpnts, maxRequiredPoints) = self.calcSparsingAndNumPoints(availableNpnts, maxRequiredPoints) - if sparsing == 1 and Npnts == availableNpnts: + if (sparsing == 1 and Npnts == availableNpnts) or decimate: # we are getting all of it cstr = f'WAVEFORM_SETUP NP,0,FP,0,SP,{sparsing}' # technically when we know Npnts and sparsing # we can use command from the follow up 'else' clause else: + # we just ask every point with 'sparsing' interval + # fast to grab but we could do better with more advance decimate + # method, which allow better precision for the price of longer acquisition time cstr = f'WAVEFORM_SETUP SP,{sparsing},NP,{Npnts},FP,0' # Note: it is not enough to provide sparsing (SP), # number of points (NP) needed to be calculated properly too! @@ -91,7 +102,11 @@ class SDS1104X(ScopeSCPI): # expected full reply: 'C1:WF DAT2,#9000000140.........' trRaw = Trace(f'Ch{chNum}') trRaw.values = wfRaw.reshape(wfRaw.size,1) - trRaw.unit = 'count' + if decimate and sparsing != 1: + numtaps = 3; # not sure it is the best case + trRaw.values = scipy.signal.decimate(trRaw.values, sparsing, 3, axis=0) + trRaw.config['unit'] = 'Count' + trRaw.config['tags']['Decimate'] = decimate return(trRaw, availableNpnts, Npnts) def getChanVoltsPerDiv(self, chNum): @@ -133,8 +148,11 @@ class SDS1104X(ScopeSCPI): return(float(numberString)) - def getWaveform(self, chNum, availableNpnts=None, maxRequiredPoints=None): - trRaw, availableNpnts, Npnts = self.getRawWaveform(chNum, availableNpnts=availableNpnts, maxRequiredPoints=maxRequiredPoints) + def getWaveform(self, chNum, availableNpnts=None, maxRequiredPoints=None, decimate=True): + """ + For decimate use see getRawWaveform. In short decimate=True is slower but more precise. + """ + trRaw, availableNpnts, Npnts = self.getRawWaveform(chNum, availableNpnts=availableNpnts, maxRequiredPoints=maxRequiredPoints, decimate=decimate) VoltageOffset = self.getChanOffset(chNum) VoltsPerDiv = self.getChanVoltsPerDiv(chNum) tr = trRaw @@ -165,8 +183,8 @@ class SDS1104X(ScopeSCPI): t.config['tags']['Sparsing'] = sparsing return(t) - def getTrace(self, chNum, availableNpnts=None, maxRequiredPoints=None): - wfVoltage, availableNpnts = self.getWaveform( chNum, availableNpnts=availableNpnts, maxRequiredPoints=maxRequiredPoints) + def getTrace(self, chNum, availableNpnts=None, maxRequiredPoints=None, decimate=True): + wfVoltage, availableNpnts = self.getWaveform( chNum, availableNpnts=availableNpnts, maxRequiredPoints=maxRequiredPoints, decimate=decimate) t = self.getTimeTrace(availableNpnts=availableNpnts, maxRequiredPoints=maxRequiredPoints) tr = TraceXY( f'Ch{chNum}' ) tr.x = t |