Пример #1
0
 def writeValues(self, chanNames, data):
     DebugLog.log("DAQhardware.writeValue(): chanNames= %s val= %s" % (repr(chanNames), repr(data)))
     
     self.analog_output = None   # ensure the output task is closed
     samplesWritten = daqmx.int32()
     analog_output = daqmx.Task()
     data = np.vstack((data, data))
     data = data.transpose()
     data = np.require(data, np.double, ['C', 'W'])
     numSamples = 2
     outputRate = 1000
     
     for chanName in chanNames:
         analog_output.CreateAOVoltageChan(chanName,"",-10.0,10.0, daqmx.DAQmx_Val_Volts, None)
     analog_output.CfgSampClkTiming("",outputRate, daqmx.DAQmx_Val_Rising, daqmx.DAQmx_Val_FiniteSamps, numSamples)
     analog_output.WriteAnalogF64(numSampsPerChan=numSamples, autoStart=True,timeout=1.0, dataLayout=daqmx.DAQmx_Val_GroupByChannel, writeArray=data, reserved=None, sampsPerChanWritten=byref(samplesWritten))
     DebugLog.log("DAQhardware.setupAnalogOutput(): Wrote %d samples" % samplesWritten.value)
     
     # wait until write is completeled
     isDone = False
     isDoneP = daqmx.c_ulong()
     while not isDone:
         err = analog_output.IsTaskDone(byref(isDoneP))
         isDone = isDoneP.value != 0
             
     analog_output = None
Пример #2
0
def loadDispersion_onStartup(appObj):   
#    infile=os.path.join(appObj.configPath, 'Dispersion','dispComp-initial.pickle')  
    infile = appObj.octSetupInfo.dispFilename
    dispData = Dispersion.loadDispData(appObj, infile)
    appObj.dispData=dispData
    DebugLog.log('JSORaw.loadDispersion_onStartup: set appObj.dispData')
    appObj.dispCompFilename_label.setText(infile)
    updateDispersionGUI(appObj, appObj.dispData)
Пример #3
0
def processSpkCalData(mic_data, freq, freq_idx, audioParams, inputRate, speakerCalIn, spkNum):
    # print("SpeakerCalProtocol: processData: mic_data=" + repr(mic_data))
    # ensure data is 1D
    if len(mic_data.shape) > 1:
        mic_data = mic_data[:, 0]
        
    numpts = len(mic_data)
    DebugLog.log("SpeakerCalProtocol: processData: numpts= %d" % (numpts))

    t = np.linspace(0, numpts/inputRate, numpts)
    zero_pad_factor = 2
    numfftpts = numpts*zero_pad_factor
    winfcn = np.hanning(numpts)
    mic_fft = np.fft.fft(winfcn*mic_data, numfftpts)
    endIdx = np.ceil(numfftpts/2)
    mic_fft = mic_fft[0:endIdx]
    mic_fft_mag = 2*np.abs(mic_fft)
    
    # convert to dB, correctting for RMS and FFT length
    fftrms_corr = 2/(numpts*np.sqrt(2))
    mic_fft_mag = fftrms_corr*mic_fft_mag 
    mic_fft_mag_log = 20*np.log10(mic_fft_mag/20e-6 )  # 20e-6 pa
    
    mic_fft_phase = np.angle(mic_fft)
    mic_freq = np.linspace(0, inputRate/2, endIdx)
    fIdx = int(np.floor(freq*numfftpts/inputRate))
    DebugLog.log("SpeakerCalibration: processData: freq= %f fIdx= %d" % (freq, fIdx))

    stim_freq_mag = np.NAN
    stim_freq_phase = np.NAN
        
    try:            
        npts = zero_pad_factor
        mag_rgn = mic_fft_mag_log[fIdx-npts:fIdx+npts]
        phase_rgn = mic_fft_phase[fIdx-npts:fIdx+npts]
        fIdx = int(np.floor(freq*numfftpts/inputRate))
        DebugLog.log("SpeakerCalibration: processData: freq= %f fIdx= %d" % (freq, fIdx))
        
        maxIdx = np.argmax(mag_rgn)
        stim_freq_mag = mag_rgn[maxIdx]
        stim_freq_phase = phase_rgn[maxIdx]
    except Exception as ex:
        DebugLog.log(ex)
    
    DebugLog.log("SpeakerCalibration: processData: stim_freq_mag= %f stim_freq_phase= %f" % (stim_freq_mag, stim_freq_phase))
    micData = MicData()
    micData.raw = mic_data
    micData.t = t
    micData.fft_mag = mic_fft_mag_log
    micData.fft_phase = mic_fft_phase
    micData.fft_freq = mic_freq
    micData.stim_freq_mag = stim_freq_mag
    micData.stim_freq_phase = stim_freq_phase
    
    speakerCalIn.magResp[spkNum, freq_idx] = stim_freq_mag
    speakerCalIn.phaseResp[spkNum, freq_idx] = stim_freq_phase
        
    return micData, speakerCalIn
Пример #4
0
 def readAnalogInput(self, timeout=3.0): 
     ## DAQmx Read Code
     read = daqmx.int32()
     numSamplesIn = len(self.dataIn)
     self.analog_input.ReadAnalogF64(numSamplesIn, timeout, daqmx.DAQmx_Val_GroupByChannel, self.dataIn, numSamplesIn, byref(read), None)
     DebugLog.log("DAQhardware.sendDigTrig(): Read %s samples" % repr(read))
     data = self.dataIn
     
     return data
Пример #5
0
 def __init__(self, freqArray):
     self.voltsOut = 0.1
     self.freq = freqArray
     numFreq = freqArray.shape[1]
     DebugLog.log("SpeakerCalData: numFreq= %d" % numFreq)
     self.magResp = np.zeros((2, numFreq))
     self.magResp[:, :] = np.NaN
     self.phaseResp = np.zeros((2, numFreq))
     self.phaseResp[:, :] = np.NaN
Пример #6
0
    def sendDigTrig(self, trigOutLine):
        # setup the digital trigger
        DebugLog.log("DAQhardware.sendDigTrig(): trigOutLine= %s " % trigOutLine)
        dig_out = daqmx.Task()
        dig_out.CreateDOChan(trigOutLine, "", daqmx.DAQmx_Val_ChanForAllLines)

        doSamplesWritten = daqmx.int32()
        doData = self.doTrigData
        numpts = len(doData)
        dig_out.WriteDigitalU32(numSampsPerChan=numpts, autoStart=True, timeout=1.0, dataLayout=daqmx.DAQmx_Val_GroupByChannel, writeArray=doData, reserved=None, sampsPerChanWritten=byref(doSamplesWritten))
        DebugLog.log("DAQhardware.sendDigTrig():  Wrote %d samples" % doSamplesWritten.value)
        dig_out.ClearTask()
Пример #7
0
def softwareProcessing(ch0_data,ch1_data,zROI,appObj, returnPhase=False, unwrapPhase=False):
    # This routine can be called from any other routine to do software processing of the raw data. 
    # It needs appObj.dispData so you must have loaded a dispersion file already for this to work.

    dispData=appObj.dispData
    pdData,mziData,actualSamplesPerTrig=channelShift(ch0_data,ch1_data,dispData)    # shift the two channels to account for delays in the sample data compared to the MZI data 
        
    t1 = time.time()
    mzi_hilbert, mzi_mag, mzi_ph, k0 = processMZI(mziData, dispData)                # calculate k0 from the phase of the MZI data
    DebugLog.log("JSOraw.softwareProcessing(): process MZI time= %0.4f" % (time.time() - t1))
    DebugLog.log("JSOraw.softwareProcessing(): numTriggers collected= %d" % (k0.shape[0]))

    k0Cleaned=cleank0Run(k0,dispData) # Adjust the k0 curves so that the unwrapping all starts at the same phase    
    Klin=dispData.Klin
    
    t1 = time.time()
    pd_interpRaw, klin = processPD(pdData, k0Cleaned, dispData, Klin)  # Interpolate the PD data based upon the MZI data    
    DebugLog.log("JSOraw.softwareProcessing(): process PD time= %0.4f" % (time.time() - t1))
    
    t1 = time.time()    
    pd_interpDispComp = dispData.magWin * pd_interpRaw * (np.cos(-1*dispData.phaseCorr) + 1j * np.sin(-1*dispData.phaseCorr))  # perform dispersion compensation
    pd_fftDispComp, alineMagDispComp, alinePhaseDispComp = calculateAline(pd_interpDispComp, returnPhase, unwrapPhase) # calculate the a-line
    DebugLog.log("JSOraw.softwareProcessing(): calc Aline time= %0.4f" % (time.time() - t1))
    oct_data = pd_fftDispComp[:, zROI[0]:zROI[1]] 
    return oct_data, klin
Пример #8
0
def cleank0Run(k0,dispData):  # for Runtime: use the cleaned k0Reference data and adjust all new k0 data by 2pi rads to overlap it
    k0Cleaned=np.copy(k0)    
    k0Init=k0Cleaned[:,dispData.startSample]
    DebugLog.log('JSOraw.cleank0Run: len(k0reference)= %d startSample= %d' % (len(dispData.k0Reference), dispData.startSample))
    k0RefInit=np.tile(dispData.k0Reference[dispData.startSample],len(k0Init))    
    
    # If there are phase jumps going on in the data, find the bad k0 curves and shift them appropriately by 2pi
    diff=k0Init-k0RefInit
    while np.max(np.abs(diff))>(1.5*np.pi): 
        indexGrp1=np.argwhere(diff>(1.5*np.pi))
        indexGrp2=np.argwhere(diff<(-1.5*np.pi))        
        k0Cleaned[indexGrp1,:]=k0Cleaned[indexGrp1,:]-2*np.pi
        k0Cleaned[indexGrp2,:]=k0Cleaned[indexGrp2,:]+2*np.pi
        k0Init=k0Cleaned[:,dispData.startSample]
        diff=k0Init-k0RefInit
    return k0Cleaned
Пример #9
0
def getSavedRawData(numTrigs,requestedSamplesPerTrig,JSOrawSavedData):
    # oct_data is a 2D arary of complex numbers
    # When used to carry raw data:
    # Photodiode data (interferogram from the sample) is encoded as imaginary part 
    # MZI data (interferogram from MZI) is encoded as imaginary part        print(self.count,self.oct_data_all.shape[0])
#        print('size/numTrigs',self.oct_data_file.shape[0],numTrigs)        
    DebugLog.log("JSOraw.getSavedRawData(): data file count= %d " % (JSOrawSavedData.count))
    ch0_data=np.zeros([numTrigs,JSOrawSavedData.ch1_data_file.shape[1]])        
    ch1_data=np.zeros([numTrigs,JSOrawSavedData.ch1_data_file.shape[1]])        
   
    for i in range(numTrigs):
        if JSOrawSavedData.count==JSOrawSavedData.ch0_data_file.shape[0]:
            JSOrawSavedData.count=0           
        ch0_data[i,:]=JSOrawSavedData.ch0_data_file[JSOrawSavedData.count,:] 
        ch1_data[i,:]=JSOrawSavedData.ch1_data_file[JSOrawSavedData.count,:] 
        JSOrawSavedData.count=JSOrawSavedData.count+1             
    return ch0_data, ch1_data
Пример #10
0
    def setupAnalogOutput(self, chanNames, digTrigChan, outputRate, data):
        numSamples = data.shape[0]

        DebugLog.log("DAQhardware.setupAnalogOutput(): chanNames= %s digTrigChan= %s outputRate= %f numSamples= %f" % (chanNames, digTrigChan, outputRate, numSamples))
        
        self.clearAnalogOutput()  # ensure the output task is closed
        samplesWritten = daqmx.int32()
        analog_output = daqmx.Task()
        data = np.require(data, np.float, ['C', 'W'])
        for chanName in chanNames:
            analog_output.CreateAOVoltageChan(chanName,"",-10.0,10.0, daqmx.DAQmx_Val_Volts, None)
        analog_output.CfgSampClkTiming("",outputRate, daqmx.DAQmx_Val_Rising, daqmx.DAQmx_Val_FiniteSamps, numSamples)
        analog_output.CfgDigEdgeStartTrig(digTrigChan, daqmx.DAQmx_Val_Rising) 
        #analog_output.WriteAnalogF64(numSampsPerChan=numSamples, autoStart=False,timeout=3.0, dataLayout=daqmx.DAQmx_Val_GroupByChannel, writeArray=data, reserved=None, sampsPerChanWritten=byref(samplesWritten))
        analog_output.WriteAnalogF64(numSampsPerChan=numSamples, autoStart=False,timeout=3.0, dataLayout=daqmx.DAQmx_Val_GroupByScanNumber, writeArray=data, reserved=None, sampsPerChanWritten=byref(samplesWritten))
        DebugLog.log("DAQhardware.setupAnalogOutput(): Wrote %d samples" % samplesWritten.value)
        
        self.analog_output = analog_output
Пример #11
0
 def setupAnalogInput(self, chanNames, digTrigChan, inputRate, numInputSamples): 
     # ensure old task has been cosed
     self.clearAnalogInput()
     
     DebugLog.log("DAQhardware.setupAnalogOutput(): chanNames= %s digTrigChan= %s inputRate= %f numInputSamples= %f" % (chanNames, digTrigChan, inputRate, numInputSamples))
     ## DAQmx Configure Code
     # analog_input.CreateAIVoltageChan("Dev1/ai0","",DAQmx_Val_Cfg_Default,-10.0,10.0,DAQmx_Val_Volts,None)
     analog_input = daqmx.Task()
     for chanName in chanNames:
         analog_input.CreateAIVoltageChan(chanName,"", daqmx.DAQmx_Val_Cfg_Default,-10.0,10.0, daqmx.DAQmx_Val_Volts,None)
         
     analog_input.CfgSampClkTiming("", inputRate, daqmx.DAQmx_Val_Rising, daqmx.DAQmx_Val_FiniteSamps, numInputSamples)
     analog_input.CfgDigEdgeStartTrig(digTrigChan, daqmx.DAQmx_Val_Rising) 
     
     numCh = len(chanNames)
     self.dataIn = np.zeros((numInputSamples*numCh,))
     #
     ## DAQmx Start Code
     self.analog_input = analog_input
Пример #12
0
  def getCalibratedOutputVoltageAndAttenLevel(self, freq, ampdB, speakerNum):
      freqArray = self.speakerCalFreq[speakerNum, :]
      calArray = self.speakerCal[speakerNum, :]
      DebugLog.log("AudioHardware.getCalibratedOutputVoltageAndAttenLevel freq= %f freqArray= %s calArray= %s" % (freq, repr(freqArray), repr(calArray)))
      caldBarr = np.interp([freq], freqArray, calArray)
      caldB = caldBarr[0]
      dBdiff = ampdB - caldB
      DebugLog.log("AudioHardware.getCalibratedOutputVoltageAndAttenLevel ampdB= %f caldB= %f dBdiff= %f" % (ampdB, caldB, dBdiff))
      outV = self.speakerCalVolts*(10 ** (dBdiff/20))
      minV = self.speakerOutputRng[0]
      maxV = self.speakerOutputRng[1]
      attenLevel = 0
      if outV > maxV:
          outV = 0
      elif outV < minV:
          attenLevel = np.ceil(20 * np.log10(minV/outV))
          attenLevel = int(attenLevel)
          outV = minV
      if attenLevel > self.maxAtten:
          outV = 0
 
      return (outV, attenLevel)
Пример #13
0
def processPD(pd_data, k0, dispData, klin=None):
    numklinpts = dispData.numKlinPts
    # this section is only run during the dispersion compensation algorithm. Then, klin is saved with the dispersion file and used from there on
    if klin is None or (len(klin) != numklinpts):   
        klin = np.linspace(k0[0,dispData.startSample], k0[0,dispData.endSample], numklinpts)

    # if num klinpts is > 2048, need to use downsampling to get interp points below 2048
    if numklinpts > 2048:
        dsf = numklinpts // 2048 + 1
        num_klin_ds = numklinpts // dsf
        DebugLog.log("JSOraw.processPD numklinpts= %d dsf= %d len(klin)= %d pd_data.shape= %s" % (numklinpts, dsf, len(klin), repr(pd_data.shape)))
        
        pd_interp = np.zeros((pd_data.shape[0], numklinpts // dsf))
        for i in range(pd_data.shape[0]):
            interp_pd = np.interp(klin, k0[i,:], pd_data[i,:])    
            interp_pd = np.reshape(interp_pd, (num_klin_ds, dsf))
            interp_pd = np.mean(interp_pd, 1)
            pd_interp[i,:] = interp_pd
    else:
        pd_interp=np.zeros((pd_data.shape[0], numklinpts))
        for i in range(pd_data.shape[0]):
            pd_interp[i,:] = np.interp(klin, k0[i,:], pd_data[i,:])    
        
    return pd_interp, klin  
Пример #14
0
def calculateAline(pd, returnPhase=True, unwrapPhase=True):
    numPts=pd.shape[1] 

    t1 = time.time()    
    pd_fft = (np.fft.fft(pd, n=2048,axis=-1)/numPts)/100
    DebugLog.log("JSOraw.calculateAline() FFT time= %0.4f" % (time.time() - t1))
    
    t1 = time.time()    
    alineMag = np.abs(pd_fft)
    DebugLog.log("JSOraw.calculateAline() abs time= %0.4f" % (time.time() - t1))
    
    t1 = time.time()    
    alineMag = 20*np.log10(alineMag + 1)
    DebugLog.log("JSOraw.calculateAline() log10 time= %0.4f" % (time.time() - t1))
    
    alinePhase = None
    if returnPhase:
        alinePhase= np.angle(pd_fft)
        if unwrapPhase:
            alinePhase= np.unwrap(alinePhase,axis=-1)
        
    return pd_fft, alineMag, alinePhase
Пример #15
0
def processMZI(mzi_data, dispData, FIRcoeff=[0+0j]):
    t1 = time.time()
    complex_FIR = 1
    if complex_FIR == 0:
        #normal way using fft/ifft approach to do the hilbert transform
    
        # filtering seems to reduce sidebands created during the interpolation process
        (b, a) = scipy.signal.butter(2, dispData.mziFilter, 'highpass')
        mzi_data=scipy.signal.lfilter(b, a, mzi_data,axis=-1)        
    
        # mean subtraction is much faster, and we only need to eliminate the zero-frequency componment
        # mzi_data = mzi_data - np.mean(mzi_data, keepdims=True)
    
        mzi_complex = scipy.signal.hilbert(mzi_data, axis=-1)
    elif complex_FIR==1:      
        # Approximate Hilbert Transform using FIR filter
        """
        # code to design the filter coefficients (This is not needed since they are pasted in below, but the code included for reference)
        filter_order = 35
        stop_freq=0.25
        pass_freq=0.15
        prt_lpf=scipy.signal.remez(filter_order, [0, pass_freq, stop_freq, 0.5], [1, 0])
        exp_len=np.arange(-filter_order/2,filter_order/2,1)
        FIRcoeff=prt_lpf*np.exp(np.complex(0,1)*2*np.pi*0.25*exp_len)
        
        for i in range(filter_order):
            print(FIRcoeff[i],',')
        """    
        # these filter coefficients come from the above code
        FIRcoeff=np.array([
        (-0.00030351655287-0.00030351655287j) ,
        (0.00113140195234-0.00113140195234j) ,
        (-9.35755583151e-05-9.35755583151e-05j) ,
        (0.00252252948249-0.00252252948249j) ,
        (0.00218108432482+0.00218108432482j) ,
        (0.0032263770108-0.0032263770108j) ,
        (0.00690123992871+0.00690123992871j) ,
        (0.0001322186872-0.0001322186872j) ,
        (0.0122523152659+0.0122523152659j) ,
        (-0.00969906300727+0.00969906300727j) ,
        (0.0128955480118+0.0128955480118j) ,
        (-0.0267326545724+0.0267326545724j) ,
        (0.000205842190372+0.000205842190372j) ,
        (-0.0472714248792+0.0472714248792j) ,
        (-0.0409251974438-0.0409251974438j) ,
        (-0.0643104412456+0.0643104412456j) ,
        (-0.212334405586-0.212334405586j) ,
        (0.282605062261-0.282605062261j) ,
        (0.212334405586+0.212334405586j) ,
        (-0.0643104412456+0.0643104412456j) ,
        (0.0409251974438+0.0409251974438j) ,
        (-0.0472714248792+0.0472714248792j) ,
        (-0.000205842190372-0.000205842190372j) ,
        (-0.0267326545724+0.0267326545724j) ,
        (-0.0128955480118-0.0128955480118j) ,
        (-0.00969906300727+0.00969906300727j) ,
        (-0.0122523152659-0.0122523152659j) ,
        (0.0001322186872-0.0001322186872j) ,
        (-0.00690123992871-0.00690123992871j) ,
        (0.0032263770108-0.0032263770108j) ,
        (-0.00218108432482-0.00218108432482j) ,
        (0.00252252948249-0.00252252948249j) ,
        (9.35755583151e-05+9.35755583151e-05j) ,
        (0.00113140195234-0.00113140195234j) ,
        (0.00030351655287+0.00030351655287j)
        ])
#        mzi_complex=np.zeros(mzi_data.shape, dtype=complex)
#        for i_th in range(0, mzi_data.shape[0]):
#            mzi_complex[i_th,:]=np.convolve(mzi_data[i_th,:],FIRcoeff, mode='same')  # this works but is slow

#        mzi_complex=scipy.ndimage.filters.convolve1d(mzi_data,FIRcoeff)  # This gives errors - doesn't work with complex numbers correctly

        mzi_complex=np.apply_along_axis(lambda m: np.convolve(m, FIRcoeff, mode='same'), axis=1, arr=mzi_data) # this works and is the fastest way to do it that I could figure out

        # mzi_complex=scipy.signal.lfilter(FIRcoeff,[1],mzi_data,axis=1)  # this works, but is also very slow
        
        
    DebugLog.log("JSOraw.processMZI() hilbert trasnform time= %0.4f" % (time.time() - t1))
    
    mzi_mag = np.abs(mzi_complex)
    t1 = time.time()    
    mzi_ph = np.angle(mzi_complex)
    DebugLog.log("JSOraw.processMZI() angle calc time= %0.4f" % (time.time() - t1))
        
    mzi_hilbert = np.imag(mzi_complex)
    
    t1 = time.time()    
    k0 = np.unwrap(mzi_ph,axis=-1)    
    DebugLog.log("JSOraw.processMZI() unwraptime= %0.4f" % (time.time() - t1))
    return mzi_hilbert, mzi_mag, mzi_ph, k0
Пример #16
0
def runJSOraw(appObj):
    DebugLog.log("runJSOraw")
    try:
        appObj.tabWidget.setCurrentIndex(7)
        appObj.doneFlag = False
        appObj.isCollecting = True
        appObj.JSOsaveDispersion_pushButton.setEnabled(True)
        appObj.JSOloadDispersion_pushButton.setEnabled(False)
        dispData = appObj.dispData             # this class holds all the dispersion compensation data    
        if dispData is None:
            dispData = Dispersion.DispersionData()
            
        laserSweepFreq=appObj.octSetupInfo.getTriggerRate()
        mirrorDriver = appObj.mirrorDriver
        
        if not appObj.oct_hw.IsOCTTestingMode():     # prepare to get new data            
            # set the mirror position to (0,0)
            chanNames = [mirrorDriver.X_daqChan, mirrorDriver.Y_daqChan]
            data = np.zeros(2)
            from DAQHardware import DAQHardware
            daq = DAQHardware()
            daq.writeValues(chanNames, data)
        else:
            appObj.savedDataBuffer.loadData(appObj)
    
        peakXPos=np.array([0],dtype=int)       
        peakYPos=np.array([0],dtype=float)       
        peakXPos1=np.array([0],dtype=int)       
        peakYPos1=np.array([0],dtype=float)       
                   
        while appObj.doneFlag == False:
            # read data analysis settings from the GUI
            numTrigs=appObj.numTrig.value()
            dispData.requestedSamplesPerTrig=appObj.requestedSamplesPerTrig.value()
            dispData.startSample=appObj.startSample.value()
            dispData.endSample=appObj.endSample.value()
            dispData.numKlinPts=appObj.numKlinPts.value()
            dispData.Klin=np.zeros(dispData.numKlinPts)         
            dispData.numShiftPts=appObj.numShiftPts.value()
            dispData.filterWidth=appObj.filterWidth.value()
            dispData.mziFilter=appObj.mziFilter.value()
            dispData.magWin_LPfilterCutoff=appObj.dispMagWindowFilter.value()
            dispData.PDfilterCutoffs=[0,0]
            dispData.dispCode=appObj.dispersionCompAlgorithm_comboBox.currentIndex() 
            dispData.dispMode=appObj.dispersionCompAlgorithm_comboBox.currentText()
                     
            # Get data using one of several methods
            if appObj.oct_hw.IsOCTTestingMode():
                ch0_data,ch1_data=getSavedRawData(numTrigs,dispData.requestedSamplesPerTrig,appObj.savedDataBuffer)
            else:
                ch0_data,ch1_data=getNewRawData(numTrigs,dispData.requestedSamplesPerTrig,appObj)
            
            if appObj.saveData_checkBox.isChecked()==True:      # save data to disk for later use if desired
                fileName='Mirror_Raw'
                dataToSave = (ch0_data, ch1_data)              
                appObj.savedDataBuffer.saveData(appObj,dataToSave,fileName)                                
                appObj.saveData_checkBox.setChecked(False)                     
                
            # delay the MZI to account for it having a shorter optical path than the sample/reference arm path, then calculate k0 as the MZI phase
            pdData,mziData,actualSamplesPerTrig=channelShift(ch0_data,ch1_data,dispData)    
            textString='Actual samples per trigger: {actualSamplesPerTrig}'.format(actualSamplesPerTrig=actualSamplesPerTrig)            
            appObj.actualSamplesPerTrig_label.setText(textString)         
            
            import time
            t1 = time.time()
            mzi_hilbert, mzi_mag, mzi_ph, k0 = processMZI(mziData, dispData) 
            mzi_proc_time = time.time() - t1
            print("MZI processing time = %0.4f ms" % (mzi_proc_time*1000))
    
            # Adjust the k0 curves so that the unwrapping all starts at the same phase
            appObj.k0_plot_3.clear()
            appObj.k0_plot_4.clear()
            appObj.k0_plot_5.clear()
            t1 = time.time()
            k0Cleaned=cleank0(k0,dispData)              
            k0clean_time = time.time() - t1
            print("k0 cleaning time = %0.4f ms" % (k0clean_time*1000))
            
            for i in range(numTrigs):
                appObj.k0_plot_3.plot(k0[i,:2*dispData.startSample], pen=(i,numTrigs)) 
            startMZIdata1=k0[:,dispData.startSample]
            appObj.k0_plot_4.plot(startMZIdata1, pen='r') 
            startMZIdata2=k0Cleaned[:,dispData.startSample]
            appObj.k0_plot_4.plot(startMZIdata2, pen='b') 
            for i in range(numTrigs):
                appObj.k0_plot_5.plot(k0Cleaned[i,:2*dispData.startSample], pen=(i,numTrigs)) 
            k0=k0Cleaned
            
            # Interpolate the PD data based upon the MZI data and calculate the a-lines before dispersion compensation      
            t1 = time.time()
            pd_interpRaw, klin = processPD(pdData, k0, dispData)
            interpPD_time = time.time() - t1
            print("Interp PD time = %0.4f ms" % (interpPD_time*1000))
            dispData.Klin=klin
            pd_fftNoInterp, alineMagNoInterp, alinePhaseNoInterp = calculateAline(pdData[:,dispData.startSample:dispData.endSample])

            t1 = time.time()
            pd_fftRaw, alineMagRaw, alinePhaseRaw = calculateAline(pd_interpRaw)
            alineCalc_time = time.time() - t1
            print("Aline calc time = %0.4f ms" % (alineCalc_time*1000))
            
            # find the mirror in the a-line to determine the filter settings, and then perform the dispersion compensatsion 
            rangePeak1=[100, 900]
            alineAve1=np.average(alineMagRaw,axis=0) 
            peakXPos1[0]=np.argmax(alineAve1[rangePeak1[0]:rangePeak1[1]])+rangePeak1[0]
            peakYPos1[0]=alineAve1[peakXPos1[0]]     
            width=dispData.filterWidth*(rangePeak1[1]-rangePeak1[0])/2         
            dispData.PDfilterCutoffs[0]=(peakXPos1[0]+width)/2048
            dispData.PDfilterCutoffs[1]=(peakXPos1[0]-width)/2048
        
            dispersionCorrection(pd_interpRaw,dispData)
            appObj.dispData=dispData      #store the local variable in the overall class so that it can be saved when the save button is pressed
            
            # now correct the data using dispersion compensation and then process the a-lines
            pd_interpDispComp = dispData.magWin * pd_interpRaw * (np.cos(-1*dispData.phaseCorr) + 1j * np.sin(-1*dispData.phaseCorr))
            pd_fftDispComp, alineMagDispComp, alinePhaseDispComp = calculateAline(pd_interpDispComp)
                  
            #scale k0 and the MZI to the same range to plot them so they overlap
            k0Ripple= scipy.signal.detrend(k0[0,500:700],axis=-1)
            k0RippleNorm=k0Ripple/k0Ripple.max()
            mziDataRipple= scipy.signal.detrend(mziData[0,500:700],axis=-1)
            mziDataNorm=mziDataRipple/mziDataRipple.max()
           
            # Find the peak of the A-line within a range and calculate the phase noise
            rangePeak=[100, 900]
            alineAve=np.average(alineMagDispComp,axis=0) 
            peakXPos[0]=np.argmax(alineAve[rangePeak[0]:rangePeak[1]])+rangePeak[0]
            peakYPos[0]=alineAve[peakXPos[0]]              
            t=np.arange(numTrigs)/laserSweepFreq
            phaseNoiseTD=np.unwrap(alinePhaseDispComp[:,peakXPos[0]])
            phaseNoiseTD=phaseNoiseTD-np.mean(phaseNoiseTD)
            phaseNoiseTD=phaseNoiseTD*1310e-9/(4*np.pi*1.32)
            phaseNoiseFFT = np.abs(np.fft.rfft(phaseNoiseTD))/(numTrigs/2)
#            phaseNoiseFD = 20*np.log10(np.abs(phaseNoiseFFT))        
            freq = np.fft.rfftfreq(numTrigs)*laserSweepFreq
    
            # Clear all of the plots
            appObj.mzi_plot_2.clear() 
            appObj.pd_plot_2.clear()
            appObj.mzi_mag_plot_2.clear()
            appObj.mzi_phase_plot_2.clear()
            appObj.k0_plot_2.clear()
            appObj.interp_pdRaw_plot.clear()
            appObj.interp_pdDispComp_plot.clear()
            appObj.alineNoInterp_plot.clear()
            appObj.alineRaw_plot.clear()
            appObj.alineDispComp_plot.clear()
            appObj.phaseNoiseTD_plot.clear()
            appObj.phaseNoiseFD_plot.clear()
            appObj.dispWnfcMag_plot.clear()
            appObj.dispWnfcPh_plot.clear()
           
            # Plot all the data
            if appObj.plotFirstOnly_checkBox.isChecked()==True:
                i=0
                appObj.pd_plot_2.plot(pdData[i,:], pen='r')            
                appObj.mzi_plot_2.plot(mziData[i,:], pen='r')            
                appObj.mzi_mag_plot_2.plot(mzi_mag[i,:], pen='r')            
                appObj.k0_plot_2.plot(k0[i,:], pen='r')
                sampleNum=np.linspace(dispData.startSample,dispData.endSample,dispData.numKlinPts)
                appObj.k0_plot_2.plot(sampleNum,klin, pen='b')                      
                appObj.interp_pdRaw_plot.plot(pd_interpRaw[i,:], pen='r')           
                appObj.interp_pdDispComp_plot.plot(np.abs(pd_interpDispComp[i,:]), pen='r')           
                appObj.alineNoInterp_plot.plot(alineMagNoInterp[i,:], pen='r')
                appObj.alineRaw_plot.plot(alineMagRaw[i,:], pen='r')
                appObj.alineDispComp_plot.plot(alineMagDispComp[i,:], pen='r')
            else:
                # limit plotting to first 10 or so triggers, otherwise this will freeze up
                nTrigs = min((numTrigs, 10))
                
                for i in range(nTrigs):
                    pen=(i,nTrigs)
                    appObj.pd_plot_2.plot(pdData[i,:], pen=pen)            
                    appObj.mzi_plot_2.plot(mziData[i,:], pen=pen)            
                    appObj.mzi_mag_plot_2.plot(mzi_mag[i,:], pen=pen)            
                    appObj.mzi_phase_plot_2.plot(mzi_ph[i,:], pen=pen)            
                    appObj.k0_plot_2.plot(k0[i,:], pen=pen)            
                    appObj.interp_pdRaw_plot.plot(pd_interpRaw[i,:], pen=pen)            
                    appObj.interp_pdDispComp_plot.plot(np.abs(pd_interpDispComp[i,:]), pen=pen)            
                    appObj.alineNoInterp_plot.plot(alineMagNoInterp[i,:], pen=pen)            
                    appObj.alineRaw_plot.plot(alineMagRaw[i,:], pen=pen)            
                    appObj.alineDispComp_plot.plot(alineMagDispComp[i,:], pen=pen)            
                
            appObj.alineRaw_plot.plot(peakXPos1,peakYPos1, pen=None, symbolBrush='k', symbolPen='b')
            appObj.alineDispComp_plot.plot(peakXPos,peakYPos, pen=None, symbolBrush='k', symbolPen='b')
            appObj.phaseNoiseTD_plot.plot(t,phaseNoiseTD, pen='r')
            appObj.phaseNoiseFD_plot.plot(freq,phaseNoiseFFT, pen='r')
            appObj.mzi_phase_plot_2.plot(mziDataNorm, pen='b')            
            appObj.mzi_phase_plot_2.plot(k0RippleNorm, pen='r')            
            
           
            # if you want to align the pd and the Mzi data
    #            plotPDPhase.plot(pdData[0,:], pen='r')
    #            plotPDPhase.plot(mziData[0,:], pen='b')
    
            appObj.dispWnfcMag_plot.plot(dispData.magWin, pen='b')
            appObj.dispWnfcPh_plot.plot(dispData.phaseCorr, pen='b')
            
            # plot filter cutoff ranges on the raw Aline plot
            yy=[np.min(alineMagRaw[0,:]),np.max(alineMagRaw[0,:])]
            xx0=[alineMagRaw.shape[1]*dispData.PDfilterCutoffs[0],alineMagRaw.shape[1]*dispData.PDfilterCutoffs[0]]        
            xx1=[alineMagRaw.shape[1]*dispData.PDfilterCutoffs[1],alineMagRaw.shape[1]*dispData.PDfilterCutoffs[1]]    
            appObj.alineRaw_plot.plot(xx0,yy, pen='b')
            appObj.alineRaw_plot.plot(xx1,yy, pen='b')
            
    #            # Now create a bscan image from the 1 aline, but sweep the shift value between the mzi and pd to see what works best
    #            nShift=201        
    #            bscan=np.zeros([nShift, alineMag.shape[0]])        
    #            for i in range(nShift):
    #                shift=i-(nShift-1)/2
    #                if shift<0:
    #                    mzi_data_temp=mzi_data[-1*shift:]
    #                    pd_data_temp=pd_data[0:mzi_data_temp.shape[0]]
    #    #                print(mzi_data_temp.shape,pd_data_temp.shape)
    #                elif shift>0:
    #                    pd_data_temp=pd_data[shift:]
    #                    mzi_data_temp=mzi_data[0:pd_data_temp.shape[0]]
    #    #                print(mzi_data_temp.shape,pd_data_temp.shape)
    #                elif shift==0:
    #                    pd_data_temp=pd_data
    #                    mzi_data_temp=mzi_data
    #                    
    #                mzi_hilbert, mzi_mag, mzi_ph, k0 = processMZI(mzi_data_temp)
    #                pd_interpRaw, pd_interpHanning, pd_fft, alineMag, alinePhase, klin = processPD(pd_data_temp, k0, klin_idx, numklinpts)
    #                bscan[i,:]=alineMag
    #    
    #            pl = self.bscan_plot
    #            pl.setImage(bscan)            
            
    #            print('alineMagDispComp ',alineMagDispComp.shape)
            if ~np.all(np.isnan(alineMagDispComp)):  # only make the bscan plot if there is data to show (this prevents an error from occurring)
                appObj.bscan_plot.setImage(alineMagDispComp)
            QtGui.QApplication.processEvents() # check for GUI events  
    except:
        traceback.print_exc(file=sys.stdout)
        QtGui.QMessageBox.critical (appObj, "Error", "Error during scan. Check command line output for details")
        
    appObj.JSOsaveDispersion_pushButton.setEnabled(False)    
    appObj.JSOloadDispersion_pushButton.setEnabled(True)
    appObj.isCollecting = False
    QtGui.QApplication.processEvents() # check for GUI events
    appObj.finishCollection()
Пример #17
0
def calibrateScanMirror(appObj):
    DebugLog.log("calibrateScanMirror")    
    appObj.tabWidget.setCurrentIndex(7)
    appObj.doneFlag = False
    appObj.isCollecting = True
    appObj.JSOsaveDispersion_pushButton.setEnabled(True)
    appObj.JSOloadDispersion_pushButton.setEnabled(False)

    if not appObj.oct_hw.IsOCTTestingMode():     # prepare to get new data            
        from DAQHardware import DAQHardware
        daq = DAQHardware()
    audioHW=appObj.audioHW
    mirrorDriver = appObj.mirrorDriver    
    chanNames = [mirrorDriver.X_daqChan, mirrorDriver.Y_daqChan]
    trigChan = audioHW.daqTrigChanIn   #use the audio trigger to start the scan
    outputRate = mirrorDriver.DAQoutputRate

    while appObj.doneFlag == False:        # keep running until the button is turned off 
        scanParams = appObj.getScanParams()
       #    create scan pattern to drive the mirrors
        mode=appObj.scanShape_comboBox.currentIndex()
        print('mode',mode)
        if mode==0:   # create a spiral scan using fast (resonant) scanning
            Vmaxx=mirrorDriver.voltRange[1] # maximum voltage for MEMS mirror for x-axis
            Vmaxy=mirrorDriver.voltRange[1] # maximum voltage for MEMS mirror for y-axis
            xAdjust = 1    
            yAdjust = scanParams.skewResonant
            phaseShift = scanParams.phaseAdjust
            fr = mirrorDriver.resonantFreq  # angular scan rate (frequency of one rotation - resonant frequency)
            fv = scanParams.volScanFreq     # plotParam scan frequency, which scans in and then out, which is actually two volumes
            DebugLog.log("freq of one rotation (fr)= %d; scan frequency (fv)= %d" % (fr, fv))
            diameter = scanParams.length
            voltsPerMM = mirrorDriver.voltsPerMillimeterResonant
            A1=(Vmaxx/2)/xAdjust
            A2=(Vmaxy/2)/yAdjust
            A3=voltsPerMM*diameter/2 
            A=np.min([A1,A2,A3])           
            fs=mirrorDriver.DAQoutputRate   # galvo output sampling rate
            t=np.arange(0,np.around(fs/fv))*1/fs  # t is the array of times for the DAQ output to the mirrors
            r=1/2*(1-np.cos(2*np.pi*fv*t))            
            x=xAdjust*A*r*np.cos(2*np.pi*fr*t) # x and y are the coordinates of the laser at each point in time
            y=yAdjust*A*r*np.sin(2*np.pi*fr*t+phaseShift*np.pi/180)
            mirrorOut= np.vstack((x,y))
            
        elif mode==1:   # create a square scan using slow parameters
            Vmaxx=mirrorDriver.voltRange[1] # maximum voltage for MEMS mirror for x-axis
            Vmaxy=mirrorDriver.voltRange[1] # maximum voltage for MEMS mirror for y-axis
            xAdjust = 1    
            yAdjust = scanParams.skewNonResonant
            diameter = scanParams.length
            voltsPerMMX = mirrorDriver.voltsPerMillimeter*xAdjust
            voltsPerMMY = mirrorDriver.voltsPerMillimeter*yAdjust
            if ((diameter/2)*voltsPerMMX)>Vmaxx:
                diameter=2*Vmaxx/voltsPerMMX
            if ((diameter/2)*voltsPerMMY)>Vmaxy:
                diameter=2*Vmaxy/voltsPerMMY
            freq = appObj.cal_freq_dblSpinBox.value()
            if freq>mirrorDriver.LPFcutoff:  # can't go faster than the maximum scan rate
                appObj.cal_freq_dblSpinBox.setValue(mirrorDriver.LPFcutoff)
            fs=mirrorDriver.DAQoutputRate   # galvo output sampling rate
            t1=np.arange(0,np.around(fs/freq))*1/fs  
            n=np.around(t1.shape[0]/4)-1   # number of points in each 4th of the cycle (reduce by 1 to make it easy to shorten t1)
            t=t1[0:4*n]  # t is the array of times for the DAQ output to the mirrors
            cornerX=(diameter/2)*voltsPerMMX     # voltage at each corner of the square            
            cornerY=(diameter/2)*voltsPerMMY     # voltage at each corner of the square            
            
            # x and y are the coordinates of the laser at each point in time
            x=np.zeros(t.shape)            
            y=np.zeros(t.shape)            
            x[0:n]=np.linspace(-cornerX,cornerX,n)
            y[0:n]=-cornerY
            x[n:2*n]=cornerX
            y[n:2*n]=np.linspace(-cornerY,cornerY,n)
            x[2*n:3*n]=np.linspace(cornerX,-cornerX,n)
            y[2*n:3*n]=cornerY
            x[3*n:4*n]=-cornerX
            y[3*n:4*n]=np.linspace(cornerY,-cornerY,n)
            mirrorOut1= np.vstack((x,y))
            if mirrorDriver.MEMS==True:
                mirrorOut=scipy.signal.filtfilt(mirrorDriver.b_filt,mirrorDriver.a_filt,mirrorOut1)           
            else:
                mirrorOut=mirrorOut1    

        # plot mirror commands to GUI 
        pl = appObj.JSOmisc_plot1
        npts = mirrorOut.shape[1]
        t = np.linspace(0, npts/outputRate, npts)
        pl.clear()
        pl.plot(t, mirrorOut[0, :], pen='b')  
        pl.plot(t, mirrorOut[1, :], pen='r')  
        labelStyle = appObj.xLblStyle
        pl.setLabel('bottom', 'Time', 's', **labelStyle)
        labelStyle = appObj.yLblStyle
        pl.setLabel('left', 'Output', 'V', **labelStyle)
    
        pl2=appObj.JSOmisc_plot2
        pl2.clear()
        pl2.plot(mirrorOut[0, :],mirrorOut[1, :], pen='b')
        labelStyle = appObj.xLblStyle
        pl2.setLabel('bottom', 'X galvo', 'V', **labelStyle)
        labelStyle = appObj.yLblStyle
        pl2.setLabel('left', 'Y galvo', 'V', **labelStyle)
     
        if not appObj.oct_hw.IsDAQTestingMode():
            # setup the analog output DAQ device
            daq.setupAnalogOutput(chanNames, trigChan, outputRate, mirrorOut.transpose())        
            daq.startAnalogOutput()
            
            #start trigger and wait for output to finish 
            daq.sendDigTrig(audioHW.daqTrigChanOut)
            daq.waitDoneOutput(timeout=3, stopAndClear=True)
            
            QtGui.QApplication.processEvents() # check for GUI events
        else:
            appObj.doneFlag = True      # just run one time through if in test mode
            appObj.CalibrateScanMirror_pushButton.setChecked(False)
                  
    # when testing is over, set the mirror position to (0,0)
    if not appObj.oct_hw.IsDAQTestingMode():
        chanNames = [mirrorDriver.X_daqChan, mirrorDriver.Y_daqChan]
        data = np.zeros(2)
        daq.writeValues(chanNames, data)
    
    appObj.JSOsaveDispersion_pushButton.setEnabled(False)    
    appObj.JSOloadDispersion_pushButton.setEnabled(True)        
    appObj.isCollecting = False
    appObj.finishCollection()
Пример #18
0
def processData(interpPD, dispData, numklinpts, PDfilterCutoffs, magWin_LPfilterCutoff, pd_background=None, bg_collect=False):
    # scanP = self.scanParams

    numTrigs = interpPD.shape[0]
    numPts = interpPD.shape[1]
    DebugLog.log("Dispersion.processData numTrigs= %d numPts= %d" % (numTrigs, numPts))
    
    pd = np.mean(interpPD, 0)
    dispData.phDiode = pd
    
    winFcn = np.hanning(numklinpts)
    k = np.linspace(0, 1000, numklinpts)

    if bg_collect:
        pd = np.real(interpPD[:, 0:numklinpts])
        pd_background = np.mean(pd, 0)
    
    magWin = np.zeros((numTrigs, numklinpts))
    phaseCorr = np.zeros((numTrigs, numklinpts))
    
    # HP filter to get rid of LF components
    # filterCutoff = procOpts.dispersion_PD_HPfilterCutoff

    # (b, a) = scipy.signal.butter(2, filterCutoff, 'highpass')
    lpfc = PDfilterCutoffs[0]
    hpfc = PDfilterCutoffs[1]
    Wn = [hpfc, lpfc]
    (b, a) = scipy.signal.butter(2, Wn=Wn, btype='bandpass')
    (b2, a2) = scipy.signal.butter(2, 0.4, 'lowpass')
    # subtract background
    sigdata = np.real(interpPD[:, 0:numklinpts])
    if pd_background is not None:
        bg = np.tile(pd_background, (numTrigs, 1))
        sigdata = sigdata - bg
        
    for n in range(0, numTrigs):
        sig = sigdata[n, :]
        #sig = scipy.signal.lfilter(b, a, sig)
        
        # filter signal perfectly by using FFT-IFFT method
        fftsig = np.fft.rfft(sig)
        ln = len(sig)
        # calculate indices in array by multipling by filter cuoffs
        idx0 = np.round(hpfc*ln)
        idx1 = np.round(lpfc*ln)
        if n == 0:
            DebugLog.log("DispersonProtocol.processData() len(sig)= %d len(fftsig)= %d idx0= %d idx1= %d" % (len(sig), len(fftsig), idx0, idx1))
            
        fftsig[0:idx0] = 0
        fftsig[idx1:] = 0
        sig = np.fft.irfft(fftsig, len(sig))
        
        # HP filter to get rid of LF components
        sig_ht = scipy.signal.hilbert(sig)
        
        #mag = np.complex(sig, np.imag(sig_ht))
        mag = np.abs(sig_ht)
        mag0 = mag[0]
        mag = mag - mag0
        mag = scipy.signal.lfilter(b2, a2, mag)
        mag = mag + mag0
#            mag = mag 
        # print("mag.shape= %s winFcn.shape= %s" % (repr(mag.shape), repr(winFcn.shape)))
        magWin[n, :] = winFcn / mag
        # magWin[n, :] = mag 
        
        ph = np.angle(sig_ht)
        ph_unwr = np.unwrap(ph)
        pcof = np.polyfit(k, ph_unwr, 1)
        fity = np.polyval(pcof, k)
        phaseCorr[n, :] = ph_unwr - fity

    magWin = np.mean(magWin, 0)
    
    # low pass filter to get rid of ripple
    filterCutoff = magWin_LPfilterCutoff
    (b, a) = scipy.signal.butter(2, filterCutoff, 'lowpass')
    magWin = scipy.signal.filtfilt(b, a, magWin)
    
    # renomalze to 0...1
    minWin = np.min(magWin)
    maxWin = np.max(magWin)
    magWin = (magWin - minWin)/(maxWin - minWin)
    
    #magWin = magWin[0, :]
    phaseCorr = np.mean(phaseCorr, 0)
            

    dispData.magWin = magWin
    dispData.phaseCorr = phaseCorr
    
    winFcnTile = np.tile(winFcn, numTrigs).reshape(numTrigs, numklinpts)
    
    # make uncorrected aline
    fft_sig_u = np.fft.fft(winFcnTile * sigdata, 2048, 1)
    dispData.uncorrAline = 20*np.log10(np.mean(np.abs(fft_sig_u) + 1, 0))
    
    # make orrected aline
    magWinTile = np.tile(magWin, numTrigs).reshape(numTrigs, numklinpts)
    phaseCorrTile = np.tile(phaseCorr, numTrigs).reshape(numTrigs, numklinpts)
    sigDataComplex = magWinTile * sigdata * (np.cos(-phaseCorrTile) + 1j * np.sin(-phaseCorrTile))
    fft_sig_c = np.fft.fft(sigDataComplex, 2048, 1)
    dispData.corrAline = 20*np.log10(np.mean(np.abs(fft_sig_c) + 1, 0))
    
    dispData.numTrigs = numTrigs
    dispData.numklinpts = numklinpts
    dispData.magWin_LPfilterCutoff = magWin_LPfilterCutoff
    dispData.PDfilterCutoffs = PDfilterCutoffs
    dispData.phDiode_background = pd_background
    
    return dispData
Пример #19
0
    def mousePressEvent(self, mouseEvent): 
        # call super to ensure that mouse events are correctly propogated to items
        QtGui.QGraphicsView.mousePressEvent(self, mouseEvent)
        
        if self._ROIdragMode != ROIImgViewdDragMode.NONE:  
            return  # mouse press event already handled by items

        pt = (mouseEvent.x(), mouseEvent.y())
        qpt = QtCore.QPoint(pt[0], pt[1])
        ptf = self.mapToScene(qpt)
        img_ptf = self.pixMapItem.mapFromScene(ptf)
        img_pt = (int(round(img_ptf.x())), int(round(img_ptf.y())))
        pt = (ptf.x(), ptf.y())
        print("ROIImageGraphicsView.mousePressEvent x= %d y= %d img_pt=%s  button= %s" % (pt[0], pt[1], repr(img_pt), repr(mouseEvent.button())))
        self.buttonPressed = mouseEvent.button()
        if mouseEvent.button() == QtCore.Qt.LeftButton:
            print("    left button");
            
            # hit test on circusors
            self._ROIdragMode = ROIImgViewdDragMode.DRAWROI
        elif mouseEvent.button() ==  QtCore.Qt.RightButton:
            print("    right button");
            self._ROIdragMode = ROIImgViewdDragMode.MOVE
            self.dragLastPt = pt
            self.dragLastPtF = ptf
            self.isMouseDrag = True
            return

        DebugLog.log("ROIImageGraphicsView.mouseMoveEvent: drawtype = %s" % self._ROIdrawType.name)
            
        if self._ROIdrawType == ROIImgViewROIDrawType.BOX:
            self.isMouseDrag = True
            self.ROIBox_pt1 = pt
        elif self._ROIdrawType == ROIImgViewROIDrawType.SINGLE_PT:
            d = self.xhair_d
            x1 = pt[0] - d
            x2 = pt[0] + d
            y1 = pt[1] - d
            y2 = pt[1] + d
            self.xhairItem1.setLine(x1, y1, x2, y2)
            self.xhairItem2.setLine(x1, y2, x2, y1)
            self.singlePt = img_pt
            
            if self.mainOCTObj is not None:
                self.mainOCTObj.mscanSinglePtSet(self.singlePt)
                
        elif self._ROIdrawType == ROIImgViewROIDrawType.MULTI_PT:
            d = self.xhair_d
            
            x1 = pt[0] - d
            x2 = pt[0] + d
            y1 = pt[1] - d
            y2 = pt[1] + d
            
            txtX = pt[0] + 2*d
            txtY = pt[1]
            scene = self.scene()
            pen = self.ptPen
            
            if self.multPtMode == ROIImgViewMultPtMode.NEW:
                xhairItem1 = scene.addLine(x1, y1, x2, y2, pen)
                xhairItem2 = scene.addLine(x1, y2, x2, y1, pen)
                ptNum = len(self.ptsList)
                
                #
                #textItem.textCursor().charFormat().setBackground(brush)
                #textItem.textCursor().blockCharFormat().setForeground(brush)
                #textItem.textCursor().blockCharFormat().setBackground(brush)
        
                #textItem.setZValue(-2)
                #textItem.setDefaultTextColor(clr)

                txtItem = scene.addSimpleText(repr(ptNum + 1), self.ptFont)
                txtItem.setPos(txtX, txtY)
                #txtItem.textCursor().charFormat().setForeground(self.txtBrush)
                #txtItem.textCursor().blockCharFormat().setForeground(self.txtBrush)
                #txtItem.textCursor().charFormat().setBackground(self.txtBrush)
                #txtItem.textCursor().blockCharFormat().setBackground(self.txtBrush)
                txtItem.setBrush(self.txtBrush)
                # txtItem.setDefaultColor(self.txtClr)
                
                self.ptsList.append(img_pt)
                self.multiPt_grItems.append((xhairItem1, xhairItem2, txtItem))
            elif self.multPtMode == ROIImgViewMultPtMode.MOVE:
                ptNum = len(self.ptsList) - 1
                (xhairItem1, xhairItem2, txtItem) = self.multiPt_grItems[ptNum]
                self.ptsList[ptNum] = img_pt
                
                xhairItem1.setLine(x1, y1, x2, y2)
                xhairItem2.setLine(x1, y2, x2, y1)
                txtItem.setPos(txtX, txtY)
                
                self.ptsList[ptNum] = img_pt
                
        elif self._ROIdrawType == ROIImgViewROIDrawType.POLYGON:
            qptf = QtCore.QPointF(pt[0], pt[1])
            if qptf != self.ROI_poly.last():
                scene = self.scene()
                self.ROI_poly.append(qptf)
                scene.removeItem(self.ROI_poly_item)
                self.ROI_poly_item = scene.addPolygon(self.ROI_poly, pen=self.linePen)
                
        elif self._ROIdrawType == ROIImgViewROIDrawType.FREE:
            self.isMouseDrag = True
Пример #20
0
def runSpeakerCal(appObj, testMode=False):
    DebugLog.log("runSpeakerCal")
    appObj.tabWidget.setCurrentIndex(1)
    appObj.doneFlag = False
    appObj.isCollecting = True
    # trigRate = octfpga.GetTriggerRate()
    audioHW = appObj.audioHW
    outputRate = audioHW.DAQOutputRate
    inputRate = audioHW.DAQInputRate
    
    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:
        audioParams = appObj.getAudioParams()
    numSpk = audioParams.getNumSpeakers()
    
    if not testMode:
        from DAQHardware import DAQHardware
        daq = DAQHardware()

    chanNamesIn= [ audioHW.mic_daqChan]
    micVoltsPerPascal = audioHW.micVoltsPerPascal


    spCal = None
    freq_array2 = audioParams.freq[1, :]
    try:
        frameNum = 0
        isSaveDirInit = False
        saveOpts = appObj.getSaveOpts()
        for spkNum in range(0, numSpk):
            chanNameOut = audioHW.speakerL_daqChan 
            attenLines = audioHW.attenL_daqChan
            spkIdx = 0
                
            if (numSpk == 1 and audioParams.speakerSel == Speaker.RIGHT) or spkNum == 2:
                chanNameOut = audioHW.speakerR_daqChan
                attenLines = audioHW.attenR_daqChan
                spkIdx = 1
    
            freq_array = audioParams.freq[spkIdx, :]
            if (audioParams.stimType == AudioStimType.TWO_TONE_DP) and (numSpk == 1):
                freq_array = np.concatenate((freq_array, freq_array2))
                freq_array = np.sort(freq_array)
                freq_array2 = freq_array
                
            if spCal is None:
                spCal = SpeakerCalData(np.vstack((freq_array, freq_array2)))
                
            DebugLog.log("runSpeakerCal freq_array=" + repr(freq_array))
            freq_idx = 0

            attenSig = AudioHardware.makeLM1972AttenSig(0)
            
            if not testMode:
                # daq.sendDigOutCmd(attenLines, attenSig)
                appObj.oct_hw.SetAttenLevel(0, attenLines)
            
            for freq in freq_array:
                DebugLog.log("runSpeakerCal freq=" + repr(freq))
                spkOut = makeSpeakerCalibrationOutput(freq, audioHW, audioParams)    
                npts = len(spkOut)
                t = np.linspace(0, npts/outputRate, npts)
                
                pl = appObj.plot_spkOut
                pl.clear()
                endIdx = int(5e-3 * outputRate)        # only plot first 5 ms
                pl.plot(t[0:endIdx], spkOut[0:endIdx], pen='b')
                        
                numInputSamples = int(inputRate*len(spkOut)/outputRate) 
                
                if testMode:
                    mic_data = OCTCommon.loadRawData(testDataDir, frameNum, dataType=3)                    
                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)
                    
                    mic_data = daq.readAnalogInput()
                    mic_data = mic_data/micVoltsPerPascal

                
                if not testMode:
                    daq.stopAnalogInput()
                    daq.stopAnalogOutput()
                    daq.clearAnalogInput()
                    daq.clearAnalogOutput()
                
                npts = len(mic_data)
                t = np.linspace(0, npts/inputRate, npts)
                pl = appObj.plot_micRaw
                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)
                
                micData, spCal = processSpkCalData(mic_data, freq*1000, freq_idx, audioParams, inputRate, spCal, spkIdx)
                
                pl = appObj.plot_micFFT
                pl.clear()
                df = micData.fft_freq[1] - micData.fft_freq[0]
                nf = len(micData.fft_freq)
                i1 = int(1000*freq_array[0]*0.9/df)
                i2 = int(1000*freq_array[-1]*1.1/df)
                DebugLog.log("SpeakerCalibration: df= %0.3f i1= %d i2= %d nf= %d" % (df, i1, i2, nf))
                pl.plot(micData.fft_freq[i1:i2], micData.fft_mag[i1:i2], pen='b')
                labelStyle = appObj.xLblStyle
                pl.setLabel('bottom', 'Frequency', 'Hz', **labelStyle)
                labelStyle = appObj.yLblStyle
                pl.setLabel('left', 'Magnitude', 'db SPL', **labelStyle)
                
                pl = appObj.plot_micMagResp
                pl.clear()
#                pl.plot(1000*spCal.freq[spkIdx, :], spCal.magResp[spkIdx, :], pen="b", symbol='o')
                pl.plot(freq_array, spCal.magResp[spkIdx, :], pen="b", symbol='o')
                labelStyle = appObj.xLblStyle
                pl.setLabel('bottom', 'Frequency', 'Hz', **labelStyle)
                labelStyle = appObj.yLblStyle
                pl.setLabel('left', 'Magnitude', 'db SPL', **labelStyle)
                
                freq_idx += 1
                
                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)
                    
                QtGui.QApplication.processEvents() # check for GUI events, such as button presses
                
                # if done flag, break out of loop
                if appObj.doneFlag:
                    break
                
                frameNum += 1

                
            # if done flag, break out of loop
            if appObj.doneFlag:
                break
                
        if not appObj.doneFlag:
            saveDir = appObj.settingsPath
            saveSpeakerCal(spCal, saveDir)
            appObj.audioHW.loadSpeakerCalFromProcData(spCal)
            appObj.spCal = spCal            
            
    except Exception as ex:
        traceback.print_exc(file=sys.stdout)
        QtGui.QMessageBox.critical (appObj, "Error", "Error during scan. 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()


    
Пример #21
0
Created on Wed Oct  7 16:27:38 2015

@author: OHNS
"""

import numpy as np

from DebugLog import DebugLog
from ctypes import byref
import time

# Patrick, please make this conditional... it won't work on my Mac
try:
    import PyDAQmx as daqmx
except ImportError:
    DebugLog.log("DAQHardware.py: could not import PyDAQmx module - DAQ hardware I/O will not work!!!")

class DAQHardware:
    def __init__(self):
        highSamples = 1000
        numpts = 3 * highSamples
        #dn = 100000
        doData = np.zeros((numpts,), dtype=np.uint32)
        doData[highSamples:2*highSamples] =  2**32 - 1
        self.doTrigData = doData
        
        
    # write single value to maultiple channels 
    def writeValues(self, chanNames, data):
        DebugLog.log("DAQhardware.writeValue(): chanNames= %s val= %s" % (repr(chanNames), repr(data)))
        
Пример #22
0
def runDispersion(appObj):
    DebugLog.log("runDispersion")
    appObj.tabWidget.setCurrentIndex(5)
    appObj.doneFlag = False
    appObj.isCollecting = True
    # trigRate = octfpga.GetTriggerRate()
    mirrorDriver = appObj.mirrorDriver
    
    # set the mirror position to (0,0)
    chanNames = [mirrorDriver.X_daqChan, mirrorDriver.Y_daqChan]
    data = np.zeros(2)
    if not appObj.oct_hw.IsDAQTestingMode():
        from DAQHardware import DAQHardware
        daq = DAQHardware()
        daq.writeValues(chanNames, data)
    
    pd_background = None
    
    fpgaOpts = appObj.oct_hw.fpgaOpts
    numklinpts = fpgaOpts.numKlinPts
    if fpgaOpts.InterpDownsample > 0:
        numklinpts =  numklinpts // 2
    
    # keep looping until we are signlaed to stop by GUI (flag set in appObj)
    try:
        frameNum = 0
        saveDirInit = False
        testDataDir = os.path.join(appObj.basePath, 'exampledata', 'Dispersion')
        dispData = DispersionData(fpgaOpts)
        klin = None # initialze klin to None so it will be computed first iteration
        savedFPGADisp = False
        
        while not appObj.doneFlag: 
            # setup and grab the OCT data - this will also fire the mirror output
            numTrigs = appObj.disp_numTrigs_spinBox.value()
            processMode = OCTCommon.ProcessMode(appObj.processMode_comboBox.currentIndex())
                
            # get proessing optiosn from GUI        
            PD_LP_fc = appObj.disp_pd_lpfilter_cutoff_dblSpinBox.value()
            PD_HP_fc = appObj.disp_pd_hpfilter_cutoff_dblSpinBox.value()
            PDfiltCutoffs = [PD_LP_fc, PD_HP_fc]
            magWin_LPfilterCutoff = appObj.disp_magwin_lpfilter_cutoff_dblSpinBox.value()
            
            dispData.mziFilter = appObj.mziFilter.value()
            dispData.magWin_LPfilterCutoff = magWin_LPfilterCutoff
            dispData.PDfilterCutoffs = PDfiltCutoffs
            
            collectBG = appObj.disp_collectBG_pushButton.isChecked()
            
            pd_background = dispData.phDiode_background                
    
            if processMode == OCTCommon.ProcessMode.FPGA:
                if appObj.oct_hw.IsOCTTestingMode():
                    pd_data = OCTCommon.loadRawData(testDataDir, frameNum % 19, dataType=1)
                    numklinpts = 1400
                else:
                    err, pd_data = appObj.oct_hw.AcquireOCTDataInterpPD(numTrigs)
                    DebugLog.log("runDispersion(): AcquireOCTDataInterpPD() err = %d" % err)
                    # process the data
                dispData = processData(pd_data, dispData, numklinpts, PDfiltCutoffs, magWin_LPfilterCutoff, pd_background, collectBG)

            elif processMode == OCTCommon.ProcessMode.SOFTWARE:
                if appObj.oct_hw.IsOCTTestingMode():
                    ch0_data,ch1_data=JSOraw.getSavedRawData(numTrigs,appObj.dispData.requestedSamplesPerTrig,appObj.savedDataBuffer)
                else:
                    # def AcquireOCTDataRaw(self, numTriggers, samplesPerTrig=-1, Ch0Shift=-1, startTrigOffset=0):
                    samplesPerTrig = fpgaOpts.SamplesPerTrig*2 + fpgaOpts.Ch0Shift*2
                    err, ch0_data,ch1_data = appObj.oct_hw.AcquireOCTDataRaw(numTrigs, samplesPerTrig)

                pdData,mziData,actualSamplesPerTrig = JSOraw.channelShift(ch0_data,ch1_data,dispData)    # shift the two channels to account for delays in the sample data compared to the MZI data 
                mzi_hilbert, mzi_mag, mzi_ph, k0 = JSOraw.processMZI(mziData, dispData)                # calculate k0 from the phase of the MZI data
                k0Cleaned = JSOraw.cleank0(k0, dispData) # Adjust the k0 curves so that the unwrapping all starts at the same phase    
                pd_data, klin = JSOraw.processPD(pdData, k0Cleaned, dispData, klin)  # Interpolate the PD data based upon the MZI data
                dispData.Klin = klin
                dispData = processUniqueDispersion(pd_data, dispData, pd_background, collectBG)
            else:
                QtGui.QMessageBox.critical (appObj, "Error", "Unsuppoted processing mode for current hardware")
                
            # plot the data
            plotDispData(appObj, dispData, PDfiltCutoffs)
            
            if appObj.getSaveState():
                dispFilePath = saveDispersionData(dispData, appObj.settingsPath)
            
                saveOpts = appObj.getSaveOpts()
                if saveOpts.saveRaw:
                    if not saveDirInit:
                        saveDir = OCTCommon.initSaveDir(saveOpts, 'Dispersion')
                        saveDirInit = True
                    
                    OCTCommon.saveRawData(pd_data, saveDir, frameNum, dataType=1)
                if processMode == OCTCommon.ProcessMode.FPGA:
                    appObj.dispDataFPGA = dispData
                    dispFilePathFPGA = dispFilePath
                    savedFPGADisp = True
                else:
                    appObj.dispData = dispData
                
            frameNum += 1
            QtGui.QApplication.processEvents() # check for GUI events, particularly the "done" flag
            
        if savedFPGADisp:
            DebugLog.log("runDispersion(): loading dispersion file into FPGA")
            appObj.loadDispersionIntoFPGA(dispFilePathFPGA, appObj.oct_hw.fpgaOpts)
            
    except Exception as ex:
        # raise ex
        traceback.print_exc(file=sys.stdout)
        QtGui.QMessageBox.critical (appObj, "Error", "Error during scan. Check command line output for details")
    finally:
        appObj.isCollecting = False
        QtGui.QApplication.processEvents() # check for GUI events
        appObj.finishCollection()        
Пример #23
0
def runSpeakerCalTest(appObj):
    DebugLog.log("runSpeakerCal")
    appObj.tabWidget.setCurrentIndex(1)
    appObj.doneFlag = False
    appObj.isCollecting = True
    # trigRate = octfpga.GetTriggerRate()
    audioHW = appObj.audioHW
    outputRate = audioHW.DAQOutputRate
    inputRate = audioHW.DAQInputRate

    audioParams = appObj.getAudioParams()
    numSpk = audioParams.getNumSpeakers()
    daq = DAQHardware()
    chanNamesIn = [audioHW.mic_daqChan]
    micVoltsPerPascal = audioHW.micVoltsPerPascal

    # spCal = SpeakerCalData(audioParams)
    try:
        testMode = appObj.oct_hw.IsDAQTestingMode()
        frameNum = 0
        isSaveDirInit = False
        saveOpts = appObj.getSaveOpts()

        if audioParams.speakerSel == Speaker.LEFT:
            chanNameOut = audioHW.speakerL_daqChan
            attenLines = audioHW.attenL_daqChan
            spkIdx = 0
        else:
            chanNameOut = audioHW.speakerR_daqChan
            attenLines = audioHW.attenR_daqChan
            spkIdx = 1

        freq_array = audioParams.freq[spkIdx, :]
        if (audioParams.stimType == AudioStimType.TWO_TONE_DP) and (numSpk == 1):
            freq2 = audioParams.freq[1, :]
            freq_array = np.concatenate((freq_array, freq2))
            freq_array = np.sort(freq_array)

        DebugLog.log("freq_array=" + repr(freq_array))
        amp_array = audioParams.amp
        numAmp = len(amp_array)
        numFreq = len(freq_array)
        magResp = np.zeros((numFreq, numAmp))
        magResp[:, :] = np.nan
        phaseResp = np.zeros((numFreq, numAmp))
        phaseResp[:, :] = np.nan
        THD = np.zeros((numFreq, numAmp))
        THD[:, :] = np.nan

        for freq_idx in range(0, numFreq):
            for amp_idx in range(0, numAmp):
                freq = freq_array[freq_idx]
                amp = amp_array[amp_idx]

                spkOut, attenLvl = makeSpkCalTestOutput(freq, amp, audioHW, audioParams, spkIdx)
                DebugLog.log("runSpeakerCalTest freq= %0.3f kHz amp= %d attenLvl= %d" % (freq, amp, attenLvl))

                if spkOut is None:
                    DebugLog.log("runSpeakerCalTest freq= %0.3f kHz cannot output %d dB" % (freq, amp))
                    frameNum = frameNum + 1
                    continue

                npts = len(spkOut)
                t = np.linspace(0, npts / outputRate, npts)

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

                attenSig = AudioHardware.makeLM1972AttenSig(attenLvl)
                numInputSamples = int(inputRate * len(spkOut) / outputRate)

                if not testMode:
                    # daq.sendDigOutCmd(attenLines, attenSig)
                    appObj.oct_hw.SetAttenLevel(attenLvl, attenLines)

                    # 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)

                    mic_data = daq.readAnalogInput()
                    mic_data = mic_data / micVoltsPerPascal

                    daq.waitDoneInput()
                    daq.waitDoneOutput()
                    daq.stopAnalogInput()
                    daq.stopAnalogOutput()
                    daq.clearAnalogInput()
                    daq.clearAnalogOutput()
                else:
                    mic_data = GetTestData(frameNum)

                npts = len(mic_data)
                t = np.linspace(0, npts / inputRate, npts)
                pl = appObj.plot_micRaw
                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)

                micData, magResp, phaseResp, THD = processSpkCalTestData(
                    mic_data, freq * 1000, freq_idx, amp_idx, audioParams, inputRate, magResp, phaseResp, THD
                )

                pl = appObj.plot_micFFT
                pl.clear()
                df = micData.fft_freq[1] - micData.fft_freq[0]
                nf = len(micData.fft_freq)
                i1 = int(1000 * freq_array[0] * 0.9 / df)
                i2 = int(1000 * freq_array[-1] * 1.1 / df)
                DebugLog.log("SpeakerCalibration: df= %0.3f i1= %d i2= %d nf= %d" % (df, i1, i2, nf))
                pl.plot(micData.fft_freq[i1:i2], micData.fft_mag[i1:i2], pen="b")
                labelStyle = appObj.xLblStyle
                pl.setLabel("bottom", "Frequency", "Hz", **labelStyle)
                labelStyle = appObj.yLblStyle
                pl.setLabel("left", "Magnitude", "db SPL", **labelStyle)

                pl = appObj.plot_micMagResp
                pl.clear()

                for a_idx in range(0, numAmp):
                    pen = (a_idx, numAmp)
                    pl.plot(1000 * freq_array, magResp[:, a_idx], pen=pen, symbol="o")

                labelStyle = appObj.xLblStyle
                pl.setLabel("bottom", "Frequency", "Hz", **labelStyle)
                labelStyle = appObj.yLblStyle
                pl.setLabel("left", "Magnitude", "db SPL", **labelStyle)

                pl = appObj.plot_speakerDistortion
                pl.clear()

                for a_idx in range(0, numAmp):
                    pen = (a_idx, numAmp)
                    pl.plot(1000 * freq_array, THD[:, a_idx], pen=pen, symbol="o")

                labelStyle = appObj.xLblStyle
                pl.setLabel("bottom", "Frequency", "Hz", **labelStyle)
                labelStyle = appObj.yLblStyle
                pl.setLabel("left", "Magnitude", "db SPL", **labelStyle)

                if appObj.getSaveState():
                    if not isSaveDirInit:
                        saveDir = OCTCommon.initSaveDir(saveOpts, "Speaker Cal Test", audioParams=audioParams)
                        isSaveDirInit = True

                    if saveOpts.saveRaw:
                        OCTCommon.saveRawData(mic_data, saveDir, frameNum, dataType=3)

                frameNum = frameNum + 1

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

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

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

    except Exception as ex:
        traceback.print_exc(file=sys.stdout)
        QtGui.QMessageBox.critical(appObj, "Error", "Error during scan. 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()
Пример #24
0
def runAOTest(daqHW,):
    chanNames = ['Dev1/ao0', 'Dev1/ao3']    
    chanNames = ['PXI1Slot2/ao0', 'PXI1Slot2/ao1']    

    data = np.zeros(2)
    daqHW.writeValues(chanNames, data)
    
    outputRate = 200000
    amp=1
    amp2 = amp/2
    outT = 100e-3
    npts = int(outputRate*outT)
    t = np.linspace(0, outT, npts)
    freq = 2000
    freq2 = freq*2
    cmd_x = amp*np.sin(2*np.pi*freq*t)
    cmd_y = amp2*np.sin(2*np.pi*freq2*t)
    
#    plt.figure(1);
#    plt.clf()
#    plt.plot(cmd_x, '-r')
#    plt.plot(cmd_y, '-b')
#    plt.show()
#    plt.draw()
    
    outData = np.vstack((cmd_x, cmd_y))
    #outData = cmd_x
    trigChan = '/Dev1/PFI0'
    trigOutLine = 'Dev1/port0/line0'
    chanName = chanNames[1]
    
#    numSamples = npts
#    samplesWritten = daqmx.int32()
#    analog_output = daqmx.Task()
#    outData = np.require(outData, np.float, ['C', 'W'])

#    analog_output.CreateAOVoltageChan(chanName,"",-10.0,10.0, daqmx.DAQmx_Val_Volts, None)
    #for chanName in chanNames:
    #    analog_output.CreateAOVoltageChan(chanName,"",-10.0,10.0, daqmx.DAQmx_Val_Volts, None)
#    analog_output.CfgSampClkTiming("",outputRate, daqmx.DAQmx_Val_Rising, daqmx.DAQmx_Val_FiniteSamps, numSamples)
#    analog_output.CfgDigEdgeStartTrig(trigChan, daqmx.DAQmx_Val_Rising) 
#    analog_output.WriteAnalogF64(numSampsPerChan=numSamples, autoStart=False,timeout=3.0, dataLayout=daqmx.DAQmx_Val_GroupByChannel, writeArray=outData, reserved=None, sampsPerChanWritten=byref(samplesWritten))

    dataOut = copy.copy(outData)
    daqHW.setupAnalogOutput(chanNames, trigChan, outputRate, dataOut.transpose())
    for n in range(0, 20):
        daqHW.startAnalogOutput()
        print("n= ", n)
        #nalog_output.StartTask()
        daqHW.sendDigTrig(trigOutLine)
        
        # wait unti output is finsihed and clean up tasks
        err = daqHW.waitDoneOutput(3)
        if err < 0:
            DebugLog.log("waitDoneOutput() err = %s" % repr(err))
        
        daqHW.stopAnalogOutput()
#        isDone = False
#        isDoneP = daqmx.c_ulong()
#        while not isDone:
#            err = analog_output.IsTaskDone(byref(isDoneP))
#            isDone = isDoneP.value != 0
#            
#        analog_output.StopTask()
        time.sleep(0.1)
        
#    analog_output.ClearTask()
    daqHW.clearAnalogOutput()
Пример #25
0
def processSpkCalTestData(mic_data, freq, freq_idx, amp_idx, audioParams, inputRate, magRespIn, phaseRespIn, THDIn):
    # print("SpeakerCalProtocol: processData: mic_data=" + repr(mic_data))
    # ensure data is 1D
    if len(mic_data.shape) > 1:
        mic_data = mic_data[:, 0]

    numpts = len(mic_data)
    DebugLog.log("SpeakerCalProtocol: processData: numpts= %d" % (numpts))

    t = np.linspace(0, numpts / inputRate, numpts)
    zero_pad_factor = 2
    numfftpts = numpts * zero_pad_factor
    winfcn = np.hanning(numpts)
    mic_fft = np.fft.fft(winfcn * mic_data, numfftpts)
    endIdx = np.ceil(numfftpts / 2)
    mic_fft = mic_fft[0:endIdx]
    mic_fft_mag = 2 * np.abs(mic_fft)

    # convert to dB, correctting for RMS and FFT length
    fftrms_corr = 2 / (numpts * np.sqrt(2))
    mic_fft_mag = fftrms_corr * mic_fft_mag  # 20e-6 pa
    mic_fft_mag_log = 20 * np.log10(mic_fft_mag / 20e-6)

    mic_fft_phase = np.angle(mic_fft)
    mic_freq = np.linspace(0, inputRate / 2, endIdx)
    fIdx = int(np.floor(freq * numfftpts / inputRate))
    DebugLog.log("SpeakerCalibration: processData: freq= %f fIdx= %d" % (freq, fIdx))

    stim_freq_mag = np.NAN
    stim_freq_phase = np.NAN

    try:
        npts = zero_pad_factor
        mag_rgn = mic_fft_mag_log[fIdx - npts : fIdx + npts]
        phase_rgn = mic_fft_phase[fIdx - npts : fIdx + npts]
        maxIdx = np.argmax(mag_rgn)
        stim_freq_mag = mag_rgn[maxIdx]
        stim_freq_phase = phase_rgn[maxIdx]

        mag_rgn = mic_fft_mag[fIdx - npts : fIdx + npts]
        stim_freq_mag_pa = mag_rgn[maxIdx]
    except Exception as ex:
        # DebugLog.log(ex)
        traceback.print_exc(file=sys.stdout)

    thd = 0
    try:
        nmax = int(np.floor((inputRate / 2) / freq))
        npts = zero_pad_factor
        #        for n in range(2, nmax+1):
        #            fIdx = int(np.floor(freq*n*numfftpts/inputRate))
        #
        #            mag_rgn = mic_fft_mag[fIdx-npts:fIdx+npts]
        #            maxIdx = np.argmax(mag_rgn)
        #            resp = mag_rgn[maxIdx]
        #
        #            idx1= fIdx+npts+2
        #            idx2 = fIdx+npts+82
        #            noise_rgn = mic_fft_mag[fIdx-npts:fIdx+npts]
        #            noise_mean = np.mean(noise_rgn)
        #            noise_std = np.std(noise_rgn)
        #            noise_lvl = noise_mean + 2*noise_std
        #            print("n= ", n, " resp= ", resp, " noise_lvl= ", noise_lvl)
        #            if resp > noise_lvl:
        #                thd += (resp**2)

        # print("sum distortions= ", thd, " stim_freq_mag_pa= ", stim_freq_mag_pa)
        # thd = (thd ** 0.5)/stim_freq_mag
        fIdx1 = int(np.floor(freq * 2 * numfftpts / inputRate))
        fIdx2 = int(np.floor((freq / 2) * numfftpts / inputRate))

        mag_rgn1 = mic_fft_mag_log[fIdx1 - npts : fIdx1 + npts]
        mag_rgn2 = mic_fft_mag_log[fIdx2 - npts : fIdx2 + npts]

        maxIdx1 = np.argmax(mag_rgn1)
        maxIdx2 = np.argmax(mag_rgn2)

        resp1 = mag_rgn1[maxIdx1]
        resp2 = mag_rgn2[maxIdx2]
        # thd = max((resp1, resp2))
        thd = resp2
        print("thd= ", thd)
    #        if thd > 0:
    #            thd = 20*np.log10(thd)  # convert to dB
    #        else:
    #            thd = np.nan
    #        print("20*log10(thd/20e-6)= ", thd)
    except Exception as ex:
        # DebugLog.log(ex)
        traceback.print_exc(file=sys.stdout)

    DebugLog.log(
        "SpeakerCalibration: processData: stim_freq_mag= %f stim_freq_phase= %f" % (stim_freq_mag, stim_freq_phase)
    )
    micData = SpeakerCalibration.MicData()
    micData.raw = mic_data
    micData.t = t
    micData.fft_mag = mic_fft_mag_log
    micData.fft_phase = mic_fft_phase
    micData.fft_freq = mic_freq
    micData.stim_freq_mag = stim_freq_mag
    micData.stim_freq_phase = stim_freq_phase
    micData.thd = thd

    magRespIn[freq_idx, amp_idx] = stim_freq_mag
    phaseRespIn[freq_idx, amp_idx] = stim_freq_phase
    THDIn[freq_idx, amp_idx] = thd

    return micData, magRespIn, phaseRespIn, THDIn
Пример #26
0
def processUniqueDispersion(pd_data, dispData, pd_background=None, bg_collect=False):
    numTrigs = pd_data.shape[0]
    numklinpts = pd_data.shape[1]
    DebugLog.log("Dispersion.processUniqueDispersion: numklinpts= %d" % numklinpts)
    winFcn = np.hanning(numklinpts)

    pd = np.mean(pd_data, 0)
    dispData.phDiode = pd
    
    if bg_collect:
        pd = np.real(pd_data[:, 0:numklinpts])
        pd_background = np.mean(pd, 0)
    
    
    magWin = np.zeros((numTrigs, numklinpts))
    phaseCorr = np.zeros((numTrigs, numklinpts))
    
    # set up filter coefficients
    idx0 = np.round(dispData.PDfilterCutoffs[1]*numklinpts)
    idx1 = np.round(dispData.PDfilterCutoffs[0]*numklinpts)            
    (b, a) = scipy.signal.butter(2, dispData.magWin_LPfilterCutoff, 'lowpass')
    
    # subtract background
    sigdata = np.real(pd_data[:, 0:numklinpts])
    if pd_background is not None:
        bg = np.tile(pd_background, (numTrigs, 1))
        sigdata = sigdata - bg
        
    for n in range(0, numTrigs):
        sig = sigdata[n, :]
        
        # first filter the interferograph using an ideal filter with the FFT-IFFT method
        fftsig = np.fft.rfft(sig)
        fftsig[0:idx0] = 0
        fftsig[idx1:] = 0
        sig = np.fft.irfft(fftsig, len(sig))
        
        """
        Hilbert Transform
        A perfect reflector like a mirror should make the interferogram like a
        sine wave. The phase of the Hilbert Transform of a sine wave should be
        a linear ramp. Any deviation from this must therefore be from dispersion.
        """
        sig_ht = scipy.signal.hilbert(sig)
        mag = np.abs(sig_ht)
        magWin[n, :] = winFcn / mag       
        ph = np.angle(sig_ht)
        ph_unwr = np.unwrap(ph)
        phaseCorr[n, :] = scipy.signal.detrend(ph_unwr)

    
    magWin = np.mean(magWin, 0)
    magWin = scipy.signal.lfilter(b, a, magWin)
    minWin = np.min(magWin)
    maxWin = np.max(magWin)
    dispData.magWin = (magWin - minWin)/(maxWin - minWin)
    phaseCorr = np.mean(phaseCorr, 0)
    dispData.phaseCorr = phaseCorr
    dispData.phDiode_background = pd_background
    
    winFcnTile = np.tile(winFcn, numTrigs).reshape(numTrigs, numklinpts)
    
    # make uncorrected aline
    fft_sig_u = np.fft.fft(winFcnTile * sigdata, 2048, 1)
    dispData.uncorrAline = 20*np.log10(np.mean(np.abs(fft_sig_u) + 1, 0))
    
    DebugLog.log("Dispersion.processUniqueDispersion: len(ph_unwr)= %d phaseCorr.shape= %s" % (len(ph_unwr), repr(phaseCorr.shape)))
    DebugLog.log("Dispersion.processUniqueDispersion: magWin.shape= %s" % repr(magWin.shape))


    # make orrected aline
    magWinTile = np.tile(magWin, numTrigs).reshape(numTrigs, numklinpts)
    phaseCorrTile = np.tile(phaseCorr, numTrigs).reshape(numTrigs, numklinpts)
    sigDataComplex = magWinTile * sigdata * (np.cos(-phaseCorrTile) + 1j * np.sin(-phaseCorrTile))
    fft_sig_c = np.fft.fft(sigDataComplex, 2048, 1)
    dispData.corrAline = 20*np.log10(np.mean(np.abs(fft_sig_c) + 1, 0))
    
    return dispData