Exemple #1
0
def runNoiseExp(appObj, testMode=False):
    print("runNoiseExp")
    appObj.tabWidget.setCurrentIndex(5)
    appObj.doneFlag = False
    appObj.isCollecting = True
    # trigRate = octfpga.GetTriggerRate()
    audioHW = appObj.audioHW
    outputRate = audioHW.DAQOutputRate
    inputRate = audioHW.DAQInputRate

    cutoffLow = 1e3 * appObj.noiseExp_filterLow_dblSpinBox.value()
    cutoffHigh = 1e3 * appObj.noiseExp_filterHigh_dblSpinBox.value()
    durationMins = appObj.noiseExp_duration_dblSpinBox.value()
    durationSecs = durationMins * 60

    try:
        if not testMode:
            from DAQHardware import DAQHardware
            daq = DAQHardware()

        chanNamesIn = [audioHW.mic_daqChan]
        micVoltsPerPascal = audioHW.micVoltsPerPascal
        # mode = 'chirp'

        # make 1 second of noise
        nOut = outputRate * 1
        magResp = np.zeros(nOut)
        fIdx1 = int(nOut * cutoffLow / outputRate)
        fIdx2 = int(nOut * cutoffHigh / outputRate)
        magResp[fIdx1:fIdx2] = 1
        phaseResp = 2 * np.pi * np.random.rand(nOut) - np.pi
        sig = magResp * np.exp(-1j * phaseResp)
        spkOut = np.real(np.fft.ifft(sig))
        mx = np.max(spkOut)
        mn = np.min(spkOut)
        # normalies signal to be between -1 and 1
        spkOut = 2 * (spkOut - mn) / (mx - mn) - 1

        maxV = audioHW.speakerOutputRng[1]
        spkOut = maxV * spkOut

        pl = appObj.spCalTest_output
        pl.clear()
        #endIdx = int(5e-3 * outputRate)        # only plot first 5 ms
        npts = len(spkOut)
        endIdx = npts
        t = np.linspace(0, npts / outputRate, npts)
        pl.plot(t[0:endIdx], spkOut[0:endIdx], pen='b')

        numInputSamples = int(inputRate * 0.1)

        if testMode:
            # mic_data = OCTCommon.loadRawData(testDataDir, frameNum, dataType=3)
            pass
        else:
            chanNameOut = audioHW.speakerL_daqChan
            attenLines = audioHW.attenL_daqChan
            attenLinesOther = audioHW.attenR_daqChan

            if not testMode:
                AudioHardware.Attenuator.setLevel(0, attenLines)
                AudioHardware.Attenuator.setLevel(60, attenLinesOther)

            # setup the output task
            daq.setupAnalogOutput([chanNameOut],
                                  audioHW.daqTrigChanIn,
                                  int(outputRate),
                                  spkOut,
                                  isContinuous=True)
            daq.startAnalogOutput()

            # trigger the acquiisiton by sending ditital pulse
            daq.sendDigTrig(audioHW.daqTrigChanOut)

        tElapsed = 0
        tLast = time.time()
        npts = numInputSamples
        t = np.linspace(0, npts / inputRate, npts)

        while tElapsed < durationSecs:
            if not testMode:
                # setup the input task
                daq.setupAnalogInput(chanNamesIn, audioHW.daqTrigChanIn,
                                     int(inputRate), numInputSamples)
                daq.startAnalogInput()

                # trigger the acquiisiton by sending ditital pulse
                daq.sendDigTrig(audioHW.daqTrigChanOut)

                daq.waitDoneInput()

                mic_data = daq.readAnalogInput()
                mic_data = mic_data[0, :]

                daq.stopAnalogInput()
                daq.clearAnalogInput()
            else:
                mic_data = np.random.rand(numInputSamples)

            mic_data = mic_data / micVoltsPerPascal

            pl = appObj.spCalTest_micInput
            pl.clear()
            pl.plot(t, mic_data, pen='b')

            labelStyle = appObj.xLblStyle
            pl.setLabel('bottom', 'Time', 's', **labelStyle)
            labelStyle = appObj.yLblStyle
            pl.setLabel('left', 'Response', 'Pa', **labelStyle)

            # calculate RMS
            nMicPts = len(mic_data)
            micRMS = np.mean(mic_data**2)
            micRMS = 20 * np.log10(micRMS**0.5 / 2e-5)
            appObj.spCalTest_rms_label.setText("%0.3f dB" % micRMS)

            nfft = int(2**np.ceil(np.log(nMicPts * 5) / np.log(2)))
            print("nfft = ", nfft)
            win_fcn = np.hanning(nMicPts)
            micFFT = 2 * np.abs(np.fft.fft(win_fcn * mic_data, nfft)) / nMicPts
            micFFT = 2 * micFFT[0:len(micFFT) // 2]
            micFFT = 20 * np.log10(micFFT / 2e-5)
            freq = np.linspace(0, inputRate / 2, len(micFFT))
            pl = appObj.spCalTest_micFFT
            pl.clear()
            #df = freq[1] - freq[0]
            #print("NoiseExp: df= %0.3f i1= %d i2= %d nf= %d" % (df, i1, i2, nf))
            pl.plot(freq, micFFT, pen='b')
            labelStyle = appObj.xLblStyle
            pl.setLabel('bottom', 'Frequency', 'Hz', **labelStyle)
            labelStyle = appObj.yLblStyle
            pl.setLabel('left', 'Magnitude', 'db SPL', **labelStyle)

            QtGui.QApplication.processEvents(
            )  # check for GUI events, such as button presses

            # if done flag, break out of loop
            if appObj.doneFlag:
                break

            t1 = time.time()
            tElapsed += (t1 - tLast)
            tLast = t1

        if not testMode:
            daq.stopAnalogOutput()
            daq.clearAnalogOutput()

    except Exception as ex:
        traceback.print_exc(file=sys.stdout)
        QtGui.QMessageBox.critical(
            appObj, "Error",
            "Error during calibration. Check command line output for details")

    8  # update the audio hardware speaker calibration
    appObj.isCollecting = False
    QtGui.QApplication.processEvents(
    )  # check for GUI events, such as button presses
    appObj.finishCollection()
Exemple #2
0
def calibrateClick(appObj, testMode=False):
    print("ABR.calibrateClick")
    
    appObj.tabWidget.setCurrentIndex(3)
    appObj.doneFlag = False
    appObj.isCollecting = True
    # trigRate = octfpga.GetTriggerRate()
    audioHW = appObj.audioHW
    outputRate = audioHW.DAQOutputRate
    inputRate = audioHW.DAQInputRate

    # freq_array2 = audioParams.freq[1, :]
    freqArray = appObj.getFrequencyArray()
    
    if testMode:
        testDataDir = os.path.join(appObj.basePath, 'exampledata', 'Speaker Calibration')
#        filePath = os.path.join(testDataDir, 'AudioParams.pickle')
#        f = open(filePath, 'rb')
#        audioParams = pickle.load(f)
#        f.close()
    else:
        pass

    # numSpk = audioParams.getNumSpeakers()
    if not testMode:
        from DAQHardware import DAQHardware
        daq = DAQHardware()

    chanNamesIn= [ audioHW.mic_daqChan]
    micVoltsPerPascal = audioHW.micVoltsPerPascal
    ABRparams = ABRParams(appObj)
    ABRparams.click = True
    ABRparams.nReps = 20
    print("ABR.calibrateClick ABRparams=", ABRparams.__dict__)
    # set input rate to three times the highest output frequency, to allow plus a 
    
#    inputRate = 3*freqArray[-1]
#    print("runABR: outputRate= ", outputRate, " inputRate= ", inputRate)
#    inputRate = np.max((inputRate, 6e3))   # inpute rate should be at least 6 kHz because ABR responses occur 0.3 - 3 kHz
#    inputRate = outputRate / int(np.floor(outputRate / inputRate))  # pick closest input rate that evenly divides output rate
#    print("runABR: inputRate(final)= ", inputRate)
    
    try:
        chanNameOut = audioHW.speakerL_daqChan 
        attenLines = audioHW.attenL_daqChan
        
        spkOut_trial = makeABROutput(4e3, ABRparams, audioHW)
        spkOut = np.tile(spkOut_trial, ABRparams.nReps)
        npts = len(spkOut_trial)
        tOut = np.linspace(0, npts/outputRate, npts)
            
        # attenSig = AudioHardware.makeLM1972AttenSig(0)
        if not testMode:
            AudioHardware.Attenuator.setLevel(0, attenLines)
                
        pl = appObj.ABR_output
        pl.clear()
        endIdx = int(5e-3 * outputRate)        # only plot first 5 ms
        #pl.plot(t[0:endIdx], spkOut[0:endIdx], pen='b')
        pl.plot(tOut, spkOut_trial, pen='b')
                
        labelStyle = appObj.xLblStyle
        pl.setLabel('bottom', 'Time', 's', **labelStyle)
        labelStyle = appObj.yLblStyle
        pl.setLabel('left', 'Output', 'V', **labelStyle)
                
        numInputSamples = int(inputRate*len(spkOut)/outputRate)
        
        if testMode:
            # mic_data = OCTCommon.loadRawData(testDataDir, frameNum, dataType=3)                    
            pass
        else:
            # setup the output task
            daq.setupAnalogOutput([chanNameOut], audioHW.daqTrigChanIn, int(outputRate), spkOut)
            daq.startAnalogOutput()
            
            # setup the input task
            daq.setupAnalogInput(chanNamesIn, audioHW.daqTrigChanIn, int(inputRate), numInputSamples) 
            daq.startAnalogInput()
        
            # trigger the acquiisiton by sending ditital pulse
            daq.sendDigTrig(audioHW.daqTrigChanOut)
            
            timeout = numInputSamples/inputRate + 2
            dataIn = daq.readAnalogInput(timeout)
            mic_data = dataIn[0, :]
            
            mic_data = mic_data/micVoltsPerPascal
        
            daq.waitDoneInput()
            daq.stopAnalogInput()
            daq.clearAnalogInput()
            
            daq.waitDoneOutput(stopAndClear=True)
        
        print("ABR.calibrateClick: plotting data")
        npts = len(mic_data)
        
        # reshape and average the mic data
        ptsPerRep = npts // ABRparams.nReps
        mic_data = np.reshape(mic_data, (ABRparams.nReps, ptsPerRep))
        mic_data = np.mean(mic_data, 0)
        
        # plot mic data
        npts = len(mic_data)
        t = np.linspace(0, npts/inputRate, npts)
        pl = appObj.ABR_micInput
        pl.clear()
        pl.plot(t, mic_data, pen='b')
        
        labelStyle = appObj.xLblStyle
        pl.setLabel('bottom', 'Time', 's', **labelStyle)
        labelStyle = appObj.yLblStyle
        pl.setLabel('left', 'Response', 'Pa', **labelStyle)
        
        idx1 = round(inputRate*ABRparams.stimOffset)
        idx2 = idx1 + round(inputRate*ABRparams.stimDur)
        
        mic_data = mic_data[idx1:idx2] 
        # apply high pass filter to get rid of LF components
#        (b, a) = scipy.signal.butter(5, 100/inputRate, 'high')
#        mic_data = scipy.signal.lfilter(b, a, mic_data) 

        rms = np.mean(mic_data ** 2) ** 0.5
        rms = 20*np.log10(rms/2e-5)
        appObj.ABRclick_RMS = rms
        
        appObj.ABR_rms_label.setText("%0.1f dB" % rms)
        print("ABR.calibrateClick: RMS= ", rms)
        
    except Exception as ex:
        traceback.print_exc(file=sys.stdout)
        QtGui.QMessageBox.critical (appObj, "Error", "Error during collection. Check command line output for details")           
        
    appObj.isCollecting = False
    QtGui.QApplication.processEvents() # check for GUI events, such as button presses
    appObj.finishCollection()
Exemple #3
0
def runABR(appObj, testMode=False):
    print("runABR")
    
    appObj.tabWidget.setCurrentIndex(3)
    appObj.doneFlag = False
    appObj.isCollecting = True
    # trigRate = octfpga.GetTriggerRate()
    audioHW = appObj.audioHW
    bioamp = appObj.bioamp
    outputRate = audioHW.DAQOutputRate
    inputRate = audioHW.DAQInputRate

    # freq_array2 = audioParams.freq[1, :]
    freqArray = appObj.getFrequencyArray()
    ABRparams = ABRParams(appObj)
    
    if testMode:
        testDataDir = os.path.join(appObj.basePath, 'exampledata', 'Speaker Calibration')
#        filePath = os.path.join(testDataDir, 'AudioParams.pickle')
#        f = open(filePath, 'rb')
#        audioParams = pickle.load(f)
#        f.close()
    else:
        # freqArray = appObj.getFrequencyArray()
        i1 = appObj.ABR_freqLow_comboBox.currentIndex()
        i2 = appObj.ABR_freqHigh_comboBox.currentIndex()
        print("runABR: i1= ", i1, "i2= ", i2)
        ampLow = appObj.ABRampLow_spinBox.value()
        ampHigh = appObj.ABRampHigh_spinBox.value()
        ampDelta = appObj.ABRampDelta_spinBox.value()
        
        # ampArray = np.arange(ampLow, ampHigh, ampDelta)
        #numSteps = np.floor((ampHigh - ampLow)/ampDelta) + 1
        #ampArray = np.linspace(ampLow, ampHigh, numSteps)
        if ampLow == ampHigh:
            ampArray = np.array([ampLow])
        else:
            ampArray = np.arange(ampLow, ampHigh, ampDelta)
            if ampArray[-1] != ampHigh:
                ampArray = np.hstack((ampArray, ampHigh))
        
        freqArray = freqArray[i1:i2+1]
    
    if ABRparams.click:
        freqArray = freqArray[0:1]  # only use single freqeucny
        clickRMS = appObj.ABRclick_RMS
        
    # numSpk = audioParams.getNumSpeakers()
    if not testMode:
        from DAQHardware import DAQHardware
        daq = DAQHardware()

    chanNamesIn= [ audioHW.mic_daqChan, bioamp.daqChan]
    micVoltsPerPascal = audioHW.micVoltsPerPascal
    
    

    # set input rate to three times the highest output frequency, to allow plus a 
    
#    inputRate = 3*freqArray[-1]
#    print("runABR: outputRate= ", outputRate, " inputRate= ", inputRate)
#    inputRate = np.max((inputRate, 6e3))   # inpute rate should be at least 6 kHz because ABR responses occur 0.3 - 3 kHz
#    inputRate = outputRate / int(np.floor(outputRate / inputRate))  # pick closest input rate that evenly divides output rate
#    print("runABR: inputRate(final)= ", inputRate)
    
    try:
        frameNum = 0
        numFrames = len(freqArray)*len(ampArray)
        isSaveDirInit = False
        chanNameOut = audioHW.speakerL_daqChan 
        attenLines = audioHW.attenL_daqChan
        
        freq_idx = 0
        ABRdata = None
        appObj.status_label.setText("Running")
        appObj.progressBar.setValue(0)
        
        for freq in freqArray:
            spkOut_trial = makeABROutput(freq, ABRparams, audioHW)
            npts = len(spkOut_trial)
            spkOut = np.tile(spkOut_trial, ABRparams.nReps)
            # invert every other trial, necessary for ABR/CAP output 
            for n in range(1, ABRparams.nReps, 2):
                idx1 = n*npts
                idx2 = (n+1)*npts
                spkOut[idx1:idx2] = -spkOut[idx1:idx2]
#            plt.figure(5)
#            plt.clf()
#            plt.plot(spkOut)
            tOut = np.linspace(0, npts/outputRate, npts)
            print("runABR npts=%d len(spkOut_trial)= %d len(tOut)= %d" % (npts, len(spkOut_trial), len(tOut)))
            amp_idx = 0
            ptsPerRep = int(inputRate*ABRparams.trialDur)
            
            for amp in ampArray:
                print("runABR freq=" + repr(freq), " amp= ", + amp, " freq_idx= ", freq_idx, " amp_idx= ", amp_idx)
                if ABRparams.click:
                    clickRMS = appObj.ABRclick_RMS
                    attenLvl = 0
                    vOut = 10**((amp - clickRMS)/20)
                    minV = audioHW.speakerOutputRng[0]
                    if vOut < minV:
                        attenLvl = int(round(20*np.log10(minV/vOut)))
                        vOut = minV
                else:
                    vOut, attenLvl = audioHW.getCalibratedOutputVoltageAndAttenLevel(freq, amp, 0)
                
                print("runABR vOut= ", vOut, " atenLvl=", attenLvl)
                
                if vOut > audioHW.speakerOutputRng[1]:
                    print("runABR vOut= ", vOut, "  out of range")
                    continue
                elif attenLvl > audioHW.maxAtten:
                    print("runABR attenLvl= ", attenLvl, "  gerater than maximum attenuation")
                    continue
                    
                # attenSig = AudioHardware.makeLM1972AttenSig(0)
                if not testMode:
                    AudioHardware.Attenuator.setLevel(attenLvl, attenLines)
                    # daq.sendDigOutABRd(attenLines, attenSig)
                    # appObj.oct_hw.SetAttenLevel(0, attenLines)
                
                pl = appObj.ABR_output
                pl.clear()
                endIdx = int(5e-3 * outputRate)        # only plot first 5 ms
                #pl.plot(t[0:endIdx], spkOut[0:endIdx], pen='b')
                pl.plot(tOut, spkOut_trial, pen='b')
                
                labelStyle = appObj.xLblStyle
                pl.setLabel('bottom', 'Time', 's', **labelStyle)
                labelStyle = appObj.yLblStyle
                pl.setLabel('left', 'Output', 'V', **labelStyle)
                
                numInputSamples = ABRparams.nReps*int(inputRate*len(spkOut_trial)/outputRate)
                
                if testMode:
                    # mic_data = OCTCommon.loadRawData(testDataDir, frameNum, dataType=3)                    
                    pass
                else:
    
                    # setup the output task
                    daq.setupAnalogOutput([chanNameOut], audioHW.daqTrigChanIn, int(outputRate), vOut*spkOut)
                    daq.startAnalogOutput()
                    
                    # setup the input task
                    daq.setupAnalogInput(chanNamesIn, audioHW.daqTrigChanIn, int(inputRate), numInputSamples) 
                    daq.startAnalogInput()
                
                    # trigger the acquiisiton by sending ditital pulse
                    daq.sendDigTrig(audioHW.daqTrigChanOut)
                    
                    timeout = numInputSamples/inputRate + 2
                    dataIn = daq.readAnalogInput(timeout)
                    mic_data = dataIn[0, :]
                    bioamp_data = dataIn[1, :]
                    
                    mic_data = mic_data/micVoltsPerPascal
                    bioamp_data = bioamp_data/bioamp.gain
                
                    daq.waitDoneInput()
                    daq.stopAnalogInput()
                    daq.clearAnalogInput()
                    
                    daq.waitDoneOutput(stopAndClear=True)
                
#                npts = len(mic_data)
#                t = np.linspace(0, npts/inputRate, npts)
#                pl = appObj.ABR_micInput
#                pl.clear()
#                pl.plot(t, mic_data, pen='b')
#                
#                labelStyle = appObj.xLblStyle
#                pl.setLabel('bottom', 'Time', 's', **labelStyle)
#                labelStyle = appObj.yLblStyle
#                pl.setLabel('left', 'Response', 'Pa', **labelStyle)
    
    # def processABRData(mic_data, bioamp_data, nReps, freq, amp_idx, inputRate, ABRdataIn):            
                ABRptData, ABRdata = processABRData(mic_data, bioamp_data, freq, freq_idx, amp_idx, freqArray, ampArray, inputRate, ABRdata, ABRparams)

                print("runABR: plotting data")
                plotABRdata(appObj, ABRptData, ABRdata)
                
    #                if appObj.getSaveState():
    #                    if not isSaveDirInit:
    #                        saveDir = OCTCommon.initSaveDir(saveOpts, 'Speaker Calibration', audioParams=audioParams)
    #                        isSaveDirInit = True
    #    
    #                    if saveOpts.saveRaw:
    #                        OCTCommon.saveRawData(mic_data, saveDir, frameNum, dataType=3)
                idx1 = round(inputRate*ABRparams.stimOffset)
                idx2 = idx1 + round(inputRate*ABRparams.stimDur)
                
                mic_data = mic_data[idx1:idx2] 
                rms = np.mean(mic_data ** 2) ** 0.5
                rms = 20*np.log10(rms/2e-5)
                
                appObj.ABR_rms_label.setText("%0.1f dB" % rms)                    
                
                QtGui.QApplication.processEvents() # check for GUI events, such as button presses
                
                # if done flag, break out of loop
                if appObj.doneFlag:
                    break
                
                frameNum += 1
                amp_idx += 1
                appObj.progressBar.setValue(frameNum/numFrames)
                
            # if done flag, break out of loop
            if appObj.doneFlag:
                break
            
            freq_idx += 1


        saveOpts = appObj.getSaveOpts()
        workbook = appObj.excelWB
        note = saveOpts.note
        number = appObj.ABRnumber
        name = 'ABR'
        d = datetime.datetime.now()
        timeStr = d.strftime('%H_%M_%S')
        excelWS = CMPCommon.initExcelSpreadsheet(workbook, name, number, timeStr, note)
    
        appObj.ABRnumber += 1                
        #saveOpts.saveTracings = appObj.ABR_saveTracings_checkBox.isChecked()
        saveOpts.saveTracings = True
        saveDir = appObj.saveDir_lineEdit.text()
        saveABRDataXLS(ABRdata, ABRparams, excelWS, saveOpts)
        #saveABRData(ABRdata, trialDur, nReps, appObj.saveFileTxt_filepath, saveOpts, timeStr)
        
        plotName = 'ABR %d %s %s' % (number, timeStr, saveOpts.note)
        saveABRDataFig(ABRdata, ABRparams, saveDir, plotName, timeStr)
        saveABRDataPickle(ABRdata, ABRparams, plotName, saveOpts, timeStr)
            
    except Exception as ex:
        traceback.print_exc(file=sys.stdout)
        QtGui.QMessageBox.critical (appObj, "Error", "Error during collection. Check command line output for details")           
        
    # update the audio hardware speaker calibration                     
    appObj.isCollecting = False
    QtGui.QApplication.processEvents() # check for GUI events, such as button presses
    appObj.finishCollection()
Exemple #4
0
def runNoiseExp(appObj, testMode=False):
    print("runNoiseExp")
    appObj.tabWidget.setCurrentIndex(5)
    appObj.doneFlag = False
    appObj.isCollecting = True
    # trigRate = octfpga.GetTriggerRate()
    audioHW = appObj.audioHW
    outputRate = audioHW.DAQOutputRate
    inputRate = audioHW.DAQInputRate
    
    cutoffLow = 1e3*appObj.noiseExp_filterLow_dblSpinBox.value()
    cutoffHigh = 1e3*appObj.noiseExp_filterHigh_dblSpinBox.value()
    durationMins = appObj.noiseExp_duration_dblSpinBox.value()
    durationSecs = durationMins*60
    
    try:
        if not testMode:
            from DAQHardware import DAQHardware
            daq = DAQHardware()
    
        chanNamesIn= [ audioHW.mic_daqChan]
        micVoltsPerPascal = audioHW.micVoltsPerPascal
        # mode = 'chirp'
        
        # make 1 second of noise         
        nOut = outputRate*1  
        magResp = np.zeros(nOut)
        fIdx1 = int(nOut*cutoffLow/outputRate)
        fIdx2 = int(nOut*cutoffHigh/outputRate)
        magResp[fIdx1:fIdx2] = 1
        phaseResp = 2*np.pi*np.random.rand(nOut) - np.pi
        sig = magResp*np.exp(-1j*phaseResp)
        spkOut = np.real(np.fft.ifft(sig))
        mx = np.max(spkOut)
        mn = np.min(spkOut)
        # normalies signal to be between -1 and 1
        spkOut = 2*(spkOut - mn)/(mx - mn) - 1
        
        maxV = audioHW.speakerOutputRng[1]
        spkOut = maxV*spkOut
        
        pl = appObj.spCalTest_output
        pl.clear()
        #endIdx = int(5e-3 * outputRate)        # only plot first 5 ms
        npts = len(spkOut)
        endIdx = npts
        t = np.linspace(0, npts/outputRate, npts)
        pl.plot(t[0:endIdx], spkOut[0:endIdx], pen='b')
                
        numInputSamples = int(inputRate*0.1)
            
        if testMode:
            # mic_data = OCTCommon.loadRawData(testDataDir, frameNum, dataType=3)                    
            pass
        else:
            chanNameOut = audioHW.speakerL_daqChan 
            attenLines = audioHW.attenL_daqChan
            attenLinesOther = audioHW.attenR_daqChan
                        
            if not testMode:
                AudioHardware.Attenuator.setLevel(0, attenLines)
                AudioHardware.Attenuator.setLevel(60, attenLinesOther)
    
            # setup the output task
            daq.setupAnalogOutput([chanNameOut], audioHW.daqTrigChanIn, int(outputRate), spkOut, isContinuous=True)
            daq.startAnalogOutput()
    
            # trigger the acquiisiton by sending ditital pulse
            daq.sendDigTrig(audioHW.daqTrigChanOut)
        
        tElapsed = 0
        tLast = time.time()
        npts = numInputSamples
        t = np.linspace(0, npts/inputRate, npts)
    
        while tElapsed < durationSecs:
            if not testMode:
                # setup the input task
                daq.setupAnalogInput(chanNamesIn, audioHW.daqTrigChanIn, int(inputRate), numInputSamples) 
                daq.startAnalogInput()
            
                # trigger the acquiisiton by sending ditital pulse
                daq.sendDigTrig(audioHW.daqTrigChanOut)
                
                daq.waitDoneInput()
    
                mic_data = daq.readAnalogInput()
                mic_data = mic_data[0, :]
                
                daq.stopAnalogInput()
                daq.clearAnalogInput()
            else:
                mic_data = np.random.rand(numInputSamples)
                
            mic_data = mic_data/micVoltsPerPascal
            
            pl = appObj.spCalTest_micInput
            pl.clear()
            pl.plot(t, mic_data, pen='b')
            
            labelStyle = appObj.xLblStyle
            pl.setLabel('bottom', 'Time', 's', **labelStyle)
            labelStyle = appObj.yLblStyle
            pl.setLabel('left', 'Response', 'Pa', **labelStyle)

            # calculate RMS
            nMicPts = len(mic_data)
            micRMS = np.mean(mic_data**2)
            micRMS = 20*np.log10(micRMS**0.5/2e-5)
            appObj.spCalTest_rms_label.setText("%0.3f dB" % micRMS)            
            
            nfft = int(2**np.ceil(np.log(nMicPts*5)/np.log(2)))
            print("nfft = ", nfft)
            win_fcn = np.hanning(nMicPts)
            micFFT = 2*np.abs(np.fft.fft(win_fcn*mic_data, nfft))/nMicPts
            micFFT = 2*micFFT[0:len(micFFT) // 2]
            micFFT = 20*np.log10(micFFT/2e-5)
            freq = np.linspace(0, inputRate/2, len(micFFT))
            pl = appObj.spCalTest_micFFT
            pl.clear()
            #df = freq[1] - freq[0]
            #print("NoiseExp: df= %0.3f i1= %d i2= %d nf= %d" % (df, i1, i2, nf))
            pl.plot(freq, micFFT, pen='b')
            labelStyle = appObj.xLblStyle
            pl.setLabel('bottom', 'Frequency', 'Hz', **labelStyle)
            labelStyle = appObj.yLblStyle
            pl.setLabel('left', 'Magnitude', 'db SPL', **labelStyle)
            
            QtGui.QApplication.processEvents() # check for GUI events, such as button presses
            
            # if done flag, break out of loop
            if appObj.doneFlag:
                break      
            
            t1 = time.time()
            tElapsed += (t1 - tLast)
            tLast = t1
    
        
        if not testMode:
            daq.stopAnalogOutput()
            daq.clearAnalogOutput()
            
    except Exception as ex:
        traceback.print_exc(file=sys.stdout)
        QtGui.QMessageBox.critical (appObj, "Error", "Error during calibration. Check command line output for details")           
        
    8# update the audio hardware speaker calibration                     
    appObj.isCollecting = False
    QtGui.QApplication.processEvents() # check for GUI events, such as button presses
    appObj.finishCollection()


    
Exemple #5
0
def calibrateClick(appObj, testMode=False):
    print("ABR.calibrateClick")

    appObj.tabWidget.setCurrentIndex(3)
    appObj.doneFlag = False
    appObj.isCollecting = True
    # trigRate = octfpga.GetTriggerRate()
    audioHW = appObj.audioHW
    outputRate = audioHW.DAQOutputRate
    inputRate = audioHW.DAQInputRate

    # freq_array2 = audioParams.freq[1, :]
    freqArray = appObj.getFrequencyArray()

    if testMode:
        testDataDir = os.path.join(appObj.basePath, 'exampledata',
                                   'Speaker Calibration')


#        filePath = os.path.join(testDataDir, 'AudioParams.pickle')
#        f = open(filePath, 'rb')
#        audioParams = pickle.load(f)
#        f.close()
    else:
        pass

    # numSpk = audioParams.getNumSpeakers()
    if not testMode:
        from DAQHardware import DAQHardware
        daq = DAQHardware()

    chanNamesIn = [audioHW.mic_daqChan]
    micVoltsPerPascal = audioHW.micVoltsPerPascal
    ABRparams = ABRParams(appObj)
    ABRparams.click = True
    ABRparams.nReps = 20
    print("ABR.calibrateClick ABRparams=", ABRparams.__dict__)
    # set input rate to three times the highest output frequency, to allow plus a

    #    inputRate = 3*freqArray[-1]
    #    print("runABR: outputRate= ", outputRate, " inputRate= ", inputRate)
    #    inputRate = np.max((inputRate, 6e3))   # inpute rate should be at least 6 kHz because ABR responses occur 0.3 - 3 kHz
    #    inputRate = outputRate / int(np.floor(outputRate / inputRate))  # pick closest input rate that evenly divides output rate
    #    print("runABR: inputRate(final)= ", inputRate)

    try:
        chanNameOut = audioHW.speakerL_daqChan
        attenLines = audioHW.attenL_daqChan

        spkOut_trial = makeABROutput(4e3, ABRparams, audioHW)
        spkOut = np.tile(spkOut_trial, ABRparams.nReps)
        npts = len(spkOut_trial)
        tOut = np.linspace(0, npts / outputRate, npts)

        # attenSig = AudioHardware.makeLM1972AttenSig(0)
        if not testMode:
            AudioHardware.Attenuator.setLevel(0, attenLines)

        pl = appObj.ABR_output
        pl.clear()
        endIdx = int(5e-3 * outputRate)  # only plot first 5 ms
        #pl.plot(t[0:endIdx], spkOut[0:endIdx], pen='b')
        pl.plot(tOut, spkOut_trial, pen='b')

        labelStyle = appObj.xLblStyle
        pl.setLabel('bottom', 'Time', 's', **labelStyle)
        labelStyle = appObj.yLblStyle
        pl.setLabel('left', 'Output', 'V', **labelStyle)

        numInputSamples = int(inputRate * len(spkOut) / outputRate)

        if testMode:
            # mic_data = OCTCommon.loadRawData(testDataDir, frameNum, dataType=3)
            pass
        else:
            # setup the output task
            daq.setupAnalogOutput([chanNameOut], audioHW.daqTrigChanIn,
                                  int(outputRate), spkOut)
            daq.startAnalogOutput()

            # setup the input task
            daq.setupAnalogInput(chanNamesIn, audioHW.daqTrigChanIn,
                                 int(inputRate), numInputSamples)
            daq.startAnalogInput()

            # trigger the acquiisiton by sending ditital pulse
            daq.sendDigTrig(audioHW.daqTrigChanOut)

            timeout = numInputSamples / inputRate + 2
            dataIn = daq.readAnalogInput(timeout)
            mic_data = dataIn[0, :]

            mic_data = mic_data / micVoltsPerPascal

            daq.waitDoneInput()
            daq.stopAnalogInput()
            daq.clearAnalogInput()

            daq.waitDoneOutput(stopAndClear=True)

        print("ABR.calibrateClick: plotting data")
        npts = len(mic_data)

        # reshape and average the mic data
        ptsPerRep = npts // ABRparams.nReps
        mic_data = np.reshape(mic_data, (ABRparams.nReps, ptsPerRep))
        mic_data = np.mean(mic_data, 0)

        # plot mic data
        npts = len(mic_data)
        t = np.linspace(0, npts / inputRate, npts)
        pl = appObj.ABR_micInput
        pl.clear()
        pl.plot(t, mic_data, pen='b')

        labelStyle = appObj.xLblStyle
        pl.setLabel('bottom', 'Time', 's', **labelStyle)
        labelStyle = appObj.yLblStyle
        pl.setLabel('left', 'Response', 'Pa', **labelStyle)

        idx1 = round(inputRate * ABRparams.stimOffset)
        idx2 = idx1 + round(inputRate * ABRparams.stimDur)

        mic_data = mic_data[idx1:idx2]
        # apply high pass filter to get rid of LF components
        #        (b, a) = scipy.signal.butter(5, 100/inputRate, 'high')
        #        mic_data = scipy.signal.lfilter(b, a, mic_data)

        rms = np.mean(mic_data**2)**0.5
        rms = 20 * np.log10(rms / 2e-5)
        appObj.ABRclick_RMS = rms

        appObj.ABR_rms_label.setText("%0.1f dB" % rms)
        print("ABR.calibrateClick: RMS= ", rms)

    except Exception as ex:
        traceback.print_exc(file=sys.stdout)
        QtGui.QMessageBox.critical(
            appObj, "Error",
            "Error during collection. Check command line output for details")

    appObj.isCollecting = False
    QtGui.QApplication.processEvents(
    )  # check for GUI events, such as button presses
    appObj.finishCollection()
Exemple #6
0
def runABR(appObj, testMode=False):
    print("runABR")

    appObj.tabWidget.setCurrentIndex(3)
    appObj.doneFlag = False
    appObj.isCollecting = True
    # trigRate = octfpga.GetTriggerRate()
    audioHW = appObj.audioHW
    bioamp = appObj.bioamp
    outputRate = audioHW.DAQOutputRate
    inputRate = audioHW.DAQInputRate

    # freq_array2 = audioParams.freq[1, :]
    freqArray = appObj.getFrequencyArray()
    ABRparams = ABRParams(appObj)

    if testMode:
        testDataDir = os.path.join(appObj.basePath, 'exampledata',
                                   'Speaker Calibration')
#        filePath = os.path.join(testDataDir, 'AudioParams.pickle')
#        f = open(filePath, 'rb')
#        audioParams = pickle.load(f)
#        f.close()
    else:
        # freqArray = appObj.getFrequencyArray()
        i1 = appObj.ABR_freqLow_comboBox.currentIndex()
        i2 = appObj.ABR_freqHigh_comboBox.currentIndex()
        print("runABR: i1= ", i1, "i2= ", i2)
        ampLow = appObj.ABRampLow_spinBox.value()
        ampHigh = appObj.ABRampHigh_spinBox.value()
        ampDelta = appObj.ABRampDelta_spinBox.value()

        # ampArray = np.arange(ampLow, ampHigh, ampDelta)
        #numSteps = np.floor((ampHigh - ampLow)/ampDelta) + 1
        #ampArray = np.linspace(ampLow, ampHigh, numSteps)
        if ampLow == ampHigh:
            ampArray = np.array([ampLow])
        else:
            ampArray = np.arange(ampLow, ampHigh, ampDelta)
            if ampArray[-1] != ampHigh:
                ampArray = np.hstack((ampArray, ampHigh))

        freqArray = freqArray[i1:i2 + 1]

    if ABRparams.click:
        freqArray = freqArray[0:1]  # only use single freqeucny
        clickRMS = appObj.ABRclick_RMS

    # numSpk = audioParams.getNumSpeakers()
    if not testMode:
        from DAQHardware import DAQHardware
        daq = DAQHardware()

    chanNamesIn = [audioHW.mic_daqChan, bioamp.daqChan]
    micVoltsPerPascal = audioHW.micVoltsPerPascal

    # set input rate to three times the highest output frequency, to allow plus a

    #    inputRate = 3*freqArray[-1]
    #    print("runABR: outputRate= ", outputRate, " inputRate= ", inputRate)
    #    inputRate = np.max((inputRate, 6e3))   # inpute rate should be at least 6 kHz because ABR responses occur 0.3 - 3 kHz
    #    inputRate = outputRate / int(np.floor(outputRate / inputRate))  # pick closest input rate that evenly divides output rate
    #    print("runABR: inputRate(final)= ", inputRate)

    try:
        frameNum = 0
        numFrames = len(freqArray) * len(ampArray)
        isSaveDirInit = False
        chanNameOut = audioHW.speakerL_daqChan
        attenLines = audioHW.attenL_daqChan

        freq_idx = 0
        ABRdata = None
        appObj.status_label.setText("Running")
        appObj.progressBar.setValue(0)

        for freq in freqArray:
            spkOut_trial = makeABROutput(freq, ABRparams, audioHW)
            npts = len(spkOut_trial)
            spkOut = np.tile(spkOut_trial, ABRparams.nReps)
            # invert every other trial, necessary for ABR/CAP output
            for n in range(1, ABRparams.nReps, 2):
                idx1 = n * npts
                idx2 = (n + 1) * npts
                spkOut[idx1:idx2] = -spkOut[idx1:idx2]
#            plt.figure(5)
#            plt.clf()
#            plt.plot(spkOut)
            tOut = np.linspace(0, npts / outputRate, npts)
            print("runABR npts=%d len(spkOut_trial)= %d len(tOut)= %d" %
                  (npts, len(spkOut_trial), len(tOut)))
            amp_idx = 0
            ptsPerRep = int(inputRate * ABRparams.trialDur)

            for amp in ampArray:
                print("runABR freq=" + repr(freq), " amp= ", +amp,
                      " freq_idx= ", freq_idx, " amp_idx= ", amp_idx)
                if ABRparams.click:
                    clickRMS = appObj.ABRclick_RMS
                    attenLvl = 0
                    vOut = 10**((amp - clickRMS) / 20)
                    minV = audioHW.speakerOutputRng[0]
                    if vOut < minV:
                        attenLvl = int(round(20 * np.log10(minV / vOut)))
                        vOut = minV
                else:
                    vOut, attenLvl = audioHW.getCalibratedOutputVoltageAndAttenLevel(
                        freq, amp, 0)

                print("runABR vOut= ", vOut, " atenLvl=", attenLvl)

                if vOut > audioHW.speakerOutputRng[1]:
                    print("runABR vOut= ", vOut, "  out of range")
                    continue
                elif attenLvl > audioHW.maxAtten:
                    print("runABR attenLvl= ", attenLvl,
                          "  gerater than maximum attenuation")
                    continue

                # attenSig = AudioHardware.makeLM1972AttenSig(0)
                if not testMode:
                    AudioHardware.Attenuator.setLevel(attenLvl, attenLines)
                    # daq.sendDigOutABRd(attenLines, attenSig)
                    # appObj.oct_hw.SetAttenLevel(0, attenLines)

                pl = appObj.ABR_output
                pl.clear()
                endIdx = int(5e-3 * outputRate)  # only plot first 5 ms
                #pl.plot(t[0:endIdx], spkOut[0:endIdx], pen='b')
                pl.plot(tOut, spkOut_trial, pen='b')

                labelStyle = appObj.xLblStyle
                pl.setLabel('bottom', 'Time', 's', **labelStyle)
                labelStyle = appObj.yLblStyle
                pl.setLabel('left', 'Output', 'V', **labelStyle)

                numInputSamples = ABRparams.nReps * int(
                    inputRate * len(spkOut_trial) / outputRate)

                if testMode:
                    # mic_data = OCTCommon.loadRawData(testDataDir, frameNum, dataType=3)
                    pass
                else:

                    # setup the output task
                    daq.setupAnalogOutput([chanNameOut], audioHW.daqTrigChanIn,
                                          int(outputRate), vOut * spkOut)
                    daq.startAnalogOutput()

                    # setup the input task
                    daq.setupAnalogInput(chanNamesIn, audioHW.daqTrigChanIn,
                                         int(inputRate), numInputSamples)
                    daq.startAnalogInput()

                    # trigger the acquiisiton by sending ditital pulse
                    daq.sendDigTrig(audioHW.daqTrigChanOut)

                    timeout = numInputSamples / inputRate + 2
                    dataIn = daq.readAnalogInput(timeout)
                    mic_data = dataIn[0, :]
                    bioamp_data = dataIn[1, :]

                    mic_data = mic_data / micVoltsPerPascal
                    bioamp_data = bioamp_data / bioamp.gain

                    daq.waitDoneInput()
                    daq.stopAnalogInput()
                    daq.clearAnalogInput()

                    daq.waitDoneOutput(stopAndClear=True)


#                npts = len(mic_data)
#                t = np.linspace(0, npts/inputRate, npts)
#                pl = appObj.ABR_micInput
#                pl.clear()
#                pl.plot(t, mic_data, pen='b')
#
#                labelStyle = appObj.xLblStyle
#                pl.setLabel('bottom', 'Time', 's', **labelStyle)
#                labelStyle = appObj.yLblStyle
#                pl.setLabel('left', 'Response', 'Pa', **labelStyle)

# def processABRData(mic_data, bioamp_data, nReps, freq, amp_idx, inputRate, ABRdataIn):
                ABRptData, ABRdata = processABRData(mic_data, bioamp_data,
                                                    freq, freq_idx, amp_idx,
                                                    freqArray, ampArray,
                                                    inputRate, ABRdata,
                                                    ABRparams)

                print("runABR: plotting data")
                plotABRdata(appObj, ABRptData, ABRdata)

                #                if appObj.getSaveState():
                #                    if not isSaveDirInit:
                #                        saveDir = OCTCommon.initSaveDir(saveOpts, 'Speaker Calibration', audioParams=audioParams)
                #                        isSaveDirInit = True
                #
                #                    if saveOpts.saveRaw:
                #                        OCTCommon.saveRawData(mic_data, saveDir, frameNum, dataType=3)
                idx1 = round(inputRate * ABRparams.stimOffset)
                idx2 = idx1 + round(inputRate * ABRparams.stimDur)

                mic_data = mic_data[idx1:idx2]
                rms = np.mean(mic_data**2)**0.5
                rms = 20 * np.log10(rms / 2e-5)

                appObj.ABR_rms_label.setText("%0.1f dB" % rms)

                QtGui.QApplication.processEvents(
                )  # check for GUI events, such as button presses

                # if done flag, break out of loop
                if appObj.doneFlag:
                    break

                frameNum += 1
                amp_idx += 1
                appObj.progressBar.setValue(frameNum / numFrames)

            # if done flag, break out of loop
            if appObj.doneFlag:
                break

            freq_idx += 1

        saveOpts = appObj.getSaveOpts()
        workbook = appObj.excelWB
        note = saveOpts.note
        number = appObj.ABRnumber
        name = 'ABR'
        d = datetime.datetime.now()
        timeStr = d.strftime('%H_%M_%S')
        excelWS = CMPCommon.initExcelSpreadsheet(workbook, name, number,
                                                 timeStr, note)

        appObj.ABRnumber += 1
        #saveOpts.saveTracings = appObj.ABR_saveTracings_checkBox.isChecked()
        saveOpts.saveTracings = True
        saveDir = appObj.saveDir_lineEdit.text()
        saveABRDataXLS(ABRdata, ABRparams, excelWS, saveOpts)
        #saveABRData(ABRdata, trialDur, nReps, appObj.saveFileTxt_filepath, saveOpts, timeStr)

        plotName = 'ABR %d %s %s' % (number, timeStr, saveOpts.note)
        saveABRDataFig(ABRdata, ABRparams, saveDir, plotName, timeStr)
        saveABRDataPickle(ABRdata, ABRparams, plotName, saveOpts, timeStr)

    except Exception as ex:
        traceback.print_exc(file=sys.stdout)
        QtGui.QMessageBox.critical(
            appObj, "Error",
            "Error during collection. Check command line output for details")

    # update the audio hardware speaker calibration
    appObj.isCollecting = False
    QtGui.QApplication.processEvents(
    )  # check for GUI events, such as button presses
    appObj.finishCollection()