Пример #1
0
    def setupDaqChannels(self):
        device = 'USB6002_B'

        # AI
        terminalConfig = daq.AiChannel.TerminalConfiguration.DIFF
        self.fetOutputMonitorChannel = daq.AiChannel(
            '%s/ai0' % device, -10., +10., terminalConfig=terminalConfig)
        self.magnetVoltageChannel = daq.AiChannel(
            '%s/ai1' % device, -10., +10., terminalConfig=terminalConfig)
        self.currentChannelFine = daq.AiChannel('%s/ai2' % device,
                                                -10.,
                                                +10.,
                                                terminalConfig=terminalConfig)
        self.currentChannelCoarse = daq.AiChannel(
            '%s/ai3' % device, -10., +10., terminalConfig=terminalConfig)

        # AO
        self.magnetVoltageControlChannel = daq.AoChannel(
            '%s/ao0' % device, -10., +10.)  # TODO Figure out proper limits
        self.outputVoltageControlChannel = daq.AoChannel(
            '%s/ao1' % device, 0,
            self.OutputVoltageLimit / self.OutputVoltageControlGain)

        # Digital
        self.doLineDisableFeedback = daq.DoChannel(
            '%s/port1/line0' % device)  # HIGH=Disable, LOW=Enable
        self.diLineDisableFeedbackCheck = daq.DiChannel(
            '%s/port2/line0' % device)  # Readback for DisableFeedback
        self.doLineMagnetVoltageLoopGain = daq.DoChannel(
            '%s/port1/line1' % device)  # HIGH=21x, LOW=441x
        self.doLineMagnetVoltageReadoutGain = daq.DoChannel(
            '%s/port1/line2' %
            device)  # HIGH=441x, LOW=21x # Might be backwards
Пример #2
0
    def setupDaqChannels(self):
        # AI
        device = 'USB6002_A'
        terminalConfig = daq.AiChannel.TerminalConfiguration.DIFF
        self.fetOutputMonitorChannel = daq.AiChannel(
            '%s/ai0' % device, -10., +10., terminalConfig=terminalConfig)
        self.currentChannelCoarse = daq.AiChannel(
            '%s/ai1' % device, -10., +10., terminalConfig=terminalConfig)
        self.currentChannelFine = daq.AiChannel('%s/ai2' % device,
                                                -10.,
                                                +10.,
                                                terminalConfig=terminalConfig)
        self.magnetVoltageChannel = daq.AiChannel(
            '%s/ai3' % device, -10., +10., terminalConfig=terminalConfig)

        # Digital
        self.doLineDisableFeedback = daq.DoChannel('%s/port1/line3' % device)
        self.diLineDisableFeedbackCheck = daq.DiChannel('%s/port1/line0' %
                                                        device)
        self.doLineResetIntegrator = daq.DoChannel('%s/port1/line2' % device)

        # AO
        self.magnetVoltageControlChannel = daq.AoChannel(
            '%s/ao0' % device, -3.4, +3.4)
        self.outputVoltageControlChannel = daq.AoChannel(
            '%s/ao1' % device, 0,
            self.OutputVoltageLimit / self.OutputVoltageControlGain)
Пример #3
0
 def __init__(self, device, channel, voltageMin, voltageMax, samples=100, drop=30):
     self.aiChannel = daq.AiChannel('%s/%s' % (device, channel), voltageMin, voltageMax)
     self.itask = daq.AiTask('Input')
     self.itask.addChannel(self.aiChannel)
     self.itask.start()
     self.nSamples = samples
     self.nDrop = drop
Пример #4
0
    def updateDevice(self):
        print("Updating device")
        self.aiChannelCombo.clear()
        self.aiDriveChannelCombo.clear()
        self.aoChannelCombo.clear()
        self.aiRangeCombo.clear()
        self.aoRangeCombo.clear()
        self.auxAoRangeCombo.clear()
        self.auxAoChannelCombo.clear()
        
        deviceName = str(self.deviceCombo.currentText())
        if len(deviceName) < 1:
            return
        device = daq.Device(deviceName)

        aiChannels = device.findAiChannels()
        for channel in aiChannels:
            self.aiChannelCombo.addItem(channel)
            self.aiDriveChannelCombo.addItem(channel)
        
        aoChannels = device.findAoChannels()
        for channel in aoChannels:
            self.aoChannelCombo.addItem(channel)
            self.auxAoChannelCombo.addItem(channel)
            
        self.aiRanges = device.voltageRangesAi()
        for r in self.aiRanges:
            self.aiRangeCombo.addItem('%+.2f -> %+.2f V' % (r.min, r.max))

        self.aoRanges = device.voltageRangesAo()            
        for r in self.aoRanges:
            self.aoRangeCombo.addItem('%+.2f -> %+.2f V' % (r.min, r.max))
            self.auxAoRangeCombo.addItem('%+.2f -> %+.2f V' % (r.min, r.max))
        
        if len(aiChannels):
            aiChannel = daq.AiChannel('%s/%s' % (deviceName, aiChannels[0]), self.aiRanges[0].min, self.aiRanges[0].max)
            aiTask = daq.AiTask('TestInputSampleRate_SineSweepDaq')
            aiTask.addChannel(aiChannel)
            aiSampleRate = aiTask.maxSampleClockRate()
            del aiTask
        else:
            aiSampleRate = 0

        if len(aoChannels):
            aoChannel = daq.AoChannel('%s/%s' % (deviceName, aoChannels[0]), self.aoRanges[0].min, self.aoRanges[0].max)
            aoTask = daq.AoTask('TestOutputSampleRate_SineSweepDaq')
            aoTask.addChannel(aoChannel)
            aoSampleRate = aoTask.maxSampleClockRate()
            del aoTask                
        else:
            aoSampleRate = 0
        
        rate = min(aiSampleRate, aoSampleRate)

        self.sampleRateSb.setMaximum(int(1E-3*rate))
        if rate < 1:
            return
        self.updateInfo()
Пример #5
0
 def __init__(self):
     #aoChannel = daq.AoChannel('USB6002_B/ao0', -10, +10)
     #aiChannel = daq.AiChannel('USB6002_B/ai1', -10, +10)
     aoChannel = daq.AoChannel('Dev2/ao0', -10, +10)
     aiChannel = daq.AiChannel('Dev2/ai0', -10, +10)
     aiChannel.setTerminalConfiguration(daq.AiChannel.TerminalConfiguration.DIFF)
     #aiChannel = None
     self.publisher = ZmqPublisher(origin='FieldCoilBiasDAQ', port=PubSub.FieldCoilBiasDAQ)
     Battery.__init__(self, aoChannel, aiChannel)
Пример #6
0
    def _startupReadback(self, deviceName, aiChannel):
        ai = daq.AiChannel('%s/%s' % (deviceName,aiChannel), -10, 10)
        itask = daq.AiTask('MagnetControl_Input')
        itask.addChannel(ai)
        itask.start()   # No timing necessary for on-demand tasks
        Vai = itask.readData(1000)[0]
        itask.stop()

        Vreadback = np.mean(Vai)
        VaiStd = np.std(Vai)
        if VaiStd > 2E-3:
            logger.warn('High std. deviation on voltage read-back: %.5g V' % VaiStd)
        return Vreadback
Пример #7
0
    def __init__(self, deviceName, aoChannel, aiChannel, minVoltage=-2.0, maxVoltage=0, continuousReadback = True):
        self.Vreadback = None
        self.Vcommand = None
        self.dev = daq.Device(deviceName)
        self.ao = daq.AoChannel('%s/%s' % (deviceName,aoChannel), minVoltage, maxVoltage)
        self.otask = daq.AoTask('MagnetControl_Output')
        self.otask.addChannel(self.ao)
        self.otask.start()   # No timing necessary for on-demand tasks

        if continuousReadback:
            self.ai = daq.AiChannel('%s/%s' % (deviceName,aiChannel), -10, 10)
            self.itask = daq.AiTask('MagnetControl_Input')
            self.itask.addChannel(self.ai)
            self.itask.start()   # No timing necessary for on-demand tasks
        else:
            self.itask = None
            self.Vcommand = self._startupReadback(deviceName, aiChannel)
Пример #8
0
def wait(seconds):
    t0 = time.time()
    while time.time() - t0 < seconds - 2:
        app.processEvents()
        time.sleep(1)
    app.processEvents()
    while time.time() - t0 < seconds:
        time.sleep(0.1)


if __name__ == '__main__':
    import logging
    logger = logging.getLogger('')
    logger.setLevel(logging.INFO)
    aiChannel = daq.AiChannel('USB6361/ai5', -10, +10)
    baseTs = np.logspace(np.log10(0.055), np.log10(1.300), 71)
    print('Temperatures:', baseTs)
    device = 'TES2'
    Cfbs = [1.5E-9]

    origin = 'NoiseVdTemperature'
    app = QApplication([])
    hdfFile = hdf.File('NoiseVsT_%s_20180130.h5' % device)
    hdfFile.attrs['program'] = origin
    hdfFile.attrs['Control'] = 'RuOx2005'
    hdfFile.attrs['Device'] = device
    hdfFile.attrs['aiChannel'] = str(aiChannel.physicalChannel)
    hdfFile.attrs['Ts'] = baseTs

    hkGroup = hdfFile.require_group('HK')
Пример #9
0
outputFileName = biasPointFileName + '_' + startTimeString + '.h5'
df = pd.DataFrame.from_csv(biasPointFileName)

#df = df[df.Tbase >= 0.140]
#df = df[df.Tbase > 0.065]
#df = df[(df.Vcoil >= 0.4) | (df.Tbase >= 0.08)]

print(df)
reply = raw_input('Continue?')

origin = 'Tes_MapTransferAndNoise'

biasChannel = daq.AoChannel('USB6361/%s' % 'ao0', -5, +5)
acBiasChannel = daq.AoChannel('USB6361/%s' % 'ao1', -5, +5)
pflChannel = daq.AiChannel('USB6361/%s' % pflChannelId, -5, +5)

tes = obtainTes(cooldown, deviceId)

tesDev = Tes(tes.Rbias, biasChannel, fieldChannel=None, pflChannel=pflChannel)
tesDev.setBias(0)
IbiasNormal = 4.5 / tes.Rbias

coil = FieldCoil()

app = QApplication([])
adr = Adr(app)

ivRemote = IvCurveDaqRemote('TesIcVsB')
osr = OpenSquidRemote(port=7894, origin=origin)
squid = Pfl102Remote(osr, deviceId)
Пример #10
0
    def run(self):            
        self.stopRequested = False
        hwm = 3 # Half-water mark (i.e. the number of chunks we try to keep buffered)
        try:
            queue = Queue.Queue()
            self.__logger.debug('Producer starting')
            d = daq.Device(self.deviceName)
            chunkSize = self.chunkSize
            timing = daq.Timing(rate = self.sampleRate, samplesPerChannel = chunkSize)
            timing.setSampleMode(timing.SampleMode.CONTINUOUS)

            aoChannel = daq.AoChannel('%s/%s' % (self.deviceName, self.aoChannel), self.aoRange.min, self.aoRange.max)
            aiChannel = daq.AiChannel('%s/%s' % (self.deviceName, self.aiChannel), self.aiRange.min, self.aiRange.max)
            aiChannel.setTerminalConfiguration(self.aiTerminalConfig)
                
            aoTask = daq.AoTask('MultiToneAO')
            aoTask.addChannel(aoChannel)
            aoTask.configureTiming(timing)
            aoTask.configureOutputBuffer((2*hwm)*chunkSize)
            aoTask.disableRegeneration()
            if 'ai/StartTrigger' in d.findTerminals():
                aoTask.digitalEdgeStartTrigger('/%s/ai/StartTrigger' % self.deviceName) # The cheap USB DAQ doesn't support this?!
                self.__logger.info("Configured digital edge start trigger for aoTask")
            aoTask.setUsbTransferRequestSize('%s/%s' % (self.deviceName, self.aoChannel), 2**16)
            
            aiTask = daq.AiTask('MultiToneAI')
            aiTask.addChannel(aiChannel)
            aiTask.configureInputBuffer((2*hwm)*chunkSize)
            aiTask.configureTiming(timing)
            aiTask.setUsbTransferRequestSize('%s/%s' % (self.deviceName, self.aiChannel), 2**16)
            aiTask.commit()
            aoTask.commit()
            decimator = DecimatorCascade(self.inputDecimation, self.chunkSize) # Set up cascade of half-band decimators before the lock-in stage
            chunkNumber = 0
            chunkTime = float(chunkSize/self.sampleRate)
            self.__logger.info("Chunk size: %d", self.chunkSize)
            self.__logger.debug("Chunk time: %f s" , chunkTime)
            started = False
            tStart = time.time() + hwm * chunkTime # Fictitious future start time
            while not self.stopRequested:
                if queue.qsize() < hwm: # Need to generate more samples
                    offset, amplitudes, wave = self.generator.generateSamples()
                    t = tStart+chunkNumber*chunkTime # Time of first sample in the chunk
                    queue.put((offset, amplitudes, t))
                    aoTask.writeData(wave); chunkNumber += 1
                    self.chunkProduced.emit(chunkNumber, t)
                elif not started: # Need to start the tasks
                    self.__logger.debug("Starting aoTask")
                    aoTask.start(); t = time.time()
                    self.__logger.debug("Starting aiTask")
                    aiTask.start()
                    started = True
                if aiTask.samplesAvailable() >= chunkSize: # Can process data
                    tAcquired = time.time()
                    data = aiTask.readData(chunkSize)
                    d = data[0]
                    minimum = np.min(d); maximum = np.max(d); mean = np.sum(d)/d.shape[0]; std = np.std(d)
                    overload = maximum > self.aiRange.max or minimum < self.aiRange.min
                    if overload:
                        #self.__logger.info("Overload")
                        bad = (d>self.aiRange.max) | (d<self.aiRange.min)
                        nBad = np.count_nonzero(bad)
                        self.__logger.info("Input overload detected for %d samples", nBad)
                        self.inputOverload.emit()
                    samples = decimator.decimate(d)
                    offset, amplitudes, tGenerated = queue.get()
                    #print('Offset', offset,'Amplitudes', amplitudes)
                    self.dataReady.emit(samples, np.asarray([tGenerated, tAcquired, minimum, maximum, mean, std, offset]), amplitudes)

        except Exception:
            exceptionString = traceback.format_exc()
            self.__logger.exception('Exception in DaqThread')
            self.error.emit(exceptionString)
        finally:
            del d
            aoTask = daq.AoTask('ReturnToZero')
            aoTask.addChannel(aoChannel)
            aoTask.writeData([0], autoStart = True)
            self.__logger.info("DAQ AO set to zero.")
Пример #11
0
    def run(self):
        self.stopRequested = False
        self.abortRequested = False
        chunkSize = 2**16
        preLoads = 6
        try:
            d = daq.Device(self.deviceName)
            timing = daq.Timing(rate = self.sampleRate, samplesPerChannel = chunkSize)
            timing.setSampleMode(timing.SampleMode.CONTINUOUS)

            aoChannel = daq.AoChannel('%s/%s' % (self.deviceName, self.aoChannel), self.aoRange.min, self.aoRange.max)
            aiChannel = daq.AiChannel('%s/%s' % (self.deviceName, self.aiChannel), self.aiRange.min, self.aiRange.max)
            #print 'Ai terminal config', self.aiTerminalConfig, type(self.aiTerminalConfig)
            aiChannel.setTerminalConfiguration(self.aiTerminalConfig)
            sampleRate = self.sampleRate
            
            for fGoal, settlePeriods, measurePeriods in zip(self.fGoals, self.settlePeriods, self.measurePeriods):
                if self.stopRequested:
                    break
                measureSamples = int(np.round(measurePeriods*sampleRate/fGoal)) # Figure out how many samples
                f = measurePeriods*sampleRate/measureSamples# Now the correct frequency for that number of samples
                #fs.append(f)
                phaseStep = TwoPi*f/sampleRate
                settleSamples = int(sampleRate * settlePeriods/f)
                startPhase = - settleSamples*phaseStep
                totalSamples = settleSamples + measureSamples
                print("fGoal, f, periods, phaseStep, settle samples, measure samples, total samples", fGoal, f, measurePeriods, phaseStep, settleSamples, measureSamples, totalSamples)
                g = SineWaveformGenerator(amplitude=self.amplitude, offset=self.offset, phaseStep=phaseStep, startingPhase=startPhase)
                g.setNumberOfSamples(totalSamples)
                
                aoTask = daq.AoTask('AO')
                aoTask.addChannel(aoChannel)
                aoTask.configureTiming(timing)
                aoTask.configureOutputBuffer(preLoads*chunkSize)
                aoTask.disableRegeneration()
                if 'ai/StartTrigger' in d.findTerminals():
                    aoTask.digitalEdgeStartTrigger('/%s/ai/StartTrigger' % self.deviceName) # The cheap USB DAQ doesn't support this?!

                samplesRead = 0
                
                aiTask = daq.AiTask('AI')
                aiTask.addChannel(aiChannel)
                aiTask.configureTiming(timing)
                phaseSet = []    
                for i in range(preLoads):
                    phases, wave = g.generateSamples(chunkSize)
                    if wave is not None:
                        phaseSet.append(phases)
                        aoTask.writeData(wave)
                aiTask.setUsbTransferRequestSize(aiChannel.physicalChannel, 2*chunkSize)
                aoTask.setUsbTransferRequestSize(aoChannel.physicalChannel, 2*chunkSize)
                #print('Chunksize:', chunkSize)
                        
                aoTask.start()
                aiTask.start()
                while not self.stopRequested:
                    phases, wave = g.generateSamples(chunkSize)
                    if wave is not None:
                        aoTask.writeData(wave)
                        phaseSet.append(phases)
                
                    samplesRemaining = totalSamples-samplesRead
                    if samplesRemaining > 0:
                        data = aiTask.readData(min(chunkSize, samplesRemaining))
                        samples = data[0]
                        nNewSamples = len(samples)
                        samplesRead += nNewSamples
                        phases = phaseSet.pop(0)
                        #print(phases.shape, len(phaseSet))
                        if samplesRead <= settleSamples:
                            pass
                        elif samplesRead > settleSamples+chunkSize: # Entire chunk is good
                            self.waveformAvailable.emit(phases, samples)
                        elif samplesRead > settleSamples: # Special case for first chunk
                            i = settleSamples - samplesRead
                            self.waveformAvailable.emit(phases[i:], samples[i:])
                    else:
                        break
                del aiTask; aiTask = None
                del aoTask; aoTask = None
                if g.samplesGenerated != totalSamples:
                    warnings.warn('Not all samples were generated')
#                if lia.nSamples != measureSamples:
#                    warnings.warn('Did not record expected number of samples')
                phase, V = g.nextSample()
                
                aoTask = daq.AoTask('AO_Final') # Now write one last sample that is back at the offset
                aoTask.addChannel(aoChannel)
                aoTask.writeData(V, autoStart = True)
                if abs(V[0]-self.offset) > 1E-3:
                    warnings.warn('Output and end was not zero as expected.')
                t = time.time()
                self.waveformComplete.emit(t, f)                           

        except Exception:
            exceptionString = traceback.format_exc()
            self.error.emit(exceptionString)
        finally:
            del d
Пример #12
0
    def doWork(self):
        aiChannel = daq.AiChannel('USB6361/AI2', -1, +1)
        aoChannel1 = daq.AoChannel('USB6361/AO0', -5, +5)
        aoChannel2 = daq.AoChannel('USB6361/AO1', -5, +5)

        Mi = self.Mi
        Mfb = self.Mfb
        Rfb = self.Rfb
        gCoil = self.gCoil
        Rcoil = self.Rcoil
        Ap = self.Ap
        Rbias = self.Rbias
        Rs = self.Rs

        aiTask = daq.AiTask('SQUID read-out')
        aiChannel.setTerminalConfiguration(
            aiChannel.TerminalConfiguration.DIFF)
        aiTask.addChannel(aiChannel)
        aiTask.start()

        aoTask = daq.AoTask('Control')
        aoTask.addChannel(aoChannel1)
        aoTask.addChannel(aoChannel2)
        aoTask.start()
        Vo = 0
        Vcoil = 0
        Vbias = limit(Rbias * self._Ibias)
        VoHistory = []
        aoTask.writeData([Vbias, Vcoil])
        while not self._stopRequested:
            Vsq = np.mean(aiTask.readData(self.nSamples)[0])
            if Vbias == 0:
                VoHistory.append(Vsq)
                VoHistory = pruneData(VoHistory)
                Vo = np.mean(VoHistory)
            else:
                VoHistory = []
            t = time.time()
            #print Mi, Mfb, Mi/Mfb, Mfb/Mi
            Ites = (1. / Mi) * Mfb * (Vsq -
                                      Vo) / Rfb - gCoil * Vcoil * Ap / Rcoil
            Ibias = Vbias / Rbias
            if Ites == 0:
                Rtes = np.nan
            else:
                Rtes = (Ibias - Ites) / Ites * Rs
            self.measurementAvailable.emit(t, Vbias, Vcoil, Vo, Vsq, Ites,
                                           Rtes)

            # Calculate new target Vcoil and Vbias
            Vcoil = limit(Rcoil / gCoil * (self.Bo - self.gTes * Ites))
            if self._controlTesCurrent:
                IbiasTarget = (1. + Rtes / Rs) * Ites
                Vbias = limit(Rbias * IbiasTarget)
                self._Ibias = Vbias / Rbias
            else:
                Vbias = limit(Rbias * self._Ibias)
            aoTask.writeData([Vbias, Vcoil])
            self.msleep(10)
        if self.disableBias:
            aoTask.writeData([0, 0])
        aoTask.stop()
        aiTask.stop()
Пример #13
0
    def run(self):
        self.sweepCount = 0
        self.stopRequested = False
        self.abortRequested = False
        try:
            d = daq.Device(self.deviceName)
            d.findTerminals()
            nSamples = len(self.wave)
            timing = daq.Timing(rate=self.sampleRate,
                                samplesPerChannel=nSamples)
            timing.setSampleMode(timing.SampleMode.FINITE)
            dt = 1. / self.sampleRate
            print "Samples:", len(self.wave)

            aoChannel = daq.AoChannel(
                '%s/%s' % (self.deviceName, self.aoChannel), self.aoRange.min,
                self.aoRange.max)
            aoTask = daq.AoTask('AO')
            aoTask.addChannel(aoChannel)
            aoTask.configureTiming(timing)
            #aoTask.configureOutputBuffer(2*len(self.wave))
            aoTask.digitalEdgeStartTrigger(
                '/%s/ai/StartTrigger' %
                self.deviceName)  # The cheap USB DAQ doesn't support this?!

            if self.aiDriveChannel is not None:  # Record drive signal on a different AI channel first
                aiChannel = daq.AiChannel(
                    '%s/%s' % (self.deviceName, self.aiDriveChannel),
                    self.aoRange.min, self.aoRange.max)
                aiChannel.setTerminalConfiguration(self.aiTerminalConfig)
                aiTask = daq.AiTask('AI')
                aiTask.addChannel(aiChannel)
                aiTask.configureTiming(timing)
                aoTask.writeData(self.wave)
                aoTask.start()
                aiTask.start()
                t = time.time()  # Time of the start of the sweep
                while aiTask.samplesAvailable(
                ) < nSamples and not self.abortRequested:
                    self.msleep(10)

                data = aiTask.readData(nSamples)
                self.driveDataReady.emit(t, dt, data[0])
                aiTask.stop()
                try:
                    aoTask.stop()
                except:
                    pass
                del aiTask
                del aiChannel

            aiChannel = daq.AiChannel(
                '%s/%s' % (self.deviceName, self.aiChannel), self.aiRange.min,
                self.aiRange.max)
            aiChannel.setTerminalConfiguration(self.aiTerminalConfig)
            aiTask = daq.AiTask('AI')
            aiTask.addChannel(aiChannel)
            aiTask.configureTiming(timing)
            import sys
            #print('Before DAQ loop:',sys.getrefcount(self.wave))
            while not self.stopRequested:
                if self.auxAoRamper is not None:
                    self.auxAoRamper.rampTo(self.newAuxAoVoltage)
                    VauxAo = self.auxAoRamper.voltage()
                else:
                    VauxAo = 0

                aoTask.writeData(self.wave)
                #print('After DAQ write:',sys.getrefcount(self.wave))
                if self.squid is not None:
                    print "Resetting SQUID:",
                    self.squid.resetPfl()
                    print "Done"
                    self.msleep(100)
                aoTask.start()
                aiTask.start()
                t = time.time()  # Time of the start of the sweep
                while aiTask.samplesAvailable(
                ) < nSamples and not self.abortRequested:
                    self.msleep(10)

                data = aiTask.readData(nSamples)
                self.dataReady.emit(t, VauxAo, dt, data[0])
                self.sweepCount += 1
                aiTask.stop()
                try:
                    aoTask.stop()
                except:
                    pass
            #print('Before wave delete:',sys.getrefcount(self.wave))
            del self.wave  # Not sure why this is needed, but get's rid of our giant memory leak.
            #print('After wave delete:',sys.getrefcount(self.wave))
            aiTask.clear()
            aoTask.clear()

        except Exception:
            exceptionString = traceback.format_exc()
            self.error.emit(exceptionString)
        finally:
            del d